1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.multiuser.widget.tests.unit.data
18 
19 import android.content.Context
20 import androidx.test.ext.junit.runners.AndroidJUnit4
21 import androidx.room.Room
22 import androidx.test.core.app.ApplicationProvider
23 import com.android.multiuser.widget.data.model.User
24 import com.android.multiuser.widget.data.UserDao
25 import com.android.multiuser.widget.data.UsersDatabase
26 import java.io.IOException
27 import java.util.concurrent.CountDownLatch
28 import kotlin.test.assertEquals
29 import kotlin.test.assertTrue
30 import kotlinx.coroutines.async
31 import kotlinx.coroutines.cancelAndJoin
32 import kotlinx.coroutines.Dispatchers
33 import kotlinx.coroutines.flow.first
34 import kotlinx.coroutines.runBlocking
35 import org.junit.After
36 import org.junit.Before
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 
40 @RunWith(AndroidJUnit4::class)
41 class UserDaoTest {
42     private lateinit var database: UsersDatabase
43     private lateinit var userDao: UserDao
44 
45     @Before
setUpDatabasenull46     fun setUpDatabase() {
47         val context = ApplicationProvider.getApplicationContext<Context>()
48         database = Room.inMemoryDatabaseBuilder(context, UsersDatabase::class.java).build()
49         userDao = database.getUserDao()
50     }
51 
52     @After
53     @Throws(IOException::class)
closeDatabasenull54     fun closeDatabase() {
55         database.close()
56     }
57 
58     @Test
<lambda>null59     fun addUser_returnsTrue() = runBlocking {
60         val fakeUser = User(
61             id = 0,
62             name = "fake_user_name",
63             creationTime = 0,
64             iconPath = "fake_icon_uri",
65             isCurrentUser = false,
66             isAdmin = false,
67         )
68         userDao.addUsers(fakeUser)
69 
70         val latch = CountDownLatch(1)
71         val job = async(Dispatchers.IO) {
72             val usersFromDatabase = userDao.getUsers().first()
73             assertEquals(usersFromDatabase.size, 1)
74             assertEquals(usersFromDatabase.get(0), fakeUser)
75             latch.countDown()
76         }
77 
78         latch.await()
79         job.cancelAndJoin()
80     }
81 
82     @Test
<lambda>null83     fun addUsers_returnsOrderedUserInfos() = runBlocking {
84         val fakeUser0 = User(
85             id = 0,
86             name = "fake_user_name_0",
87             creationTime = 0,
88             iconPath = "fake_icon_path_0",
89             isCurrentUser = false,
90             isAdmin = false,
91         )
92         val fakeUser1 = User(
93             id = 1,
94             name = "fake_user_name_1",
95             creationTime = 1,
96             iconPath = "fake_icon_path_1",
97             isCurrentUser = false,
98             isAdmin = false,
99         )
100 
101         userDao.addUsers(fakeUser1)
102         userDao.addUsers(fakeUser0)
103 
104         val latch = CountDownLatch(1)
105         val job = async(Dispatchers.IO) {
106             val usersFromDatabase = userDao.getUsers().first()
107             assertEquals(usersFromDatabase.size, 2)
108             assertTrue(usersFromDatabase.get(0).creationTime
109                     <= usersFromDatabase.get(1).creationTime)
110             latch.countDown()
111         }
112 
113         latch.await()
114         job.cancelAndJoin()
115     }
116 
117     @Test
<lambda>null118     fun addUsers_returnsCurrentUser() = runBlocking {
119         val fakeCurrentUser = User(
120             id = 0,
121             name = "fake_user_name_0",
122             creationTime = 0,
123             iconPath = "fake_icon_path_0",
124             isCurrentUser = true,
125             isAdmin = false,
126         )
127         val fakeUser = User(
128             id = 1,
129             name = "fake_user_name_1",
130             creationTime = 1,
131             iconPath = "fake_icon_path_1",
132             isCurrentUser = false,
133             isAdmin = false,
134         )
135 
136         userDao.addUsers(fakeCurrentUser)
137         userDao.addUsers(fakeUser)
138 
139         val latch = CountDownLatch(1)
140         val job = async(Dispatchers.IO) {
141             val currentUser = userDao.getCurrentUser().first()
142             assertEquals(currentUser, fakeCurrentUser)
143             latch.countDown()
144         }
145 
146         latch.await()
147         job.cancelAndJoin()
148     }
149 
150     @Test
<lambda>null151     fun updateUsers_replacesExistingUserInfoWithNew() = runBlocking {
152         val fakeUser = User(
153             id = 0,
154             name = "fake_user_name",
155             creationTime = 0,
156             iconPath = "fake_icon_path",
157             isCurrentUser = false,
158             isAdmin = false,
159         )
160         val updatedFakeUser = User(
161             id = 0,
162             name = "updated_fake_user_name",
163             creationTime = 0,
164             iconPath = "fake_icon_path",
165             isCurrentUser = false,
166             isAdmin = false,
167         )
168         userDao.addUsers(fakeUser)
169         userDao.addUsers(updatedFakeUser)
170 
171         val latch = CountDownLatch(1)
172         val job = async(Dispatchers.IO) {
173             val usersFromDatabase = userDao.getUsers().first()
174             assertEquals(usersFromDatabase.size, 1)
175             assertEquals(usersFromDatabase.get(0), updatedFakeUser)
176             latch.countDown()
177         }
178 
179         latch.await()
180         job.cancelAndJoin()
181     }
182 }
183