> ## Documentation Index
> Fetch the complete documentation index at: https://system.muzemus.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Unit & Integration Tests

> How backend unit and integration tests are structured

## Test configuration

Backend unit tests run on Jest with ts-jest, configured in `backend/package.json`:

```json theme={null}
{
  "jest": {
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": { "^.+\\.(t|j)s$": "ts-jest" }
  }
}
```

Backend API E2E suites run through a separate Jest config: `pnpm test:e2e` uses `test/jest-e2e.json` with Supertest.

## Unit tests

Unit tests verify individual functions in isolation, with no external dependencies.

### Entitlement criteria tests

```typescript theme={null}
// backend/src/entitlements/entitlement-criteria.spec.ts
import { evaluateRuleCriteria } from '../entitlement-criteria';

describe('evaluateRuleCriteria', () => {
  it('should match employee with matching department', () => {
    const criteria = [{
      attribute: 'department',
      operator: 'IN',
      values: ['dept-1', 'dept-2'],
    }];
    const employee = { departmentId: 'dept-1' };

    expect(evaluateRuleCriteria(criteria, employee)).toBe(true);
  });

  it('should reject employee with non-matching department', () => {
    const criteria = [{
      attribute: 'department',
      operator: 'IN',
      values: ['dept-1'],
    }];
    const employee = { departmentId: 'dept-99' };

    expect(evaluateRuleCriteria(criteria, employee)).toBe(false);
  });

  it('should handle empty criteria (match all)', () => {
    const employee = { departmentId: 'any' };
    expect(evaluateRuleCriteria([], employee)).toBe(true);
  });
});
```

### Entitlement phase tests

```typescript theme={null}
// backend/src/entitlements/entitlement-criteria.sql.spec.ts
import { computeEntitlementPhase } from '../entitlement-phase.util';

describe('computeEntitlementPhase', () => {
  it('should return INITIAL phase before first boundary', () => {
    const result = computeEntitlementPhase({
      hireDate: new Date('2025-01-01'),
      storeRolloutAnchor: new Date('2024-06-01'),
      replacementCycleMonths: 24,
      currentDate: new Date('2026-01-01'),
    });

    expect(result.currentPhase).toBe('INITIAL');
  });

  it('should return REPLACEMENT phase after first boundary', () => {
    const result = computeEntitlementPhase({
      hireDate: new Date('2024-01-01'),
      storeRolloutAnchor: new Date('2024-06-01'),
      replacementCycleMonths: 24,
      currentDate: new Date('2026-07-01'),
    });

    expect(result.currentPhase).toBe('REPLACEMENT');
  });
});
```

## API E2E tests

Backend E2E suites exercise services and controllers against a real database through Supertest.

### Access-control E2E tests (representative)

The access-control suite boots the real app with Supertest and asserts each role can only reach its permitted endpoints:

```typescript theme={null}
// backend/test/access-control.e2e-spec.ts (abridged)
const mockAuthApi = {
  getSession: jest.fn().mockResolvedValue(null),
};

jest.mock('better-auth', () => ({
  betterAuth: jest.fn().mockReturnValue({ api: mockAuthApi }),
}));

describe('Role & Scope Access Control E2E', () => {
  // Boots AppModule against a real database, seeds two clients with stores,
  // then asserts:
  //  - admins can narrow to any client via ?clientId=
  //  - HR is rejected with 403 for data outside their client
  //  - a STORE_MANAGER is never silently given another store's data
});
```

## Test conventions

* Each E2E suite mocks the better-auth session resolver and boots the real `AppModule`, so HTTP flows run against the database
* Suites seed their own fixture data with a run-id suffix and clean up after themselves
* Auth context arrives through `mockRequest` objects in service-level tests

## Mocking patterns

| What to mock   | When                   | How                                |
| -------------- | ---------------------- | ---------------------------------- |
| Prisma queries | Unit tests (isolation) | vi.mock() with return values       |
| HTTP requests  | Frontend unit tests    | MSW (Mock Service Worker)          |
| Auth context   | Service tests          | Mock RequestWithPermissions object |
| Email service  | Integration tests      | Mock nodemailer transport          |
