summaryrefslogtreecommitdiff
path: root/java/tests
diff options
context:
space:
mode:
author mrenouf <mrenouf@google.com> 2023-11-14 14:03:27 -0500
committer Mark Renouf <mrenouf@google.com> 2023-11-15 10:01:26 -0500
commit43fe454f23a95ec11f25620975340bf392ddb161 (patch)
treef646ca7c6334ddab9b2edef99c67a9ae349e8b6c /java/tests
parent55da290431232e15b5a8c175561ea57796b572d5 (diff)
Rename UserDataSource to UserRepository
Adds requestState to allow modification of user profile state, including availability (quiet mode). Test: UserRepositoryImplTest Change-Id: Ic38f24475c73390841ee599c48d965117981faa0
Diffstat (limited to 'java/tests')
-rw-r--r--java/tests/src/com/android/intentresolver/v2/data/UserDataSourceImplTest.kt194
-rw-r--r--java/tests/src/com/android/intentresolver/v2/data/repository/UserRepositoryImplTest.kt222
-rw-r--r--java/tests/src/com/android/intentresolver/v2/platform/FakeUserManager.kt39
3 files changed, 258 insertions, 197 deletions
diff --git a/java/tests/src/com/android/intentresolver/v2/data/UserDataSourceImplTest.kt b/java/tests/src/com/android/intentresolver/v2/data/UserDataSourceImplTest.kt
deleted file mode 100644
index 56d5de35..00000000
--- a/java/tests/src/com/android/intentresolver/v2/data/UserDataSourceImplTest.kt
+++ /dev/null
@@ -1,194 +0,0 @@
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.intentresolver.v2.data
-
-import android.content.Intent.ACTION_PROFILE_ADDED
-import android.content.Intent.ACTION_PROFILE_AVAILABLE
-import android.content.Intent.ACTION_PROFILE_REMOVED
-import android.content.pm.UserInfo
-import android.os.UserHandle
-import android.os.UserHandle.USER_NULL
-import android.os.UserManager
-import com.android.intentresolver.mock
-import com.android.intentresolver.v2.coroutines.collectLastValue
-import com.android.intentresolver.v2.data.User.Role
-import com.android.intentresolver.v2.data.UserDataSourceImpl.UserEvent
-import com.android.intentresolver.v2.platform.FakeUserManager
-import com.android.intentresolver.v2.platform.FakeUserManager.ProfileType
-import com.android.intentresolver.whenever
-import com.google.common.truth.Truth.assertThat
-import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.mockito.Mockito.anyInt
-import org.mockito.Mockito.doReturn
-import org.mockito.Mockito.eq
-
-internal class UserDataSourceImplTest {
- private val userManager = FakeUserManager()
- private val userState = userManager.state
-
- @Test
- fun initialization() = runTest {
- val dataSource = createUserDataSource(userManager)
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users)
- .containsExactly(
- userState.primaryUserHandle,
- User(userState.primaryUserHandle.identifier, Role.PERSONAL)
- )
- }
-
- @Test
- fun createProfile() = runTest {
- val dataSource = createUserDataSource(userManager)
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users!!.values.filter { it.role.type == User.Type.PROFILE }).isEmpty()
-
- val profile = userState.createProfile(ProfileType.WORK)
- assertThat(users).containsEntry(profile, User(profile.identifier, Role.WORK))
- }
-
- @Test
- fun removeProfile() = runTest {
- val dataSource = createUserDataSource(userManager)
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- val work = userState.createProfile(ProfileType.WORK)
- assertThat(users).containsEntry(work, User(work.identifier, Role.WORK))
-
- userState.removeProfile(work)
- assertThat(users).doesNotContainEntry(work, User(work.identifier, Role.WORK))
- }
-
- @Test
- fun isAvailable() = runTest {
- val dataSource = createUserDataSource(userManager)
- val work = userState.createProfile(ProfileType.WORK)
-
- val available by collectLastValue(dataSource.isAvailable(work))
- assertThat(available).isTrue()
-
- userState.setQuietMode(work, true)
- assertThat(available).isFalse()
-
- userState.setQuietMode(work, false)
- assertThat(available).isTrue()
- }
-
- /**
- * This and all the 'recovers_from_*' tests below all configure a static event flow instead of
- * using [FakeUserManager]. These tests verify that a invalid broadcast causes the flow to
- * reinitialize with the user profile group.
- */
- @Test
- fun recovers_from_invalid_profile_added_event() = runTest {
- val userManager =
- mockUserManager(validUser = UserHandle.USER_SYSTEM, invalidUser = USER_NULL)
- val events = flowOf(UserEvent(ACTION_PROFILE_ADDED, UserHandle.of(USER_NULL)))
- val dataSource =
- UserDataSourceImpl(
- profileParent = UserHandle.SYSTEM,
- userManager = userManager,
- userEvents = events,
- scope = backgroundScope,
- backgroundDispatcher = Dispatchers.Unconfined
- )
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users)
- .containsExactly(UserHandle.SYSTEM, User(UserHandle.USER_SYSTEM, Role.PERSONAL))
- }
-
- @Test
- fun recovers_from_invalid_profile_removed_event() = runTest {
- val userManager =
- mockUserManager(validUser = UserHandle.USER_SYSTEM, invalidUser = USER_NULL)
- val events = flowOf(UserEvent(ACTION_PROFILE_REMOVED, UserHandle.of(USER_NULL)))
- val dataSource =
- UserDataSourceImpl(
- profileParent = UserHandle.SYSTEM,
- userManager = userManager,
- userEvents = events,
- scope = backgroundScope,
- backgroundDispatcher = Dispatchers.Unconfined
- )
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users)
- .containsExactly(UserHandle.SYSTEM, User(UserHandle.USER_SYSTEM, Role.PERSONAL))
- }
-
- @Test
- fun recovers_from_invalid_profile_available_event() = runTest {
- val userManager =
- mockUserManager(validUser = UserHandle.USER_SYSTEM, invalidUser = USER_NULL)
- val events = flowOf(UserEvent(ACTION_PROFILE_AVAILABLE, UserHandle.of(USER_NULL)))
- val dataSource =
- UserDataSourceImpl(
- UserHandle.SYSTEM,
- userManager,
- events,
- backgroundScope,
- Dispatchers.Unconfined
- )
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users)
- .containsExactly(UserHandle.SYSTEM, User(UserHandle.USER_SYSTEM, Role.PERSONAL))
- }
-
- @Test
- fun recovers_from_unknown_event() = runTest {
- val userManager =
- mockUserManager(validUser = UserHandle.USER_SYSTEM, invalidUser = USER_NULL)
- val events = flowOf(UserEvent("UNKNOWN_EVENT", UserHandle.of(USER_NULL)))
- val dataSource =
- UserDataSourceImpl(
- profileParent = UserHandle.SYSTEM,
- userManager = userManager,
- userEvents = events,
- scope = backgroundScope,
- backgroundDispatcher = Dispatchers.Unconfined
- )
- val users by collectLastValue(dataSource.users)
-
- assertWithMessage("collectLast(dataSource.users)").that(users).isNotNull()
- assertThat(users)
- .containsExactly(UserHandle.SYSTEM, User(UserHandle.USER_SYSTEM, Role.PERSONAL))
- }
-}
-
-@Suppress("SameParameterValue", "DEPRECATION")
-private fun mockUserManager(validUser: Int, invalidUser: Int) =
- mock<UserManager> {
- val info = UserInfo(validUser, "", "", UserInfo.FLAG_FULL)
- doReturn(listOf(info)).whenever(this).getEnabledProfiles(anyInt())
-
- doReturn(info).whenever(this).getUserInfo(eq(validUser))
-
- doReturn(listOf<UserInfo>()).whenever(this).getEnabledProfiles(eq(invalidUser))
-
- doReturn(null).whenever(this).getUserInfo(eq(invalidUser))
- }
-
-private fun TestScope.createUserDataSource(userManager: FakeUserManager) =
- UserDataSourceImpl(
- profileParent = userManager.state.primaryUserHandle,
- userManager = userManager,
- userEvents = userManager.state.userEvents,
- scope = backgroundScope,
- backgroundDispatcher = Dispatchers.Unconfined
- )
diff --git a/java/tests/src/com/android/intentresolver/v2/data/repository/UserRepositoryImplTest.kt b/java/tests/src/com/android/intentresolver/v2/data/repository/UserRepositoryImplTest.kt
new file mode 100644
index 00000000..4f514db5
--- /dev/null
+++ b/java/tests/src/com/android/intentresolver/v2/data/repository/UserRepositoryImplTest.kt
@@ -0,0 +1,222 @@
+package com.android.intentresolver.v2.data.repository
+
+import android.content.Intent
+import android.content.pm.UserInfo
+import android.os.UserHandle
+import android.os.UserHandle.SYSTEM
+import android.os.UserHandle.USER_SYSTEM
+import android.os.UserManager
+import com.android.intentresolver.mock
+import com.android.intentresolver.v2.coroutines.collectLastValue
+import com.android.intentresolver.v2.data.model.User
+import com.android.intentresolver.v2.data.model.User.Role
+import com.android.intentresolver.v2.platform.FakeUserManager
+import com.android.intentresolver.v2.platform.FakeUserManager.ProfileType
+import com.android.intentresolver.whenever
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.mockito.Mockito
+import org.mockito.Mockito.doReturn
+
+internal class UserRepositoryImplTest {
+ private val userManager = FakeUserManager()
+ private val userState = userManager.state
+
+ @Test
+ fun initialization() = runTest {
+ val repo = createUserRepository(userManager)
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users)
+ .containsExactly(
+ userState.primaryUserHandle,
+ User(userState.primaryUserHandle.identifier, Role.PERSONAL)
+ )
+ }
+
+ @Test
+ fun createProfile() = runTest {
+ val repo = createUserRepository(userManager)
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users!!.values.filter { it.role.type == User.Type.PROFILE }).isEmpty()
+
+ val profile = userState.createProfile(ProfileType.WORK)
+ assertThat(users).containsEntry(profile, User(profile.identifier, Role.WORK))
+ }
+
+ @Test
+ fun removeProfile() = runTest {
+ val repo = createUserRepository(userManager)
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ val work = userState.createProfile(ProfileType.WORK)
+ assertThat(users).containsEntry(work, User(work.identifier, Role.WORK))
+
+ userState.removeProfile(work)
+ assertThat(users).doesNotContainEntry(work, User(work.identifier, Role.WORK))
+ }
+
+ @Test
+ fun isAvailable() = runTest {
+ val repo = createUserRepository(userManager)
+ val work = userState.createProfile(ProfileType.WORK)
+
+ val available by collectLastValue(repo.isAvailable(work))
+ assertThat(available).isTrue()
+
+ userState.setQuietMode(work, true)
+ assertThat(available).isFalse()
+
+ userState.setQuietMode(work, false)
+ assertThat(available).isTrue()
+ }
+
+ @Test
+ fun requestState() = runTest {
+ val repo = createUserRepository(userManager)
+ val work = userState.createProfile(ProfileType.WORK)
+
+ val available by collectLastValue(repo.isAvailable(work))
+ assertThat(available).isTrue()
+
+ repo.requestState(work, false)
+ assertThat(available).isFalse()
+
+ repo.requestState(work, true)
+ assertThat(available).isTrue()
+ }
+
+ @Test(expected = IllegalArgumentException::class)
+ fun requestState_invalidForFullUser() = runTest {
+ val repo = createUserRepository(userManager)
+ val primaryUser = User(userState.primaryUserHandle.identifier, Role.PERSONAL)
+ repo.requestState(primaryUser, available = false)
+ }
+
+ /**
+ * This and all the 'recovers_from_*' tests below all configure a static event flow instead of
+ * using [FakeUserManager]. These tests verify that a invalid broadcast causes the flow to
+ * reinitialize with the user profile group.
+ */
+ @Test
+ fun recovers_from_invalid_profile_added_event() = runTest {
+ val userManager =
+ mockUserManager(validUser = USER_SYSTEM, invalidUser = UserHandle.USER_NULL)
+ val events =
+ flowOf(
+ UserRepositoryImpl.UserEvent(
+ Intent.ACTION_PROFILE_ADDED,
+ UserHandle.of(UserHandle.USER_NULL)
+ )
+ )
+ val repo =
+ UserRepositoryImpl(
+ profileParent = SYSTEM,
+ userManager = userManager,
+ userEvents = events,
+ scope = backgroundScope,
+ backgroundDispatcher = Dispatchers.Unconfined
+ )
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users).containsExactly(SYSTEM, User(USER_SYSTEM, Role.PERSONAL))
+ }
+
+ @Test
+ fun recovers_from_invalid_profile_removed_event() = runTest {
+ val userManager =
+ mockUserManager(validUser = USER_SYSTEM, invalidUser = UserHandle.USER_NULL)
+ val events =
+ flowOf(
+ UserRepositoryImpl.UserEvent(
+ Intent.ACTION_PROFILE_REMOVED,
+ UserHandle.of(UserHandle.USER_NULL)
+ )
+ )
+ val repo =
+ UserRepositoryImpl(
+ profileParent = SYSTEM,
+ userManager = userManager,
+ userEvents = events,
+ scope = backgroundScope,
+ backgroundDispatcher = Dispatchers.Unconfined
+ )
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users).containsExactly(SYSTEM, User(USER_SYSTEM, Role.PERSONAL))
+ }
+
+ @Test
+ fun recovers_from_invalid_profile_available_event() = runTest {
+ val userManager =
+ mockUserManager(validUser = USER_SYSTEM, invalidUser = UserHandle.USER_NULL)
+ val events =
+ flowOf(
+ UserRepositoryImpl.UserEvent(
+ Intent.ACTION_PROFILE_AVAILABLE,
+ UserHandle.of(UserHandle.USER_NULL)
+ )
+ )
+ val repo =
+ UserRepositoryImpl(SYSTEM, userManager, events, backgroundScope, Dispatchers.Unconfined)
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users).containsExactly(SYSTEM, User(USER_SYSTEM, Role.PERSONAL))
+ }
+
+ @Test
+ fun recovers_from_unknown_event() = runTest {
+ val userManager =
+ mockUserManager(validUser = USER_SYSTEM, invalidUser = UserHandle.USER_NULL)
+ val events =
+ flowOf(
+ UserRepositoryImpl.UserEvent("UNKNOWN_EVENT", UserHandle.of(UserHandle.USER_NULL))
+ )
+ val repo =
+ UserRepositoryImpl(
+ profileParent = SYSTEM,
+ userManager = userManager,
+ userEvents = events,
+ scope = backgroundScope,
+ backgroundDispatcher = Dispatchers.Unconfined
+ )
+ val users by collectLastValue(repo.users)
+
+ assertWithMessage("collectLastValue(repo.users)").that(users).isNotNull()
+ assertThat(users).containsExactly(SYSTEM, User(USER_SYSTEM, Role.PERSONAL))
+ }
+}
+
+@Suppress("SameParameterValue", "DEPRECATION")
+private fun mockUserManager(validUser: Int, invalidUser: Int) =
+ mock<UserManager> {
+ val info = UserInfo(validUser, "", "", UserInfo.FLAG_FULL)
+ doReturn(listOf(info)).whenever(this).getEnabledProfiles(Mockito.anyInt())
+
+ doReturn(info).whenever(this).getUserInfo(Mockito.eq(validUser))
+
+ doReturn(listOf<UserInfo>()).whenever(this).getEnabledProfiles(Mockito.eq(invalidUser))
+
+ doReturn(null).whenever(this).getUserInfo(Mockito.eq(invalidUser))
+ }
+
+private fun TestScope.createUserRepository(userManager: FakeUserManager) =
+ UserRepositoryImpl(
+ profileParent = userManager.state.primaryUserHandle,
+ userManager = userManager,
+ userEvents = userManager.state.userEvents,
+ scope = backgroundScope,
+ backgroundDispatcher = Dispatchers.Unconfined
+ )
diff --git a/java/tests/src/com/android/intentresolver/v2/platform/FakeUserManager.kt b/java/tests/src/com/android/intentresolver/v2/platform/FakeUserManager.kt
index ef1e5917..370e5a00 100644
--- a/java/tests/src/com/android/intentresolver/v2/platform/FakeUserManager.kt
+++ b/java/tests/src/com/android/intentresolver/v2/platform/FakeUserManager.kt
@@ -1,7 +1,10 @@
package com.android.intentresolver.v2.platform
import android.content.Context
+import android.content.Intent.ACTION_MANAGED_PROFILE_AVAILABLE
+import android.content.Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE
import android.content.Intent.ACTION_PROFILE_ADDED
+import android.content.Intent.ACTION_PROFILE_AVAILABLE
import android.content.Intent.ACTION_PROFILE_REMOVED
import android.content.Intent.ACTION_PROFILE_UNAVAILABLE
import android.content.pm.UserInfo
@@ -12,9 +15,10 @@ import android.content.pm.UserInfo.NO_PROFILE_GROUP_ID
import android.os.IUserManager
import android.os.UserHandle
import android.os.UserManager
+import androidx.annotation.NonNull
import com.android.intentresolver.THROWS_EXCEPTION
import com.android.intentresolver.mock
-import com.android.intentresolver.v2.data.UserDataSourceImpl.UserEvent
+import com.android.intentresolver.v2.data.repository.UserRepositoryImpl.UserEvent
import com.android.intentresolver.v2.platform.FakeUserManager.State
import com.android.intentresolver.whenever
import kotlin.random.Random
@@ -77,6 +81,14 @@ class FakeUserManager(val state: State = State()) :
}
}
+ override fun requestQuietModeEnabled(
+ enableQuietMode: Boolean,
+ @NonNull userHandle: UserHandle
+ ): Boolean {
+ state.setQuietMode(userHandle, enableQuietMode)
+ return true
+ }
+
override fun isQuietModeEnabled(userHandle: UserHandle): Boolean {
return state.getUser(userHandle).isQuietModeEnabled
}
@@ -136,8 +148,29 @@ class FakeUserManager(val state: State = State()) :
}
fun setQuietMode(user: UserHandle, quietMode: Boolean) {
- userInfoMap[user]?.also { it.flags = it.flags or UserInfo.FLAG_QUIET_MODE }
- eventChannel.trySend(UserEvent(ACTION_PROFILE_UNAVAILABLE, user, quietMode))
+ userInfoMap[user]?.also {
+ it.flags =
+ if (quietMode) {
+ it.flags or UserInfo.FLAG_QUIET_MODE
+ } else {
+ it.flags and UserInfo.FLAG_QUIET_MODE.inv()
+ }
+ val actions = mutableListOf<String>()
+ if (quietMode) {
+ actions += ACTION_PROFILE_UNAVAILABLE
+ if (it.isManagedProfile) {
+ actions += ACTION_MANAGED_PROFILE_UNAVAILABLE
+ }
+ } else {
+ actions += ACTION_PROFILE_AVAILABLE
+ if (it.isManagedProfile) {
+ actions += ACTION_MANAGED_PROFILE_AVAILABLE
+ }
+ }
+ actions.forEach { action ->
+ eventChannel.trySend(UserEvent(action, user, quietMode))
+ }
+ }
}
fun createProfile(type: ProfileType, parent: UserHandle = primaryUserHandle): UserHandle {