Spaces:
Sleeping
Sleeping
| # TradeFlow AI Test Suite | |
| ## Overview | |
| Comprehensive test suite covering critical security and reliability fixes implemented in the audit remediation. | |
| ## Test Files | |
| ### `conftest.py` | |
| Shared fixtures for all tests: | |
| - `test_client`: FastAPI test client | |
| - `mock_current_user`: Authenticated operator user | |
| - `mock_admin_user`: Authenticated admin user | |
| - `mock_supabase`: Mocked Supabase AsyncClient | |
| - Sample file bytes (PDF, PNG, malicious) | |
| ### `test_config.py` | |
| Configuration and environment variable tests: | |
| - ✅ `GEMINI_API_KEY` is required (not hardcoded) | |
| - ✅ `GEMINI_API_KEY` must come from environment variable | |
| - ✅ CORS origins are controlled (not wildcard) | |
| ### `test_routers_batches.py` | |
| File upload validation tests: | |
| - File magic number validation (detects spoofed files) | |
| - File size limits (50MB max) | |
| - MIME type validation | |
| - Filename path traversal protection | |
| - Batch creation with invalid files (rollback) | |
| - Maximum 3 files per batch | |
| - doc_types validation | |
| ### `test_routers_blockchain.py` | |
| Authorization and access control tests: | |
| - ✅ Authentication required for blockchain endpoints | |
| - ✅ Users can only access their company's batches | |
| - ✅ Admins can access any batch | |
| - ✅ Non-existent batch handling | |
| - ✅ Batch ownership verification | |
| ### `test_ai_nodes_extract.py` | |
| AI node error handling tests: | |
| - ✅ Validates required document fields (doc_id, pages) | |
| - ✅ Handles empty document lists | |
| - ✅ Catches only specific exceptions (ValueError, KeyError) | |
| - ✅ Re-raises unexpected exceptions | |
| - ✅ Correctly combines data from multiple documents | |
| ### `test_dependencies.py` | |
| JWT and authentication tests: | |
| - ✅ Keycloak JWKS cached with TTL (1 hour) | |
| - ✅ JWKS refreshes after TTL expires | |
| - ✅ HTTP errors in JWKS fetch are handled | |
| - ✅ CurrentUser stores all required fields | |
| ### `test_storage_service.py` | |
| Storage security tests: | |
| - ✅ MinIO bucket created with private policy | |
| - ✅ Bucket policy denies public access | |
| - ✅ Existing buckets are handled correctly | |
| - ✅ File upload paths are sanitized | |
| ## Running Tests | |
| ```bash | |
| # Install dev dependencies | |
| pip install -e ".[dev]" | |
| # Run all tests | |
| pytest tests/ | |
| # Run with coverage | |
| pytest tests/ --cov=src --cov-report=html | |
| # Run specific test file | |
| pytest tests/test_config.py -v | |
| # Run specific test | |
| pytest tests/test_config.py::test_gemini_api_key_required -v | |
| ``` | |
| ## Coverage Goals | |
| Target: **70% code coverage** (as per pyproject.toml) | |
| Current coverage baseline: 0% → Target: 70%+ after implementation | |
| ## Critical Security Tests (Must Pass) | |
| 1. **Config Tests** - Ensure API keys are not hardcoded | |
| ```bash | |
| pytest tests/test_config.py -v | |
| ``` | |
| 2. **Authorization Tests** - Ensure cross-company access is blocked | |
| ```bash | |
| pytest tests/test_routers_blockchain.py::test_get_blockchain_receipt_requires_ownership -v | |
| ``` | |
| 3. **File Validation Tests** - Ensure spoofed files are rejected | |
| ```bash | |
| pytest tests/test_routers_batches.py::test_file_magic_number_validation -v | |
| ``` | |
| 4. **Error Handling Tests** - Ensure exceptions are properly caught | |
| ```bash | |
| pytest tests/test_ai_nodes_extract.py::test_extraction_node_reraises_unknown_exceptions -v | |
| ``` | |
| 5. **Storage Security Tests** - Ensure bucket policy is private | |
| ```bash | |
| pytest tests/test_storage_service.py::test_minio_bucket_policy_denies_public_access -v | |
| ``` | |
| ## Next Steps | |
| 1. **Implement missing test bodies** - The test structure is in place, implementation code needs to be added | |
| 2. **Add integration tests** - Test full pipeline (upload → extract → validate → blockchain) | |
| 3. **Add performance tests** - Ensure large file uploads are handled efficiently | |
| 4. **Add stress tests** - Test behavior under load (rate limiting, timeouts) | |
| 5. **CI/CD integration** - Add to GitHub Actions for automatic testing on PRs | |
| ## Integration Testing | |
| - Integration tests are marked with `@pytest.mark.integration` and should run against real service instances. | |
| - Use `docker-compose.integration.yml` to start the required local services: Redis, MinIO, and ChromaDB. | |
| - Run integration tests with: | |
| ```bash | |
| cd apps/api | |
| .venv/bin/python -m pytest -m integration tests/integration -q | |
| ``` | |
| ## Deterministic E2E Testing | |
| When you want reliable end-to-end pipeline validation without external LLM variability, enable deterministic mode: | |
| ```bash | |
| set DETERMINISTIC_E2E=1&&set RUN_KEYCLOAK=1&&set RUN_FULL_E2E=1&&python -m pytest tests/integration -q | |
| ``` | |
| The deterministic mode uses a stable LLM stub for `apps/api/src/ai/nodes/extract.py`, so the extraction and review flow can be validated without Gemini or other external model dependencies. | |
| ## Keycloak E2E Provisioning | |
| The repo includes `scripts/keycloak/provision_e2e.py` to provision a Keycloak E2E client/user and emit a `.env.e2e` file with an `E2E_BEARER_TOKEN`. | |
| ```bash | |
| set KEYCLOAK_SERVER_URL=http://localhost:8080 | |
| set KEYCLOAK_ADMIN=admin | |
| set KEYCLOAK_ADMIN_PASSWORD=admin1234 | |
| python scripts\keycloak\provision_e2e.py | |
| ``` | |
| Then run the guarded auth/E2E tests: | |
| ```bash | |
| set RUN_KEYCLOAK=1&&set RUN_FULL_E2E=1&&python -m pytest tests/integration -q | |
| ``` | |
| > The CI workflow `.github/workflows/e2e.yml` runs the full E2E flow with `DETERMINISTIC_E2E=1` so the test pipeline remains stable without requiring a live LLM. | |
| ## Notes | |
| - All tests use `pytest` with `pytest-asyncio` for async support | |
| - Tests use mocks to avoid external dependencies (Supabase, Gemini API) | |
| - Tests follow AAA pattern: Arrange, Act, Assert | |