mirror of
https://github.com/bitwarden/android.git
synced 2026-06-02 02:36:58 -05:00
BIT-151: Added Wireframe for Vault Screen (#48)
This commit is contained in:
@@ -68,6 +68,7 @@ class FakeNavHostController : NavHostController(context = mockk()) {
|
||||
private val internalGraph =
|
||||
mockk<NavGraph>().apply {
|
||||
every { id } returns graphId
|
||||
every { startDestinationId } returns graphId
|
||||
}
|
||||
|
||||
override var graph: NavGraph
|
||||
|
||||
@@ -1,13 +1,28 @@
|
||||
package com.x8bit.bitwarden.ui.platform.feature.vaultunlockednavbar
|
||||
|
||||
import androidx.compose.ui.test.onNodeWithTag
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import androidx.navigation.navOptions
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import com.x8bit.bitwarden.ui.platform.base.FakeNavHostController
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import org.junit.Test
|
||||
|
||||
class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
||||
private val fakeNavHostController = FakeNavHostController()
|
||||
|
||||
private val expectedNavOptions = navOptions {
|
||||
// When changing root navigation state, pop everything else off the back stack:
|
||||
popUpTo(fakeNavHostController.graphId) {
|
||||
inclusive = false
|
||||
saveState = true
|
||||
}
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `vault tab click should send VaultTabClick action`() {
|
||||
@@ -16,13 +31,40 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
onNodeWithTag("vault").performClick()
|
||||
onNodeWithText("My vault").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultUnlockedNavBarAction.VaultTabClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToVaultScreen should navigate to VaultScreen`() {
|
||||
val vaultUnlockedNavBarEventFlow = MutableSharedFlow<VaultUnlockedNavBarEvent>(
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns vaultUnlockedNavBarEventFlow
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToVaultScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
route = "vault",
|
||||
navOptions = expectedNavOptions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `send tab click should send SendTabClick action`() {
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true)
|
||||
@@ -30,13 +72,40 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
onNodeWithTag("send").performClick()
|
||||
onNodeWithText("Send").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultUnlockedNavBarAction.SendTabClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToSendScreen should navigate to SendScreen`() {
|
||||
val vaultUnlockedNavBarEventFlow = MutableSharedFlow<VaultUnlockedNavBarEvent>(
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns vaultUnlockedNavBarEventFlow
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToSendScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
route = "send",
|
||||
navOptions = expectedNavOptions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `generator tab click should send GeneratorTabClick action`() {
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true)
|
||||
@@ -44,13 +113,40 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
onNodeWithTag("generator").performClick()
|
||||
onNodeWithText("Generator").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultUnlockedNavBarAction.GeneratorTabClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToGeneratorScreen should navigate to GeneratorScreen`() {
|
||||
val vaultUnlockedNavBarEventFlow = MutableSharedFlow<VaultUnlockedNavBarEvent>(
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns vaultUnlockedNavBarEventFlow
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToGeneratorScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
route = "generator",
|
||||
navOptions = expectedNavOptions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `settings tab click should send SendTabClick action`() {
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true)
|
||||
@@ -58,10 +154,37 @@ class VaultUnlockedNavBarScreenTest : BaseComposeTest() {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
onNodeWithTag("settings").performClick()
|
||||
onNodeWithText("Settings").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultUnlockedNavBarAction.SettingsTabClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `NavigateToSettingsScreen should navigate to SettingsScreen`() {
|
||||
val vaultUnlockedNavBarEventFlow = MutableSharedFlow<VaultUnlockedNavBarEvent>(
|
||||
extraBufferCapacity = Int.MAX_VALUE,
|
||||
)
|
||||
val viewModel = mockk<VaultUnlockedNavBarViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns vaultUnlockedNavBarEventFlow
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultUnlockedNavBarScreen(
|
||||
viewModel = viewModel,
|
||||
navController = fakeNavHostController,
|
||||
)
|
||||
}
|
||||
runOnIdle { fakeNavHostController.assertCurrentRoute("vault") }
|
||||
vaultUnlockedNavBarEventFlow.tryEmit(VaultUnlockedNavBarEvent.NavigateToSettingsScreen)
|
||||
runOnIdle {
|
||||
fakeNavHostController.assertLastNavigation(
|
||||
route = "settings",
|
||||
navOptions = expectedNavOptions,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class VaultUnlockedNavBarViewModelTest : BaseViewModelTest() {
|
||||
val viewModel = VaultUnlockedNavBarViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultUnlockedNavBarAction.VaultTabClick)
|
||||
assertEquals(VaultUnlockedNavBarEvent.NavigateToVaultScreenNavBar, awaitItem())
|
||||
assertEquals(VaultUnlockedNavBarEvent.NavigateToVaultScreen, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.x8bit.bitwarden.ui.vault.feature.vault
|
||||
|
||||
import androidx.compose.ui.test.onNodeWithContentDescription
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import org.junit.Test
|
||||
|
||||
class VaultScreenTest : BaseComposeTest() {
|
||||
|
||||
@Test
|
||||
fun `search icon click should send SearchIconClick action`() {
|
||||
val viewModel = mockk<VaultViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { stateFlow } returns MutableStateFlow(VaultState.NoItems)
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultScreen(
|
||||
viewModel = viewModel,
|
||||
)
|
||||
}
|
||||
onNodeWithContentDescription("Search vault").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultAction.SearchIconClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `floating action button click should send AddItemClick action`() {
|
||||
val viewModel = mockk<VaultViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { stateFlow } returns MutableStateFlow(VaultState.NoItems)
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultScreen(
|
||||
viewModel = viewModel,
|
||||
)
|
||||
}
|
||||
onNodeWithContentDescription("Add Item").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultAction.AddItemClick) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `add an item button click should send AddItemClick action`() {
|
||||
val viewModel = mockk<VaultViewModel>(relaxed = true) {
|
||||
every { eventFlow } returns emptyFlow()
|
||||
every { stateFlow } returns MutableStateFlow(VaultState.NoItems)
|
||||
}
|
||||
composeTestRule.apply {
|
||||
setContent {
|
||||
VaultScreen(
|
||||
viewModel = viewModel,
|
||||
)
|
||||
}
|
||||
onNodeWithText("Add an Item").performClick()
|
||||
}
|
||||
verify { viewModel.trySendAction(VaultAction.AddItemClick) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.x8bit.bitwarden.ui.vault.feature.vault
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class VaultViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `AddItemClick should navigate to the add item screen`() = runTest {
|
||||
val viewModel = VaultViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.AddItemClick)
|
||||
assertEquals(VaultEvent.NavigateToAddItemScreen, awaitItem())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `SearchIconClick should navigate to the vault search screen`() = runTest {
|
||||
val viewModel = VaultViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.trySendAction(VaultAction.SearchIconClick)
|
||||
assertEquals(VaultEvent.NavigateToVaultSearchScreen, awaitItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user