git-subtree-dir: fiscal git-subtree-mainline:d95165fc8fgit-subtree-split:102ba84500
81 lines
3.3 KiB
Python
81 lines
3.3 KiB
Python
"""Missão 5 / Fase 1.2: 'Tabelas oficiais' admin screen - list, diff, approve/reject (CSRF, audited)."""
|
|
from sqlalchemy import select
|
|
|
|
from central.app.models import AuditEvent, Dataset
|
|
from central.app.reference_registry import register_draft
|
|
from central.tests.test_control_panel_pages import _panel_client
|
|
from central.tests.test_rtc_security import _become, _post
|
|
|
|
|
|
def _seed_draft(client, **kw):
|
|
with client._session_factory() as s:
|
|
d = register_draft(s, kind=kw.get("kind", "NCM"), provider=kw.get("provider", "Siscomex"), source_url="https://x",
|
|
sha256=kw.get("sha256", "a" * 64), version_label=kw.get("version_label", "v1"), record_count=kw.get("record_count", 100),
|
|
parse_errors=kw.get("parse_errors") or {})
|
|
return d.id
|
|
|
|
|
|
def test_page_requires_admin():
|
|
client, agent_id, _ = _panel_client()
|
|
_become(client, "PADRAO")
|
|
resp = client.get("/admin/reference-datasets", follow_redirects=False)
|
|
assert resp.status_code == 403
|
|
|
|
|
|
def test_admin_sees_the_draft_and_its_diff():
|
|
client, agent_id, _ = _panel_client()
|
|
_seed_draft(client)
|
|
_become(client, "ADMIN")
|
|
page = client.get("/admin/reference-datasets").text
|
|
assert "Tabelas oficiais" in page and "NCM" in page and "DRAFT" in page
|
|
assert "Primeira vers" in page # first version of this kind, no vigente to diff against
|
|
|
|
|
|
def test_approve_promotes_and_is_audited():
|
|
client, agent_id, _ = _panel_client()
|
|
dataset_id = _seed_draft(client)
|
|
_become(client, "ADMIN")
|
|
resp = _post(client, f"/admin/reference-datasets/{dataset_id}/decide", action="approve")
|
|
assert resp.status_code == 303
|
|
with client._session_factory() as s:
|
|
assert s.get(Dataset, dataset_id).status == "VIGENTE"
|
|
acts = [e.action for e in s.scalars(select(AuditEvent))]
|
|
assert "REFERENCE_DATASET_APPROVE" in acts
|
|
|
|
|
|
def test_reject_never_promotes():
|
|
client, agent_id, _ = _panel_client()
|
|
dataset_id = _seed_draft(client)
|
|
_become(client, "ADMIN")
|
|
assert _post(client, f"/admin/reference-datasets/{dataset_id}/decide", action="reject").status_code == 303
|
|
with client._session_factory() as s:
|
|
assert s.get(Dataset, dataset_id).status == "REJECTED"
|
|
|
|
|
|
def test_approve_with_parse_errors_is_refused_with_422():
|
|
client, agent_id, _ = _panel_client()
|
|
dataset_id = _seed_draft(client, parse_errors={"MINIMUM_ENTRIES": "too few"})
|
|
_become(client, "ADMIN")
|
|
resp = _post(client, f"/admin/reference-datasets/{dataset_id}/decide", action="approve")
|
|
assert resp.status_code == 422
|
|
with client._session_factory() as s:
|
|
assert s.get(Dataset, dataset_id).status == "DRAFT"
|
|
|
|
|
|
def test_non_admin_cannot_decide_and_it_is_audited_as_a_denial():
|
|
client, agent_id, _ = _panel_client()
|
|
dataset_id = _seed_draft(client)
|
|
_become(client, "PADRAO")
|
|
resp = _post(client, f"/admin/reference-datasets/{dataset_id}/decide", action="approve")
|
|
assert resp.status_code == 403
|
|
with client._session_factory() as s:
|
|
assert s.get(Dataset, dataset_id).status == "DRAFT"
|
|
|
|
|
|
def test_wrong_csrf_is_refused():
|
|
client, agent_id, _ = _panel_client()
|
|
dataset_id = _seed_draft(client)
|
|
_become(client, "ADMIN")
|
|
resp = client.post(f"/admin/reference-datasets/{dataset_id}/decide", data={"csrf_token": "bad", "action": "approve"}, follow_redirects=False)
|
|
assert resp.status_code in (400, 403)
|