BIT-1076 Requesting Camera Permission (#415)

This commit is contained in:
Oleg Semenenko
2023-12-19 13:27:35 -06:00
committed by GitHub
parent ea4825b8b8
commit 370ac3df3b
11 changed files with 247 additions and 19 deletions

View File

@@ -0,0 +1,46 @@
package com.x8bit.bitwarden.ui.platform.base.util
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.compose.runtime.Composable
import io.mockk.every
import io.mockk.mockk
/**
* A helper class used to test permissions
*/
class FakePermissionManager : PermissionsManager {
/**
* The value returned when we check if we have the permission.
*/
var checkPermissionResult: Boolean = false
/**
* The value returned when the user is asked for permission.
*/
var getPermissionsResult: Boolean = false
/**
* * The value for whether a rationale should be shown to the user.
*/
var shouldShowRequestRationale: Boolean = false
@Composable
override fun getLauncher(
onResult: (Boolean) -> Unit,
): ManagedActivityResultLauncher<String, Boolean> {
return mockk {
every { launch(any()) } answers { onResult.invoke(getPermissionsResult) }
}
}
override fun checkPermission(permission: String): Boolean {
return checkPermissionResult
}
override fun shouldShouldRequestPermissionRationale(
permission: String,
): Boolean {
return shouldShowRequestRationale
}
}

View File

@@ -30,6 +30,7 @@ import com.x8bit.bitwarden.ui.util.onAllNodesWithTextAfterScroll
import com.x8bit.bitwarden.ui.util.onNodeWithContentDescriptionAfterScroll
import com.x8bit.bitwarden.ui.util.onNodeWithTextAfterScroll
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
import com.x8bit.bitwarden.ui.platform.base.util.FakePermissionManager
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
import io.mockk.every
import io.mockk.mockk
@@ -49,6 +50,8 @@ class VaultAddItemScreenTest : BaseComposeTest() {
private val mutableEventFlow = MutableSharedFlow<VaultAddItemEvent>(Int.MAX_VALUE)
private val mutableStateFlow = MutableStateFlow(DEFAULT_STATE_LOGIN)
private val fakePermissionManager: FakePermissionManager = FakePermissionManager()
private val viewModel = mockk<VaultAddItemViewModel>(relaxed = true) {
every { eventFlow } returns mutableEventFlow
every { stateFlow } returns mutableStateFlow
@@ -60,6 +63,7 @@ class VaultAddItemScreenTest : BaseComposeTest() {
VaultAddItemScreen(
viewModel = viewModel,
onNavigateBack = { onNavigateBackCalled = true },
permissionsManager = fakePermissionManager,
)
}
}
@@ -315,15 +319,52 @@ class VaultAddItemScreenTest : BaseComposeTest() {
.assertTextContains("•••••••••••")
}
@Suppress("MaxLineLength")
@Test
fun `in ItemType_Login state clicking Set up TOTP button should trigger SetupTotpClick`() {
fun `in ItemType_Login state clicking SetupTOTP button with a positive result should send true if permission check returns true`() {
fakePermissionManager.checkPermissionResult = true
composeTestRule
.onNodeWithTextAfterScroll(text = "Set up TOTP")
.performClick()
verify {
viewModel.trySendAction(
VaultAddItemAction.ItemType.LoginType.SetupTotpClick,
VaultAddItemAction.ItemType.LoginType.SetupTotpClick(true),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `in ItemType_Login state clicking SetupTOTP button with a positive result should send true`() {
fakePermissionManager.checkPermissionResult = false
fakePermissionManager.getPermissionsResult = true
composeTestRule
.onNodeWithTextAfterScroll(text = "Set up TOTP")
.performClick()
verify {
viewModel.trySendAction(
VaultAddItemAction.ItemType.LoginType.SetupTotpClick(true),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `in ItemType_Login state clicking Set up TOTP button with a negative result should send false`() {
fakePermissionManager.checkPermissionResult = false
fakePermissionManager.getPermissionsResult = false
composeTestRule
.onNodeWithTextAfterScroll(text = "Set up TOTP")
.performClick()
verify {
viewModel.trySendAction(
VaultAddItemAction.ItemType.LoginType.SetupTotpClick(false),
)
}
}

View File

@@ -474,12 +474,37 @@ class VaultAddItemViewModelTest : BaseViewModelTest() {
@Suppress("MaxLineLength")
@Test
fun `SetupTotpClick should emit ShowToast with 'Setup TOTP' message`() = runTest {
fun `SetupTotpClick should emit ShowToast with permission granted when isGranted is true`() = runTest {
val viewModel = createAddVaultItemViewModel()
viewModel.eventFlow.test {
viewModel.actionChannel.trySend(VaultAddItemAction.ItemType.LoginType.SetupTotpClick)
assertEquals(VaultAddItemEvent.ShowToast("Setup TOTP"), awaitItem())
viewModel.actionChannel.trySend(
VaultAddItemAction.ItemType.LoginType.SetupTotpClick(
true,
),
)
assertEquals(
VaultAddItemEvent.ShowToast("Permission Granted, QR Code Scanner Not Implemented"),
awaitItem(),
)
}
}
@Suppress("MaxLineLength")
@Test
fun `SetupTotpClick should emit ShowToast with permission not granted when isGranted is false`() = runTest {
val viewModel = createAddVaultItemViewModel()
viewModel.eventFlow.test {
viewModel.actionChannel.trySend(
VaultAddItemAction.ItemType.LoginType.SetupTotpClick(
false,
),
)
assertEquals(
VaultAddItemEvent.ShowToast("Permission Not Granted, Manual QR Code Entry Not Implemented"),
awaitItem(),
)
}
}