app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 0ac555a6d9935a1097d9f0c010284276aeff6446
parent 5364a4dee745f7097f1f7fc4a96e903406a0ff28
Author: triesap <tyson@radroots.org>
Date:   Sat,  1 Aug 2026 18:31:31 +0000

runtime: compose the production account store

- construct an empty store at the application boundary
- inject UUID account identifiers only in production composition
- retain store replacement for deterministic UI tests
- prove independent application stores create distinct accounts

Diffstat:
Mapp/desktop/src/main/kotlin/org/radroots/studio/application/RadrootsApplication.kt | 33+++++++++++++++++++++++++++------
Mapp/desktop/src/test/kotlin/org/radroots/studio/application/RadrootsApplicationTest.kt | 23+++++++++++++++++++++++
2 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/app/desktop/src/main/kotlin/org/radroots/studio/application/RadrootsApplication.kt b/app/desktop/src/main/kotlin/org/radroots/studio/application/RadrootsApplication.kt @@ -4,15 +4,36 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.text.BasicText import androidx.compose.runtime.Composable +import androidx.compose.runtime.key +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import java.util.UUID +import org.radroots.studio.accounts.model.AccountId +import org.radroots.studio.accounts.model.AccountsState +import org.radroots.studio.accounts.state.AccountIdFactory +import org.radroots.studio.accounts.state.AccountsReducer +import org.radroots.studio.accounts.state.AccountsStore @Composable -fun RadrootsApplication() { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - BasicText("radroots") +fun RadrootsApplication( + store: AccountsStore = remember { createAccountsStore() }, +) { + key(store.state.value) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + BasicText("radroots") + } } } + +internal fun createAccountsStore( + accountIdFactory: AccountIdFactory = AccountIdFactory { + AccountId(UUID.randomUUID().toString()) + }, +) = AccountsStore( + initialState = AccountsState(), + reducer = AccountsReducer(accountIdFactory), +) diff --git a/app/desktop/src/test/kotlin/org/radroots/studio/application/RadrootsApplicationTest.kt b/app/desktop/src/test/kotlin/org/radroots/studio/application/RadrootsApplicationTest.kt @@ -5,6 +5,9 @@ import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.v2.runComposeUiTest import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals +import org.radroots.studio.accounts.model.AccountsAction class RadrootsApplicationTest { @OptIn(ExperimentalTestApi::class) @@ -16,4 +19,24 @@ class RadrootsApplicationTest { onNodeWithText("radroots").assertIsDisplayed() } + + @Test + fun applicationStoresStartEmptyAndGenerateIndependentIds() { + val first = createAccountsStore() + val second = createAccountsStore() + + listOf(first, second).forEach { store -> + assertEquals(emptyList(), store.state.value.accounts) + store.dispatch(AccountsAction.EditAddDisplayName("Farm Account")) + store.dispatch( + AccountsAction.EditAddServerUrl("https://farm.example.test"), + ) + store.dispatch(AccountsAction.SubmitAddAccount) + } + + assertNotEquals( + first.state.value.accounts.single().id, + second.state.value.accounts.single().id, + ) + } }