Files
diegosouzapw--omniroute/tests/unit/custom-endpoint-system-prompt.test.ts
2026-07-13 13:39:12 +08:00

157 lines
6.3 KiB
TypeScript

/**
* TDD test for per-endpoint custom system prompt injection (port of upstream #2063).
*
* Validates that injectCustomSystemPrompt():
* - Appends the custom prompt to an existing system message (string content)
* - Appends the custom prompt to an existing system message (array content)
* - Creates a new system message when none exists
* - Injects into Claude-style `system` field (string)
* - Injects into Claude-style `system` field (array)
* - Does NOT inject when prompt is empty string
* - Does NOT inject when body has _skipSystemPrompt flag
* - Leaves body unchanged when prompt is falsy
*
* Also validates settings defaults include customSystemPromptEnabled / customSystemPrompt.
*/
import test from "node:test";
import assert from "node:assert/strict";
const { injectCustomSystemPrompt } = await import(
"../../open-sse/services/systemPrompt.ts"
);
// ─── injectCustomSystemPrompt ────────────────────────────────────────────────
test("injectCustomSystemPrompt: appends to existing string system message", () => {
const body = {
messages: [
{ role: "system", content: "You are a helpful assistant." },
{ role: "user", content: "Hello" },
],
};
const result = injectCustomSystemPrompt(body, "Always respond formally.");
const sysMsg = result.messages.find((m) => m.role === "system");
assert.ok(sysMsg, "system message must exist");
assert.ok(
typeof sysMsg.content === "string" && sysMsg.content.includes("You are a helpful assistant."),
"original content preserved"
);
assert.ok(
typeof sysMsg.content === "string" && sysMsg.content.includes("Always respond formally."),
"custom prompt appended"
);
});
test("injectCustomSystemPrompt: appends to existing array-content system message", () => {
const body = {
messages: [
{ role: "system", content: [{ type: "text", text: "Base instructions." }] },
{ role: "user", content: "Hi" },
],
};
const result = injectCustomSystemPrompt(body, "Speak like a pirate.");
const sysMsg = result.messages.find((m) => m.role === "system");
assert.ok(sysMsg, "system message must exist");
assert.ok(Array.isArray(sysMsg.content), "content must remain array");
const texts = (sysMsg.content as Array<{ type: string; text: string }>).map((c) => c.text);
assert.ok(texts.includes("Base instructions."), "original block preserved");
assert.ok(texts.includes("Speak like a pirate."), "custom prompt block appended");
});
test("injectCustomSystemPrompt: creates system message when none exists", () => {
const body = {
messages: [{ role: "user", content: "What is 2+2?" }],
};
const result = injectCustomSystemPrompt(body, "Think step by step.");
assert.equal(result.messages[0].role, "system", "system message prepended");
assert.equal(result.messages[0].content, "Think step by step.", "prompt is the content");
assert.equal(result.messages[1].role, "user", "user message preserved after system");
});
test("injectCustomSystemPrompt: injects into Claude-style string system field", () => {
const body = {
system: "You are Claude.",
messages: [{ role: "user", content: "Hello" }],
};
const result = injectCustomSystemPrompt(body, "Be concise.");
assert.ok(typeof result.system === "string", "system field still a string");
assert.ok(result.system.includes("You are Claude."), "original system preserved");
assert.ok(result.system.includes("Be concise."), "custom prompt appended to system");
});
test("injectCustomSystemPrompt: injects into Claude-style array system field", () => {
const body = {
system: [{ type: "text", text: "You are Claude." }],
messages: [{ role: "user", content: "Hello" }],
};
const result = injectCustomSystemPrompt(body, "Be concise.");
assert.ok(Array.isArray(result.system), "system field still an array");
const texts = (result.system as Array<{ type: string; text: string }>).map((c) => c.text);
assert.ok(texts.includes("You are Claude."), "original system block preserved");
assert.ok(texts.includes("Be concise."), "custom prompt block appended");
});
test("injectCustomSystemPrompt: no-op when prompt is empty string", () => {
const body = {
messages: [{ role: "user", content: "Hello" }],
};
const result = injectCustomSystemPrompt(body, "");
assert.deepEqual(result, body, "body unchanged when prompt is empty");
});
test("injectCustomSystemPrompt: no-op when body has _skipSystemPrompt flag", () => {
const body = {
_skipSystemPrompt: true,
messages: [{ role: "user", content: "Hello" }],
};
const result = injectCustomSystemPrompt(body as Record<string, unknown>, "Be formal.");
assert.deepEqual(result, body, "body unchanged when _skipSystemPrompt is set");
});
test("injectCustomSystemPrompt: does not mutate input body (immutable)", () => {
const body = {
messages: [
{ role: "system", content: "Original." },
{ role: "user", content: "Hi" },
],
};
const original = JSON.stringify(body);
injectCustomSystemPrompt(body, "New instruction.");
assert.equal(JSON.stringify(body), original, "input body not mutated");
});
// ─── Settings defaults ───────────────────────────────────────────────────────
// Verify that getSettings() returns the expected defaults for the new keys.
// Uses an in-memory DB (DATA_DIR set to a temp path so no production DB is touched).
import { tmpdir } from "node:os";
import { join } from "node:path";
import { mkdirSync } from "node:fs";
const tmpDir = join(tmpdir(), `omniroute-test-${Date.now()}`);
mkdirSync(tmpDir, { recursive: true });
process.env["DATA_DIR"] = tmpDir;
test("settings defaults include customSystemPromptEnabled=false and customSystemPrompt=''", async (t) => {
// Dynamic import after setting DATA_DIR to avoid polluting other tests
const { resetDbInstance } = await import("../../src/lib/db/core.ts");
const { getSettings } = await import("../../src/lib/db/settings.ts");
const settings = await getSettings();
assert.equal(
settings.customSystemPromptEnabled,
false,
"customSystemPromptEnabled default is false"
);
assert.equal(
settings.customSystemPrompt,
"",
"customSystemPrompt default is empty string"
);
t.after(() => {
resetDbInstance();
});
});