Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,73 @@ It covers the definition of done, module conventions, and local verification ste

---

## Testing

Stellar Tipz uses a **two-layer testing strategy** to balance speed and confidence:

### Unit Tests (Fast, Mocked)

Unit tests use heavy mocking (Prisma, external services) for fast feedback during development.
They verify business logic, validation, error handling, and HTTP contracts.

```bash
npm run test # Run all unit tests
npm run test:watch # Watch mode for development
npm run test:coverage # Generate coverage report
```

**When to use:** TDD, refactoring, quick validation of business logic changes.

### Integration Tests (Real Database)

Integration tests run against a **real Postgres instance** to catch issues that mocks cannot detect:
- **Constraint violations** (unique, foreign key, check constraints)
- **Transaction bugs** (deadlocks, isolation issues)
- **Migration drift** (schema changes that break existing code)
- **Concurrent operations** (race conditions, P2002 handling)

```bash
# Start test database (isolated from dev DB)
npm run test:db:up

# Run integration tests
npm run test:integration

# Watch mode for integration tests
npm run test:integration:watch

# Stop test database
npm run test:db:down

# Reset test database (clean slate)
npm run test:db:reset
```

**Test database:** Runs on port `5433` (different from dev DB on `5432`) to avoid conflicts.
Each test runs in **isolation** — the database is cleaned before every test.

**Critical flows covered:**
- Auth: challenge creation, user registration, token lifecycle
- Tips: recording with P2002 handling, user relations, status transitions
- Refunds: unique constraint enforcement, concurrent request handling (#1249)
- Withdrawals: balance calculations, duplicate prevention, cascade deletes

### CI Behavior

Both test suites run in parallel on every PR:
- **Unit tests:** Fast feedback (< 1 minute)
- **Integration tests:** Real Postgres via GitHub service containers, migrations applied
to verify schema validity before deploy

See `.github/workflows/backend-integration-tests.yml` for CI configuration.

### Migration Validation

Integration tests apply migrations at suite start — **this is a major win by itself**.
If a migration is broken, CI fails before the code reaches production.

---

## Tech stack

| Concern | Choice |
Expand Down
41 changes: 41 additions & 0 deletions backend/docker-compose.test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Test infrastructure for integration tests: PostgreSQL and Redis
# Usage: docker compose -f backend/docker-compose.test.yml up -d
#
# This compose file provides isolated test databases that don't conflict with
# the development environment. Integration tests run migrations and use real
# Postgres to catch constraint violations, transaction bugs, and migration drift.

services:
postgres-test:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: tipz_test
POSTGRES_PASSWORD: tipz_test
POSTGRES_DB: tipz_test
ports:
- '5433:5432' # Different port to avoid conflict with dev DB
volumes:
- tipz_test_pgdata:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U tipz_test']
interval: 5s
timeout: 5s
retries: 5

redis-test:
image: redis:7-alpine
restart: unless-stopped
ports:
- '6380:6379' # Different port to avoid conflict with dev Redis
volumes:
- tipz_test_redisdata:/data
healthcheck:
test: ['CMD', 'redis-cli', 'ping']
interval: 5s
timeout: 5s
retries: 5

volumes:
tipz_test_pgdata:
tipz_test_redisdata:
5 changes: 5 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"test:integration": "vitest run --config vitest.integration.config.ts",
"test:integration:watch": "vitest --config vitest.integration.config.ts",
"test:db:up": "docker compose -f docker-compose.test.yml up -d",
"test:db:down": "docker compose -f docker-compose.test.yml down",
"test:db:reset": "docker compose -f docker-compose.test.yml down -v && docker compose -f docker-compose.test.yml up -d",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:studio": "prisma studio",
Expand Down
Loading
Loading