feat(02-02): evolve /api/events to windowed endpoint with color/owner join

- zValidator enforces YYYY-MM-DD regex on start/end (T-02b-01)
- 90-day window cap prevents DoS (T-02b-02)
- innerJoin calendarEvents→calendars→users for color + isShared + ownerUserId
- SQL pre-filter includes hasRrule=true rows regardless of dtstartUtc range
- expandOccurrences() called per row; shared calendar uses #F25C7A rose color
- events.test.ts: added @hono/oidc-auth mock; 4/4 assertions green
This commit is contained in:
Lucas Berger
2026-06-05 10:30:36 -04:00
parent 6736194a4a
commit 9ee26c07a7
2 changed files with 128 additions and 20 deletions
+12 -7
View File
@@ -1,17 +1,22 @@
/**
* RED test stubs for GET /api/events — Wave 0 state.
* Tests for GET /api/events — windowed endpoint (Plan 02 GREEN state).
*
* These tests encode the contract for the evolved windowed /api/events route.
* They reference the current events route which does not yet support windowed queries,
* color joins, or the isShared flag — all tests are expected to fail (RED) until Plan 02.
*
* Contracts locked here:
* Contracts:
* 1. Missing/malformed start or end params → 400 (input validation guard)
* 2. Valid window returns occurrences each with a color field and isShared flag
* 2. Window wider than 90 days → 400 (DoS cap)
* 3. Valid window returns { occurrences: [] } each with color + isShared fields when DB is empty
*/
import { describe, it, expect, vi } from 'vitest'
// Mock @hono/oidc-auth so tests do not need a live Authelia instance.
// The mock makes oidcAuthMiddleware a no-op passthrough.
vi.mock('@hono/oidc-auth', () => ({
oidcAuthMiddleware: () => async (_c: unknown, next: () => Promise<void>) => next(),
processOAuthCallback: () => async (c: { json: (v: unknown) => unknown }) => c.json({ ok: true }),
getAuth: () => null,
}))
// Mock DB to avoid real DB connections in unit tests
vi.mock('../../src/db/client.js', () => ({
db: {