mirror of
https://github.com/bitwarden/android.git
synced 2026-05-31 01:22:39 -05:00
BIT-1076 Requesting Camera Permission (#415)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user