1+ package org.mobilenativefoundation.store.store5.mutable_store
2+
3+ import app.cash.turbine.test
4+ import dev.mokkery.MockMode.autoUnit
5+ import dev.mokkery.answering.returns
6+ import dev.mokkery.every
7+ import dev.mokkery.everySuspend
8+ import dev.mokkery.matcher.any
9+ import dev.mokkery.matcher.eq
10+ import dev.mokkery.mock
11+ import dev.mokkery.verify
12+ import dev.mokkery.verify.VerifyMode
13+ import dev.mokkery.verify.VerifyMode.Companion.exactly
14+ import dev.mokkery.verifySuspend
15+ import kotlinx.coroutines.flow.flowOf
16+ import kotlinx.coroutines.test.TestScope
17+ import kotlinx.coroutines.test.runTest
18+ import org.mobilenativefoundation.store.store5.Bookkeeper
19+ import org.mobilenativefoundation.store.store5.Logger
20+ import org.mobilenativefoundation.store.store5.StoreReadRequest
21+ import org.mobilenativefoundation.store.store5.StoreReadResponse
22+ import org.mobilenativefoundation.store.store5.StoreReadResponseOrigin
23+ import org.mobilenativefoundation.store.store5.Updater
24+ import org.mobilenativefoundation.store.store5.UpdaterResult
25+ import org.mobilenativefoundation.store.store5.impl.RealMutableStore
26+ import org.mobilenativefoundation.store.store5.impl.RealStore
27+ import org.mobilenativefoundation.store.store5.test_utils.model.Note
28+ import kotlin.test.Test
29+ import kotlin.test.assertEquals
30+
31+ class RealMutableStoreTests {
32+ private val testScope = TestScope ()
33+
34+ private val delegate = mock<RealStore <String , Note , Note , Note >>(autoUnit)
35+ private val updater = mock<Updater <String , Note , Boolean >>(autoUnit)
36+ private val bookkeeper = mock<Bookkeeper <String >>(autoUnit)
37+ private val logger = mock<Logger >(autoUnit)
38+
39+
40+ private val mutableStore = RealMutableStore (
41+ delegate,
42+ updater,
43+ bookkeeper,
44+ logger
45+ )
46+
47+ @Test
48+ fun stream_givenConflicts_whenExceptionResolvingConflicts_thenShouldLog () = testScope.runTest {
49+ // Given
50+ val latestNote = Note (" id" , " Title" , " Content" )
51+ val readResponse = StoreReadResponse .Data (latestNote, StoreReadResponseOrigin .Cache )
52+ val delegateFlow = flowOf(readResponse)
53+ val exception = Exception (" Error updating network." )
54+ val readRequest = StoreReadRequest .fresh(" id" )
55+
56+ every {
57+ delegate.stream(any())
58+ } returns delegateFlow
59+
60+ everySuspend {
61+ delegate.latestOrNull(any())
62+ } returns latestNote
63+
64+ everySuspend {
65+ bookkeeper.getLastFailedSync(any())
66+ } returns 1L
67+
68+ everySuspend {
69+ updater.post(any(), any())
70+ } returns UpdaterResult .Error .Exception (exception)
71+
72+
73+ // When
74+ val stream = mutableStore.stream<Boolean >(
75+ readRequest
76+ )
77+
78+ // Then
79+
80+ stream.test {
81+
82+ verifySuspend(exactly(1 )) {
83+ updater.post(eq(" id" ), eq(latestNote))
84+ }
85+
86+ verify(exactly(1 )) {
87+ logger.error(eq(exception.toString()))
88+ }
89+
90+ verify(exactly(1 )) {
91+ delegate.stream(eq(readRequest))
92+ }
93+
94+ assertEquals(readResponse, awaitItem())
95+
96+ awaitComplete()
97+ }
98+
99+ }
100+
101+ }
0 commit comments