# Testing Guide for KMS API

This directory contains comprehensive testing for the Key Management Service (KMS) API, including both Go integration tests and end-to-end bash script tests.

## Test Types

### 1. Go Integration Tests (`integration_test.go`)
Comprehensive Go-based integration tests using the testify framework.

### 2. End-to-End Bash Tests (`e2e_test.sh`)
Curl-based end-to-end tests that can be run against any running KMS server instance.

---

## Go Integration Tests

### Test Coverage

The Go integration tests cover:

#### **Health Check Endpoints**
- Basic health check (`/health`)
- Readiness check with database connectivity (`/ready`)

#### **Application CRUD Operations**
- Create new applications
- List applications with pagination
- Get specific applications by ID
- Update application details
- Delete applications

#### **Static Token Workflow**
- Create static tokens for applications
- Verify static token permissions
- Token validation and permission checking

#### **User Token Authentication Flow**
- User login process
- Token generation for users
- Permission-based access control

#### **Authentication Middleware**
- Header-based authentication validation
- Unauthorized access handling
- User context management

#### **Error Handling**
- Invalid JSON request handling
- Non-existent resource handling
- Proper HTTP status codes

#### **Concurrent Load Testing**
- Multiple simultaneous health checks
- Concurrent application listing requests
- Database connection pooling under load

### Prerequisites

Before running the integration tests, ensure you have:

1. **PostgreSQL Database**: Running on localhost:5432
2. **Test Database**: Create a test database named `kms_test`
3. **Go Dependencies**: All required Go modules installed

#### Database Setup

```bash
# Connect to PostgreSQL
psql -U postgres -h localhost

# Create test database
CREATE DATABASE kms_test;

# Grant permissions
GRANT ALL PRIVILEGES ON DATABASE kms_test TO postgres;
```

### Running Go Integration Tests

#### Run All Integration Tests

```bash
# From the project root directory
go test -v ./test/...
```

#### Run with Coverage

```bash
# Generate coverage report
go test -v -coverprofile=coverage.out ./test/...
go tool cover -html=coverage.out -o coverage.html
```

#### Run Specific Test Suites

```bash
# Run only health endpoint tests
go test -v ./test/ -run TestHealthEndpoints

# Run only application CRUD tests
go test -v ./test/ -run TestApplicationCRUD

# Run only token workflow tests
go test -v ./test/ -run TestStaticTokenWorkflow

# Run concurrent load tests
go test -v ./test/ -run TestConcurrentRequests
```

#### Run with Docker/Podman

```bash
# Start the services first
podman-compose up -d

# Wait for services to be ready
sleep 10

# Run the tests
go test -v ./test/...

# Clean up
podman-compose down
```

---

## End-to-End Bash Tests

### Overview

The `e2e_test.sh` script provides comprehensive end-to-end testing of the KMS API using curl commands. It tests all major functionality including health checks, authentication, application management, and token operations.

### Prerequisites

- `curl` command-line tool installed
- KMS server running (either locally or remotely)
- Bash shell environment

### Quick Start

#### 1. Start the KMS Server

First, make sure your KMS server is running. You can start it using Docker Compose:

```bash
# From the project root directory
docker-compose up -d
```

Or run it directly:

```bash
go run cmd/server/main.go
```

#### 2. Run the E2E Tests

```bash
# Run with default settings (server at localhost:8080)
./test/e2e_test.sh

# Or run with custom configuration
BASE_URL=http://localhost:8080 USER_EMAIL=admin@example.com ./test/e2e_test.sh
```

### Configuration

The script supports several environment variables for configuration:

| Variable | Default | Description |
|----------|---------|-------------|
| `BASE_URL` | `http://localhost:8080` | Base URL of the KMS server |
| `USER_EMAIL` | `test@example.com` | User email for authentication headers |
| `USER_ID` | `test-user-123` | User ID for authentication headers |

#### Examples

```bash
# Test against a remote server
BASE_URL=https://kms-api.example.com ./test/e2e_test.sh

# Use different user credentials
USER_EMAIL=admin@company.com USER_ID=admin-456 ./test/e2e_test.sh

# Test against local server on different port
BASE_URL=http://localhost:3000 ./test/e2e_test.sh
```

### E2E Test Coverage

The bash script tests the following functionality:

#### Health Endpoints
- `GET /health` - Basic health check
- `GET /ready` - Readiness check with database connectivity

#### Authentication Endpoints
- `POST /api/login` - User login (with and without auth headers)
- `POST /api/verify` - Token verification
- `POST /api/renew` - Token renewal

#### Application Management
- `GET /api/applications` - List applications (with pagination)
- `POST /api/applications` - Create new application
- `GET /api/applications/:id` - Get application by ID
- `PUT /api/applications/:id` - Update application
- `DELETE /api/applications/:id` - Delete application

#### Token Management
- `GET /api/applications/:id/tokens` - List tokens for application
- `POST /api/applications/:id/tokens` - Create static token
- `DELETE /api/tokens/:id` - Delete token

#### Error Handling
- Invalid endpoints (404 errors)
- Malformed JSON requests
- Missing authentication headers
- Invalid request formats

#### Documentation
- `GET /api/docs` - API documentation endpoint

---

## Test Configuration

### Go Integration Tests Configuration
The Go tests use a separate test configuration that:

- Uses a dedicated test database (`kms_test`)
- Disables rate limiting for testing
- Disables metrics collection
- Uses debug logging level
- Configures shorter timeouts

### Test Data Management

Both test suites:

- **Clean up after themselves**: Each test cleans up its test data
- **Use isolated data**: Test data is prefixed with `test-` to avoid conflicts
- **Reset state**: Database state is reset between test runs
- **Use transactions**: Where possible, tests use database transactions

## Troubleshooting

### Common Issues

1. **Database Connection Failed**
   ```
   Error: failed to connect to database
   ```
   - Ensure PostgreSQL is running
   - Check database credentials
   - Verify test database exists

2. **Migration Errors**
   ```
   Error: failed to run migrations
   ```
   - Ensure migration files are in the correct location
   - Check database permissions
   - Verify migration file format

3. **Port Already in Use**
   ```
   Error: bind: address already in use
   ```
   - The test server uses random ports, but check if other services are running
   - Stop any running instances of the API service

4. **Server Not Ready (E2E Tests)**
   ```
   [FAIL] Server failed to start within timeout
   ```
   - Ensure the KMS server is running
   - Check if the server is accessible at the configured URL
   - Verify database connectivity

### Debug Mode

#### For Go Tests
```bash
# Enable debug logging
LOG_LEVEL=debug go test -v ./test/...

# Run with race detection
go test -race -v ./test/...

# Run with memory profiling
go test -memprofile=mem.prof -v ./test/...
```

#### For E2E Tests
For more detailed output, you can modify the script to include verbose curl output by adding `-v` flag to curl commands.

## Integration with CI/CD

Both test suites work well in CI/CD pipelines:

```yaml
# Example GitHub Actions workflow
- name: Run Integration Tests
  run: |
    docker-compose up -d
    sleep 10  # Wait for services to start
    go test -v ./test/...
    ./test/e2e_test.sh
    docker-compose down
  env:
    BASE_URL: http://localhost:8080
    USER_EMAIL: ci@example.com
```

## Performance Benchmarks

The concurrent load tests provide basic performance benchmarks:

- **Health Check Load**: 50 concurrent requests
- **Application Listing Load**: 20 concurrent requests
- **Expected Response Time**: < 100ms for health checks
- **Expected Throughput**: > 100 requests/second

These benchmarks help ensure the service can handle reasonable concurrent load.

## Test Architecture

### Go Integration Tests
The integration tests use:

- **testify/suite**: For organized test suites with setup/teardown
- **httptest**: For HTTP server testing
- **testify/assert**: For test assertions
- **testify/require**: For test requirements

### E2E Bash Tests
The bash script provides:

- **Automatic Server Detection**: Waits for server readiness
- **Dynamic Test Data**: Creates and cleans up test resources
- **Comprehensive Error Testing**: Tests various error conditions
- **Robust Error Handling**: Graceful cleanup and clear error messages

## Contributing

When adding new tests:

1. Follow the existing test patterns
2. Clean up test data properly
3. Use descriptive test names
4. Add appropriate assertions
5. Update this documentation if needed

## File Structure

```
test/
├── integration_test.go    # Go integration test suite
├── test_helpers.go        # Test utilities and mocks
├── mock_repositories.go   # Mock implementations for testing
├── e2e_test.sh           # Bash end-to-end test script
└── README.md             # This comprehensive testing guide
