Updated on 2026-08-14

This commit is contained in:
Tangem 2025-08-08 21:28:44 +04:00
parent 06263e1193
commit abbfa57a2f
8 changed files with 44 additions and 20 deletions

View file

@ -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(

View file

@ -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<Error>.saveAccounts(accountList: AccountList) {

View file

@ -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)

View file

@ -66,12 +66,12 @@ class AccountListTest {
}
@Test
fun createEmpty() {
fun empty() {
// Arrange
val userWallet = mockk<UserWallet>(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(),
),
)
}

View file

@ -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")

View file

@ -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()!!

View file

@ -11,7 +11,11 @@ fun createAccounts(userWalletId: UserWalletId, count: Int): Set<Account.CryptoPo
add(Account.CryptoPortfolio.createMainAccount(userWalletId))
repeat(count - 1) {
val account = createAccount(userWalletId = userWalletId, derivationIndex = it + 1)
val account = createAccount(
userWalletId = userWalletId,
name = "Test Account ${it + 1}",
derivationIndex = it + 1,
)
add(account)
}