import io from datetime import date import uuid from fastapi.testclient import TestClient from app.main import app from app.auth.security import get_current_user def _csv_file(name: str, text: str): return ("files", (name, io.BytesIO(text.encode("utf-8")), "text/csv")) def _seed_file(client: TestClient, file_no: str, owner_id: str = None) -> None: owner_id = owner_id or f"R{uuid.uuid4().hex[:6]}" rolodex_csv = f"Id,Last\n{owner_id},Alpha\n" files_csv = ( "File_No,Id,File_Type,Regarding,Opened,Empl_Num,Status,Rate_Per_Hour\n" f"{file_no},{owner_id},CIVIL,Test,{date.today():%Y-%m-%d},E01,ACTIVE,100\n" ) client.post("/api/import/batch-upload", files=[ _csv_file("ROLODEX.csv", rolodex_csv), _csv_file("FILES.csv", files_csv), ]) def _auth(): app.dependency_overrides[get_current_user] = lambda: { "id": 1, "username": "tester", "is_admin": True, "is_active": True, } def test_pension_crud_and_validation(): _auth() client = TestClient(app) file_no = f"PF-CRUD-{uuid.uuid4().hex[:8]}" _seed_file(client, file_no) # Create create_payload = { "file_no": file_no, "version": "01", "plan_id": "PID1", "plan_name": "Plan A", "vested_per": 50, "tax_rate": 25, } r = client.post("/api/pensions/", json=create_payload) assert r.status_code == 201 pid = r.json()["id"] # Get rg = client.get(f"/api/pensions/{pid}") assert rg.status_code == 200 and rg.json()["plan_name"] == "Plan A" # Update ru = client.put(f"/api/pensions/{pid}", json={"plan_name": "Plan B", "vested_per": 75}) assert ru.status_code == 200 and ru.json()["plan_name"] == "Plan B" and ru.json()["vested_per"] == 75 # Validation edges: negative values or over 100 should fail bads = [ {"vested_per": -1}, {"vested_per": 101}, {"tax_rate": -5}, {"tax_rate": 150}, {"valu": -0.01}, ] for payload in bads: rv = client.put(f"/api/pensions/{pid}", json=payload) assert rv.status_code == 422 # Delete rd = client.delete(f"/api/pensions/{pid}") assert rd.status_code == 204 r404 = client.get(f"/api/pensions/{pid}") assert r404.status_code == 404 app.dependency_overrides.pop(get_current_user, None)