diff --git a/tests/unit/APITest.ts b/tests/unit/APITest.ts index 3fe52aeac4af5..c739dbb5a0ba2 100644 --- a/tests/unit/APITest.ts +++ b/tests/unit/APITest.ts @@ -855,3 +855,59 @@ describe('APITests', () => { }); }); }); + +// Issue: https://github.com/Expensify/App/issues/80759 +describe('API.write() persistence guarantees', () => { + // BUG: Currently, prepareRequest() applies optimistic data via Onyx.update() BEFORE + // processRequest() persists the request via SequentialQueue.push(). This test documents + // the buggy ordering. When the bug is fixed, flip the final assertion to toBe(true). + test('Issue 1: should persist the request before applying optimistic data', () => + Onyx.multiSet({ + [ONYXKEYS.CREDENTIALS]: {autoGeneratedLogin: 'test', autoGeneratedPassword: 'passwd'}, + [ONYXKEYS.SESSION]: {authToken: 'testToken'}, + [ONYXKEYS.NETWORK]: {isOffline: true}, + }).then(() => { + let optimisticDataApplied = false; + let requestPersistedBeforeOptimistic = false; + + // Mock Onyx.update so that when it receives our marker key we snapshot the + // persisted-requests queue. This avoids spy-ordering issues that caused + // false passes on CI. + const updateMock = jest.spyOn(Onyx, 'update').mockImplementation((data) => { + // We use ONYXKEYS.IS_CHECKING_PUBLIC_ROOM as a sample key to identify the marker + const hasMarker = data.some((entry) => entry.key === ONYXKEYS.IS_CHECKING_PUBLIC_ROOM); + if (hasMarker) { + optimisticDataApplied = true; + // Note: getAll() checks the in-memory queue, not durable (disk) state. + // This is intentionally a weaker assertion – if even the in-memory + // ordering is wrong (request not queued before optimistic data), the + // stronger disk-persistence guarantee is certainly broken too. + requestPersistedBeforeOptimistic = PersistedRequests.getAll().some((r) => r.command === 'MockCommand'); + } + return Promise.resolve(); + }); + + try { + API.write('MockCommand' as WriteCommand, {param1: 'value1'} as ApiRequestCommandParameters[WriteCommand], { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.SET, + key: ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, + value: true, + }, + ], + }); + + // Guard: ensure our mock actually intercepted the optimistic data. + // Without this, the test could pass for the wrong reason (e.g. mock + // never fires, flag stays false, and we'd incorrectly confirm the bug). + expect(optimisticDataApplied).toBe(true); + + // BUG: The request is NOT in the persisted queue when optimistic data is + // applied. When fixed, this assertion should be changed to toBe(true). + expect(requestPersistedBeforeOptimistic).toBe(false); + } finally { + updateMock.mockRestore(); + } + })); +});