| """ |
| Tests for application tracking routes. |
| """ |
| import uuid |
|
|
| import pytest |
| from httpx import AsyncClient |
|
|
|
|
| @pytest.mark.asyncio |
| class TestApplicationsCRUD: |
| async def test_create_application(self, client: AsyncClient, auth_headers): |
| response = await client.post( |
| "/api/v1/applications", |
| json={ |
| "custom_job_title": "Senior Engineer", |
| "custom_company_name": "TechCorp", |
| "custom_job_url": "https://techcorp.com/jobs/123", |
| "status": "applying", |
| "notes": "Found via referral", |
| }, |
| headers=auth_headers, |
| ) |
| assert response.status_code == 201 |
| data = response.json() |
| assert data["custom_job_title"] == "Senior Engineer" |
| assert data["custom_company_name"] == "TechCorp" |
| assert data["status"] == "applying" |
|
|
| async def test_list_applications_kanban(self, client: AsyncClient, auth_headers): |
| |
| for status in ["wishlist", "applied", "interviewing"]: |
| await client.post( |
| "/api/v1/applications", |
| json={ |
| "custom_job_title": f"Job ({status})", |
| "custom_company_name": "Company", |
| "status": status, |
| }, |
| headers=auth_headers, |
| ) |
|
|
| response = await client.get("/api/v1/applications", headers=auth_headers) |
| assert response.status_code == 200 |
| data = response.json() |
| assert data["total"] == 3 |
| assert "columns" in data |
| assert len(data["columns"]["wishlist"]) == 1 |
| assert len(data["columns"]["applied"]) == 1 |
| assert len(data["columns"]["interviewing"]) == 1 |
|
|
| async def test_update_application_status(self, client: AsyncClient, auth_headers): |
| |
| create_resp = await client.post( |
| "/api/v1/applications", |
| json={ |
| "custom_job_title": "Engineer", |
| "custom_company_name": "Corp", |
| "status": "applied", |
| }, |
| headers=auth_headers, |
| ) |
| app_id = create_resp.json()["id"] |
|
|
| |
| response = await client.patch( |
| f"/api/v1/applications/{app_id}", |
| json={"status": "interviewing", "notes": "Phone screen scheduled"}, |
| headers=auth_headers, |
| ) |
| assert response.status_code == 200 |
| assert response.json()["status"] == "interviewing" |
|
|
| async def test_delete_application(self, client: AsyncClient, auth_headers): |
| |
| create_resp = await client.post( |
| "/api/v1/applications", |
| json={"custom_job_title": "Delete Me", "custom_company_name": "Corp"}, |
| headers=auth_headers, |
| ) |
| app_id = create_resp.json()["id"] |
|
|
| |
| response = await client.delete(f"/api/v1/applications/{app_id}", headers=auth_headers) |
| assert response.status_code == 204 |
|
|
| async def test_add_interview(self, client: AsyncClient, auth_headers): |
| |
| create_resp = await client.post( |
| "/api/v1/applications", |
| json={"custom_job_title": "Engineer", "custom_company_name": "Corp", "status": "interviewing"}, |
| headers=auth_headers, |
| ) |
| app_id = create_resp.json()["id"] |
|
|
| |
| response = await client.post( |
| f"/api/v1/applications/{app_id}/interviews", |
| json={ |
| "interview_type": "technical", |
| "duration_minutes": 60, |
| "location": "https://meet.google.com/xyz", |
| "notes": "DSA focus", |
| }, |
| headers=auth_headers, |
| ) |
| assert response.status_code == 201 |
|
|
| async def test_unauthorized_access(self, client: AsyncClient): |
| response = await client.get("/api/v1/applications") |
| assert response.status_code == 401 |
|
|
| async def test_cannot_access_others_application(self, client: AsyncClient, auth_headers, admin_headers): |
| |
| create_resp = await client.post( |
| "/api/v1/applications", |
| json={"custom_job_title": "Private", "custom_company_name": "Corp"}, |
| headers=auth_headers, |
| ) |
| app_id = create_resp.json()["id"] |
|
|
| |
| response = await client.patch( |
| f"/api/v1/applications/{app_id}", |
| json={"status": "rejected"}, |
| headers=admin_headers, |
| ) |
| assert response.status_code == 404 |
|
|