Skip to content

test(client): happy-path tests for governance mutators (#416)#466

Merged
intendednull merged 1 commit into
claude/friendly-maxwell-Oggvwfrom
auto-fix/issue-416-governance-mutation-tests
Apr 28, 2026
Merged

test(client): happy-path tests for governance mutators (#416)#466
intendednull merged 1 commit into
claude/friendly-maxwell-Oggvwfrom
auto-fix/issue-416-governance-mutation-tests

Conversation

@intendednull
Copy link
Copy Markdown
Owner

what

five new tests in crates/client/src/tests/governance.rs. one per mutator that lacked tier-2 coverage:

  • propose_grant_admin_emits_propose_grant_admin_event -> asserts EventKind::Propose { ProposedAction::GrantAdmin { peer_id } } lands in DAG with right peer
  • propose_revoke_admin_emits_propose_revoke_admin_event -> asserts EventKind::Propose { ProposedAction::RevokeAdmin { peer_id } } (mutator also fires a follow-up RevokePermission(SendMessages) per its docs; we just assert the propose is there)
  • propose_kick_member_emits_propose_kick_member_event -> asserts EventKind::Propose { ProposedAction::KickMember { peer_id } }
  • propose_set_threshold_emits_propose_set_threshold_event -> asserts EventKind::Propose { ProposedAction::SetVoteThreshold { threshold } } carries the threshold the caller passed (Unanimous)
  • delete_role_emits_delete_role_event -> asserts EventKind::DeleteRole { role_id } carries the requested id, authored by local identity

how

test_client() genesis author = server owner = automatic admin + root-of-trust override. so all five mutators succeed without further permission setup.

each test reads the managed DAG via client.dag_addr and matches the kind variant. why DAG and not wire? test_client() doesn't subscribe to any topic so broadcast_event drops the bytes with a warning. the same signed Event value is fed to both apply_event and broadcast_event in the mutator, so DAG inspection is a faithful proxy.

scope is tier-2 only: mutator -> right EventKind. downstream effects (vote tally, role removal in materialised state) belong in tier-1 state-machine tests; not duplicated here. mirrors the voice.rs (#464) convention.

tradeoffs considered

  • subscribe a MemHub and intercept the wire broadcast -- rejected. would test serialisation + topic plumbing alongside the mutator. the issue specifically asks to assert the resulting EventKind; DAG inspection isolates that. wire-level path is already covered by multi_peer_sync.rs.
  • subscribe ClientEvent::ProposalCreated via broker -- rejected. that variant carries action_description: format!("{:?}", action), a stringified debug. matching against debug strings is brittle. matching the typed EventKind enum is precise.
  • also seed CreateRole before delete_role -- rejected for this tier. state-machine accepts DeleteRole regardless of whether the role exists; that's tier-1's problem. tier-2 just asserts the event carries the id we asked for.

verification

local on worktree (just was available):

  • cargo test -p willow-client governance -> 5 ok
  • cargo fmt --check -> clean
  • cargo clippy --workspace --all-targets -- -D warnings -> clean
  • cargo test --workspace -> all green
  • cargo check --target wasm32-unknown-unknown -p willow-client -> clean

Refs #416


Generated by Claude Code

Adds five tests in crates/client/src/tests/governance.rs covering
the mutators previously only Playwright-covered (or with zero
coverage anywhere):

  * propose_grant_admin     -> Propose { GrantAdmin }
  * propose_revoke_admin    -> Propose { RevokeAdmin }
  * propose_kick_member     -> Propose { KickMember }
  * propose_set_threshold   -> Propose { SetVoteThreshold }
  * delete_role             -> DeleteRole

Each test drives the mutator against a `test_client()` fixture
(genesis author = owner = automatic admin) and inspects the
managed DAG to assert the expected EventKind variant and payload.
Downstream materialisation (vote tally, role removal) is tier-1
state-machine territory and stays out of scope, mirroring the
convention from voice.rs (#464).

Refs #416
@intendednull intendednull merged commit 286da78 into claude/friendly-maxwell-Oggvw Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants