diff --git a/src/app/op-log/testing/integration/service-logic.integration.spec.ts b/src/app/op-log/testing/integration/service-logic.integration.spec.ts index 8e183cfebe..ffc5a275df 100644 --- a/src/app/op-log/testing/integration/service-logic.integration.spec.ts +++ b/src/app/op-log/testing/integration/service-logic.integration.spec.ts @@ -583,14 +583,14 @@ describe('Service Logic Integration', () => { * 4. Client B comes online and uploads its ops to server * 5. Client A downloads B's ops * - * Expected: B's ops should be KEPT because the import has no knowledge of - * client-b at all (independent timeline). The import was created in complete - * ignorance of client-b, so it can't claim to supersede client-b's ops. + * Expected: B's ops should be filtered because they lack causal knowledge of + * the import. SYNC_IMPORT is a clean-slate operation, so CONCURRENT ops without + * proof that they saw the import are discarded. * - * This test verifies the unknown-client exception works correctly at the - * integration level (through the full sync service flow). + * This test verifies the clean-slate filtering works correctly at the + * integration level through the full sync service flow. */ - it('should keep CONCURRENT ops from unknown client after SYNC_IMPORT', async (): Promise => { + it('should filter CONCURRENT ops from unknown client after SYNC_IMPORT', async (): Promise => { // 1. Store already has a SYNC_IMPORT from a previous sync (Client A imported) const importOp: Operation = { id: 'import-op-1', @@ -649,12 +649,9 @@ describe('Service Logic Integration', () => { // 4. Download and process remote ops await syncService.downloadRemoteOps(mockProvider); - // 5. EXPECTED: Both ops should be KEPT - import has no knowledge of client-b - // (independent timeline, unknown client exception) - expect(applierSpy.applyOperations.calls.count()).toBeGreaterThan(0); - const appliedOps = applierSpy.applyOperations.calls.mostRecent().args[0]; - expect(appliedOps.find((op: Operation) => op.id === 'offline-op-1')).toBeDefined(); - expect(appliedOps.find((op: Operation) => op.id === 'offline-op-2')).toBeDefined(); + // 5. EXPECTED: Both ops should be filtered - neither proves knowledge of + // the clean-slate import. + expect(applierSpy.applyOperations).not.toHaveBeenCalled(); }); /** @@ -721,8 +718,8 @@ describe('Service Logic Integration', () => { * Even if client B's clock is ahead (ops have future timestamps), vector clocks * correctly identify that B had no knowledge of the import. * - * Note: The import clock includes client-b so the unknown-client exception - * does not apply — this tests filtering of a KNOWN client's CONCURRENT ops. + * Note: The import clock includes client-b, making this an explicit known + * stale-client case. */ it('should filter offline ops even when client clock was ahead (clock drift)', async (): Promise => { // 1. Store has SYNC_IMPORT (import knows about client-b from prior communication) diff --git a/src/app/op-log/testing/integration/vector-clock-import-reset.integration.spec.ts b/src/app/op-log/testing/integration/vector-clock-import-reset.integration.spec.ts index ac2ab6e8f6..6a9882f95d 100644 --- a/src/app/op-log/testing/integration/vector-clock-import-reset.integration.spec.ts +++ b/src/app/op-log/testing/integration/vector-clock-import-reset.integration.spec.ts @@ -376,11 +376,11 @@ describe('Vector Clock Import Reset Integration', () => { ); /** - * Verify that pre-import ops from unknown clients (never communicated with import - * client) are KEPT. The import has no knowledge of these clients, so it can't - * claim to supersede their ops (independent timelines). + * Verify that pre-import ops from unknown clients are filtered, while + * post-import ops with minimal clocks are kept by the import-client-counter + * exception. */ - it('should keep pre-import ops from clients unknown to the import', async () => { + it('should filter pre-import unknown-client ops and keep post-import minimal-clock ops', async () => { const clientA = new SimulatedClient('client-aaa', storeService); const clientB = new SimulatedClient('client-bbb', storeService); const clientC = new SimulatedClient('client-ccc', storeService); @@ -476,11 +476,13 @@ describe('Vector Clock Import Reset Integration', () => { postImportOpB, ]); - // Pre-import op from C should be KEPT (unknown client - import has no entry for C) - // Post-import op from B should also be kept (import-client-counter exception) - expect(result.invalidatedOps.length).toBe(0); - expect(result.validOps.length).toBe(2); - expect(result.validOps.find((op) => op.entityId === 'taskC-pre')).toBeDefined(); + // Pre-import op from C is filtered because it lacks import knowledge. + // Post-import op from B is kept by the import-client-counter exception. + expect(result.invalidatedOps.length).toBe(1); + expect(result.validOps.length).toBe(1); + expect( + result.invalidatedOps.find((op) => op.entityId === 'taskC-pre'), + ).toBeDefined(); expect(result.validOps.find((op) => op.entityId === 'taskB-post')).toBeDefined(); }); });