= test-approvals == purpose Tests for the approval subsystem: tier immutability, grant semantics, mode-based approval, approval engine edge cases, and the decoupling of approval decisions from tool execution. == responsibilities * Verify that tier levels are immutable and cannot be downgraded * Test grant semantics — who can approve what at which tier * Test mode-based approval (auto-approve, prompt, deny) behavior * Test approval engine edge cases (concurrent requests, expired requests, missing state) * Verify that approval decisions do not couple to tool execution (decoupling invariant) * Test the `ApprovalTrigger` mechanism for policy-driven approval initiation == non-responsibilities * Does not test the `ApprovalCoordinator` server module (tested via `:apps:server`'s own tests) * Does not test the WebSocket approval flow end-to-end * Does not test the approval UI components == key types === TierImmutabilityTest * **kind**: JUnit 5 test class * **purpose**: Verifies that once a tier level is set, it cannot be modified — tier is an immutable value object. === GrantSemanticsTest * **kind**: JUnit 5 test class * **purpose**: Tests that the approval engine correctly grants or denies requests based on tier of the approving entity vs. tier of the request. === ModeApprovalTest * **kind**: JUnit 5 test class * **purpose**: Tests approval mode behavior: auto-approve mode skips user interaction, prompt mode requires explicit decision, deny mode rejects everything. === ApprovalEngineEdgeCasesTest * **kind**: JUnit 5 test class * **purpose**: Tests edge cases in the approval engine: duplicate request IDs, expired timestamps, null fields, concurrent resolution. === NoExecutionCouplingTest * **kind**: JUnit 5 test class * **purpose**: Verifies that approval decisions are evaluated independently of tool execution — rejecting an approval does not require understanding the tool's execution plan. === ApprovalTriggerTest * **kind**: JUnit 5 test class * **purpose**: Tests the approval trigger mechanism — which actions/conditions should trigger an approval request. == event flow *inbound:* Constructed `DomainApprovalRequest` and `DomainApprovalDecision` instances. *outbound:* Assertions on approval state (approved, rejected, pending) and event outcomes. == integration points * `:core:approvals` — `DefaultApprovalEngine`, `ApprovalEngine`, `Tier`, `ApprovalOutcome`, `ApprovalStatus`, approval model types * `:core:events` — approval-related event payload types * `:testing:fixtures` — `ApprovalFixtures` == invariants * Tier levels are immutable — once assigned to a request or tool, the tier cannot change * Policy denial is absolute — an approval cannot override a policy denial * Approval decisions are independent of tool execution details * Duplicate resolution of the same request is idempotent == PlantUML diagram [plantuml, test-approvals, "png"] ---- include::../../diagrams/test-approvals.puml[] ---- == known issues * `ApprovalTriggerTest` behavior depends on how triggers are defined — if the trigger mechanism is not yet fully implemented, the test may be skeletal == open questions * Should there be tests for approval escalation (promoting a request to a higher tier if unresolved)? * Should the approval engine support batch approval (approve N requests at once)?