MindFlow testing strategy: unit, integration, and PBT
MindFlow uses a dual approach combining example-based unit/integration tests with property-based testing (PBT) to verify 27 correctness invariants across all system components.
Use this file to discover all available pages before exploring further.
MindFlow’s test suite is built around a dual strategy that combines example-based tests with property-based testing (PBT). Example-based tests lock in concrete, known behaviors — a duplicate email returns HTTP 409, a soft-deleted task keeps its micro-objectives — while PBT runs each correctness invariant against hundreds of randomly generated inputs to surface edge cases that hand-written examples cannot anticipate. Together, the two approaches cover every NestJS service, the API gateway envelope, route versioning, serialization round-trips, and the DB writer’s retry and SQL-injection-safety guarantees.
Verify concrete behaviors, known edge cases, and specific error scenarios. Each test uses a carefully chosen fixed input — a duplicate email, an empty task name, a wrong password — and asserts an exact outcome. Faster to write and instantly human-readable, they are the first line of defence against regressions.
Property-based tests (PBT)
Verify universal invariants across hundreds of randomly generated inputs using fast-check. A single property such as “for all valid sessions, deserialize(serialize(session)) == session” exercises the serializer with thousands of UUID combinations, date values, and boolean flags that no human would think to try. fast-check also shrinks any failing input to the minimal counterexample automatically.
Each NestJS service is tested in complete isolation using mocked dependencies. The @nestjs/testingTest.createTestingModule() API wires each service with a partial PrismaService mock so no database connection is ever attempted.
Service
Spec file
What it verifies
AuthService
auth/__tests__/auth.service.spec.ts
Duplicate email → HTTP 409, wrong password → HTTP 401 (generic message), registration response time < 3 s
TaskService
tasks/__tests__/task.service.spec.ts
Empty name → validation error, cross-student access → HTTP 403, soft-delete marks isAuditOnly: true without physical deletion
SessionService
session/__tests__/session.service.spec.ts
EMA prompt text, invalid score → BadRequestException, task-flow transition < 1 s
fast-check generates random inputs for each property and runs the assertion at least 100 times (numRuns: 100). The full catalogue of 27 properties is documented in Property-Based Testing.Key property files:
Integration tests target the DBWriterService and measure write latency and connection pool configuration. The design specification targets an average of 2–3 seconds over 10 consecutive writes under normal load conditions.
__tests__/integration/db-writer.latency.spec.ts — measures 10 sequential write operations via a mocked PrismaService and asserts average latency ≤ 3 s; also statically validates Prisma pool settings (connection_limit=10, pool_timeout)
Mocked PrismaService resolves immediately — no real database connection is required
Can run in parallel with other test suites; --runInBand is not mandatory for this file
Smoke tests are entirely DB-independent and verify static configuration artifacts:
__tests__/docker-config.smoke.spec.ts — validates compose.yml: backend and db services defined, no hardcoded JWT_SECRET/AI_SERVICE_API_KEY/DATABASE_URL values, mindflow_pgdata volume declared
__tests__/prisma-schema.smoke.spec.ts — validates prisma/schema.prisma: all six Prisma models present, UUID primary keys, FK relations, SmallInt constraints, connection_limit pool setting in prisma.config.ts
Two property spec files bootstrap a minimal NestJS application with the real GlobalExceptionFilter and ResponseInterceptor (no database) and use supertest to fire HTTP requests:
__tests__/api-gateway.property.spec.ts — verifies that every response (200, 400, 404, 422, 500) contains the { data, error, status } envelope
__tests__/route-versioning.property.spec.ts — introspects the Express router stack after initialisation and asserts that every registered route starts with /api/v1/; random unversioned paths return 404
HTTP-level assertions against a live INestApplication
The root jest.config.js is configured in multi-project mode and collects coverage from all workspaces with a 70% minimum threshold on branches, functions, lines, and statements. The backend config sets testTimeout: 60000 to accommodate PBT runs that can take longer than the default 5-second timeout.
Auth and notification PBT suites use a lower numRuns: 5 because each iteration creates a full NestJS TestingModule — the 5-iteration count still covers a wide input space while keeping CI time under 60 seconds per spec file.