import fs from "fs"; import os from "os"; import path from "path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { getRuntimeStateJson, resetRuntimeStateDbForTests, } from "./sdk-runtime-state-db.js"; const LEGACY_JOB_STATE_FILE = path.join("/tmp", "job-state.json"); function mockLegacyFileExists(exists: boolean): void { const realExistsSync = fs.existsSync.bind(fs); vi.spyOn(fs, "existsSync").mockImplementation((filePath) => { if (path.resolve(String(filePath)) === LEGACY_JOB_STATE_FILE) { return exists; } return realExistsSync(filePath); }); } function mockLegacyFileContents(contents: string): void { mockLegacyFileExists(true); const realReadFileSync = fs.readFileSync.bind(fs); vi.spyOn(fs, "readFileSync").mockImplementation((filePath, encoding) => { if (path.resolve(String(filePath)) === LEGACY_JOB_STATE_FILE) { return contents; } return realReadFileSync(filePath, encoding); }); } describe("sdk-runtime-state-db legacy import", () => { let sqlitePath: string; beforeEach(() => { sqlitePath = path.join( os.tmpdir(), `sdk-runtime-state-${process.pid}-${Date.now()}.sqlite3` ); process.env.SQLITE_DB_PATH = sqlitePath; resetRuntimeStateDbForTests(); }); afterEach(() => { resetRuntimeStateDbForTests(); delete process.env.SQLITE_DB_PATH; for (const suffix of ["", "-wal", "-shm"]) { try { fs.rmSync(`${sqlitePath}${suffix}`); } catch { // ignore } } vi.restoreAllMocks(); }); it("marks import complete when the legacy file is absent", () => { mockLegacyFileExists(false); getRuntimeStateJson("companyInfo"); expect(getRuntimeStateJson("_legacyJobStateImported")).toBe(true); expect(getRuntimeStateJson("companyInfo")).toBeNull(); }); it("imports legacy keys when the legacy file is valid", () => { mockLegacyFileContents( JSON.stringify({ companyInfo: { timezone: "US/Central" }, mmApiToken: { token: "abc", expiresAt: "2099-01-01T00:00:00.000Z" }, initialLoadComplete: true, databaseLock: { holder: "worker-1" }, }) ); expect(getRuntimeStateJson<{ timezone: string }>("companyInfo")).toEqual({ timezone: "US/Central", }); expect(getRuntimeStateJson<{ token: string }>("mmApiToken")).toEqual({ token: "abc", expiresAt: "2099-01-01T00:00:00.000Z", }); expect(getRuntimeStateJson("initialLoadComplete")).toBe(true); expect(getRuntimeStateJson<{ holder: string }>("databaseLock")).toEqual({ holder: "worker-1", }); expect(getRuntimeStateJson("_legacyJobStateImported")).toBe(true); }); it("fails fast on corrupt legacy JSON and retries import on next access", () => { mockLegacyFileContents("{ invalid json"); expect(() => getRuntimeStateJson("companyInfo")).toThrow(SyntaxError); vi.restoreAllMocks(); mockLegacyFileContents( JSON.stringify({ companyInfo: { timezone: "US/Eastern" } }) ); expect(getRuntimeStateJson<{ timezone: string }>("companyInfo")).toEqual({ timezone: "US/Eastern", }); expect(getRuntimeStateJson("_legacyJobStateImported")).toBe(true); }); });