PunimTag Web Application - Major Feature Release #1
@ -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
|
||||
|
||||
|
||||
18
README.md
18
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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
```
|
||||
|
||||
111
tests/README.md
Normal file
111
tests/README.md
Normal file
@ -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`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user