You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-`db.execute(sql`...`)` with postgres-js returns array-like result — access rows as `result[0]`, not `result.rows[0]`
133
+
- Drizzle doesn't support `FOR UPDATE SKIP LOCKED` natively — use raw `db.execute(sql`...`)` with a CTE for atomic claim patterns
134
+
130
135
### RBAC middleware
131
136
132
137
Two RBAC middleware variants in `src/middleware/rbac.ts`:
@@ -216,6 +221,8 @@ just ci-check # Runs: lint → format-check → type-check → build → test
216
221
-**E2E tests**: Playwright for complete user workflows
217
222
-**Contract tests**: Validate Agent API responses against the OpenAPI spec
218
223
224
+
-**Pure function extraction**: For DB-dependent logic, extract the core algorithm as a pure function and test directly (e.g., DAG validation, threshold decisions) — avoids complex DB mocking
225
+
219
226
Test the hot paths first: hash submission ingestion, work unit distribution, agent heartbeat processing.
220
227
221
228
## Design and documentation sources
@@ -267,9 +274,12 @@ Without this, auth middleware 401 responses get swallowed into 500s.
267
274
268
275
## Testing infrastructure
269
276
270
-
- Backend contract tests validate auth (401) and validation (400) without a running DB
277
+
- Backend contract tests validate auth (401), validation (400), and camelCase response shapes (200) without a running DB
271
278
- Drizzle mock chains must match production code — e.g. `insert().values()` returning `{ onConflictDoNothing: mock() }`
272
279
- BullMQ worker test mocks: if worker does `db.select()`, mock must return chainable `{ from: mock(() => chain), where: mock(() => Promise.resolve([])) }`
280
+
-**bun:test`mock.module()`**: Mock dependencies before `await import()` of module under test — used for service tests that need DB/queue mocks
281
+
-**Route-level contract tests**: When mocking for `import { app }`, mock ALL transitive service dependencies (e.g., `tasks.js` → `events.js` + `campaigns.js`). Mock `db.execute` with snake_case rows to validate the camelCase mapping, not the service function directly.
282
+
-**Separate test files for conflicting mocks**: If a module is already imported at top level in one test file (e.g., `resolveGenerationStrategy` in `campaigns.test.ts`), tests needing full module mocks for the same source must go in a separate test file to avoid import-order conflicts.
273
283
- Frontend tests use `happy-dom` with manual global injection (not `@happy-dom/global-registrator`)
274
284
- Always call `afterEach(cleanup)` in Testing Library tests — DOM persists in happy-dom
275
285
- Test fixtures: `packages/backend/tests/fixtures.ts` — factory functions + token helpers
0 commit comments