File size: 3,114 Bytes
f833573 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | from unittest.mock import patch
from fastapi.testclient import TestClient
from app import main
def test_clear_scope_deletes_only_session_assets_preserves_findings():
original_assets, original_jobs = main.assets, main.jobs
main.assets, main.jobs = {}, {}
try:
with TestClient(main.app) as first, TestClient(main.app) as second:
sid_a = first.get("/api/assets").headers["X-ASFB-Session"]
sid_b = second.get("/api/assets").headers["X-ASFB-Session"]
assert sid_a != sid_b
main.assets["a1"] = {"id": "a1", "owner": sid_a, "name": "https://a.example"}
main.assets["a2"] = {"id": "a2", "owner": sid_a, "name": "https://b.example"}
main.assets["b1"] = {"id": "b1", "owner": sid_b, "name": "https://other.example"}
main.jobs["historical"] = {
"id": "historical", "owner": sid_a, "asset_id": "a1",
"status": "completed", "alerts": [{"source": "zap", "name": "example"}],
}
result = first.delete("/api/assets")
assert result.status_code == 200
assert result.json()["cleared"] == 2
assert first.get("/api/assets").json()["assets"] == []
assert len(second.get("/api/assets").json()["assets"]) == 1
assert main.jobs["historical"]["alerts"][0]["name"] == "example"
assert main.jobs["historical"]["status"] == "completed"
assert first.delete("/api/assets").json()["cleared"] == 0
finally:
main.assets, main.jobs = original_assets, original_jobs
def test_scope_clear_only_cancels_jobs_referencing_removed_assets():
original_assets, original_jobs = main.assets, main.jobs
main.assets, main.jobs = {}, {}
try:
with TestClient(main.app) as client:
sid = client.get("/api/assets").headers["X-ASFB-Session"]
main.assets["target"] = {"id": "target", "owner": sid, "name": "https://example.org"}
main.jobs["queued"] = {
"id": "queued", "owner": sid, "asset_id": "target", "status": "queued"
}
main.jobs["other"] = {
"id": "other", "owner": sid, "asset_id": "unrelated", "status": "queued"
}
with patch.object(main, "cancel_owned_jobs", return_value={
"cancelled_queued": 1, "cancellation_requested_running": 0
}) as cancel:
result = client.delete("/api/assets")
assert result.status_code == 200
assert result.json()["cancelled_queued"] == 1
cancel.assert_called_once_with(sid, {"queued"})
assert "target" not in main.assets
finally:
main.assets, main.jobs = original_assets, original_jobs
def test_scope_clear_dashboard_button_is_distinct_from_clear_selection():
from pathlib import Path
source = Path("app/index.html").read_text()
assert 'id="clearScope"' in source
assert "async function clearScope()" in source
assert "api('/assets',{method:'DELETE'})" in source
assert "function clearSelection()" in source
|