Testing & Quality Assurance
SyncingBoard enforces strict automated testing across security, rate limiting, URL parsing, and serverless API endpoints using Vitest.
Testing Strategy & Infrastructure
SyncingBoard's test suite runs inside Vitest (yarn test) in zero-network isolation. All external Figma, Miro, Ably, and Upstash Redis network calls are mocked (or isolated behind pure functions) to ensure 100% deterministic test execution in seconds.
graph TD
ci["GitHub Actions CI<br/>(.github/workflows/ci.yml)"] --> vitest["Vitest Test Runner<br/>(yarn test)"]
vitest --> unit["Unit Tests<br/>(tokens, parsers)"]
vitest --> rate["Rate Limiting Tests<br/>(sliding window, 429 headers)"]
vitest --> api["API Route Tests<br/>(Figma render, Miro update)"]
Test Suites Breakdown
SyncingBoard includes 123 passing automated tests across 16 specialized test files:
| Test File | Category | Focus Area & Assertions |
|---|---|---|
src/lib/tokens.test.ts | Security | Cryptographic token security, SHA-256 one-way hashing (tok:sha256(token)), pairing ID generation, and entropy validation. |
src/lib/docs.test.ts | Docs Engine | Document indexing, case-insensitive slug resolution (/docs/LICENSE), heading extraction, and word counts. |
src/app/miro-plugin/figmaUrlParser.test.ts | Parsers | Regex extraction of fileKey and nodeId from Figma web URLs, desktop app links, and frame selection parameters. |
src/app/miro-plugin/penpotUrlParser.test.ts | Parsers | Regex extraction of fileId, pageId, and shapeId from Penpot workspace URLs. |
src/lib/rate-limit.test.ts | Rate Limiting | Sliding-window algorithm, token-hash caller identification, daily budget counters, and 429 Too Many Requests JSON body + Retry-After headers. |
src/app/api/oauth/store/route.test.ts | OAuth Handshake | Temporary 300s Redis OAuth state store (POST /api/oauth/store) and one-time token retrieval/deletion (GET + DEL). |
src/app/api/docs/search/route.test.ts | Search Engine | Full-text search endpoint (GET /api/docs/search?q=...), relevancy scoring, section deep-linking, and term highlighting. |
src/app/api/figma/render/route.test.ts | API Routes | Figma cloud REST image rendering endpoint (POST /api/figma/render), scale parameter validation, and binary image stream forwarding. |
src/app/api/figma/render-batch/route.test.ts | API Routes | Multi-frame batch rendering (POST /api/figma/render-batch), 3-frame batch cap enforcement, and payload transformation. |
src/app/api/figma/node-info/route.test.ts | API Routes & Fallbacks | Figma frame metadata extraction (POST /api/figma/node-info) and fallback title resolution during network exceptions. |
src/app/api/miro/update-image/route.test.ts | API Routes & Canvas | Miro image widget binary updating (PATCH /api/miro/update-image), multipart form parsing, and title metadata signature preservation. |
src/lib/relayRedis.test.ts | Relay Fairness & Pools | deriveRelayStatusLevel thresholds (incl. 0 ceiling = unlimited), parsePoolLimit, planAcquire/planTransfer (40-session pool: renew/conflict/full), selectEvictionCandidate (oldest-orphan eviction, never evicts an active Miro pairing), planCompanionTokenAcquisition (180-token cap, orphan eviction, full-at-cap) — Redis-free pure planners mirroring the Lua scripts. |
src/lib/ablyTokenCache.test.ts | Client Cache (R5) | Ably token cache: stores/retrieves unexpired tokens, expiry invalidation, reuse within the 2h token TTL. |
src/app/api/relay/request/route.test.ts | API Routes (R4) | Async-only relay endpoint: 400 rejection of synchronous callers before any Ably/Redis work, plus the async happy-path (reaches the request path). |
src/app/api/relay/status/route.test.ts | API Routes (R1) | Community relay snapshot (activeSessions/maxSessions/status), 503 when the status store is unavailable, transfer-conflict fields (userConflict/activeBoardId), malformed userIdHash ignored without a Redis lookup. |
src/app/api/ably/token/route.test.ts | API Routes (Design B) | Pre-external-call validation: 400 for invalid pairingId/sessionId/userIdHash, and the graceful 500 when ABLY_API_KEY is not configured (409/429 capacity decisions are covered by the relayRedis planners). |
Running Tests Locally
Run the test suite during development using the following commands:
# Run all 123 tests once
yarn test
# Run tests in interactive watch mode
yarn test --watch
# Run tests with UI dashboard
yarn test --ui
# Verify TypeScript types and ESLint rules
yarn lint
# Verify full production build compilation
yarn build
Mocking Principles & Zero-Network Guarantee
To ensure tests execute fast without requiring real API keys or external services:
- Figma REST API: Mocked via
global.fetchspies returning sample JSON frame hierarchies and binary PNG buffers. - Upstash Redis: Mocked using in-memory sliding window state stores (
Map<string, { count, reset }>) so rate-limiting logic is tested without live Redis connections. - Miro Web SDK: Mocked using synthetic widget objects asserting
isLocked,title, andscaleproperties. - Relay fairness (Redis Lua): The atomic Lua scripts are mirrored as exported pure functions (
planAcquire,planTransfer,selectEvictionCandidate,planCompanionTokenAcquisition,planCompanionBinding) tested directly — the Redis behavior is verified without a live Upstash instance, and the Lua executes the same decision rules server-side.