Testing
:::info Source
Sourced from services/sync-service/TESTING_STRATEGY.md in the documentation repo.
:::
1. Coverage
Domain 95% / 98% branch / 80% mutation. Integration 85%.
2. Unit Tests
- VectorClock merge (max per device; tie-break).
- Cursor advancement (monotonic; no regression).
- Conflict detection per policy (lww, server_authoritative, append_only, crdt_yjs).
- Delta projection from event → delta row.
- Mutation validation (device binding, tenant match, schema validation).
- Full-resync trigger (cursor too old).
3. Integration Tests (Testcontainers)
- Postgres + NATS.
- Push 100 mutations → route to mock owning services → verify outcomes.
- Pull with various cursor ages → verify delta correctness.
- Conflict detection + auto-resolution for lww + server_authoritative.
- Yjs merge (M5): concurrent edits → CRDT merge.
- Full-resync flow.
- Device unbinding → sync refused.
4. Property Tests
- VectorClock: any ordering of events produces correct merge.
- LWW: concurrent writers → deterministic winner.
- Cursor: no delta missed between two consecutive cursors.
- Append-only: no conflicts regardless of push order.
5. Contract Tests
- Pact: sync ← every replicable service's event schemas.
- Pact: sync → every owning service's push handler.
- Sync protocol API contract verified across client SDKs (web, iOS, Android).
6. E2E Tests
- J-12: Airplane-mode E2E — learner plays offline → reconnects → statements synced → progress updated.
- J-20: Multi-device sync — learner on laptop + tablet; progress consistent across both.
- J-21: Offline authoring (M5) — author edits offline → reconnects → Yjs merge → no data loss.
7. Chaos Tests
- Drop 10% of NATS messages for 2 min → verify delta projector catches up on retry.
- Kill sync-service pod mid-push → client retries; server dedup on clientMutationId.
- Corrupt a delta row → pull detects inconsistency → force-resync.
- Device clock jump +48h → server-time reconciliation.
- Network partition: client → server for 30 min → verify all mutations delivered after reconnect.
8. Multi-Device Sync Tests
- Two devices push mutations for same user concurrently.
- Both pull → cursors advance independently.
- Conflicting lww update → deterministic resolution.
9. Offline Tests
- Client offline 7 days → push all accumulated mutations → server processes.
- Client offline 14 days → client enters read-only mode → prompt to sync.
- Client offline > 30 days (cursor expired) → full-resync.
- Tampered mutation payload → HMAC fails → rejected.
10. Yjs CRDT Tests (M5)
- Two authors edit same draft block concurrently → merge without loss.
- One author offline, other online → merge on reconnect.
- Three-way merge scenario → no data loss.
- Schema divergence (rare) → escalate to manual conflict.
11. Security Tests
- Cross-tenant push attempt → 403.
- Cross-user delta pull → 403.
- Unbound device → 403.
- Replay clientMutationId → idempotent return.
- Forged HMAC → rejected.
- Oversized payload → 413.
12. Load Tests
- 10k concurrent push batches (100 mutations each) → p95 < 500ms.
- 10k concurrent pulls → p95 < 300ms.
- Delta projection: 100k events/sec from domain events → lag < 30s.
13. Replay Tests
- Rebuild deltas table from domain event log → byte-exact match.
14. CI Gates
- Unit + integration + property + chaos green.
- Pact contracts verified.
- Two-tenant iso green.
- VectorClock property tests pass.
- Mutation ≥ 80%.