# Dangerous Pi Test Suite

Comprehensive test suite for the Dangerous Pi backend refactoring.

## Test Structure

```
tests/
├── conftest.py                 # Shared fixtures and configuration
├── unit/                       # Unit tests (isolated, fast)
│   └── services/              # Service layer tests
│       ├── test_pm3_service.py
│       ├── test_system_service.py
│       ├── test_wifi_service.py
│       └── test_update_service.py
└── integration/               # Integration tests (API + services)
    └── api/                   # API endpoint tests
        ├── test_pm3_api.py
        └── ...
```

## Running Tests

### Run all tests
```bash
pytest
```

### Run specific test types
```bash
# Unit tests only
pytest tests/unit/

# Integration tests only
pytest tests/integration/

# Specific service tests
pytest tests/unit/services/test_pm3_service.py
```

### Run with coverage
```bash
# Generate coverage report
pytest --cov=app/backend/services --cov=app/backend/api --cov-report=html

# View coverage report
open htmlcov/index.html
```

### Run specific test classes or methods
```bash
# Run specific test class
pytest tests/unit/services/test_pm3_service.py::TestPM3ServiceCommandExecution

# Run specific test method
pytest tests/unit/services/test_pm3_service.py::TestPM3ServiceCommandExecution::test_execute_command_success
```

### Run with markers
```bash
# Run only async tests
pytest -m asyncio

# Run only unit tests
pytest -m unit

# Skip slow tests
pytest -m "not slow"
```

## Test Coverage

The test suite covers:

### Unit Tests (tests/unit/services/)

**PM3Service** (test_pm3_service.py):
- ✅ Command execution with session validation
- ✅ Session locked error handling
- ✅ PM3 not connected error handling
- ✅ Command failure handling
- ✅ Exception handling
- ✅ Status queries
- ✅ Connection management
- ✅ Session management (create, release, get info)

**SystemService** (test_system_service.py):
- ✅ System information queries (CPU, memory, disk)
- ✅ CPU temperature reading
- ✅ Shutdown operations (immediate and delayed)
- ✅ Restart operations (immediate and delayed)
- ✅ Shutdown cancellation
- ✅ Log retrieval
- ✅ Service status queries
- ✅ Error handling for all operations

**WiFiService** (test_wifi_service.py):
- ✅ WiFi status queries (AP and client modes)
- ✅ Network scanning
- ✅ Network connection (encrypted and open)
- ✅ Network disconnection
- ✅ Mode switching (AP, client, dual, auto, off)
- ✅ Invalid mode handling
- ✅ Dual mode without USB adapter error
- ✅ Saved network management
- ✅ Forget network operation

**UpdateService** (test_update_service.py):
- ✅ Update checking (available and up-to-date)
- ✅ Update downloading
- ✅ Update installation
- ✅ Progress monitoring (all states)
- ✅ Release notes retrieval
- ✅ Combined operations (check+download, full update)
- ✅ Error handling for no update available/downloaded

### Integration Tests (tests/integration/api/)

**PM3 API** (test_pm3_api.py):
- ✅ Status endpoint integration with PM3Service
- ✅ Command endpoint with session management
- ✅ HTTP status code mapping (423 for session locked, 503 for not connected)
- ✅ Connection/disconnection endpoints
- ✅ Request/response format consistency

## Best Practices Demonstrated

### 1. Proper Test Isolation
- Each test is independent and can run in any order
- Mocks are used to isolate unit tests from external dependencies
- Fixtures provide clean test setup

### 2. Clear Test Structure
- Tests follow Arrange-Act-Assert (AAA) pattern
- Descriptive test names explain what is being tested
- Test classes group related tests logically

### 3. Comprehensive Coverage
- Both success and error paths tested
- Edge cases covered (session locked, not connected, etc.)
- Exception handling verified

### 4. Async Test Support
- `pytest-asyncio` used for testing async code
- Proper mocking of async functions with `AsyncMock`

### 5. Integration Testing
- API endpoints tested with FastAPI TestClient
- Service integration verified
- HTTP status codes validated

### 6. Maintainability
- Shared fixtures in conftest.py reduce duplication
- Clear documentation in test docstrings
- Consistent naming conventions

## Writing New Tests

### Unit Test Template
```python
@pytest.mark.asyncio
async def test_feature_success(self, mock_dependency):
    """Test description."""
    # Arrange
    mock_dependency.method.return_value = expected_value
    service = YourService(mock_dependency)

    # Act
    result = await service.your_method()

    # Assert
    assert result.success is True
    assert result.data["key"] == expected_value
    mock_dependency.method.assert_called_once()
```

### Integration Test Template
```python
def test_api_endpoint_success(self, test_client, mock_service):
    """Test API endpoint description."""
    # Arrange
    mock_service.method.return_value = ServiceResult(...)

    # Act
    with patch('app.backend.api.module.container.service', mock_service):
        response = test_client.post("/api/endpoint", json={...})

    # Assert
    assert response.status_code == 200
    assert response.json()["key"] == expected_value
```

## CI/CD Integration

Tests can be run in CI/CD pipelines:

```yaml
# Example GitHub Actions
- name: Run tests
  run: |
    pytest --cov --cov-report=xml

- name: Upload coverage
  uses: codecov/codecov-action@v3
  with:
    file: ./coverage.xml
```

## Troubleshooting

### Tests fail with "RuntimeError: Event loop is closed"
- Ensure `pytest-asyncio` is installed and configured
- Check that `asyncio_mode = auto` is set in pytest.ini

### Import errors
- Verify that PYTHONPATH includes project root
- Check that all __init__.py files are present

### Coverage not generated
- Ensure `pytest-cov` is installed
- Check that source paths in pytest.ini are correct

## Contributing

When adding new features:
1. Write unit tests for the service layer
2. Write integration tests for API endpoints
3. Ensure tests pass: `pytest`
4. Verify coverage: `pytest --cov`
5. Follow existing test patterns and naming conventions
