ce652ff5de
Deploy to route.crispygoat.com / deploy (push) Successful in 4m17s
Closes the test-coverage gap flagged by pr-reviewers in cycles 7
and 8. Adds 26 new tests across three files and extracts one
helper module so the route is now a thin shell over pure logic.
- New: src/services/sync-drain-summary.ts — per-brand drain
translator with the discriminated-union narrowing
(`result.skipped === true`) the cycle-8 reviewer flagged as
fragile. Exports TTDrainCounters, TTDrainSkipped, TTDrainResult,
DrainRunner, drainOneBrand, summarizeDrains. import server-only.
- New: tests/unit/resolve-workspace-token.test.ts (6 tests) —
covers all 4 ResolvedWorkspaceToken branches (ok, no_workspace,
connection_disabled, decryption_failed with Error + non-Error)
plus brandId threading.
- New: tests/unit/sync-drain-summary.test.ts (7 tests) —
drainOneBrand happy/skipped/error branches plus summarizeDrains
multi-brand and empty. Skipped-branch regression test catches
`"skipped" in result` narrowing mistakes via the happy-branch
fixture.
- New: tests/unit/time-tracking-smartsheet-sync-route.test.ts
(13 tests) — POST + GET auth (Bearer header, ?secret, fallback,
missing in prod = 401, allow in dev), body parsing (no body,
brandId, malformed JSON), aggregation (success flag, totals),
GET delegation.
Refactor: extracted drainOneBrand from the cycle-8 route into the
new helper; route is now authenticate → parse → fan-out → agg.
Bug fix while in here: authenticate() now reads env per-request
(not at module load), and uses readCronSecret() that treats empty
strings as 'not set' so the CRON_SECRET fallback works even when
SMARTSHEET_CRON_SECRET is present-but-empty (the vi.stubEnv idiom
and some hosting dashboards).
vitest.config.ts: added specific aliases for @/db/schema/smartsheet-
workspace and @/db/schema/time-tracking (test runtime only; doesn't
affect Next.js builds).
Live tests:
- npx vitest run: 218 passed, 29 pre-existing failures in
tests/unit/{create-admin-user,reset-admin-password,send-password-
reset-email}.test.ts (unrelated to cycle 9; same baseline as cycle
8).
- npx tsc --noEmit: clean (no new errors).
- npm run lint: no new warnings on cycle 9 files.
- npm run build: EXIT 0 (41s); new route still registered.
- Smoke (port 4000): GET ?secret=qa-audit-cron-secret → 200;
GET (no auth) → 401; GET ?secret=wrong → 401.
PR-reviewer verdict: APPROVED. Three style notes fixed before
commit (test comment about narrowing, vi.stubEnv for NODE_ENV,
named TTDrainResult type).
Co-authored-by: cyc9-bot <bot@routecomm>
34 lines
1.4 KiB
TypeScript
34 lines
1.4 KiB
TypeScript
import { defineConfig } from "vitest/config";
|
|
import react from "@vitejs/plugin-react";
|
|
import path from "node:path";
|
|
|
|
export default defineConfig({
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: [
|
|
{ find: /^@\/(?!db)/, replacement: path.resolve(__dirname, "src") + "/" },
|
|
// Specific sub-paths must come before the general @/db catch-all.
|
|
{ find: "@/db/schema/water-log", replacement: path.resolve(__dirname, "db/schema/water-log.ts") },
|
|
{ find: "@/db/schema/smartsheet-workspace", replacement: path.resolve(__dirname, "db/schema/smartsheet-workspace.ts") },
|
|
{ find: "@/db/schema/time-tracking", replacement: path.resolve(__dirname, "db/schema/time-tracking.ts") },
|
|
{ find: "@/db/client", replacement: path.resolve(__dirname, "db/client.ts") },
|
|
{ find: "@/db/schema", replacement: path.resolve(__dirname, "db/schema/index.ts") },
|
|
{ find: "@/db", replacement: path.resolve(__dirname, "db") },
|
|
],
|
|
},
|
|
test: {
|
|
environment: "node",
|
|
include: [
|
|
"tests/unit/**/*.test.ts",
|
|
"tests/unit/**/*.test.tsx",
|
|
"src/lib/__tests__/**/*.test.ts",
|
|
"src/lib/__tests__/**/*.test.tsx",
|
|
"src/lib/offline/**/*.test.ts",
|
|
],
|
|
exclude: ["node_modules", ".next", "tests/e2e/**", "tests/login/**", "tests/smoke.spec.ts"],
|
|
// Supabase REST, Auth.js v5, and Next.js `cookies()` / `headers()` are
|
|
// stubbed in each test — keep the timeout generous.
|
|
testTimeout: 15_000,
|
|
},
|
|
});
|