# Testing Guide

**Last Updated**: 2025-01-09 for Sankofa Phoenix

## Overview

This guide covers testing strategies, test suites, and best practices for the Sankofa Phoenix platform.

## Test Structure

```
api/
  src/
    services/
      __tests__/
        *.test.ts          # Unit tests for services
    adapters/
      __tests__/
        *.test.ts          # Adapter tests
    schema/
      __tests__/
        *.test.ts          # GraphQL resolver tests

src/
  components/
    __tests__/
      *.test.tsx           # Component tests
  lib/
    __tests__/
      *.test.ts            # Utility tests

blockchain/
  tests/
    *.test.ts              # Smart contract tests
```

## Running Tests

### Frontend Tests

```bash
npm test                    # Run all frontend tests
npm test -- --ui           # Run with Vitest UI
npm test -- --coverage     # Generate coverage report
```

### Backend Tests

```bash
cd api
npm test                    # Run all API tests
npm test -- --coverage     # Generate coverage report
```

### Blockchain Tests

```bash
cd blockchain
npm test                    # Run smart contract tests
```

### E2E Tests

```bash
npm run test:e2e           # Run end-to-end tests
```

## Test Types

### 1. Unit Tests

Test individual functions and methods in isolation.

**Example: Resource Service Test**

```typescript
import { describe, it, expect, vi } from 'vitest'
import { getResources } from '../services/resource'

describe('getResources', () => {
  it('should return resources', async () => {
    const mockContext = createMockContext()
    const result = await getResources(mockContext)
    expect(result).toBeDefined()
  })
})
```

### 2. Integration Tests

Test interactions between multiple components.

**Example: GraphQL Resolver Test**

```typescript
import { describe, it, expect } from 'vitest'
import { createTestSchema } from '../schema'
import { graphql } from 'graphql'

describe('Resource Resolvers', () => {
  it('should query resources', async () => {
    const query = `
      query {
        resources {
          id
          name
        }
      }
    `
    const result = await graphql(createTestSchema(), query)
    expect(result.data).toBeDefined()
  })
})
```

### 3. Component Tests

Test React components in isolation.

**Example: ResourceList Component Test**

```typescript
import { render, screen } from '@testing-library/react'
import { ResourceList } from '../ResourceList'

describe('ResourceList', () => {
  it('should render resources', async () => {
    render(<ResourceList />)
    await waitFor(() => {
      expect(screen.getByText('Test Resource')).toBeInTheDocument()
    })
  })
})
```

### 4. E2E Tests

Test complete user workflows.

**Example: Resource Provisioning E2E**

```typescript
import { test, expect } from '@playwright/test'

test('should provision resource', async ({ page }) => {
  await page.goto('/resources')
  await page.click('text=Provision Resource')
  await page.fill('[name="name"]', 'test-resource')
  await page.selectOption('[name="type"]', 'VM')
  await page.click('text=Create')
  
  await expect(page.locator('text=test-resource')).toBeVisible()
})
```

## Test Coverage Goals

- **Unit Tests**: >80% coverage
- **Integration Tests**: >60% coverage
- **Component Tests**: >70% coverage
- **E2E Tests**: Critical user paths covered

## Mocking

### Mock Database

```typescript
const mockDb = {
  query: vi.fn().mockResolvedValue({ rows: [] }),
}
```

### Mock GraphQL Client

```typescript
vi.mock('@/lib/graphql/client', () => ({
  apolloClient: {
    query: vi.fn(),
    mutate: vi.fn(),
  },
}))
```

### Mock Provider APIs

```typescript
global.fetch = vi.fn().mockResolvedValue({
  ok: true,
  json: async () => ({ data: [] }),
})
```

## Test Utilities

### Test Helpers

```typescript
// test-utils.tsx
export function createMockContext(): Context {
  return {
    db: createMockDb(),
    user: {
      id: 'test-user',
      email: 'test@sankofa.nexus',
      name: 'Test User',
      role: 'ADMIN',
    },
  }
}
```

### Test Data Factories

```typescript
export function createMockResource(overrides = {}) {
  return {
    id: 'resource-1',
    name: 'Test Resource',
    type: 'VM',
    status: 'RUNNING',
    ...overrides,
  }
}
```

## CI/CD Integration

Tests run automatically on:

- **Pull Requests**: All test suites
- **Main Branch**: All tests + coverage reports
- **Releases**: Full test suite + E2E tests

## Best Practices

1. **Write tests before fixing bugs** (TDD approach)
2. **Test edge cases and error conditions**
3. **Keep tests independent and isolated**
4. **Use descriptive test names**
5. **Mock external dependencies**
6. **Clean up after tests**
7. **Maintain test coverage**

## Performance Testing

### Load Testing

```bash
# Use k6 for load testing
k6 run tests/load/api-load-test.js
```

### Stress Testing

```bash
# Test API under load
artillery run tests/stress/api-stress.yml
```

## Security Testing

- **Dependency scanning**: `npm audit`
- **SAST**: SonarQube analysis
- **DAST**: OWASP ZAP scans
- **Penetration testing**: Quarterly assessments

## Test Reports

Test reports are generated in:
- `coverage/` - Coverage reports
- `test-results/` - Test execution results
- `playwright-report/` - E2E test reports

## Troubleshooting Tests

### Tests Timing Out

- Check for unclosed connections
- Verify mocks are properly reset
- Increase timeout values if needed

### Flaky Tests

- Ensure tests are deterministic
- Fix race conditions
- Use proper wait conditions

### Database Test Issues

- Ensure test database is isolated
- Clean up test data after each test
- Use transactions for isolation

