diff --git a/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepository.kt b/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepository.kt index bbf6fa861..71925a124 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepository.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepository.kt @@ -5,9 +5,9 @@ import com.bitwarden.core.PasswordGeneratorRequest import com.bitwarden.core.PasswordHistoryView import com.bitwarden.core.UsernameGeneratorRequest import com.x8bit.bitwarden.data.platform.repository.model.LocalDataState +import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPassphraseResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPasswordResult -import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.PasscodeGenerationOptions import kotlinx.coroutines.flow.StateFlow diff --git a/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryImpl.kt index 7a4b77688..a128eb08e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryImpl.kt @@ -13,9 +13,9 @@ import com.x8bit.bitwarden.data.tools.generator.datasource.disk.PasswordHistoryD import com.x8bit.bitwarden.data.tools.generator.datasource.disk.entity.toPasswordHistory import com.x8bit.bitwarden.data.tools.generator.datasource.disk.entity.toPasswordHistoryEntity import com.x8bit.bitwarden.data.tools.generator.datasource.sdk.GeneratorSdkSource +import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPassphraseResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPasswordResult -import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.PasscodeGenerationOptions import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/GeneratorViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/GeneratorViewModel.kt index 9a0cbc011..087e47f90 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/GeneratorViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/GeneratorViewModel.kt @@ -9,9 +9,9 @@ import com.bitwarden.core.PassphraseGeneratorRequest import com.bitwarden.core.PasswordGeneratorRequest import com.x8bit.bitwarden.R import com.x8bit.bitwarden.data.tools.generator.repository.GeneratorRepository +import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPassphraseResult import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedPasswordResult -import com.x8bit.bitwarden.data.tools.generator.repository.model.GeneratedForwardedServiceUsernameResult import com.x8bit.bitwarden.data.tools.generator.repository.model.PasscodeGenerationOptions import com.x8bit.bitwarden.ui.platform.base.BaseViewModel import com.x8bit.bitwarden.ui.platform.base.util.Text @@ -879,6 +879,7 @@ class GeneratorViewModel @Inject constructor( generateForwardedEmailAlias(selectedType) } } + is CatchAllEmail -> { // TODO: Implement catch all email generation (BIT-1334) } diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensions.kt index d0ef3055f..fbf957543 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensions.kt @@ -19,24 +19,28 @@ fun ServiceType.toUsernameGeneratorRequest(): UsernameGeneratorRequest.Forwarded website = null, ) } + is ServiceType.DuckDuckGo -> { UsernameGeneratorRequest.Forwarded( service = ForwarderServiceType.DuckDuckGo(token = this.apiKey), website = null, ) } + is ServiceType.FirefoxRelay -> { UsernameGeneratorRequest.Forwarded( service = ForwarderServiceType.Firefox(apiToken = this.apiAccessToken), website = null, ) } + is ServiceType.FastMail -> { UsernameGeneratorRequest.Forwarded( service = ForwarderServiceType.Fastmail(apiToken = this.apiKey), website = null, ) } + is ServiceType.SimpleLogin -> { UsernameGeneratorRequest.Forwarded( service = ForwarderServiceType.SimpleLogin(apiKey = this.apiKey), diff --git a/app/src/test/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryTest.kt index ef0fc70d6..0438ab088 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/tools/generator/repository/GeneratorRepositoryTest.kt @@ -76,95 +76,103 @@ class GeneratorRepositoryTest { @Suppress("MaxLineLength") @Test - fun `generatePassword should emit Success result and store the generated password when shouldSave is true`() = runTest { - val fixedInstant = Instant.parse("2021-01-01T00:00:00Z") + fun `generatePassword should emit Success result and store the generated password when shouldSave is true`() = + runTest { + val fixedInstant = Instant.parse("2021-01-01T00:00:00Z") - mockkStatic(Instant::class) - every { Instant.now() } returns fixedInstant + mockkStatic(Instant::class) + every { Instant.now() } returns fixedInstant - val userId = "testUserId" - val request = PasswordGeneratorRequest( - lowercase = true, - uppercase = true, - numbers = true, - special = true, - length = 12.toUByte(), - avoidAmbiguous = false, - minLowercase = null, - minUppercase = null, - minNumber = null, - minSpecial = null, - ) - val generatedPassword = "GeneratedPassword123!" - val encryptedPasswordHistory = - PasswordHistory(password = generatedPassword, lastUsedDate = Instant.now()) - - coEvery { authDiskSource.userState?.activeUserId } returns userId - - coEvery { generatorSdkSource.generatePassword(request) } returns - Result.success(generatedPassword) - - coEvery { vaultSdkSource.encryptPasswordHistory(any()) } returns - Result.success(encryptedPasswordHistory) - - coEvery { passwordHistoryDiskSource.insertPasswordHistory(any()) } just runs - - val result = repository.generatePassword(request, true) - - assertEquals(generatedPassword, (result as GeneratedPasswordResult.Success).generatedString) - coVerify { generatorSdkSource.generatePassword(request) } - - coVerify { - passwordHistoryDiskSource.insertPasswordHistory( - encryptedPasswordHistory.toPasswordHistoryEntity(userId), + val userId = "testUserId" + val request = PasswordGeneratorRequest( + lowercase = true, + uppercase = true, + numbers = true, + special = true, + length = 12.toUByte(), + avoidAmbiguous = false, + minLowercase = null, + minUppercase = null, + minNumber = null, + minSpecial = null, ) + val generatedPassword = "GeneratedPassword123!" + val encryptedPasswordHistory = + PasswordHistory(password = generatedPassword, lastUsedDate = Instant.now()) + + coEvery { authDiskSource.userState?.activeUserId } returns userId + + coEvery { generatorSdkSource.generatePassword(request) } returns + Result.success(generatedPassword) + + coEvery { vaultSdkSource.encryptPasswordHistory(any()) } returns + Result.success(encryptedPasswordHistory) + + coEvery { passwordHistoryDiskSource.insertPasswordHistory(any()) } just runs + + val result = repository.generatePassword(request, true) + + assertEquals( + generatedPassword, + (result as GeneratedPasswordResult.Success).generatedString, + ) + coVerify { generatorSdkSource.generatePassword(request) } + + coVerify { + passwordHistoryDiskSource.insertPasswordHistory( + encryptedPasswordHistory.toPasswordHistoryEntity(userId), + ) + } } - } @Suppress("MaxLineLength") @Test - fun `generatePassword should emit Success result but not store the generated password when shouldSave is false`() = runTest { - val fixedInstant = Instant.parse("2021-01-01T00:00:00Z") + fun `generatePassword should emit Success result but not store the generated password when shouldSave is false`() = + runTest { + val fixedInstant = Instant.parse("2021-01-01T00:00:00Z") - mockkStatic(Instant::class) - every { Instant.now() } returns fixedInstant + mockkStatic(Instant::class) + every { Instant.now() } returns fixedInstant - val userId = "testUserId" - val request = PasswordGeneratorRequest( - lowercase = true, - uppercase = true, - numbers = true, - special = true, - length = 12.toUByte(), - avoidAmbiguous = false, - minLowercase = null, - minUppercase = null, - minNumber = null, - minSpecial = null, - ) - val generatedPassword = "GeneratedPassword123!" - val encryptedPasswordHistory = - PasswordHistory(password = generatedPassword, lastUsedDate = Instant.now()) + val userId = "testUserId" + val request = PasswordGeneratorRequest( + lowercase = true, + uppercase = true, + numbers = true, + special = true, + length = 12.toUByte(), + avoidAmbiguous = false, + minLowercase = null, + minUppercase = null, + minNumber = null, + minSpecial = null, + ) + val generatedPassword = "GeneratedPassword123!" + val encryptedPasswordHistory = + PasswordHistory(password = generatedPassword, lastUsedDate = Instant.now()) - coEvery { authDiskSource.userState?.activeUserId } returns userId + coEvery { authDiskSource.userState?.activeUserId } returns userId - coEvery { generatorSdkSource.generatePassword(request) } returns - Result.success(generatedPassword) + coEvery { generatorSdkSource.generatePassword(request) } returns + Result.success(generatedPassword) - coEvery { vaultSdkSource.encryptPasswordHistory(any()) } returns - Result.success(encryptedPasswordHistory) + coEvery { vaultSdkSource.encryptPasswordHistory(any()) } returns + Result.success(encryptedPasswordHistory) - coEvery { passwordHistoryDiskSource.insertPasswordHistory(any()) } just runs + coEvery { passwordHistoryDiskSource.insertPasswordHistory(any()) } just runs - val result = repository.generatePassword(request, false) + val result = repository.generatePassword(request, false) - assertEquals(generatedPassword, (result as GeneratedPasswordResult.Success).generatedString) - coVerify { generatorSdkSource.generatePassword(request) } + assertEquals( + generatedPassword, + (result as GeneratedPasswordResult.Success).generatedString, + ) + coVerify { generatorSdkSource.generatePassword(request) } - coVerify(exactly = 0) { - passwordHistoryDiskSource.insertPasswordHistory(any()) + coVerify(exactly = 0) { + passwordHistoryDiskSource.insertPasswordHistory(any()) + } } - } @Test fun `generatePassword should emit InvalidRequest result when SDK throws exception`() = runTest { @@ -232,7 +240,6 @@ class GeneratorRepositoryTest { } } - @Suppress("MaxLineLength") @Test fun `generatePassphrase should emit InvalidRequest result when SDK throws exception`() = runTest { @@ -253,47 +260,49 @@ class GeneratorRepositoryTest { coVerify { generatorSdkSource.generatePassphrase(request) } } - @Suppress("MaxLineLength") @Test - fun `generateForwardedService should emit Success result and store the generated email`() = runTest { - val userId = "testUserId" - val request = UsernameGeneratorRequest.Forwarded( - service = ForwarderServiceType.DuckDuckGo( - token = "testToken", - ), - website = null, - ) + fun `generateForwardedService should emit Success result and store the generated email`() = + runTest { + val userId = "testUserId" + val request = UsernameGeneratorRequest.Forwarded( + service = ForwarderServiceType.DuckDuckGo( + token = "testToken", + ), + website = null, + ) - val generatedEmail = "generated@email.com" + val generatedEmail = "generated@email.com" - coEvery { authDiskSource.userState?.activeUserId } returns userId - coEvery { generatorSdkSource.generateForwardedServiceEmail(request) } returns - Result.success(generatedEmail) + coEvery { authDiskSource.userState?.activeUserId } returns userId + coEvery { generatorSdkSource.generateForwardedServiceEmail(request) } returns + Result.success(generatedEmail) - val result = repository.generateForwardedServiceUsername(request) + val result = repository.generateForwardedServiceUsername(request) - assertEquals( - generatedEmail, - (result as GeneratedForwardedServiceUsernameResult.Success).generatedEmailAddress, - ) - coVerify { generatorSdkSource.generateForwardedServiceEmail(request) } - } + assertEquals( + generatedEmail, + (result as GeneratedForwardedServiceUsernameResult.Success).generatedEmailAddress, + ) + coVerify { generatorSdkSource.generateForwardedServiceEmail(request) } + } - @Suppress("MaxLineLength") @Test - fun `generateForwardedService should emit InvalidRequest result when SDK throws exception`() = runTest { - val request = UsernameGeneratorRequest.Forwarded( - service = ForwarderServiceType.DuckDuckGo(token = "testToken"), - website = null, - ) - val exception = RuntimeException("An error occurred") - coEvery { generatorSdkSource.generateForwardedServiceEmail(request) } returns Result.failure(exception) + fun `generateForwardedService should emit InvalidRequest result when SDK throws exception`() = + runTest { + val request = UsernameGeneratorRequest.Forwarded( + service = ForwarderServiceType.DuckDuckGo(token = "testToken"), + website = null, + ) + val exception = RuntimeException("An error occurred") + coEvery { + generatorSdkSource.generateForwardedServiceEmail(request) + } returns Result.failure(exception) - val result = repository.generateForwardedServiceUsername(request) + val result = repository.generateForwardedServiceUsername(request) - assertTrue(result is GeneratedForwardedServiceUsernameResult.InvalidRequest) - coVerify { generatorSdkSource.generateForwardedServiceEmail(request) } - } + assertTrue(result is GeneratedForwardedServiceUsernameResult.InvalidRequest) + coVerify { generatorSdkSource.generateForwardedServiceEmail(request) } + } @Test fun `getPasscodeGenerationOptions should return options when available`() = runTest { diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/FakePermissionManager.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/FakePermissionManager.kt index 4f56b89ff..12031675b 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/FakePermissionManager.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/base/util/FakePermissionManager.kt @@ -41,6 +41,6 @@ class FakePermissionManager : PermissionsManager { override fun shouldShouldRequestPermissionRationale( permission: String, ): Boolean { - return shouldShowRequestRationale + return shouldShowRequestRationale } } diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/passwordhistory/PasswordHistoryViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/passwordhistory/PasswordHistoryViewModelTest.kt index 8f488bdfc..a54b7a1ea 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/passwordhistory/PasswordHistoryViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/passwordhistory/PasswordHistoryViewModelTest.kt @@ -2,9 +2,9 @@ package com.x8bit.bitwarden.ui.tools.feature.generator.passwordhistory import app.cash.turbine.test import com.bitwarden.core.PasswordHistoryView +import com.x8bit.bitwarden.R import com.x8bit.bitwarden.data.platform.repository.model.LocalDataState import com.x8bit.bitwarden.data.tools.generator.repository.util.FakeGeneratorRepository -import com.x8bit.bitwarden.R import com.x8bit.bitwarden.ui.platform.base.BaseViewModelTest import com.x8bit.bitwarden.ui.platform.base.util.asText import com.x8bit.bitwarden.ui.tools.feature.generator.util.toFormattedPattern diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensionsTest.kt index ae9aa99aa..ea468e91b 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/tools/feature/generator/util/ServiceTypeExtensionsTest.kt @@ -2,8 +2,8 @@ package com.x8bit.bitwarden.ui.tools.feature.generator.util import com.bitwarden.core.ForwarderServiceType import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType -import org.junit.jupiter.api.Test import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test internal class ServiceTypeExtensionsTest { @@ -21,7 +21,8 @@ internal class ServiceTypeExtensionsTest { apiToken = "testToken", domain = "test.com", baseUrl = "http://test.com", - ), request.service, + ), + request.service, ) assertEquals(null, request.website) }