mirror of
https://github.com/bitwarden/android.git
synced 2026-10-23 03:23:53 -05:00
BIT-1499 listing screen pull-to-refresh (#690)
This commit is contained in:
1 parent
c487074de6
commit
88e4b45f7d
4 files changed
+222
-90
No files matched your search
+1
@@ -699,6 +699,7 @@ private val DEFAULT_STATE = VaultItemListingState(
|
||||
baseWebSendUrl = Environment.Us.environmentUrlData.baseWebSendUrl,
|
||||
isIconLoadingDisabled = false,
|
||||
baseIconUrl = Environment.Us.environmentUrlData.baseIconUrl,
|
||||
isPullToRefreshSettingEnabled = false,
|
||||
dialogState = null,
|
||||
)
|
||||
|
||||
|
||||
+139
-86
@@ -66,10 +66,12 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
every { environmentStateFlow } returns mockk()
|
||||
}
|
||||
|
||||
private val mutablePullToRefreshEnabledFlow = MutableStateFlow(false)
|
||||
private val mutableIsIconLoadingDisabledFlow = MutableStateFlow(false)
|
||||
private val settingsRepository: SettingsRepository = mockk {
|
||||
every { isIconLoadingDisabled } returns false
|
||||
every { isIconLoadingDisabledFlow } returns mutableIsIconLoadingDisabledFlow
|
||||
every { getPullToRefreshEnabledFlow() } returns mutablePullToRefreshEnabledFlow
|
||||
}
|
||||
private val initialState = createVaultItemListingState()
|
||||
private val initialSavedStateHandle = createSavedStateHandleWithVaultItemListingType(
|
||||
@@ -350,25 +352,27 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
fun `vaultDataStateFlow Loaded with items should update ViewState to Content`() =
|
||||
runTest {
|
||||
setupMockUri()
|
||||
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(
|
||||
createMockCipherView(
|
||||
number = 1,
|
||||
isDeleted = false,
|
||||
),
|
||||
val dataState = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(
|
||||
createMockCipherView(
|
||||
number = 1,
|
||||
isDeleted = false,
|
||||
),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.Content(
|
||||
@@ -384,17 +388,19 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
@Test
|
||||
fun `vaultDataStateFlow Loaded with empty items should update ViewState to NoItems`() =
|
||||
runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
val dataState = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
)
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(viewState = VaultItemListingState.ViewState.NoItems),
|
||||
viewModel.stateFlow.value,
|
||||
@@ -404,17 +410,20 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
@Test
|
||||
fun `vaultDataStateFlow Loaded with trash items should update ViewState to NoItems`() =
|
||||
runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
val dataState = DataState.Loaded(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
)
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.NoItems,
|
||||
@@ -508,14 +517,16 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow Error without data should update state to Error`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
error = IllegalStateException(),
|
||||
),
|
||||
val dataState = DataState.Error<VaultData>(
|
||||
error = IllegalStateException(),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.Error(
|
||||
@@ -530,20 +541,22 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
fun `vaultDataStateFlow Error with data should update state to Content`() = runTest {
|
||||
setupMockUri()
|
||||
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = false)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
val dataState = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = false)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.Content(
|
||||
@@ -560,20 +573,22 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow Error with empty data should update state to NoItems`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
val dataState = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.NoItems,
|
||||
@@ -584,20 +599,22 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow Error with trash data should update state to NoItems`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = true)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
val dataState = DataState.Error(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = true)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
error = IllegalStateException(),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.NoItems,
|
||||
@@ -608,12 +625,14 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow NoNetwork without data should update state to Error`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.NoNetwork(),
|
||||
)
|
||||
val dataState = DataState.NoNetwork<VaultData>()
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.Error(
|
||||
@@ -630,19 +649,21 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
fun `vaultDataStateFlow NoNetwork with data should update state to Content`() = runTest {
|
||||
setupMockUri()
|
||||
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = false)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
val dataState = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = false)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.Content(
|
||||
@@ -659,19 +680,21 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow NoNetwork with empty data should update state to NoItems`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
val dataState = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = emptyList(),
|
||||
folderViewList = emptyList(),
|
||||
collectionViewList = emptyList(),
|
||||
sendViewList = emptyList(),
|
||||
),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.NoItems,
|
||||
@@ -682,19 +705,21 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
|
||||
@Test
|
||||
fun `vaultDataStateFlow NoNetwork with trash data should update state to NoItems`() = runTest {
|
||||
mutableVaultDataStateFlow.tryEmit(
|
||||
value = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = true)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
val dataState = DataState.NoNetwork(
|
||||
data = VaultData(
|
||||
cipherViewList = listOf(createMockCipherView(number = 1, isDeleted = true)),
|
||||
folderViewList = listOf(createMockFolderView(number = 1)),
|
||||
collectionViewList = listOf(createMockCollectionView(number = 1)),
|
||||
sendViewList = listOf(createMockSendView(number = 1)),
|
||||
),
|
||||
)
|
||||
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.eventFlow.test {
|
||||
mutableVaultDataStateFlow.tryEmit(value = dataState)
|
||||
assertEquals(VaultItemListingEvent.DismissPullToRefresh, awaitItem())
|
||||
}
|
||||
assertEquals(
|
||||
createVaultItemListingState(
|
||||
viewState = VaultItemListingState.ViewState.NoItems,
|
||||
@@ -713,6 +738,33 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
assertTrue(viewModel.stateFlow.value.isIconLoadingDisabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `RefreshPull should call vault repository sync`() {
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.trySendAction(VaultItemListingsAction.RefreshPull)
|
||||
|
||||
verify(exactly = 1) {
|
||||
vaultRepository.sync()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `PullToRefreshEnableReceive should update isPullToRefreshEnabled`() = runTest {
|
||||
val viewModel = createVaultItemListingViewModel()
|
||||
|
||||
viewModel.trySendAction(
|
||||
VaultItemListingsAction.Internal.PullToRefreshEnableReceive(
|
||||
isPullToRefreshEnabled = true,
|
||||
),
|
||||
)
|
||||
|
||||
assertEquals(
|
||||
initialState.copy(isPullToRefreshSettingEnabled = true),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("CyclomaticComplexMethod")
|
||||
private fun createSavedStateHandleWithVaultItemListingType(
|
||||
vaultItemListingType: VaultItemListingType,
|
||||
@@ -779,6 +831,7 @@ class VaultItemListingViewModelTest : BaseViewModelTest() {
|
||||
baseWebSendUrl = Environment.Us.environmentUrlData.baseWebSendUrl,
|
||||
baseIconUrl = environmentRepository.environment.environmentUrlData.baseIconUrl,
|
||||
isIconLoadingDisabled = settingsRepository.isIconLoadingDisabled,
|
||||
isPullToRefreshSettingEnabled = false,
|
||||
dialogState = null,
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user