diff --git a/domain/account/src/main/java/com/tangem/domain/account/models/AccountList.kt b/domain/account/src/main/java/com/tangem/domain/account/models/AccountList.kt index 670a7b2bb6..319babf91b 100644 --- a/domain/account/src/main/java/com/tangem/domain/account/models/AccountList.kt +++ b/domain/account/src/main/java/com/tangem/domain/account/models/AccountList.kt @@ -108,6 +108,11 @@ data class AccountList private constructor( data object DuplicateAccountIds : Error { override fun toString(): String = "$tag: Account list contains duplicate account IDs" } + + @Serializable + data object DuplicateAccountNames : Error { + override fun toString(): String = "$tag: Account list contains duplicate account names" + } } companion object { @@ -144,6 +149,9 @@ data class AccountList private constructor( val uniqueAccountIdsCount = accounts.map { it.accountId.value }.distinct().size ensure(accounts.size == uniqueAccountIdsCount) { Error.DuplicateAccountIds } + val uniqueAccountNameCount = accounts.map { it.name.value }.distinct().size + ensure(accounts.size == uniqueAccountNameCount) { Error.DuplicateAccountNames } + AccountList(userWallet = userWallet, accounts = accounts, totalAccounts = totalAccounts) } @@ -152,7 +160,7 @@ data class AccountList private constructor( * * @param userWallet the user wallet associated with the account list */ - fun createEmpty(userWallet: UserWallet): AccountList { + fun empty(userWallet: UserWallet): AccountList { return AccountList( userWallet = userWallet, accounts = setOf( diff --git a/domain/account/src/main/java/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCase.kt b/domain/account/src/main/java/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCase.kt index 8c9d43c18f..75722f9824 100644 --- a/domain/account/src/main/java/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCase.kt +++ b/domain/account/src/main/java/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCase.kt @@ -46,8 +46,9 @@ class AddCryptoPortfolioUseCase( createNewAccountList(userWalletId = userWalletId) } - val updatedAccounts = (accountList + newAccount) - .getOrElse { raise(Error.AccountListRequirementsNotMet(it)) } + val updatedAccounts = (accountList + newAccount).getOrElse { + raise(Error.AccountListRequirementsNotMet(it)) + } saveAccounts(updatedAccounts) @@ -87,7 +88,7 @@ class AddCryptoPortfolioUseCase( catch = { raise(Error.DataOperationFailed(cause = it)) }, ) - return AccountList.createEmpty(userWallet = userWallet) + return AccountList.empty(userWallet = userWallet) } private suspend fun Raise.saveAccounts(accountList: AccountList) { diff --git a/domain/account/src/main/java/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCase.kt b/domain/account/src/main/java/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCase.kt index d73f3e9eaa..8c2208e552 100644 --- a/domain/account/src/main/java/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCase.kt +++ b/domain/account/src/main/java/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCase.kt @@ -50,8 +50,9 @@ class UpdateCryptoPortfolioUseCase( .setName(name = accountName) .setIcon(icon = icon) - val updatedAccounts = (accountList + updatedAccount) - .getOrElse { raise(Error.CriticalTechError.AccountListRequirementsNotMet(it)) } + val updatedAccounts = (accountList + updatedAccount).getOrElse { + raise(Error.CriticalTechError.AccountListRequirementsNotMet(it)) + } saveAccounts(updatedAccounts) diff --git a/domain/account/src/test/kotlin/com/tangem/domain/account/models/AccountListTest.kt b/domain/account/src/test/kotlin/com/tangem/domain/account/models/AccountListTest.kt index 69e846a06a..d5323c0a85 100644 --- a/domain/account/src/test/kotlin/com/tangem/domain/account/models/AccountListTest.kt +++ b/domain/account/src/test/kotlin/com/tangem/domain/account/models/AccountListTest.kt @@ -66,12 +66,12 @@ class AccountListTest { } @Test - fun createEmpty() { + fun empty() { // Arrange val userWallet = mockk(relaxed = true) // Act - val actual = AccountList.createEmpty(userWallet) + val actual = AccountList.empty(userWallet) // Assert val expected = AccountList( @@ -152,6 +152,13 @@ class AccountListTest { ), expected = AccountList.Error.DuplicateAccountIds.left(), ), + CreateTestModel( + accounts = setOf( + createAccount(userWalletId = userWalletId, name = "Name", derivationIndex = 0), + createAccount(userWalletId = userWalletId, name = "Name", derivationIndex = 1), + ), + expected = AccountList.Error.DuplicateAccountNames.left(), + ), ) } diff --git a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCaseTest.kt b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCaseTest.kt index 1e7d026c11..cf47f9b807 100644 --- a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCaseTest.kt +++ b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/AddCryptoPortfolioUseCaseTest.kt @@ -30,13 +30,15 @@ class AddCryptoPortfolioUseCaseTest { @BeforeEach fun resetMocks() { clearMocks(crudRepository, userWallet) + + every { userWallet.walletId } returns userWalletId } @Test fun `invoke should add new crypto portfolio account to existing list`() = runTest { // Arrange val newAccount = createNewAccount() - val accountList = AccountList.createEmpty(userWallet) + val accountList = AccountList.empty(userWallet) val updatedAccountList = (accountList + newAccount).getOrNull()!! coEvery { crudRepository.getAccounts(userWalletId) } returns accountList.toOption() @@ -65,7 +67,7 @@ class AddCryptoPortfolioUseCaseTest { fun `invoke should create new account list if none exists`() = runTest { // Arrange val newAccount = createNewAccount() - val newAccountList = (AccountList.createEmpty(userWallet) + newAccount).getOrNull()!! + val newAccountList = (AccountList.empty(userWallet) + newAccount).getOrNull()!! coEvery { crudRepository.getAccounts(userWalletId) } returns None coEvery { crudRepository.getUserWallet(userWalletId) } returns userWallet @@ -157,7 +159,7 @@ class AddCryptoPortfolioUseCaseTest { fun `invoke should return error if saveAccounts throws exception`() = runTest { // Arrange val newAccount = createNewAccount() - val accountList = AccountList.createEmpty(userWallet) + val accountList = AccountList.empty(userWallet) val updatedAccountList = (accountList + newAccount).getOrNull()!! val exception = IllegalStateException("Test error") diff --git a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCaseTest.kt b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCaseTest.kt index 073c68e1d6..d6638b5c05 100644 --- a/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCaseTest.kt +++ b/domain/account/src/test/kotlin/com/tangem/domain/account/usecase/UpdateCryptoPortfolioUseCaseTest.kt @@ -41,7 +41,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke should update crypto portfolio account with new name`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId val newAccountName = AccountName("New name").getOrNull()!! @@ -66,7 +66,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke should update crypto portfolio account with new icon`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId val newAccountIcon = CryptoPortfolioIcon.ofCustomAccount( @@ -94,7 +94,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke should update crypto portfolio account with new name and icon`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId val newAccountName = AccountName("New name").getOrNull()!! @@ -123,7 +123,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke if name and icon are null`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId coEvery { crudRepository.getAccounts(userWalletId = userWalletId) } returns accountList.toOption() @@ -144,7 +144,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke if getAccounts throws exception`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId val newAccountName = AccountName("New name").getOrNull()!! @@ -191,7 +191,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke if getAccounts does not contain accountId`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = AccountId.forCryptoPortfolio( userWalletId = userWalletId, derivationIndex = DerivationIndex(1).getOrNull()!!, @@ -215,7 +215,7 @@ class UpdateCryptoPortfolioUseCaseTest { @Test fun `invoke if saveAccounts throws exception`() = runTest { // Arrange - val accountList = AccountList.createEmpty(userWallet = userWallet) + val accountList = AccountList.empty(userWallet = userWallet) val accountId = accountList.mainAccount.accountId val newAccountName = AccountName("New name").getOrNull()!! diff --git a/domain/account/src/test/kotlin/com/tangem/domain/account/utils/AccountExt.kt b/domain/account/src/test/kotlin/com/tangem/domain/account/utils/AccountExt.kt index 6246176a50..597d6aa059 100644 --- a/domain/account/src/test/kotlin/com/tangem/domain/account/utils/AccountExt.kt +++ b/domain/account/src/test/kotlin/com/tangem/domain/account/utils/AccountExt.kt @@ -11,7 +11,11 @@ fun createAccounts(userWalletId: UserWalletId, count: Int): Set