1+ /*
2+ * Copyright (c) 2025 Olivier Patry
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining
5+ * a copy of this software and associated documentation files (the "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the Software
9+ * is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+ package net.opatry.tasks.data
24+
25+ import androidx.sqlite.driver.bundled.BundledSQLiteDriver
26+ import kotlinx.coroutines.test.TestScope
27+ import kotlinx.coroutines.test.runTest
28+ import net.opatry.tasks.data.entity.UserEntity
29+ import net.opatry.tasks.data.util.inMemoryTasksAppDatabaseBuilder
30+ import kotlin.test.Test
31+ import kotlin.test.assertEquals
32+ import kotlin.test.assertFalse
33+ import kotlin.test.assertNotNull
34+ import kotlin.test.assertNull
35+ import kotlin.test.assertTrue
36+
37+
38+ private fun runWithInMemoryDatabase (
39+ test : suspend TestScope .(UserDao ) -> Unit
40+ ) = runTest {
41+ val db = inMemoryTasksAppDatabaseBuilder()
42+ .setDriver(BundledSQLiteDriver ())
43+ .setQueryCoroutineContext(backgroundScope.coroutineContext)
44+ .build()
45+
46+ try {
47+ test(db.getUserDao())
48+ } finally {
49+ db.close()
50+ }
51+ }
52+
53+ class UserDaoTest {
54+
55+ @Test
56+ fun `when insert full user then it should be inserted and returned by getById with same content` () = runWithInMemoryDatabase { userDao ->
57+ val user = UserEntity (
58+ remoteId = " remoteId" ,
59+ name = " name" ,
60+ email = " email" ,
61+ avatarUrl = " avatarUrl" ,
62+ isSignedIn = true ,
63+ )
64+
65+ val id = userDao.insert(user)
66+
67+ val insertedUser = userDao.getById(id)
68+ assertNotNull(insertedUser)
69+ assertEquals(id, insertedUser.id)
70+ assertEquals(" remoteId" , insertedUser.remoteId)
71+ assertEquals(" name" , insertedUser.name)
72+ assertEquals(" email" , insertedUser.email)
73+ assertEquals(" avatarUrl" , insertedUser.avatarUrl)
74+ assertTrue(insertedUser.isSignedIn)
75+ }
76+
77+ @Test
78+ fun `when upsert user with remoteId then it should be inserted` () = runWithInMemoryDatabase { userDao -> // Given
79+ val user = UserEntity (
80+ remoteId = " remoteId" ,
81+ name = " name" ,
82+ email = " email" ,
83+ avatarUrl = " avatarUrl" ,
84+ isSignedIn = true ,
85+ )
86+ val id = userDao.insert(user)
87+
88+ val updatedId = userDao.upsert(user.copy(id = id, remoteId = " newRemoteId" , name = " newName" ))
89+
90+ val updatedUser = userDao.getById(id)
91+ assertNotNull(updatedUser)
92+ assertEquals(id, updatedId)
93+ assertEquals(updatedId, updatedUser.id)
94+ assertEquals(" newRemoteId" , updatedUser.remoteId)
95+ assertEquals(" newName" , updatedUser.name)
96+ }
97+
98+ @Test
99+ fun `when insert remote user then getByRemoteId(remoteId) should return the remote user` () = runWithInMemoryDatabase { userDao ->
100+ val userId = userDao.insert(UserEntity (remoteId = " remoteId" , name = " name" , isSignedIn = true ))
101+
102+ val remoteUser = userDao.getByRemoteId(" remoteId" )
103+
104+ assertNotNull(remoteUser)
105+ assertEquals(userId, remoteUser.id)
106+ assertEquals(" remoteId" , remoteUser.remoteId)
107+ assertEquals(" name" , remoteUser.name)
108+ }
109+
110+ @Test
111+ fun `when querying user by remote id with invalid id then should return null` () = runWithInMemoryDatabase { userDao ->
112+ userDao.insert(UserEntity (remoteId = " remoteId" , name = " name" ))
113+
114+ val user = userDao.getByRemoteId(" invalidRemoteId" )
115+
116+ assertNull(user)
117+ }
118+
119+ @Test
120+ fun `when insert remote user then getById(Id) should return the user` () = runWithInMemoryDatabase { userDao ->
121+ val userId = userDao.insert(UserEntity (name = " name" , isSignedIn = false ))
122+
123+ val user = userDao.getById(userId)
124+
125+ assertNotNull(user)
126+ assertEquals(userId, user.id)
127+ assertFalse(user.isSignedIn)
128+ }
129+
130+ @Test
131+ fun `when querying user by id with invalid id then should return null` () = runWithInMemoryDatabase { userDao ->
132+ val userId = userDao.insert(UserEntity (name = " name" ))
133+
134+ val user = userDao.getById(userId - 1 )
135+
136+ assertNull(user)
137+ }
138+
139+ @Test
140+ fun `when clearAllSignedInStatus then all signed in users should be unsigned` () = runWithInMemoryDatabase { userDao ->
141+ val user0Id = userDao.insert(UserEntity (name = " name3" , isSignedIn = false ))
142+ val user1Id = userDao.insert(UserEntity (remoteId = " remoteId1" , name = " name1" , isSignedIn = true ))
143+ val user2Id = userDao.insert(UserEntity (remoteId = " remoteId2" , name = " name2" , isSignedIn = true ))
144+
145+ userDao.clearAllSignedInStatus()
146+
147+ val user0 = userDao.getById(user0Id)
148+ assertNotNull(user0)
149+ assertFalse(user0.isSignedIn)
150+ val user1 = userDao.getById(user1Id)
151+ assertNotNull(user1)
152+ assertFalse(user1.isSignedIn)
153+ val user2 = userDao.getById(user2Id)
154+ assertNotNull(user2)
155+ assertFalse(user2.isSignedIn)
156+ }
157+
158+ @Test
159+ fun `when clearSignedInStatus(id) then signed in user with id should be unsigned` () = runWithInMemoryDatabase { userDao ->
160+ val user0Id = userDao.insert(UserEntity (name = " name3" , isSignedIn = true ))
161+ val user1Id = userDao.insert(UserEntity (remoteId = " remoteId1" , name = " name1" , isSignedIn = true ))
162+
163+ userDao.clearSignedInStatus(user1Id)
164+
165+ val user0 = userDao.getById(user0Id)
166+ assertNotNull(user0)
167+ assertTrue(user0.isSignedIn)
168+ val user1 = userDao.getById(user1Id)
169+ assertNotNull(user1)
170+ assertFalse(user1.isSignedIn)
171+ }
172+
173+ @Test
174+ fun `when getCurrentUser without signed in user then should return unsigned user` () = runWithInMemoryDatabase { userDao ->
175+ val userId = userDao.insert(UserEntity (name = " name" , isSignedIn = false ))
176+
177+ val user = userDao.getCurrentUser()
178+
179+ assertNotNull(user)
180+ assertEquals(userId, user.id)
181+ }
182+
183+ @Test
184+ fun `when getCurrentUser with signed in user then should return signed user` () = runWithInMemoryDatabase { userDao ->
185+ val userId = userDao.insert(UserEntity (name = " name" , isSignedIn = false ))
186+
187+ val user = userDao.getCurrentUser()
188+
189+ assertNotNull(user)
190+ assertEquals(userId, user.id)
191+ }
192+
193+ @Test
194+ fun `when getCurrentUser without user then should return null` () = runWithInMemoryDatabase { userDao ->
195+ val userId = userDao.insert(UserEntity (name = " name" , isSignedIn = false ))
196+
197+ val user = userDao.getCurrentUser()
198+
199+ assertNotNull(user)
200+ assertEquals(userId, user.id)
201+ }
202+
203+ @Test
204+ fun `when setSignedInUser then any signed in user should be unsigned and given user signed` () = runWithInMemoryDatabase { userDao ->
205+ val user0Id = userDao.insert(UserEntity (name = " name3" , isSignedIn = false ))
206+ val user1Id = userDao.insert(UserEntity (remoteId = " remoteId1" , name = " name1" , isSignedIn = true ))
207+ val user2Id = userDao.insert(UserEntity (remoteId = " remoteId1" , name = " name1" , isSignedIn = true ))
208+
209+ val user0 = userDao.getById(user0Id)
210+ assertNotNull(user0)
211+ userDao.setSignedInUser(user0)
212+
213+ val signedUser0 = userDao.getById(user0Id)
214+ assertNotNull(signedUser0)
215+ assertTrue(signedUser0.isSignedIn)
216+ val user1 = userDao.getById(user1Id)
217+ assertNotNull(user1)
218+ assertFalse(user1.isSignedIn)
219+ val user2 = userDao.getById(user2Id)
220+ assertNotNull(user2)
221+ assertFalse(user2.isSignedIn)
222+ }
223+ }
0 commit comments