diff --git a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt index c08dc25206..3e842ba68f 100644 --- a/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt +++ b/authenticator/src/main/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryImpl.kt @@ -187,7 +187,8 @@ class AuthenticatorRepositoryImpl @Inject constructor( is DataState.Error -> flowOf(DataState.Error(authenticatorItems.error)) is DataState.NoNetwork -> flowOf(DataState.NoNetwork()) DataState.Loading -> flowOf(DataState.Loading) - is DataState.Loaded -> totpCodeManager.getTotpCodesFlow(authenticatorItems.data) + is DataState.Loaded -> totpCodeManager + .getTotpCodesFlow(authenticatorItems.data) .map { DataState.Loaded(it) } is DataState.Pending -> totpCodeManager @@ -287,7 +288,12 @@ class AuthenticatorRepositoryImpl @Inject constructor( is AccountSyncState.Success -> { val verificationCodesList = accounts.toAuthenticatorItems() totpCodeManager - .getTotpCodesFlow(verificationCodesList) + .getTotpCodesFlow( + itemList = verificationCodesList + .filter { + it.otpUri.isNotEmpty() + }, + ) .map { SharedVerificationCodesState.Success(it) } } } diff --git a/authenticator/src/test/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryTest.kt b/authenticator/src/test/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryTest.kt index 8c77cc119c..273494458d 100644 --- a/authenticator/src/test/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryTest.kt +++ b/authenticator/src/test/kotlin/com/bitwarden/authenticator/data/authenticator/repository/AuthenticatorRepositoryTest.kt @@ -6,6 +6,7 @@ import com.bitwarden.authenticator.data.authenticator.datasource.disk.util.FakeA import com.bitwarden.authenticator.data.authenticator.datasource.entity.createMockAuthenticatorItemEntity import com.bitwarden.authenticator.data.authenticator.manager.TotpCodeManager import com.bitwarden.authenticator.data.authenticator.manager.model.VerificationCodeItem +import com.bitwarden.authenticator.data.authenticator.manager.util.createMockAuthenticatorItem import com.bitwarden.authenticator.data.authenticator.repository.model.AuthenticatorItem import com.bitwarden.authenticator.data.authenticator.repository.model.CreateItemResult import com.bitwarden.authenticator.data.authenticator.repository.model.DeleteItemResult @@ -157,7 +158,7 @@ class AuthenticatorRepositoryTest { fun `sharedCodesStateFlow should emit Success when authenticatorBridgeManager emits Success`() = runTest { val sharedAccounts = emptyList() - val authenticatorItems = mockk>() + val authenticatorItems = emptyList() val verificationCodes = mockk>() every { sharedAccounts.toAuthenticatorItems() } returns authenticatorItems every { @@ -170,6 +171,39 @@ class AuthenticatorRepositoryTest { } } + @Suppress("MaxLineLength") + @Test + fun `sharedCodesStateFlow should filter out items with empty otpUri when authenticatorBridgeManager emits Success`() = + runTest { + val sharedAccounts = emptyList() + val itemWithUri = createMockAuthenticatorItem(number = 1) + val itemWithEmptyUri = createMockAuthenticatorItem( + number = 2, + otpUri = "", + ) + val allItems = listOf(itemWithUri, itemWithEmptyUri) + val filteredItems = listOf(itemWithUri) + val verificationCodes = mockk>() + every { sharedAccounts.toAuthenticatorItems() } returns allItems + every { + mockTotpCodeManager.getTotpCodesFlow(filteredItems) + } returns MutableStateFlow(verificationCodes) + authenticatorRepository.sharedCodesStateFlow.test { + assertEquals( + SharedVerificationCodesState.Loading, + awaitItem(), + ) + mutableAccountSyncStateFlow.value = AccountSyncState.Success(sharedAccounts) + assertEquals( + SharedVerificationCodesState.Success(verificationCodes), + awaitItem(), + ) + verify(exactly = 1) { + mockTotpCodeManager.getTotpCodesFlow(filteredItems) + } + } + } + @Test @Suppress("MaxLineLength") fun `firstTimeAccountSyncFlow should emit the first time an account syncs and update SettingsRepository`() =