"""Bounded source counts do not equate occurrence, acknowledgment and acceptance.""" from dataclasses import replace from datetime import timedelta, timezone from urllib.parse import urlencode import pytest from approval_engine.api import App, call from approval_engine.auth import StaticTokenAuthenticator from approval_engine.errors import StoreUnavailable from approval_engine.store import EVENT_CLASSES from tests.conftest import FROZEN, approve def query(since=FROZEN, until=FROZEN + timedelta(seconds=1)): return urlencode({"since": since.isoformat(), "until": until.isoformat()}) def test_occurrence_window_separates_pending_and_delayed_acknowledgments(engine, app): engine.clock = lambda: FROZEN - timedelta(seconds=1) approve(engine) engine.clock = lambda: FROZEN current = approve(engine) engine.clock = lambda: FROZEN + timedelta(seconds=1) engine.consume(current.id, current.binding_digest) status, before = call(app, "GET", "/v1/cadence", query_string=query()) assert status == 200 assert before["counts"]["issuance"] == { "committed": 1, "drained": 0, "pending": 1, "acknowledged_in_window": 0, } assert before["counts"]["use"]["committed"] == 0 # until is exclusive engine.clock = lambda: FROZEN + timedelta(seconds=2) engine.drain(lambda _: None) _, after = call(app, "GET", "/v1/cadence", query_string=query()) assert after["counts"]["issuance"] == { "committed": 1, "drained": 1, "pending": 0, "acknowledged_in_window": 0, } _, ack = call(app, "GET", "/v1/cadence", query_string=query( FROZEN + timedelta(seconds=2), FROZEN + timedelta(seconds=3))) assert ack["counts"]["issuance"]["acknowledged_in_window"] == 2 assert ack["counts"]["use"]["acknowledged_in_window"] == 1 assert all(c["committed"] == 0 for c in ack["counts"].values()) assert set(after["counts"]) == set(EVENT_CLASSES) assert after["source"] == "approval-engine" and after["tenant"] == engine.tenant assert after["window_basis"] == "created_at" assert "acceptance-time" in after["means"] assert "approvers" not in str(after) and current.id not in str(after) def test_timezone_and_subsecond_bounds_are_preserved(app, engine): approve(engine) offset = FROZEN.astimezone(timezone(timedelta(hours=2))) _, result = call(app, "GET", "/v1/cadence", query_string=query(offset, offset + timedelta(seconds=1))) assert result["counts"]["issuance"]["committed"] == 1 _, result = call(app, "GET", "/v1/cadence", query_string=query( FROZEN + timedelta(microseconds=1), FROZEN + timedelta(seconds=1))) assert result["counts"]["issuance"]["committed"] == 0 @pytest.mark.parametrize("qs", [ "since=bad&until=bad", "since=2026-10-04&until=2026-10-05", query(FROZEN, FROZEN), query(FROZEN + timedelta(seconds=1), FROZEN), "since=x", "until=x", "since=&until=x", "since=x&since=y&until=z", query() + "&tenant=other", "window=all", ]) def test_bad_or_unbounded_queries_are_refused(app, qs): assert call(app, "GET", "/v1/cadence", query_string=qs)[0] == 422 def test_window_counts_preserve_lifetime_endpoint_and_authentication(app, engine): approve(engine) _, counts = call(app, "GET", "/v1/cadence") assert counts["issuance"] == 1 and counts["form"] == "heartbeat-or-reconciliation" assert call(app, "GET", "/v1/cadence", authorization=None, query_string=query())[0] == 401 identity = app.authenticator.identities["test-token"] for altered in (replace(identity, scopes=frozenset({"approval:read"})), replace(identity, tenant="tenant:other")): other = App(engine, StaticTokenAuthenticator({"test-token": altered})) assert call(other, "GET", "/v1/cadence", query_string=query())[0] == 403 def test_window_counts_fail_closed_on_store_failure(app, engine, monkeypatch): def unavailable(): raise StoreUnavailable("unavailable") monkeypatch.setattr(engine, "_conn", unavailable) assert call(app, "GET", "/v1/cadence", query_string=query())[0] == 503