test(desktop): pin the RelayAgentInfo Tauri payload to snake_case - #6245
rmichelena wants to merge 1 commit into
Conversation
RelayAgentInfo is the payload of list_relay_agents and revalidate_relay_agents, and the frontend maps it by hand: fromRawRelayAgent in desktop/src/shared/api/tauri.ts reads owner_pubkey, agent_type, channel_ids, respond_to and respond_to_allowlist and rewrites them to camelCase. That contract rests entirely on this struct not carrying #[serde(rename_all = "camelCase")]. Adding it is the reflex when a Rust struct feeds a TypeScript client, and here it fails silently: RawRelayAgent marks all five fields optional, so the mapper does not throw -- it yields null / [] / null -- and nothing in the repo asserts the wire shape, so no test goes red. Every relay agent would arrive owner-less, typeless, channel-less and with respondTo null, which relayAgentIsSharedWithUser treats as deny. The directory would stop being mentionable on a green build. The blast radius grew recently: owner_pubkey and channel_ids joined this struct after the mapper was written, so it is five hand-mapped fields now. The test asserts both halves -- the snake_case keys are present with the expected values, and the camelCase spellings are absent -- because only the second half catches an added rename_all. Checked by breaking it, not by watching it pass: with rename_all = "camelCase" the test fails on the owner_pubkey assertion, and passes again once removed. It sits with the existing serde-contract tests in the same file (respond_to_serde_is_kebab_case, and the needs_restart / restart_diff snake_case assertion), and runs in CI through just desktop-tauri-test. Split out of block#5483, closed as superseded by block#6086, block#6182 and block#6224 -- those implemented the directory work it proposed, but nothing carried this contract across. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Roberto Michelena <77797875+rmichelena@users.noreply.github.com>
99936c8 to
499963f
Compare
|
Rebased onto Re-verified against current
The second row is the point of the PR: the acceptance criterion was proven by breaking it. Nothing else in the repo fails when that attribute is added, yet No CI has ever run on this branch: the workflow runs sit at |
🔐 Codex Security Review
|
Summary
Add one regression test pinning that
RelayAgentInfocrosses the Tauri boundary withsnake_case keys, and that the camelCase spellings never appear on the wire.
No behaviour change — this is a test-only PR closing a silent-failure hole.
Why
RelayAgentInfois the payload oflist_relay_agentsandrevalidate_relay_agents, andthe frontend maps it by hand.
fromRawRelayAgent(desktop/src/shared/api/tauri.ts:655)reads
owner_pubkey,agent_type,channel_ids,respond_toandrespond_to_allowlistand rewrites them to camelCase for the
RelayAgenttype.That contract rests entirely on the struct not carrying
#[serde(rename_all = "camelCase")].Adding it is the reflex when a Rust struct feeds a TypeScript client, and here it fails
silently in both directions:
RawRelayAgent(tauri.ts:101) marks all five fields optional, so the mapper does notthrow — it produces
null/[]/null.The runtime result is every relay agent arriving owner-less, typeless, channel-less and
with
respondTo: null— whichrelayAgentIsSharedWithUser(
desktop/src/features/agents/lib/agentAutocompleteEligibility.ts:39) treats as deny.The whole relay directory would quietly stop being mentionable, with a green build.
The blast radius grew recently:
owner_pubkeyandchannel_idswere added to this structafter the original mapper, so it is five hand-mapped fields now, not three.
Validation
just desktop-tauri-testruns this (.github/workflows/ci.yml:204→cd desktop/src-tauri && cargo test --workspace, path-filtered ondesktop/src-tauri/**),so the test actually executes in CI rather than only existing.
Acceptance criterion checked by breaking it, not just by watching it pass: adding
#[serde(rename_all = "camelCase")]toRelayAgentInfomakes the test fail on the firstassertion (
owner_pubkeyabsent); removing it makes it pass again. A contract test thatdoes not go red when the contract breaks buys nothing.
cd desktop/src-tauri && cargo test --workspace relay_agent_info_wire_keys— 1 passedcargo fmtcleanNotes
The test lives next to the existing serde-contract tests in the same file
(
respond_to_serde_is_kebab_case, and theneeds_restart/restart_diffsnake_caseassertion at the end), so it follows the file's established shape rather than introducing
a new one.
Split out of #5483, which I closed as superseded by #6086 / #6182 / #6224 — those PRs
implemented the directory work it proposed, but nothing carried this contract test across.