Download backend/tests/test_api.py from Eklavya16/Shortlist: direct link, hf CLI and curl.
- Browser
- Download file 4.85 kB
-
https://huggingface.co/spaces/Eklavya16/Shortlist/resolve/main/backend/tests/test_api.py
- Command line
-
hf download hf://spaces/Eklavya16/Shortlist/backend/tests/test_api.py
-
curl -L -o test_api.py https://huggingface.co/spaces/Eklavya16/Shortlist/resolve/main/backend/tests/test_api.py
4.85 kB
| """ | |
| Shortlist — API Endpoint Tests | |
| Tests for the FastAPI application endpoints. | |
| Uses TestClient for synchronous testing. | |
| """ | |
| import pytest | |
| from fastapi.testclient import TestClient | |
| from app.main import app | |
| def client(): | |
| """Create a test client for the FastAPI app.""" | |
| return TestClient(app) | |
| class TestHealthCheck: | |
| """Tests for the /health endpoint.""" | |
| def test_health_returns_200(self, client): | |
| response = client.get("/health") | |
| assert response.status_code == 200 | |
| def test_health_returns_status(self, client): | |
| response = client.get("/health") | |
| data = response.json() | |
| assert data["status"] == "healthy" | |
| assert "version" in data | |
| assert "environment" in data | |
| def test_health_has_security_headers(self, client): | |
| response = client.get("/health") | |
| assert response.headers.get("X-Content-Type-Options") == "nosniff" | |
| assert response.headers.get("X-Frame-Options") == "DENY" | |
| assert response.headers.get("X-XSS-Protection") == "1; mode=block" | |
| class TestCORS: | |
| """Tests for CORS configuration.""" | |
| def test_cors_allows_configured_origin(self, client): | |
| response = client.options( | |
| "/health", | |
| headers={ | |
| "Origin": "http://localhost:3000", | |
| "Access-Control-Request-Method": "GET", | |
| }, | |
| ) | |
| assert response.headers.get("access-control-allow-origin") == "http://localhost:3000" | |
| def test_cors_blocks_unknown_origin(self, client): | |
| response = client.options( | |
| "/health", | |
| headers={ | |
| "Origin": "http://evil.com", | |
| "Access-Control-Request-Method": "GET", | |
| }, | |
| ) | |
| # Unknown origins should not get CORS headers | |
| assert response.headers.get("access-control-allow-origin") != "http://evil.com" | |
| class TestAuthRequiredEndpoints: | |
| """Tests that protected endpoints require authentication.""" | |
| def test_jd_analyze_requires_auth(self, client): | |
| response = client.post("/api/v1/jd/analyze", json={ | |
| "jd_text": "x" * 100, | |
| "role": "Backend Engineer", | |
| "company_type": "startup", | |
| }) | |
| assert response.status_code == 401 | |
| def test_capstone_generate_requires_auth(self, client): | |
| response = client.post("/api/v1/capstone/generate", json={ | |
| "analysis_id": "test-id", | |
| }) | |
| assert response.status_code == 401 | |
| def test_repo_analyze_requires_auth(self, client): | |
| response = client.post("/api/v1/repo/analyze", json={ | |
| "github_url": "https://github.com/test/repo", | |
| }) | |
| assert response.status_code == 401 | |
| def test_scaffold_generate_requires_auth(self, client): | |
| response = client.post("/api/v1/scaffold/generate", json={ | |
| "project_title": "Test Project", | |
| "project_description": "A test project description here", | |
| }) | |
| assert response.status_code == 401 | |
| def test_portfolio_optimize_requires_auth(self, client): | |
| response = client.post("/api/v1/portfolio/optimize", json={ | |
| "project_title": "Test", | |
| "project_description": "A test project description here", | |
| }) | |
| assert response.status_code == 401 | |
| class TestInputValidation: | |
| """Tests for request validation (Pydantic enforcement).""" | |
| def test_jd_rejects_short_text(self, client): | |
| """JD text under 50 chars should be rejected (auth blocks first with fake token).""" | |
| response = client.post( | |
| "/api/v1/jd/analyze", | |
| json={ | |
| "jd_text": "too short", | |
| "role": "Engineer", | |
| "company_type": "startup", | |
| }, | |
| headers={"Authorization": "Bearer fake-token"}, | |
| ) | |
| # Auth runs before validation, so we get 401 with fake token | |
| assert response.status_code in (401, 422) | |
| def test_jd_rejects_invalid_company_type(self, client): | |
| """Invalid company type should be rejected (auth blocks first with fake token).""" | |
| response = client.post( | |
| "/api/v1/jd/analyze", | |
| json={ | |
| "jd_text": "x" * 100, | |
| "role": "Engineer", | |
| "company_type": "invalid_type", | |
| }, | |
| headers={"Authorization": "Bearer fake-token"}, | |
| ) | |
| assert response.status_code in (401, 422) | |
| def test_repo_rejects_invalid_github_url(self, client): | |
| """Non-GitHub URLs should be rejected (auth blocks first with fake token).""" | |
| response = client.post( | |
| "/api/v1/repo/analyze", | |
| json={"github_url": "https://gitlab.com/user/repo"}, | |
| headers={"Authorization": "Bearer fake-token"}, | |
| ) | |
| assert response.status_code in (401, 422) | |