fix(tests): restrict On Hold/Resume to whichever team currently owns the test

canHold checked role OR role instead of matching the current phase, so
a red_tech still saw (and could call) Hold/Resume on a test already
sitting in blue_evaluating. Fixed on both frontend and backend — the
API had the same gap, not just the button visibility.
This commit is contained in:
kitos
2026-07-14 17:24:05 +02:00
parent 8fcd733d4a
commit 1b7fd6fb36
3 changed files with 85 additions and 3 deletions
+60
View File
@@ -31,6 +31,20 @@ def _seed_executing_test(db, technique, created_by) -> Test:
return test
def _seed_blue_evaluating_test(db, technique, created_by) -> Test:
test = Test(
technique_id=technique.id,
name="Holdable test (blue)",
created_by=created_by,
state=TestState.blue_evaluating,
blue_started_at=datetime.utcnow() - timedelta(minutes=10),
)
db.add(test)
db.commit()
db.refresh(test)
return test
def test_hold_pauses_the_running_timer(client, db, red_tech_headers, red_tech_user):
technique = _seed_technique(db)
test = _seed_executing_test(db, technique, red_tech_user.id)
@@ -88,3 +102,49 @@ def test_hold_does_not_double_pause_an_already_paused_timer(client, db, red_tech
db.refresh(test)
assert test.paused_at == manual_pause_time
def test_red_tech_cannot_hold_a_test_in_blue_evaluating(
client, db, red_tech_headers, red_tech_user,
):
"""Once a test has moved into Blue's queue, only blue_tech may hold it —
a red_tech is no longer involved at this stage."""
technique = _seed_technique(db)
test = _seed_blue_evaluating_test(db, technique, red_tech_user.id)
resp = client.post(
f"/api/v1/tests/{test.id}/hold",
json={"reason": "waiting on lab access"},
headers=red_tech_headers,
)
assert resp.status_code == 403
def test_blue_tech_can_hold_a_test_in_blue_evaluating(
client, db, blue_tech_headers, red_tech_user,
):
technique = _seed_technique(db)
test = _seed_blue_evaluating_test(db, technique, red_tech_user.id)
resp = client.post(
f"/api/v1/tests/{test.id}/hold",
json={"reason": "waiting on EDR access"},
headers=blue_tech_headers,
)
assert resp.status_code == 200, resp.text
def test_blue_tech_cannot_resume_a_test_that_was_held_during_red_executing(
client, db, api, red_tech_headers, blue_tech_headers, red_tech_user,
):
technique = _seed_technique(db)
test = _seed_executing_test(db, technique, red_tech_user.id)
resp = api(
"post", f"/api/v1/tests/{test.id}/hold", red_tech_headers,
json={"reason": "waiting on lab access"},
)
assert resp.status_code == 200, resp.text
resp = api("post", f"/api/v1/tests/{test.id}/resume", blue_tech_headers)
assert resp.status_code == 403