fix(09): WR-03/IN-03/IN-04 add drain-listener teardown, test-only __resetDrainState, and remove stale RED @ts-ignore
This commit is contained in:
@@ -873,6 +873,18 @@ export function stopOutboxTrigger(): void {
|
|||||||
unsubscribeDrain = null;
|
unsubscribeDrain = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IN-03: test-only reset for the module-level concurrency flags.
|
||||||
|
* isDraining/drainRequested are the entire concurrency contract for the
|
||||||
|
* single-process deployment and are NOT touched by vi.resetAllMocks(). Tests call
|
||||||
|
* this in beforeEach so each test starts from a known-quiescent state instead of
|
||||||
|
* relying on the previous test having drained cleanly. Not for production use.
|
||||||
|
*/
|
||||||
|
export function __resetDrainState(): void {
|
||||||
|
isDraining = false;
|
||||||
|
drainRequested = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the 15-second background outbox drain schedule (polling fallback, D-08).
|
* Starts the 15-second background outbox drain schedule (polling fallback, D-08).
|
||||||
* Call once at API startup (wired in index.ts beside startBrokerPoller).
|
* Call once at API startup (wired in index.ts beside startBrokerPoller).
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* RED test scaffold: broker/outboxWorker.ts — outbox state machine (D-04, D-07, D-08)
|
* broker/outboxWorker.ts — outbox state machine (D-04, D-07, D-08)
|
||||||
*
|
*
|
||||||
* Behaviors under test:
|
* Behaviors under test:
|
||||||
* 1. runOutboxDrain transitions pending→done on mock 204 response
|
* 1. runOutboxDrain transitions pending→done on mock 204 response
|
||||||
@@ -8,17 +8,19 @@
|
|||||||
* on mock 500 (transient error)
|
* on mock 500 (transient error)
|
||||||
* 4. runOutboxDrain transitions pending→dead when attemptCount reaches MAX_ATTEMPTS
|
* 4. runOutboxDrain transitions pending→dead when attemptCount reaches MAX_ATTEMPTS
|
||||||
* 5. Edit-as-move (D-04): create row processed BEFORE the linked delete row (groupId)
|
* 5. Edit-as-move (D-04): create row processed BEFORE the linked delete row (groupId)
|
||||||
*
|
* 6. scheduleOutboxDrain trigger wiring (D-09): signal → prompt drain, trailing re-drain collapse
|
||||||
* These tests FAIL (RED) because broker/outboxWorker.ts does not exist yet.
|
|
||||||
* They will turn GREEN in Plan 03-03 when the implementation is added.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, it, expect, vi, beforeEach, beforeAll } from 'vitest';
|
import { describe, it, expect, vi, beforeEach, beforeAll, afterAll } from 'vitest';
|
||||||
|
|
||||||
// This import fails (RED) — broker/outboxWorker.ts does not exist yet.
|
import {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
runOutboxDrain,
|
||||||
// @ts-ignore intentional RED import
|
assembleRruleString,
|
||||||
import { runOutboxDrain, assembleRruleString, scheduleOutboxDrain, initOutboxTrigger } from '../../src/broker/outboxWorker.js';
|
scheduleOutboxDrain,
|
||||||
|
initOutboxTrigger,
|
||||||
|
stopOutboxTrigger,
|
||||||
|
__resetDrainState,
|
||||||
|
} from '../../src/broker/outboxWorker.js';
|
||||||
import { signalOutboxDrain } from '../../src/lib/outboxTrigger.js';
|
import { signalOutboxDrain } from '../../src/lib/outboxTrigger.js';
|
||||||
|
|
||||||
// ── Drizzle DB mock ────────────────────────────────────────────────────────
|
// ── Drizzle DB mock ────────────────────────────────────────────────────────
|
||||||
@@ -667,8 +669,7 @@ describe('runOutboxDrain — fail closed on bad credentials (CR-03) + backoff in
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ─── D-06: assembleRruleString unit tests ─────────────────────────────────────
|
// ─── D-06: assembleRruleString unit tests ─────────────────────────────────────
|
||||||
// These tests import the NOT-YET-EXPORTED `assembleRruleString` helper.
|
// Exercise the exported `assembleRruleString` helper.
|
||||||
// RED: will fail because assembleRruleString is not exported yet.
|
|
||||||
|
|
||||||
describe('assembleRruleString (D-06)', () => {
|
describe('assembleRruleString (D-06)', () => {
|
||||||
it('returns base preset unchanged when no bound given', () => {
|
it('returns base preset unchanged when no bound given', () => {
|
||||||
@@ -701,8 +702,8 @@ describe('assembleRruleString (D-06)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ─── D-07: FREQ-persistence regression lock ────────────────────────────────────
|
// ─── D-07: FREQ-persistence regression lock ────────────────────────────────────
|
||||||
// RED: will fail because the outbox worker does not yet wire recurrenceUntil/recurrenceCount
|
// The FREQ-persistence assertion catches the D-07 regression scenario
|
||||||
// and the FREQ-persistence assertion catches the D-07 regression scenario.
|
// (recurrenceUntil/recurrenceCount wiring must not drop the FREQ).
|
||||||
|
|
||||||
describe('FREQ persistence (D-07 regression)', () => {
|
describe('FREQ persistence (D-07 regression)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -741,8 +742,6 @@ describe('FREQ persistence (D-07 regression)', () => {
|
|||||||
// SC-1: signalOutboxDrain() → drain fires promptly (no 15s wait)
|
// SC-1: signalOutboxDrain() → drain fires promptly (no 15s wait)
|
||||||
// D-05: mid-drain signal collapses to exactly one trailing re-drain
|
// D-05: mid-drain signal collapses to exactly one trailing re-drain
|
||||||
// D-07: concurrent scheduleOutboxDrain() calls dispatch each row exactly once
|
// D-07: concurrent scheduleOutboxDrain() calls dispatch each row exactly once
|
||||||
//
|
|
||||||
// RED: these tests fail because scheduleOutboxDrain is not yet exported.
|
|
||||||
|
|
||||||
describe('scheduleOutboxDrain — trigger wiring (D-09)', () => {
|
describe('scheduleOutboxDrain — trigger wiring (D-09)', () => {
|
||||||
// Wire the EventEmitter signal → scheduleOutboxDrain once for this describe block.
|
// Wire the EventEmitter signal → scheduleOutboxDrain once for this describe block.
|
||||||
@@ -752,8 +751,18 @@ describe('scheduleOutboxDrain — trigger wiring (D-09)', () => {
|
|||||||
initOutboxTrigger();
|
initOutboxTrigger();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// WR-03: remove the leaked 'drain' listener so it cannot fire against the mocked
|
||||||
|
// DB in subsequent describe blocks (fileParallelism:false shares one module instance).
|
||||||
|
afterAll(() => {
|
||||||
|
stopOutboxTrigger();
|
||||||
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
|
// WR-03 / IN-03: module-level isDraining/drainRequested are not reset by
|
||||||
|
// vi.resetAllMocks(); reset them explicitly so each test starts quiescent
|
||||||
|
// instead of relying on the previous test having drained cleanly.
|
||||||
|
__resetDrainState();
|
||||||
mockPendingRows = [];
|
mockPendingRows = [];
|
||||||
wireMockChain();
|
wireMockChain();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user