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