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
2026-07-05 23:21:02 +02:00
2026-07-28 09:10:20 +02:00
2026-03-24 04:47:19 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00
2026-03-23 01:41:39 +02:00

This is a Kotlin Multiplatform project targeting Android, iOS, Desktop (JVM).

  • /composeApp is for code that will be shared across your Compose Multiplatform applications. It contains several subfolders:

    • commonMain is for code thats common for all targets.
    • Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. For example, if you want to use Apples CoreCrypto for the iOS part of your Kotlin app, the iosMain folder would be the right place for such calls. Similarly, if you want to edit the Desktop (JVM) specific part, the jvmMain folder is the appropriate location.
  • /iosApp contains iOS applications. Even if youre sharing your UI with Compose Multiplatform, you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project.

Build and Run Android Application

To build and run the development version of the Android app, use the run configuration from the run widget in your IDEs toolbar or build it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:assembleDebug
    
  • on Windows
    .\gradlew.bat :composeApp:assembleDebug
    

Build and Run Desktop (JVM) Application

To build and run the development version of the desktop app, use the run configuration from the run widget in your IDEs toolbar or run it directly from the terminal:

  • on macOS/Linux
    ./gradlew :composeApp:run
    
  • on Windows
    .\gradlew.bat :composeApp:run
    

Build and Run iOS Application

To build and run the development version of the iOS app, use the run configuration from the run widget in your IDEs toolbar or open the /iosApp directory in Xcode and run it from there.


Learn more about Kotlin Multiplatform

Description
Mantra as a kotlin multiplatform project
https://mantra.press
Readme 8.2 MiB
Languages
Kotlin 100%