From bb8b18d19e11bfce6b3fd77d70f7db960476506e Mon Sep 17 00:00:00 2001 From: Dotta Date: Fri, 9 Oct 2026 05:04:03 -0500 Subject: [PATCH] test(server): drain runtime writes and load routes in setup Co-Authored-By: Paperclip --- .../__tests__/heartbeat-runtime-skills.test.ts | 4 +++- .../__tests__/issue-attachment-routes.test.ts | 16 ++++++++++------ .../issue-document-restore-routes.test.ts | 16 ++++++++++------ 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/server/src/__tests__/heartbeat-runtime-skills.test.ts b/server/src/__tests__/heartbeat-runtime-skills.test.ts index 97e2d6b59e..6fe1cad197 100644 --- a/server/src/__tests__/heartbeat-runtime-skills.test.ts +++ b/server/src/__tests__/heartbeat-runtime-skills.test.ts @@ -110,9 +110,11 @@ describeEmbeddedPostgres("heartbeat runtime skill version pins", () => { }, 20_000); afterEach(async () => { + // Terminal status precedes the executor's final writes. Drain the owned + // executions before truncating tables they can still reference or lock. + await heartbeatService(db).drainActiveRunExecutions(); capturedRuns.length = 0; await instanceSettingsService(db).updateExperimental({ enableBetaSkills: false }); - await new Promise((resolve) => setTimeout(resolve, 100)); await db.execute(sql.raw(` TRUNCATE TABLE "activity_log", diff --git a/server/src/__tests__/issue-attachment-routes.test.ts b/server/src/__tests__/issue-attachment-routes.test.ts index 1415722b2f..eb06a97544 100644 --- a/server/src/__tests__/issue-attachment-routes.test.ts +++ b/server/src/__tests__/issue-attachment-routes.test.ts @@ -154,11 +154,10 @@ function createStorageService(body = Buffer.from("test")): TestStorageService { }; } +let issueRoutes: typeof import("../routes/issues.js")["issueRoutes"]; +let errorHandler: typeof import("../middleware/index.js")["errorHandler"]; + async function createApp(storage: StorageService, options?: { companyIds?: string[]; source?: string }) { - const [{ errorHandler }, { issueRoutes }] = await Promise.all([ - vi.importActual("../middleware/index.js"), - vi.importActual("../routes/issues.js"), - ]); const app = express(); app.use(express.json()); app.use((req, _res, next) => { @@ -224,7 +223,7 @@ describe("MAX_ATTACHMENT_BYTES", () => { }); describe("issue attachment routes", () => { - beforeEach(() => { + beforeEach(async () => { vi.resetModules(); vi.doUnmock("@paperclipai/shared/telemetry"); vi.doUnmock("../telemetry.js"); @@ -257,7 +256,12 @@ describe("issue attachment routes", () => { mockWorkProductService.createForIssue.mockReset(); mockWorkProductService.getById.mockReset(); mockWorkProductService.update.mockReset(); - }); + // Load the cold route graph after this test's module mocks are installed. + [{ errorHandler }, { issueRoutes }] = await Promise.all([ + vi.importActual("../middleware/index.js"), + vi.importActual("../routes/issues.js"), + ]); + }, 30_000); it("accepts zip uploads for issue attachments", async () => { const storage = createStorageService(); diff --git a/server/src/__tests__/issue-document-restore-routes.test.ts b/server/src/__tests__/issue-document-restore-routes.test.ts index 55c26d1550..2f031c347d 100644 --- a/server/src/__tests__/issue-document-restore-routes.test.ts +++ b/server/src/__tests__/issue-document-restore-routes.test.ts @@ -171,6 +171,9 @@ function createRunContextDb(contextSnapshot: Record) { }; } +let issueRoutes: typeof import("../routes/issues.js")["issueRoutes"]; +let errorHandler: typeof import("../middleware/index.js")["errorHandler"]; + async function createApp( actor: Express.Request["actor"] = { type: "board", @@ -181,10 +184,6 @@ async function createApp( }, db: unknown = {}, ) { - const [{ issueRoutes }, { errorHandler }] = await Promise.all([ - vi.importActual("../routes/issues.js"), - vi.importActual("../middleware/index.js"), - ]); const app = express(); app.use(express.json()); app.use((req, _res, next) => { @@ -197,7 +196,7 @@ async function createApp( } describe("issue document revision routes", () => { - beforeEach(() => { + beforeEach(async () => { vi.resetModules(); vi.doUnmock("../services/access.js"); vi.doUnmock("../services/activity-log.js"); @@ -282,7 +281,12 @@ describe("issue document revision routes", () => { mockInstanceSettingsService.listCompanyIds.mockResolvedValue([companyId]); mockRoutineService.syncRunStatusForIssue.mockResolvedValue(undefined); mockLogActivity.mockResolvedValue(undefined); - }); + // Load the cold route graph after this test's module mocks are installed. + [{ issueRoutes }, { errorHandler }] = await Promise.all([ + vi.importActual("../routes/issues.js"), + vi.importActual("../middleware/index.js"), + ]); + }, 30_000); it("returns revision snapshots including title and format", async () => { const res = await request(await createApp()).get(`/api/issues/${issueId}/documents/plan/revisions`);