"""GET /tests/{id} must resolve assignee IDs into usernames directly, since GET /users/operators (the only other source of that mapping) is restricted to leads/managers — a plain operator viewing their own assigned test has no other way to find out who they're looking at. Regression: the detail page badge showed "RT: Unassigned" for the assigned operator themselves.""" from app.models.test import Test from app.models.technique import Technique def _seed_technique(db) -> Technique: technique = Technique( mitre_id="T9996", name="Assignee Username Test Technique", tactic="execution", platforms=["linux"], ) db.add(technique) db.commit() db.refresh(technique) return technique def _seed_test(db, technique, created_by, **overrides) -> Test: test = Test(technique_id=technique.id, name="Assignee username test", created_by=created_by, **overrides) db.add(test) db.commit() db.refresh(test) return test def test_red_tech_assignee_username_resolved_for_the_assigned_operator( client, db, red_tech_headers, red_tech_user, red_lead_user, ): technique = _seed_technique(db) test = _seed_test(db, technique, red_lead_user.id, red_tech_assignee=red_tech_user.id) resp = client.get(f"/api/v1/tests/{test.id}", headers=red_tech_headers) assert resp.status_code == 200, resp.text body = resp.json() assert body["red_tech_assignee"] == str(red_tech_user.id) assert body["red_tech_assignee_username"] == red_tech_user.username def test_blue_tech_assignee_username_resolved(client, db, red_lead_headers, red_lead_user, blue_tech_user): technique = _seed_technique(db) test = _seed_test(db, technique, red_lead_user.id, blue_tech_assignee=blue_tech_user.id) resp = client.get(f"/api/v1/tests/{test.id}", headers=red_lead_headers) assert resp.status_code == 200, resp.text assert resp.json()["blue_tech_assignee_username"] == blue_tech_user.username def test_assignee_username_is_none_when_unassigned(client, db, red_lead_headers, red_lead_user): technique = _seed_technique(db) test = _seed_test(db, technique, red_lead_user.id) resp = client.get(f"/api/v1/tests/{test.id}", headers=red_lead_headers) assert resp.status_code == 200, resp.text body = resp.json() assert body["red_tech_assignee"] is None assert body["red_tech_assignee_username"] is None def test_list_endpoint_resolves_assignee_usernames_for_team_queue_overview( client, db, red_lead_headers, red_lead_user, red_tech_user, blue_tech_user, ): """The leads' 'All Tests — Team Queue Overview' section reads assignee usernames off GET /tests (the list endpoint), not just the detail endpoint — both must resolve them the same way.""" technique = _seed_technique(db) _seed_test( db, technique, red_lead_user.id, red_tech_assignee=red_tech_user.id, blue_tech_assignee=blue_tech_user.id, ) resp = client.get("/api/v1/tests", headers=red_lead_headers) assert resp.status_code == 200, resp.text body = resp.json() match = next(t for t in body if t["red_tech_assignee"] == str(red_tech_user.id)) assert match["red_tech_assignee_username"] == red_tech_user.username assert match["blue_tech_assignee_username"] == blue_tech_user.username