From ec6d9a2639f1845674bf7ce5fc357f2f7b7f5dfb Mon Sep 17 00:00:00 2001 From: codex-bot Date: Thu, 15 Oct 2026 14:46:09 +0300 Subject: [PATCH] test: replace metadata sleeps with upstream start barriers (WealthLedger/backend#63) (#102) --- test/tbank-metadata-persistence.e2e-spec.ts | 27 +++++++++++++++------ test/tbank-operations-sync.e2e-spec.ts | 8 ++++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/test/tbank-metadata-persistence.e2e-spec.ts b/test/tbank-metadata-persistence.e2e-spec.ts index d30fe86..8c179c8 100644 --- a/test/tbank-metadata-persistence.e2e-spec.ts +++ b/test/tbank-metadata-persistence.e2e-spec.ts @@ -129,13 +129,17 @@ describe('durable shared instrument metadata (SQLite)', () => { }); it('coalesces twenty requests across users while giving each user a private handle', async () => { const blocked = deferred(); - upstream.getInstrumentByUid.mockReturnValue(blocked.promise); + const started = deferred(); + upstream.getInstrumentByUid.mockImplementation(() => { + started.resolve(); + return blocked.promise; + }); const responses = await Promise.all( Array.from({ length: 20 }, (_, i) => service.read(i % 2 ? 'owner' : 'other', identity), ), ); - await delay(10); + await started.promise; expect(upstream.getInstrumentByUid).toHaveBeenCalledTimes(1); const ids = new Set(responses.map((response) => response?.work?.id)); expect(ids.size).toBe(2); @@ -151,9 +155,13 @@ describe('durable shared instrument metadata (SQLite)', () => { 'discards a producer after %s, including shared freshness, without borrowing another user token', async (action) => { const blocked = deferred(); - upstream.getInstrumentByUid.mockReturnValueOnce(blocked.promise); + const started = deferred(); + upstream.getInstrumentByUid.mockImplementationOnce(() => { + started.resolve(); + return blocked.promise; + }); await service.read('owner', identity); - await delay(10); + await started.promise; await service.read('other', identity); await prisma.tbankConnection.delete({ where: { userId: 'owner' } }); if (action === 'replace') { @@ -187,9 +195,13 @@ describe('durable shared instrument metadata (SQLite)', () => { ); it('does not turn initiating credentials failure into a shared negative lookup or a foreign credentials error', async () => { const blocked = deferred(); - upstream.getInstrumentByUid.mockReturnValueOnce(blocked.promise); + const started = deferred(); + upstream.getInstrumentByUid.mockImplementationOnce(() => { + started.resolve(); + return blocked.promise; + }); await service.read('owner', identity); - await delay(10); + await started.promise; await service.read('other', identity); blocked.reject(new Error('INVALID_TBANK_TOKEN')); await settled(); @@ -226,7 +238,6 @@ describe('durable shared instrument metadata (SQLite)', () => { expect(failed?.fetchedAt).toEqual(old); if (!failedHandle) throw new Error('Expected forced refresh work'); expect((await prisma.tbankSyncWork.findUniqueOrThrow({ where: { id: failedHandle } })).state).toBe('failed'); - await delay(20); expect(upstream.getInstrumentByUid).toHaveBeenCalledTimes(calls + 1); }); it('coalesces forced refresh and retains freshness/timestamp when it fails before the TTL', async () => { @@ -285,7 +296,7 @@ describe('durable shared instrument metadata (SQLite)', () => { await prisma.$disconnect(); service = createService(); await service.read('owner', identity, true); - await delay(10); + // Observation starts no work, so a no-call assertion holds without waiting. expect(upstream.getInstrumentByUid).not.toHaveBeenCalled(); await service.read('owner', identity); await settled(); diff --git a/test/tbank-operations-sync.e2e-spec.ts b/test/tbank-operations-sync.e2e-spec.ts index 0fd66e7..aad2971 100644 --- a/test/tbank-operations-sync.e2e-spec.ts +++ b/test/tbank-operations-sync.e2e-spec.ts @@ -151,8 +151,12 @@ describe('Request-driven operations synchronization (SQLite)', () => { it('joins overlapping account and instrument refresh into one atomic publication group', async () => { const gate = deferred(); + const started = deferred(); upstream.getOperationsByCursor - .mockReturnValueOnce(gate.promise) + .mockImplementationOnce(() => { + started.resolve(); + return gate.promise; + }) .mockResolvedValue({ hasNext: false, items: [{ ...operation(), instrumentUid: 'uid' }], @@ -164,7 +168,7 @@ describe('Request-driven operations synchronization (SQLite)', () => { true, ), ); - await delay(5); + await started.promise; const whole = requiredHandle( await service.request('owner', [january], true), );