1717package io.getstream.chat.android.offline.repository
1818
1919import app.cash.turbine.test
20+ import io.getstream.chat.android.DeliveryReceipts
21+ import io.getstream.chat.android.PrivacySettings
22+ import io.getstream.chat.android.ReadReceipts
23+ import io.getstream.chat.android.TypingIndicators
2024import io.getstream.chat.android.client.persistance.repository.UserRepository
25+ import io.getstream.chat.android.models.Mute
2126import io.getstream.chat.android.models.User
27+ import io.getstream.chat.android.offline.randomPrivacySettingsEntity
28+ import io.getstream.chat.android.offline.randomUserEntity
29+ import io.getstream.chat.android.offline.randomUserMuteEntity
30+ import io.getstream.chat.android.offline.repository.domain.push.internal.toEntity
2231import io.getstream.chat.android.offline.repository.domain.user.internal.DatabaseUserRepository
32+ import io.getstream.chat.android.offline.repository.domain.user.internal.DeliveryReceiptsEntity
33+ import io.getstream.chat.android.offline.repository.domain.user.internal.PrivacySettingsEntity
34+ import io.getstream.chat.android.offline.repository.domain.user.internal.ReadReceiptsEntity
35+ import io.getstream.chat.android.offline.repository.domain.user.internal.TypingIndicatorsEntity
2336import io.getstream.chat.android.offline.repository.domain.user.internal.UserDao
37+ import io.getstream.chat.android.offline.repository.domain.user.internal.UserEntity
38+ import io.getstream.chat.android.offline.repository.domain.user.internal.UserMuteEntity
39+ import io.getstream.chat.android.offline.repository.domain.user.internal.toEntity
40+ import io.getstream.chat.android.randomMute
41+ import io.getstream.chat.android.randomPrivacySettings
42+ import io.getstream.chat.android.randomString
2443import io.getstream.chat.android.randomUser
2544import io.getstream.chat.android.test.TestCoroutineRule
2645import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -29,13 +48,15 @@ import kotlinx.coroutines.flow.onEach
2948import kotlinx.coroutines.test.runTest
3049import org.amshove.kluent.shouldBeEqualTo
3150import org.junit.Rule
51+ import org.junit.jupiter.api.Assertions.assertEquals
3252import org.junit.jupiter.api.BeforeEach
3353import org.junit.jupiter.api.Test
3454import org.mockito.kotlin.any
35- import org.mockito.kotlin.argThat
3655import org.mockito.kotlin.mock
3756import org.mockito.kotlin.never
57+ import org.mockito.kotlin.times
3858import org.mockito.kotlin.verify
59+ import org.mockito.kotlin.whenever
3960
4061@ExperimentalCoroutinesApi
4162internal class UserRepositoryTests {
@@ -45,7 +66,6 @@ internal class UserRepositoryTests {
4566 private lateinit var sut: UserRepository
4667
4768 private lateinit var userDao: UserDao
48- private val currentUser: User = randomUser(id = " currentUserId" )
4969
5070 @BeforeEach
5171 fun setup () {
@@ -55,11 +75,55 @@ internal class UserRepositoryTests {
5575
5676 @Test
5777 fun `When insert users Should insert to dao` () = runTest {
58- val users = listOf (randomUser(), randomUser())
78+ val users = listOf (
79+ randomUser(
80+ privacySettings = randomPrivacySettings(),
81+ mutes = List (10 ) { randomMute() },
82+ ),
83+ )
5984
6085 sut.insertUsers(users)
6186
62- verify(userDao).insertMany(argThat { size == 2 })
87+ val expected = users.map { user ->
88+ UserEntity (
89+ id = user.id,
90+ originalId = user.id,
91+ name = user.name,
92+ image = user.image,
93+ role = user.role,
94+ createdAt = user.createdAt,
95+ updatedAt = user.updatedAt,
96+ lastActive = user.lastActive,
97+ invisible = user.isInvisible,
98+ privacySettings = PrivacySettingsEntity (
99+ typingIndicators = TypingIndicatorsEntity (
100+ enabled = user.privacySettings?.typingIndicators?.enabled ? : false ,
101+ ),
102+ readReceipts = ReadReceiptsEntity (
103+ enabled = user.privacySettings?.readReceipts?.enabled ? : false ,
104+ ),
105+ deliveryReceipts = DeliveryReceiptsEntity (
106+ enabled = user.privacySettings?.deliveryReceipts?.enabled ? : false ,
107+ ),
108+ ),
109+ banned = user.isBanned,
110+ mutes = user.mutes.map { mute ->
111+ UserMuteEntity (
112+ userId = mute.user?.id,
113+ targetId = mute.target?.id,
114+ createdAt = mute.createdAt,
115+ updatedAt = mute.updatedAt,
116+ expires = mute.expires,
117+ )
118+ },
119+ teams = user.teams,
120+ teamsRole = user.teamsRole,
121+ extraData = user.extraData,
122+ avgResponseTime = user.avgResponseTime,
123+ pushPreference = user.pushPreference?.toEntity(),
124+ )
125+ }
126+ verify(userDao).insertMany(expected)
63127 }
64128
65129 @Test
@@ -70,12 +134,44 @@ internal class UserRepositoryTests {
70134 }
71135
72136 @Test
73- fun `When insert me Should insert entity with me id to dao` () = runTest {
74- val user = randomUser(id = " userId" )
137+ fun `When insert current user Should insert entity with me id to dao` () = runTest {
138+ val user = randomUser(
139+ privacySettings = randomPrivacySettings(),
140+ mutes = List (10 ) { randomMute() },
141+ )
75142
76143 sut.insertCurrentUser(user)
77144
78- verify(userDao).insert(argThat { id == " me" && originalId == " userId" })
145+ val expected = UserEntity (
146+ id = " me" ,
147+ originalId = user.id,
148+ name = user.name,
149+ image = user.image,
150+ role = user.role,
151+ createdAt = user.createdAt,
152+ updatedAt = user.updatedAt,
153+ lastActive = user.lastActive,
154+ invisible = user.isInvisible,
155+ privacySettings = PrivacySettingsEntity (
156+ typingIndicators = TypingIndicatorsEntity (
157+ enabled = user.privacySettings?.typingIndicators?.enabled ? : false ,
158+ ),
159+ readReceipts = ReadReceiptsEntity (
160+ enabled = user.privacySettings?.readReceipts?.enabled ? : false ,
161+ ),
162+ deliveryReceipts = DeliveryReceiptsEntity (
163+ enabled = user.privacySettings?.deliveryReceipts?.enabled ? : false ,
164+ ),
165+ ),
166+ banned = user.isBanned,
167+ mutes = user.mutes.map(Mute ::toEntity),
168+ teams = user.teams,
169+ teamsRole = user.teamsRole,
170+ extraData = user.extraData,
171+ avgResponseTime = user.avgResponseTime,
172+ pushPreference = user.pushPreference?.toEntity(),
173+ )
174+ verify(userDao).insert(expected)
79175 }
80176
81177 @Test
@@ -168,4 +264,75 @@ internal class UserRepositoryTests {
168264 cancelAndConsumeRemainingEvents()
169265 }
170266 }
267+
268+ @Test
269+ fun `When selectUser If user in cache Should return from cache without querying dao` () = runTest {
270+ val user = randomUser(
271+ privacySettings = randomPrivacySettings(),
272+ mutes = List (10 ) { randomMute() },
273+ )
274+ sut.insertUser(user)
275+
276+ val result = sut.selectUser(user.id)
277+
278+ assertEquals(user, result)
279+ verify(userDao, never()).select(any<String >())
280+ }
281+
282+ @Test
283+ fun `When selectUser If user not in cache but in dao Should query dao and cache result` () = runTest {
284+ val userId = randomString()
285+ val userEntity = randomUserEntity(
286+ id = userId,
287+ originalId = userId,
288+ privacySettings = randomPrivacySettingsEntity(),
289+ mutes = List (10 ) { randomUserMuteEntity() },
290+ )
291+ whenever(userDao.select(userId)).thenReturn(userEntity)
292+
293+ val result = sut.selectUser(userId)
294+
295+ val expected = User (
296+ id = userEntity.id,
297+ name = userEntity.name,
298+ image = userEntity.image,
299+ role = userEntity.role,
300+ createdAt = userEntity.createdAt,
301+ updatedAt = userEntity.updatedAt,
302+ lastActive = userEntity.lastActive,
303+ invisible = userEntity.invisible,
304+ privacySettings = PrivacySettings (
305+ typingIndicators = TypingIndicators (
306+ enabled = userEntity.privacySettings?.typingIndicators?.enabled ? : false ,
307+ ),
308+ readReceipts = ReadReceipts (
309+ enabled = userEntity.privacySettings?.readReceipts?.enabled ? : false ,
310+ ),
311+ deliveryReceipts = DeliveryReceipts (
312+ enabled = userEntity.privacySettings?.deliveryReceipts?.enabled ? : false ,
313+ ),
314+ ),
315+ banned = userEntity.banned,
316+ mutes = userEntity.mutes.map { mute ->
317+ Mute (
318+ user = mute.userId?.let (::User ),
319+ target = mute.targetId?.let (::User ),
320+ createdAt = mute.createdAt,
321+ updatedAt = mute.updatedAt,
322+ expires = mute.expires,
323+ )
324+ },
325+ teams = userEntity.teams,
326+ teamsRole = userEntity.teamsRole,
327+ avgResponseTime = userEntity.avgResponseTime,
328+ pushPreference = null ,
329+ extraData = userEntity.extraData,
330+ )
331+ assertEquals(expected, result)
332+ // Verify it's now in cache - second call should not query dao
333+ val cachedResult = sut.selectUser(userId)
334+ assertEquals(expected, cachedResult)
335+ // Should only query dao once (first call), second call uses cache
336+ verify(userDao, times(1 )).select(userId)
337+ }
171338}
0 commit comments