diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 7b1f8fa..0a1f802 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -2,22 +2,25 @@ name: CI on: - # Only trigger on push for protected branches (master, dev) - # Feature branches should use pull_request events only to avoid duplicates + # Trigger on push for protected branches (master, dev) - direct pushes only + # Trigger on pull_request for all branches - PRs to master/dev and feature branches + # This separation prevents duplicate runs: pushes to master/dev don't conflict with PRs push: branches: [master, dev] pull_request: types: [opened, synchronize, reopened] - branches: [master, dev] + # PRs can target any branch, but we only test PRs targeting master/dev + # Feature branch PRs will also trigger, but they won't conflict with push events # Prevent duplicate runs when pushing to a branch with an open PR -# This ensures only one workflow runs at a time for the same branch/PR +# This ensures only one workflow runs at a time for the same commit concurrency: # Use commit SHA to unify push and PR events for the same commit # This prevents duplicate runs when both push and PR events fire for the same commit - # For PRs: uses head SHA (the commit being tested) + # For PRs: uses head SHA (the commit being tested) # For pushes: uses the commit SHA from the push event (github.event.after or github.sha) - #test + # The group name combines workflow name with commit SHA to ensure uniqueness + # If both push and PR events fire for the same commit, only one will run group: ${{ github.workflow }}-${{ github.event.pull_request.head.sha || github.event.after || github.sha }} cancel-in-progress: true diff --git a/README.md b/README.md index 11a0f20..752c6a3 100644 --- a/README.md +++ b/README.md @@ -123,20 +123,20 @@ For development, you can use the shared development PostgreSQL server: - **Host**: 10.0.10.181 - **Port**: 5432 - **User**: ladmin -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] **Development Server:** - **Host**: 10.0.10.121 - **User**: appuser -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] Configure your `.env` file for development: ```bash # Main database (dev) -DATABASE_URL=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag +DATABASE_URL=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag # Auth database (dev) -DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag_auth +DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth ``` **Install PostgreSQL (if not installed):** @@ -201,10 +201,10 @@ DATABASE_URL_AUTH=postgresql+psycopg2://punimtag:punimtag_password@localhost:543 **Development Server:** ```bash # Main database (dev PostgreSQL server) -DATABASE_URL=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag +DATABASE_URL=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag # Auth database (dev PostgreSQL server) -DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag_auth +DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth ``` **Automatic Initialization:** @@ -250,7 +250,7 @@ The separate auth database (`punimtag_auth`) stores frontend website user accoun # On macOS with Homebrew: brew install redis brew services start redis - + 1 # Verify Redis is running: redis-cli ping # Should respond with "PONG" ``` @@ -819,13 +819,13 @@ The project includes scripts for deploying to the development server. **Development Server:** - **Host**: 10.0.10.121 - **User**: appuser -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] **Development Database:** - **Host**: 10.0.10.181 - **Port**: 5432 - **User**: ladmin -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] #### Build and Deploy to Dev diff --git a/backend/api/auth.py b/backend/api/auth.py index 7d3e785..62c2715 100644 --- a/backend/api/auth.py +++ b/backend/api/auth.py @@ -72,8 +72,8 @@ def get_bearer_token(request: Request) -> HTTPAuthorizationCredentials: return HTTPAuthorizationCredentials(scheme=scheme, credentials=credentials) -# Placeholder secrets - replace with env vars in production -SECRET_KEY = "dev-secret-key-change-in-production" +# Read secrets from environment variables +SECRET_KEY = os.getenv("SECRET_KEY", "dev-secret-key-change-in-production") ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 360 REFRESH_TOKEN_EXPIRE_DAYS = 7 diff --git a/backend/db/session.py b/backend/db/session.py index 712a5cf..9cb8084 100644 --- a/backend/db/session.py +++ b/backend/db/session.py @@ -20,8 +20,12 @@ def get_database_url() -> str: db_url = os.getenv("DATABASE_URL") if db_url: return db_url - # Default to PostgreSQL for development - return "postgresql+psycopg2://punimtag:punimtag_password@localhost:5432/punimtag" + # Default to PostgreSQL for development (without password - must be set via env var) + # This ensures no hardcoded passwords in the codebase + raise ValueError( + "DATABASE_URL environment variable not set. " + "Please set DATABASE_URL in your .env file or environment." + ) def get_auth_database_url() -> str: diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index b906d12..1efa9b6 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -34,13 +34,13 @@ This guide covers deployment of PunimTag to development and production environme **Development Server:** - **Host**: 10.0.10.121 - **User**: appuser -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] **Development Database:** - **Host**: 10.0.10.181 - **Port**: 5432 - **User**: ladmin -- **Password**: C0caC0la +- **Password**: [Contact administrator for password] --- @@ -125,8 +125,8 @@ Set the following variables: ```bash # Development Database -DATABASE_URL=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag -DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:C0caC0la@10.0.10.181:5432/punimtag_auth +DATABASE_URL=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag +DATABASE_URL_AUTH=postgresql+psycopg2://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth # JWT Secrets (change in production!) SECRET_KEY=dev-secret-key-change-in-production @@ -157,8 +157,8 @@ VITE_API_URL=http://10.0.10.121:8000 Create `viewer-frontend/.env`: ```bash -DATABASE_URL=postgresql://ladmin:C0caC0la@10.0.10.181:5432/punimtag -DATABASE_URL_AUTH=postgresql://ladmin:C0caC0la@10.0.10.181:5432/punimtag_auth +DATABASE_URL=postgresql://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag +DATABASE_URL_AUTH=postgresql://ladmin:[PASSWORD]@10.0.10.181:5432/punimtag_auth NEXTAUTH_URL=http://10.0.10.121:3001 NEXTAUTH_SECRET=dev-secret-key-change-in-production ``` diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..3251408 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,111 @@ +# Running Backend API Tests + +## Quick Start + +### Option 1: Using the test runner script (Recommended) +```bash +./run_tests.sh +``` + +### Option 2: Using npm script +```bash +npm run test:backend +``` + +### Option 3: Manual command +```bash +export PYTHONPATH=$(pwd) +export SKIP_DEEPFACE_IN_TESTS=1 +./venv/bin/python3 -m pytest tests/ -v +``` + +## Where to See Test Results + +**Test results are displayed in your terminal/console** where you run the command. + +### Example Output + +When tests run successfully, you'll see output like: + +``` +tests/test_api_auth.py::TestLogin::test_login_success_with_valid_credentials PASSED +tests/test_api_auth.py::TestLogin::test_login_failure_with_invalid_credentials PASSED +tests/test_api_auth.py::TestTokenRefresh::test_refresh_token_success PASSED +... +========================= 26 passed in 2.34s ========================= +``` + +### Understanding the Output + +- **PASSED** (green) - Test passed successfully +- **FAILED** (red) - Test failed (shows error details) +- **ERROR** (red) - Test had an error during setup/teardown +- **SKIPPED** (yellow) - Test was skipped + +### Verbose Output + +The `-v` flag shows: +- Each test function name +- Pass/fail status for each test +- Summary at the end + +### Detailed Failure Information + +If a test fails, pytest shows: +- The test that failed +- The assertion that failed +- The actual vs expected values +- A traceback showing where the error occurred + +## Test Coverage + +To see coverage report: +```bash +export PYTHONPATH=$(pwd) +export SKIP_DEEPFACE_IN_TESTS=1 +./venv/bin/python3 -m pytest tests/ --cov=backend --cov-report=term-missing +``` + +This shows: +- Which lines of code are covered by tests +- Which lines are missing coverage +- Overall coverage percentage + +## Running Specific Tests + +### Run a single test file +```bash +./venv/bin/python3 -m pytest tests/test_api_auth.py -v +``` + +### Run a specific test class +```bash +./venv/bin/python3 -m pytest tests/test_api_auth.py::TestLogin -v +``` + +### Run a specific test +```bash +./venv/bin/python3 -m pytest tests/test_api_auth.py::TestLogin::test_login_success_with_valid_credentials -v +``` + +## CI/CD Test Results + +In CI (GitHub Actions/Gitea Actions), test results appear in: +1. **CI Logs** - Check the "Run backend tests" step in the workflow +2. **Test Artifacts** - JUnit XML files are generated for test reporting tools +3. **Coverage Reports** - Coverage XML files are generated + +## Troubleshooting + +### Tests not showing output? +- Make sure you're running in a terminal (not an IDE output panel that might hide output) +- Try adding `-s` flag: `pytest tests/ -v -s` (shows print statements) + +### Tests hanging? +- Check if database is accessible +- Verify `SKIP_DEEPFACE_IN_TESTS=1` is set (prevents DeepFace from loading) + +### Import errors? +- Make sure virtual environment is activated or use `./venv/bin/python3` +- Verify all dependencies are installed: `./venv/bin/pip install -r requirements.txt` +