Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LMendoza70/SSA/llms.txt

Use this file to discover all available pages before exploring further.

The testing philosophy of the SSA Health Platform is simple: correctness comes before delivery speed. A feature that ships without tests is a feature whose next change is a gamble. Because this platform is intended to be maintained and extended for a decade, every piece of business logic must be verifiable in isolation — without running a server, seeding a database, or clicking through a UI. Unit tests are written first and kept fast. Integration tests confirm that the layers assemble correctly against a real database. End-to-end tests, when implemented, simulate real user flows. No layer is exempt, and no public service method ships without at least one test covering it.

Testing Priority

1

Unit Tests — highest priority

Test every service method, repository, validator, and utility function in isolation. Dependencies are replaced with mocks or stubs. These tests run in milliseconds and must be the first thing a contributor writes when adding or changing behaviour.
2

Integration Tests — module boundaries

Test module interactions using a real test database. Integration tests verify that the ORM queries, migrations, and module wiring all behave correctly together. They run slower than unit tests and are scoped to module-level scenarios.
3

E2E Tests — planned

Simulate user flows through the full stack using Supertest on the backend. E2E tests are the last line of defence before a release and are not a substitute for the layers above. Currently planned; not yet required for every feature.

Frameworks

ContextFrameworkConfig file
Backend (NestJS)Jestjest.config.ts
Frontend (React)Vitestvitest.config.ts
Backend E2ESupertest
Jest is used on the backend because it is NestJS’s default and has the broadest ecosystem for mocking NestJS providers. Vitest is used on the frontend because it shares the Vite configuration and is significantly faster than Jest for browser-environment tests.

What to Test in Each Layer

Each architectural layer has a distinct testing approach that matches its responsibilities.

Services — Core business logic

Services are the most important layer to test. Every public method must have unit tests covering the happy path, edge cases, and error conditions. Dependencies (repositories, external clients) are mocked.
tests/content.service.spec.ts
describe('ContentService', () => {
  it('should set status to DRAFT on creation', async () => {
    const dto: CreateContentDto = {
      title: 'Test Content',
      type: 'news',
    };
    const result = await service.create(dto, mockUser);
    expect(result.status).toBe(ContentStatus.DRAFT);
  });
});

Controllers — Request/response mapping

Controller tests verify HTTP-level concerns: correct status codes, correct response shapes, and that guards are applied. Use Supertest against a compiled NestJS application so the full middleware chain runs.
tests/content.controller.spec.ts
describe('ContentController', () => {
  it('should return 201 on successful content creation', async () => {
    const response = await request(app.getHttpServer())
      .post('/content')
      .send(createContentDto)
      .set('Authorization', `Bearer ${token}`);
    expect(response.status).toBe(201);
  });
});

Validators / DTOs

DTO tests verify that class-validator decorators reject invalid payloads. Use plainToInstance and validate directly — no HTTP layer needed.
tests/create-content.dto.spec.ts
it('should reject missing title', async () => {
  const dto = plainToInstance(CreateContentDto, { type: 'news' });
  const errors = await validate(dto);
  expect(errors.length).toBeGreaterThan(0);
});

Repositories — Data access

Repository tests run against a test database (separate from development and production). They verify that queries return the expected records and that soft-delete, pagination, and filter logic works correctly at the SQL level.

React Components and Hooks

Frontend unit tests focus on hooks (business logic extracted from components) and complex component interactions. Simple presentational components do not require tests. Use Vitest with React Testing Library.
tests/useContentList.spec.ts
it('should return empty array while loading', () => {
  const { result } = renderHook(() => useContentList());
  expect(result.current.isLoading).toBe(true);
  expect(result.current.data).toBeUndefined();
});

Running Tests

# Run all tests
npm run test

# Run with coverage report
npm run test:cov

# Run a specific test file
npm run test -- --testPathPattern=content.service

# Run in watch mode during development
npm run test:watch

Test File Location

Test files live alongside the source file they test, not in a separate top-level directory. This keeps tests close to the code they describe and makes it immediately obvious when a source file has no corresponding test.
src/modules/cms/services/content.service.ts
src/modules/cms/services/content.service.spec.ts

src/modules/cms/controllers/content.controller.ts
src/modules/cms/controllers/content.controller.spec.ts

src/modules/cms/dto/create-content.dto.ts
src/modules/cms/dto/create-content.dto.spec.ts
The .spec.ts suffix is the project-wide convention for all test files on both frontend and backend.

Test Database Setup

Integration tests that hit the database use a separate PostgreSQL database named ssa_test. This database is:
  • Created and migrated automatically by the test setup script using prisma migrate deploy
  • Seeded with minimal fixture data per test suite
  • Cleaned between test runs using prisma migrate reset --force
Never run integration tests against the development or production database. The test runner will truncate tables as part of setup and teardown.

Mocking Guidelines

Use the NestJS testing module (@nestjs/testing) to replace real providers with mocks. Create a mock factory function for each service to keep mock definitions consistent across test files.
const mockContentRepository = {
  findAll: jest.fn(),
  findById: jest.fn(),
  create: jest.fn(),
  update: jest.fn(),
};
Use jest-mock-extended or manual mocks to replace the Prisma client in unit tests. Repository unit tests should never open a real database connection.
Use axios-mock-adapter or Vitest’s vi.mock() to intercept HTTP calls in frontend unit and component tests. Never make real network calls in unit tests.

Quality Gate

All new features require tests before the PR is merged. There is no enforced minimum coverage percentage, but every public service method must have at least one test covering its primary behaviour. A PR that adds a service method without a corresponding .spec.ts entry will be rejected in code review.
When adding to an existing module, check the current .spec.ts file first. If the test file is missing, create it as part of the same PR — do not defer it to a follow-up.

Coding Conventions

File naming, TypeScript rules, and layer responsibilities.

Tech Stack

Jest, Vitest, and Supertest in context with the rest of the stack.

Architecture Overview

The modular structure that determines what gets unit-tested vs integration-tested.

Deployment

How the CI pipeline runs tests before every deployment.

Build docs developers (and LLMs) love