# MPC System Test Suite

This directory contains the automated test suite for the MPC Distributed Signature System.

## Test Structure

```
tests/
├── unit/                     # Unit tests for domain logic
│   ├── session_coordinator/  # Session coordinator domain tests
│   ├── account/              # Account domain tests
│   └── pkg/                  # Shared package tests
├── integration/              # Integration tests (require database)
│   ├── session_coordinator/  # Session coordinator repository tests
│   └── account/              # Account repository tests
├── e2e/                      # End-to-end tests (require full services)
│   ├── keygen_flow_test.go   # Complete keygen workflow test
│   └── account_flow_test.go  # Complete account workflow test
├── mocks/                    # Mock implementations for testing
├── docker-compose.test.yml   # Docker Compose for test environment
├── Dockerfile.test           # Dockerfile for test runner
└── README.md                 # This file
```

## Running Tests

### Unit Tests

Unit tests don't require any external dependencies:

```bash
# Run all unit tests
make test-unit

# Or directly with go test
go test -v -race -short ./...
```

### Integration Tests

Integration tests require PostgreSQL, Redis, and RabbitMQ:

```bash
# Start test infrastructure
docker-compose -f tests/docker-compose.test.yml up -d postgres-test redis-test rabbitmq-test migrate

# Run integration tests
make test-integration

# Or directly with go test
go test -v -race -tags=integration ./tests/integration/...
```

### End-to-End Tests

E2E tests require all services running:

```bash
# Start full test environment
docker-compose -f tests/docker-compose.test.yml up -d

# Run E2E tests
make test-e2e

# Or directly with go test
go test -v -race -tags=e2e ./tests/e2e/...
```

### All Tests with Docker

Run all tests in isolated Docker environment:

```bash
# Run integration tests
docker-compose -f tests/docker-compose.test.yml run --rm integration-tests

# Run E2E tests
docker-compose -f tests/docker-compose.test.yml run --rm e2e-tests

# Clean up
docker-compose -f tests/docker-compose.test.yml down -v
```

## Test Coverage

Generate test coverage report:

```bash
make test-coverage
```

This will generate:
- `coverage.out` - Coverage data file
- `coverage.html` - HTML coverage report

## Test Environment Variables

### Integration Tests

- `TEST_DATABASE_URL` - PostgreSQL connection string
  - Default: `postgres://mpc_user:mpc_password@localhost:5432/mpc_system_test?sslmode=disable`
- `TEST_REDIS_URL` - Redis connection string
  - Default: `localhost:6379`
- `TEST_RABBITMQ_URL` - RabbitMQ connection string
  - Default: `amqp://mpc_user:mpc_password@localhost:5672/`

### E2E Tests

- `SESSION_COORDINATOR_URL` - Session Coordinator service URL
  - Default: `http://localhost:8080`
- `ACCOUNT_SERVICE_URL` - Account service URL
  - Default: `http://localhost:8083`

## Writing Tests

### Unit Test Guidelines

1. Test domain entities and value objects
2. Test use case logic with mocked dependencies
3. Use table-driven tests for multiple scenarios
4. Follow naming convention: `TestEntityName_MethodName`

Example:
```go
func TestMPCSession_AddParticipant(t *testing.T) {
    t.Run("should add participant successfully", func(t *testing.T) {
        // Test implementation
    })

    t.Run("should fail when participant limit reached", func(t *testing.T) {
        // Test implementation
    })
}
```

### Integration Test Guidelines

1. Use `//go:build integration` build tag
2. Create and clean up test data in SetupTest/TearDownTest
3. Use testify suite for complex test scenarios
4. Test repository implementations against real database

### E2E Test Guidelines

1. Use `//go:build e2e` build tag
2. Test complete user workflows
3. Verify API contracts
4. Test error scenarios and edge cases

## Mocks

Mock implementations are provided in `tests/mocks/`:

- `MockSessionRepository` - Session coordinator repository mock
- `MockAccountRepository` - Account repository mock
- `MockAccountShareRepository` - Account share repository mock
- `MockEventPublisher` - Event publisher mock
- `MockTokenService` - JWT token service mock
- `MockCacheService` - Cache service mock

Usage:
```go
import "github.com/rwadurian/mpc-system/tests/mocks"

func TestSomething(t *testing.T) {
    mockRepo := new(mocks.MockSessionRepository)
    mockRepo.On("Create", mock.Anything, mock.Anything).Return(nil)

    // Use mockRepo in test

    mockRepo.AssertExpectations(t)
}
```

## CI/CD Integration

The test suite is designed to run in CI/CD pipelines:

```yaml
# GitHub Actions example
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v4
        with:
          go-version: '1.21'

      - name: Run unit tests
        run: make test-unit

      - name: Start test services
        run: docker-compose -f tests/docker-compose.test.yml up -d postgres-test redis-test rabbitmq-test

      - name: Wait for services
        run: sleep 10

      - name: Run migrations
        run: docker-compose -f tests/docker-compose.test.yml run --rm migrate

      - name: Run integration tests
        run: make test-integration

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage.out
```

## Troubleshooting

### Database Connection Issues

If integration tests fail with connection errors:
1. Ensure PostgreSQL is running on port 5433
2. Check `TEST_DATABASE_URL` environment variable
3. Verify database user permissions

### Service Health Check Failures

If E2E tests timeout waiting for services:
1. Check service logs: `docker-compose -f tests/docker-compose.test.yml logs <service-name>`
2. Ensure all required environment variables are set
3. Verify port mappings in docker-compose.test.yml

### Flaky Tests

If tests are intermittently failing:
1. Add appropriate waits for async operations
2. Ensure test data isolation between tests
3. Check for race conditions with `-race` flag
