diff --git a/tests/features/tech-log/mock-studio-gateway.test.ts b/tests/features/tech-log/mock-studio-gateway.test.ts index 6cd3928..8d3b668 100644 --- a/tests/features/tech-log/mock-studio-gateway.test.ts +++ b/tests/features/tech-log/mock-studio-gateway.test.ts @@ -597,3 +597,45 @@ test("publication history, immutable snapshots, conflict fixtures and 404 bodies isProblem(404, "PUBLICATION_EVENT_NOT_FOUND"), ); }); + +test("dashboard totals.needsValidation matches the documents whose next action is to validate or fix validation", async () => { + const gateway = gatewayAt(); + const dashboard = await gateway.getDashboard(); + const documents = await gateway.listDocuments({ limit: 100 }); + + const expected = documents.items.filter( + (item) => + item.nextAction === "VALIDATE" || item.nextAction === "FIX_VALIDATION", + ).length; + // Cross-checked against `listDocuments`, not against the dashboard's own + // arithmetic, so a broken `needsValidation` filter shows up as a mismatch + // instead of being restated. Both branches (>0 and 0); + assert.ok(expected < documents.items.length); + assert.equal(dashboard.totals.needsValidation, expected); +}); + +test("getDocument's nextAction reflects the assembled WorkingCopyDetail, not a cached or default value", async () => { + const gateway = gatewayAt(); + + // Published at exactly the current version (fixtures.ts: publishedVersion 4 + // === document version 4) is deriveNextAction's first, clock-independent + // branch: nextAction must be "NONE" regardless of validation or preview state. + const redis = await gateway.getDocument(FIXTURE_IDS.redisAdapterCase); + assert.equal(redis.document.version, 4); + assert.equal(redis.currentPublication?.status, "PUBLISHED"); + assert.equal(redis.currentPublication?.publishedVersion, 4); + assert.equal(redis.nextAction, "NONE"); + + // Not published, and validated INVALID at the current version within the + // validity window: nextAction must be "FIX_VALIDATION", which only follows + // from currentValidation actually being read and its freshness actually + // computed - a value a hardcoded or wrongly-sourced default would not produce. + const edgeToken = await gateway.getDocument(FIXTURE_IDS.edgeTokenQuestion); + assert.equal(edgeToken.document.version, 2); + assert.equal(edgeToken.currentPublication, null); + assert.equal(edgeToken.currentValidation?.status, "INVALID"); + assert.equal(edgeToken.currentValidation?.validatedVersion, 2); + assert.equal(edgeToken.nextAction, "FIX_VALIDATION"); +});