# Testing Guide

Comprehensive testing strategy for MotoVaultPro Modified Feature Capsule architecture.

## Testing Philosophy

Each feature capsule contains complete, isolated test suites with no cross-feature dependencies.

## Test Structure

### Per Feature Organization
```
backend/src/features/[name]/tests/
├── fixtures/           # Test data
├── unit/              # Isolated unit tests
│   ├── [name].service.test.ts
│   └── [external].client.test.ts
└── integration/       # Full API tests
    └── [name].integration.test.ts
```

## Docker Testing Workflow

### Backend Testing

```bash
# Enter backend container shell
make shell-backend

# Inside container:

# Test all features
npm test

# Test single feature (complete isolation)
npm test -- --testPathPattern=src/features/vehicles

# Test specific test type
npm test -- --testPathPattern=src/features/vehicles/tests/unit
npm test -- --testPathPattern=src/features/vehicles/tests/integration

# Test with coverage
npm test -- --testPathPattern=src/features/vehicles --coverage

# Watch mode
npm run test:watch
```

### Frontend Testing

```bash
# From project root, run tests in frontend container
docker compose exec mvp-frontend npm test

# Watch mode
docker compose exec mvp-frontend npm run test:watch

# With coverage
docker compose exec mvp-frontend npm test -- --coverage
```

### Test Environment Setup
1. **Container-Based**: All tests run inside Docker containers
2. **Database**: Uses the development database in the stack (`motovaultpro`)
3. **Mock External APIs**: No real API calls during testing (where implemented)
4. **Cleanup**: Prefer transactions/cleanup per test; see feature tests for patterns

## Test Types

### Unit Tests
**Location**: `features/[name]/tests/unit/`
**Purpose**: Test business logic in isolation
**Mocking**: All external dependencies mocked

Example: `vehicles.service.test.ts`
- Tests VIN validation logic
- Tests vehicle creation with mocked vPIC responses
- Tests caching behavior with mocked Redis
- Tests error handling paths

### Integration Tests  
**Location**: `features/[name]/tests/integration/`
**Purpose**: Test complete API workflows
**Database**: Real test database with transactions

Example: `vehicles.integration.test.ts`
- Tests complete POST /api/vehicles workflow
- Tests authentication middleware
- Tests database persistence
- Tests error responses

### Test Data
**Location**: Inline within test files
**Purpose**: Test-specific mock data
**Format**: TypeScript objects defined in test files

Tests use inline mock data rather than external fixture files. Example pattern:
```typescript
const mockVehicle = {
  vin: "1HGBH41JXMN109186",
  nickname: "Test Honda",
  color: "Blue"
};

const mockPlatformResponse = {
  make: "Honda",
  model: "Civic",
  year: 2021
};
```

## Testing Commands Reference

### Development Testing
```bash
# Enter backend container
make shell-backend

# Run all tests
npm test

# Run specific feature
npm test -- --testPathPattern=src/features/vehicles
npm test -- --testPathPattern=src/features/fuel-logs
npm test -- --testPathPattern=src/features/maintenance
npm test -- --testPathPattern=src/features/stations

# Run with file watching
npm run test:watch

# Run single test file
npm test -- vehicles.service.test.ts

# Run tests matching pattern
npm test -- --testNamePattern="VIN validation"

# Frontend tests (Jest)
docker compose exec mvp-frontend npm test
```

### Coverage Reports
```bash
# Generate coverage for specific feature
npm test -- --testPathPattern=src/features/vehicles --coverage

# View coverage report
# Inside the container, open using your OS tooling,
# or copy the report out of the container as needed
```

### Container Management
```bash
# Restart containers with fresh database
make rebuild

# View test logs
make logs-backend

# Clean all test data
make clean && make start
```

## Test Configuration

### Jest Configuration
- Backend: `backend/jest.config.js`
- Frontend: `frontend/jest.config.ts`
  - React + TypeScript via `ts-jest`
  - jsdom environment
  - Testing Library setup in `frontend/setupTests.ts`

### Database Testing
- **DB**: Same as development (`motovaultpro`) within Docker
- **Transactions**: Recommended pattern is one transaction per test
- **Isolation**: Keep tests independent; avoid shared state
- **Seeding**: Use feature-level fixtures when needed

### Coverage and Availability
All 15 features have test suites with unit and/or integration tests:
- `admin` - Unit + integration tests
- `auth` - Unit + integration tests
- `backup` - Unit + integration tests
- `documents` - Unit + integration tests
- `fuel-logs` - Unit + integration tests
- `maintenance` - Unit + integration tests
- `notifications` - Unit + integration tests
- `onboarding` - Unit tests
- `platform` - Unit + integration tests
- `stations` - Unit + integration tests (including community stations)
- `terms-agreement` - Unit tests
- `user-export` - Unit tests
- `user-preferences` - Unit tests
- `user-profile` - Unit + integration tests
- `vehicles` - Unit + integration tests

### Mock Strategy
- **External APIs**: Completely mocked (vPIC, Google Maps)
- **Database**: Real database with transactions
- **Redis**: Mocked for unit tests, real for integration
- **Auth**: Mocked JWT tokens for protected endpoints

## Test Data Management

### Inline Mock Data Strategy
```typescript
// In test files - define mock data inline
const mockVehicle = {
  vin: '1HGBH41JXMN109186',
  nickname: 'Test Honda',
  year: 2021,
  make: 'Honda',
  model: 'Civic'
};

describe('Vehicle Service', () => {
  it('should create vehicle', async () => {
    const result = await vehicleService.create(mockVehicle, 'user123');
    expect(result.make).toBe('Honda');
  });
});
```

### Database Seeding
```javascript
beforeEach(async () => {
  // Clean slate for each test
  await db.query('TRUNCATE TABLE vehicles CASCADE');
  
  // Insert test-specific data
  await db.query('INSERT INTO vehicles ...', testData);
});
```

## Debugging Tests

### Debug Single Test
```bash
# Run specific test with debugging
npm test -- --testNamePattern="should create vehicle" --verbose

# Debug integration test
npm test -- features/vehicles/tests/integration --detectOpenHandles
```

### Common Issues

#### Container Connection Issues
```bash
# Check container health
make logs-backend

# Restart with fresh state
make rebuild
```

#### Database Connection Issues
```bash
# Check postgres container
docker compose logs postgres

# Reset database
make clean && make start
```

#### Test Timeout Issues
```bash
# Increase timeout in jest config
# Or debug hanging connections
npm test -- --detectOpenHandles
```

## Continuous Integration

### Pre-commit Testing
All tests must pass before commits:
```bash
# Backend: Enter shell and run tests
make shell-backend
npm run lint
npm test

# Frontend: Run tests from project root
docker compose exec mvp-frontend npm run lint
docker compose exec mvp-frontend npm test
```

### Feature Development Workflow
1. **Write tests first**: TDD approach preferred
2. **Run tests continuously**: Use `npm run test:watch`
3. **Test in containers**: Always verify with `docker compose exec mvp-backend npm test`
4. **Check coverage**: Ensure new code is covered
5. **Integration last**: Run full test suite before PR

## Test Performance

### Parallel Execution
- Jest runs tests in parallel by default
- Feature isolation allows true parallel testing
- No shared state between feature tests

### Test Speed Optimization
- **Unit tests**: Fast (< 1 second per test)
- **Integration tests**: Medium (< 5 seconds per test)
- **Full suite**: Target < 30 seconds total

### Database Optimization
- Use transactions for rollback (faster than truncate)
- Minimal fixture data
- Avoid complex joins in test setup

## Error Testing Strategy

### Expected Error Cases
```javascript
describe('Error Handling', () => {
  it('should handle invalid VIN', async () => {
    await expect(
      vehicleService.create({ vin: 'INVALID' }, 'user123')
    ).rejects.toThrow('Invalid VIN format');
  });
  
  it('should handle vPIC API failure', async () => {
    mockVpicClient.decode.mockRejectedValue(new Error('API down'));
    
    const result = await vehicleService.create(validVehicle, 'user123');
    expect(result.make).toBeNull(); // Graceful degradation
  });
});
```

### External Service Failures
- Mock API failures to test error handling
- Test timeout scenarios
- Test network connectivity issues
- Verify graceful degradation paths
