Files
mantra-kmp/composeApp
Kgothatso Ngako 02e70d992a test: cover the MarmotOutboundDao membership guards
Both entry points that change a group's membership start by restoring the MLS
state off the ChatRoom row, and a room restored from an inbound gift wrap has
none -- there is nothing to add a member to. The comment on
inviteMemberToChatRoom says the throw exists to "say so instead of silently
doing nothing and letting the caller report success", which is a claim about
behaviour and therefore something a test can hold to. A guard that returned
quietly would still compile, still look like it worked, and leave a room whose
members believe someone was invited who was not.

Covered: inviteMemberToChatRoom and addMembersToChatRoom each raise
MarmotMissingChatGroupException against a room whose mlsGroupState is null,
which is exactly the shape a gift-wrap-restored room has.

Covered separately, because ordering is the substance of it: a refused invite
leaves no Participant row behind. The guard has to run before that write, not
after. sealGiftWrapPayload walks a room's participants to decide who to wrap a
Welcome for, so a participant persisted by a failed invite would make the room
look like it has a member no MLS group knows about -- and the next Welcome would
be sealed for them.

Covered last: the empty-batch guard returns before the MLS state is looked at,
so addMembersToChatRoom with no peers must *not* throw on the same stateless
room the other two tests reject. Adding nobody is not a failure to add somebody,
and pinning that keeps the two guards from being collapsed into one.

Deliberately not covered, and the test file says so rather than implying the DAO
is done: everything past the guard -- the MLS commit, the Welcome, the epoch
advance and persisting it back to the room -- needs a real peer key package,
which means an MLS fixture this change does not build. That gap includes the
batching rationale on addMembersToChatRoom, which is the more interesting
property of the two: one commit and one Welcome so no member ever has to process
a commit for an epoch they were not yet in, since MarmotInboundManager refuses
future-epoch messages outright with no queue and no replay. Worth covering once
there is a fixture to build a key package with.

The MarmotKeyPackage these tests pass carries an empty byte array, which is
honest: no test here reaches the MLS layer, so the bytes only have to exist. A
test that got past the guard could not use it.

4 tests. composeApp jvmTest is 258 tests, 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 03:05:51 +02:00
..