Kgothatso Ngako 93f8ab313c test(projects): cover the three view models and the query nothing asked about
The feature's logic was tested from the events down to the chronicle and not at
all above the repository. Four gaps, each one something no other layer would
catch.

**AddProjectViewModel.** A project and its contents go out as one batch whose
memberships carry the project's id -- which is a hash over the group's key at
the room's path and does not exist until the proposal is made, so the screen
hands over a function of the signed lead. Nothing downstream notices if that
function returns the wrong thing: a membership naming another project is a
valid event, signs cleanly, and lands as a row pointing elsewhere. Eight cases
assert the batch's shape against a recording repository that signs the lead the
way a finished session does, including that the creator is the member filling
the form in -- there is no field for it and nothing else to check it against.

**AddToProjectViewModel.** The candidate filtering is the only thing stopping a
duplicate membership, because a duplicate is a valid event with its own id: the
keys are satisfied, the signature is good, the row gets written. A wrong filter
would spend a quorum saying what the group has already said and look like the
feature working. Ten cases, including that the two halves filter independently.

**FrostSigningViewModel's resolver.** Unresolved, the signing screen asks a
member to agree to "a4f1be55d0c3". Seven cases through the same `summarize`
call the screen makes: a membership reads as the artifact and label, a stranger
falls back to a hash rather than an invented name, the room owning its own work
says nothing, and a project being signed in the same batch resolves to nothing
-- which is why a membership says the version first.

**getProjectsByTranslationArtifactVersionId** had no test at any layer while its
artifact-side twin had one from the start. That asymmetry is what a copied join
hides.

Two notes for whoever writes the next view-model test. These view models hold
state in `mutableStateOf` and initiate on `Dispatchers.IO`, so there is nothing
to collect and the call returns before the work is done -- hence `awaitValue`,
polling in real time for the same reason `NavigationIdentityRoutingJvmTest`
does. And `NostrRepository.NO_OP_NOSTR_REPOSITORY.getProfileWithPublicKey` is a
`TODO()`, so a resolver that asks it about anybody throws on a background
dispatcher and surfaces as a timeout rather than a failure anybody can read;
these read profiles from the seeded database instead, which also gives the
honest answer for a stranger.

983 jvmTest, 447 testDebugUnitTest, no failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-10-02 20:26:05 +02:00
2026-09-09 17:04:09 +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 that’s 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 Apple’s 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 you’re 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 IDE’s 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 IDE’s 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 IDE’s 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 13 MiB
Languages
Kotlin 100%