test: cover gateway legacy auto-migrate
This commit is contained in:
@@ -130,6 +130,11 @@ let testGatewayBind: "auto" | "lan" | "tailnet" | "loopback" | undefined;
|
|||||||
let testGatewayAuth: Record<string, unknown> | undefined;
|
let testGatewayAuth: Record<string, unknown> | undefined;
|
||||||
let testHooksConfig: Record<string, unknown> | undefined;
|
let testHooksConfig: Record<string, unknown> | undefined;
|
||||||
let testCanvasHostPort: number | undefined;
|
let testCanvasHostPort: number | undefined;
|
||||||
|
let testLegacyIssues: Array<{ path: string; message: string }> = [];
|
||||||
|
let testLegacyParsed: Record<string, unknown> = {};
|
||||||
|
let testMigrationConfig: Record<string, unknown> | null = null;
|
||||||
|
let testMigrationChanges: string[] = [];
|
||||||
|
let testIsNixMode = false;
|
||||||
const sessionStoreSaveDelayMs = vi.hoisted(() => ({ value: 0 }));
|
const sessionStoreSaveDelayMs = vi.hoisted(() => ({ value: 0 }));
|
||||||
vi.mock("../config/sessions.js", async () => {
|
vi.mock("../config/sessions.js", async () => {
|
||||||
const actual = await vi.importActual<typeof import("../config/sessions.js")>(
|
const actual = await vi.importActual<typeof import("../config/sessions.js")>(
|
||||||
@@ -151,6 +156,21 @@ vi.mock("../config/config.js", () => {
|
|||||||
path.join(os.homedir(), ".clawdis", "clawdis.json");
|
path.join(os.homedir(), ".clawdis", "clawdis.json");
|
||||||
|
|
||||||
const readConfigFileSnapshot = async () => {
|
const readConfigFileSnapshot = async () => {
|
||||||
|
if (testLegacyIssues.length > 0) {
|
||||||
|
return {
|
||||||
|
path: resolveConfigPath(),
|
||||||
|
exists: true,
|
||||||
|
raw: JSON.stringify(testLegacyParsed ?? {}),
|
||||||
|
parsed: testLegacyParsed ?? {},
|
||||||
|
valid: false,
|
||||||
|
config: {},
|
||||||
|
issues: testLegacyIssues.map((issue) => ({
|
||||||
|
path: issue.path,
|
||||||
|
message: issue.message,
|
||||||
|
})),
|
||||||
|
legacyIssues: testLegacyIssues,
|
||||||
|
};
|
||||||
|
}
|
||||||
const configPath = resolveConfigPath();
|
const configPath = resolveConfigPath();
|
||||||
try {
|
try {
|
||||||
await fs.access(configPath);
|
await fs.access(configPath);
|
||||||
@@ -193,20 +213,20 @@ vi.mock("../config/config.js", () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const writeConfigFile = async (cfg: Record<string, unknown>) => {
|
const writeConfigFile = vi.fn(async (cfg: Record<string, unknown>) => {
|
||||||
const configPath = resolveConfigPath();
|
const configPath = resolveConfigPath();
|
||||||
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
||||||
const raw = JSON.stringify(cfg, null, 2).trimEnd().concat("\n");
|
const raw = JSON.stringify(cfg, null, 2).trimEnd().concat("\n");
|
||||||
await fs.writeFile(configPath, raw, "utf-8");
|
await fs.writeFile(configPath, raw, "utf-8");
|
||||||
};
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
CONFIG_PATH_CLAWDIS: resolveConfigPath(),
|
CONFIG_PATH_CLAWDIS: resolveConfigPath(),
|
||||||
STATE_DIR_CLAWDIS: path.dirname(resolveConfigPath()),
|
STATE_DIR_CLAWDIS: path.dirname(resolveConfigPath()),
|
||||||
isNixMode: false,
|
isNixMode: testIsNixMode,
|
||||||
migrateLegacyConfig: (raw: unknown) => ({
|
migrateLegacyConfig: (raw: unknown) => ({
|
||||||
config: raw as Record<string, unknown>,
|
config: testMigrationConfig ?? (raw as Record<string, unknown>),
|
||||||
changes: [],
|
changes: testMigrationChanges,
|
||||||
}),
|
}),
|
||||||
loadConfig: () => ({
|
loadConfig: () => ({
|
||||||
agent: {
|
agent: {
|
||||||
@@ -286,6 +306,11 @@ beforeEach(async () => {
|
|||||||
testGatewayAuth = undefined;
|
testGatewayAuth = undefined;
|
||||||
testHooksConfig = undefined;
|
testHooksConfig = undefined;
|
||||||
testCanvasHostPort = undefined;
|
testCanvasHostPort = undefined;
|
||||||
|
testLegacyIssues = [];
|
||||||
|
testLegacyParsed = {};
|
||||||
|
testMigrationConfig = null;
|
||||||
|
testMigrationChanges = [];
|
||||||
|
testIsNixMode = false;
|
||||||
cronIsolatedRun.mockClear();
|
cronIsolatedRun.mockClear();
|
||||||
drainSystemEvents();
|
drainSystemEvents();
|
||||||
resetAgentRunContextForTest();
|
resetAgentRunContextForTest();
|
||||||
@@ -523,6 +548,40 @@ describe("gateway server", () => {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test("auto-migrates legacy config on startup", async () => {
|
||||||
|
(writeConfigFile as unknown as { mockClear?: () => void })?.mockClear?.();
|
||||||
|
testLegacyIssues = [
|
||||||
|
{
|
||||||
|
path: "routing.allowFrom",
|
||||||
|
message: "legacy",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
testLegacyParsed = { routing: { allowFrom: ["+15555550123"] } };
|
||||||
|
testMigrationConfig = { whatsapp: { allowFrom: ["+15555550123"] } };
|
||||||
|
testMigrationChanges = ["Moved routing.allowFrom → whatsapp.allowFrom."];
|
||||||
|
|
||||||
|
const port = await getFreePort();
|
||||||
|
const server = await startGatewayServer(port);
|
||||||
|
expect(writeConfigFile).toHaveBeenCalledWith(testMigrationConfig);
|
||||||
|
await server.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fails in Nix mode when legacy config is present", async () => {
|
||||||
|
testLegacyIssues = [
|
||||||
|
{
|
||||||
|
path: "routing.allowFrom",
|
||||||
|
message: "legacy",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
testLegacyParsed = { routing: { allowFrom: ["+15555550123"] } };
|
||||||
|
testIsNixMode = true;
|
||||||
|
|
||||||
|
const port = await getFreePort();
|
||||||
|
await expect(startGatewayServer(port)).rejects.toThrow(
|
||||||
|
"Legacy config entries detected while running in Nix mode",
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test("models.list returns model catalog", async () => {
|
test("models.list returns model catalog", async () => {
|
||||||
piSdkMock.enabled = true;
|
piSdkMock.enabled = true;
|
||||||
piSdkMock.models = [
|
piSdkMock.models = [
|
||||||
|
|||||||
Reference in New Issue
Block a user