# Postgres Crate Tests This document explains how to set up and run the unit tests for the postgres crate. ## Prerequisites 1. **PostgreSQL Database**: You need a PostgreSQL database running locally or remotely 2. **Test Database**: Create a test database (e.g., `sharenet_test`) 3. **Environment Variables**: Set up the `DATABASE_URL` environment variable ## Setup ### 1. Database Setup Create a test database: ```sql CREATE DATABASE sharenet_test; ``` ### 2. Environment Configuration Set the `DATABASE_URL` environment variable: ```bash export DATABASE_URL="postgres://username:password@localhost:5432/sharenet_test" ``` Or create a `.env` file in the postgres crate directory: ```env DATABASE_URL=postgres://username:password@localhost:5432/sharenet_test ``` ### 3. SQLx Setup If you're using SQLx with offline mode, prepare the query cache: ```bash cd backend/crates/postgres cargo sqlx prepare ``` ## Migrations and Schema - The `users` table now enforces a unique constraint on the `username` field. This is implemented via a separate migration file: - `20240101000001_add_username_unique_constraint.sql` - If you have already run previous migrations, make sure to apply the new migration: ```bash cd backend/crates/postgres sqlx migrate run ``` ## Running Tests ### Run All Tests ```bash cd backend/crates/postgres cargo test ``` ### Run Specific Test Modules ```bash # Run only user repository tests cargo test user_repository_tests # Run only product repository tests cargo test product_repository_tests # Run only service tests cargo test service_tests # Run only error handling tests cargo test error_handling_tests ``` ### Run Tests with Output ```bash cargo test -- --nocapture ``` ## Test Isolation - The test setup function (`setup_test_db`) now always cleans up the database at the start of each test, ensuring a clean state for every test run. - For full isolation and to avoid concurrency issues, run tests with a single thread: ```bash cargo test -- --test-threads=1 ``` ## Test Structure The tests are organized into the following modules: ### 1. User Repository Tests (`user_repository_tests`) Tests for the `PostgresUserRepository` implementation: - **CRUD Operations**: Create, Read, Update, Delete users - **Error Handling**: Not found scenarios, duplicate constraints - **Edge Cases**: Empty results, partial updates ### 2. Product Repository Tests (`product_repository_tests`) Tests for the `PostgresProductRepository` implementation: - **CRUD Operations**: Create, Read, Update, Delete products - **Error Handling**: Not found scenarios - **Edge Cases**: Empty results, partial updates ### 3. Service Tests (`service_tests`) Tests for the service layer that wraps the repositories: - **Full Workflow**: Complete CRUD operations through services - **Integration**: Repository and service interaction ### 4. Error Handling Tests (`error_handling_tests`) Tests for error scenarios: - **Database Connection**: Invalid connection strings - **Concurrent Access**: Multiple simultaneous operations ## Test Database Management Each test automatically: 1. **Sets up** a fresh database connection 2. **Runs migrations** to ensure schema is up to date 3. **Cleans up** test data after completion The test setup functions handle: - Database connection pooling - Migration execution - Data cleanup ## Troubleshooting ### Common Issues 1. **Database Connection Failed** - Verify PostgreSQL is running - Check `DATABASE_URL` format - Ensure database exists 2. **Migration Errors** - Ensure migrations are up to date - Check database permissions 3. **SQLx Compilation Errors** - Run `cargo sqlx prepare` to update query cache - Or set `DATABASE_URL` for online mode ### Debug Mode To run tests with more verbose output: ```bash RUST_LOG=debug cargo test -- --nocapture ``` ## Test Data Tests use isolated data and clean up after themselves. Each test: - Creates its own test data - Verifies operations work correctly - Cleans up all created data This ensures tests are independent and don't interfere with each other. ## Performance Considerations - Tests use a connection pool with max 5 connections - Each test runs in isolation - Database operations are async for better performance ## Continuous Integration For CI/CD pipelines: 1. Set up a PostgreSQL service container 2. Configure `DATABASE_URL` environment variable 3. Run `cargo test` in the postgres crate directory Example GitHub Actions setup: ```yaml - name: Setup PostgreSQL uses: Harmon758/postgresql-action@v1.0.0 with: postgresql version: '15' postgresql db: 'sharenet_test' - name: Run Postgres Tests env: DATABASE_URL: postgres://postgres:postgres@localhost:5432/sharenet_test run: | cd backend/crates/postgres cargo test ```