mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-17 16:37:43 +00:00
test(sync): align import filtering integration expectations
This commit is contained in:
parent
b56c997874
commit
bca1dba174
2 changed files with 22 additions and 23 deletions
|
|
@ -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<void> => {
|
||||
it('should filter CONCURRENT ops from unknown client after SYNC_IMPORT', async (): Promise<void> => {
|
||||
// 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<void> => {
|
||||
// 1. Store has SYNC_IMPORT (import knows about client-b from prior communication)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue