Updated on 2026-08-14
This commit is contained in:
commit
37694bb2a4
12 changed files with 68 additions and 13 deletions
|
|
@ -195,10 +195,12 @@ internal class DefaultAddressBookRepositoryTest {
|
|||
assertThat(result).isEqualTo(bob)
|
||||
}
|
||||
|
||||
private fun createContact(id: String, name: String): Contact = Contact(
|
||||
private fun createContact(id: String, name: String, iconColor: String = "KekColor"): Contact = Contact(
|
||||
id = ContactId(id),
|
||||
walletId = UserWalletId(WALLET_A),
|
||||
name = ContactName(name).getOrNull()!!,
|
||||
icon = "",
|
||||
iconColor = iconColor,
|
||||
createdAt = TIMESTAMP,
|
||||
updatedAt = TIMESTAMP,
|
||||
addressEntries = emptyList(),
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ data class Contact(
|
|||
val id: ContactId,
|
||||
val walletId: UserWalletId,
|
||||
val name: ContactName,
|
||||
val icon: String,
|
||||
val iconColor: String,
|
||||
val createdAt: String,
|
||||
val updatedAt: String,
|
||||
val addressEntries: List<AddressEntry>,
|
||||
|
|
|
|||
|
|
@ -25,10 +25,10 @@ class CreateContactUseCase(
|
|||
private val timestampProvider: IsoTimestampProvider,
|
||||
) {
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
suspend operator fun invoke(
|
||||
userWallet: UserWallet,
|
||||
name: String,
|
||||
iconColor: String,
|
||||
network: Network,
|
||||
addressEntries: List<AddressEntry>,
|
||||
): Either<SaveContactError, Contact> = either {
|
||||
|
|
@ -42,6 +42,8 @@ class CreateContactUseCase(
|
|||
id = ContactId(UUID.randomUUID().toString()),
|
||||
walletId = userWalletId,
|
||||
name = validName,
|
||||
icon = "",
|
||||
iconColor = iconColor,
|
||||
createdAt = now,
|
||||
updatedAt = now,
|
||||
addressEntries = addressEntries,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ class UpdateContactUseCase(
|
|||
userWallet: UserWallet,
|
||||
contact: Contact,
|
||||
name: String,
|
||||
iconColor: String,
|
||||
addressEntries: List<AddressEntry>,
|
||||
): Either<SaveContactError, Contact> = either {
|
||||
val validName = ContactName(name)
|
||||
|
|
@ -29,6 +30,7 @@ class UpdateContactUseCase(
|
|||
|
||||
val updated = contact.copy(
|
||||
name = validName,
|
||||
iconColor = iconColor,
|
||||
addressEntries = addressEntries,
|
||||
updatedAt = timestampProvider.now(),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -36,8 +36,16 @@ internal class AddressBookCipherTest {
|
|||
fun `GIVEN multi-contact book WHEN encrypt then decrypt THEN original book is restored`() {
|
||||
// Arrange
|
||||
val book = addressBook(
|
||||
contact("Alice", entry("addr-1", "0xabc", memo = "memo")),
|
||||
contact("Bob", entry("addr-2", "0xdef", memo = null)),
|
||||
contact(
|
||||
name = "Alice",
|
||||
iconColor = "TestColor1",
|
||||
entries = arrayOf(entry("addr-1", "0xabc", memo = "memo")),
|
||||
),
|
||||
contact(
|
||||
name = "Bob",
|
||||
iconColor = "TestColor2",
|
||||
entries = arrayOf(entry("addr-2", "0xdef", memo = null)),
|
||||
),
|
||||
)
|
||||
|
||||
// Act
|
||||
|
|
@ -64,7 +72,13 @@ internal class AddressBookCipherTest {
|
|||
@Test
|
||||
fun `GIVEN a book WHEN encrypt THEN blob metadata and field sizes match the spec`() {
|
||||
// Arrange
|
||||
val book = addressBook(contact("Alice", entry("addr-1", "0xabc", memo = null)))
|
||||
val book = addressBook(
|
||||
contact(
|
||||
name = "Alice",
|
||||
iconColor = "TestColor",
|
||||
entries = arrayOf(entry("addr-1", "0xabc", memo = null)),
|
||||
)
|
||||
)
|
||||
|
||||
// Act
|
||||
val blob = cipher.encrypt(book, wallet, updatedAt).rightValue()
|
||||
|
|
@ -94,7 +108,13 @@ internal class AddressBookCipherTest {
|
|||
@Test
|
||||
fun `GIVEN same book encrypted twice WHEN compared THEN nonce differs but both decrypt to original`() {
|
||||
// Arrange
|
||||
val book = addressBook(contact("Alice", entry("addr-1", "0xabc", memo = null)))
|
||||
val book = addressBook(
|
||||
contact(
|
||||
name = "Alice",
|
||||
iconColor = "TestColor",
|
||||
entries = arrayOf(entry("addr-1", "0xabc", memo = null)),
|
||||
)
|
||||
)
|
||||
|
||||
// Act
|
||||
val first = cipher.encrypt(book, wallet, updatedAt).rightValue()
|
||||
|
|
@ -222,10 +242,12 @@ internal class AddressBookCipherTest {
|
|||
private fun addressBook(walletId: UserWalletId): AddressBook =
|
||||
AddressBook(walletId = walletId, contacts = emptyList())
|
||||
|
||||
private fun contact(name: String, vararg entries: AddressEntry): Contact = Contact(
|
||||
private fun contact(name: String, iconColor: String, vararg entries: AddressEntry): Contact = Contact(
|
||||
id = ContactId("contact-$name"),
|
||||
walletId = wallet.walletId,
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = iconColor,
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-05-22T09:00:00.000Z",
|
||||
addressEntries = entries.toList(),
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ class CreateContactUseCaseTest {
|
|||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
name = "Alice",
|
||||
iconColor = "TestColor",
|
||||
network = network,
|
||||
addressEntries = addressEntries,
|
||||
)
|
||||
|
|
@ -102,6 +103,7 @@ class CreateContactUseCaseTest {
|
|||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
name = "Alice",
|
||||
iconColor = "TestColor",
|
||||
network = network,
|
||||
addressEntries = addressEntries,
|
||||
)
|
||||
|
|
@ -112,11 +114,16 @@ class CreateContactUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `duplicate name fails without persisting`() = runTest {
|
||||
every { repository.getContacts(walletId) } returns flowOf(listOf(contact(name = "Alice")))
|
||||
every { repository.getContacts(walletId) } returns flowOf(
|
||||
listOf(
|
||||
contact(name = "Alice", iconColor = "TestColor")
|
||||
)
|
||||
)
|
||||
|
||||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
name = "alice",
|
||||
iconColor = "TestColor",
|
||||
network = network,
|
||||
addressEntries = addressEntries,
|
||||
)
|
||||
|
|
@ -133,6 +140,7 @@ class CreateContactUseCaseTest {
|
|||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
name = "",
|
||||
iconColor = "TestColor",
|
||||
network = network,
|
||||
addressEntries = addressEntries,
|
||||
)
|
||||
|
|
@ -142,10 +150,12 @@ class CreateContactUseCaseTest {
|
|||
coVerify(exactly = 0) { repository.saveContact(any()) }
|
||||
}
|
||||
|
||||
private fun contact(name: String): Contact = Contact(
|
||||
private fun contact(name: String, iconColor: String): Contact = Contact(
|
||||
id = ContactId("id-$name"),
|
||||
walletId = walletId,
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = iconColor,
|
||||
createdAt = expectedTimestamp,
|
||||
updatedAt = expectedTimestamp,
|
||||
addressEntries = listOf(
|
||||
|
|
|
|||
|
|
@ -90,6 +90,8 @@ class GetContactsUseCaseTest {
|
|||
id = ContactId("id-$name"),
|
||||
walletId = UserWalletId("011"),
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = "KekColor",
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-01-01T00:00:00.000Z",
|
||||
addressEntries = listOf(
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@ class GetVerifiedContactsUseCaseTest {
|
|||
id = ContactId("id-$name"),
|
||||
walletId = walletId,
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = "KekColor",
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-01-01T00:00:00.000Z",
|
||||
addressEntries = entries,
|
||||
|
|
|
|||
|
|
@ -124,6 +124,8 @@ class SignAddressEntriesUseCaseTest {
|
|||
id = ContactId("contact-1"),
|
||||
walletId = UserWalletId("011"),
|
||||
name = requireNotNull(ContactName("Alice").getOrNull()),
|
||||
icon = "",
|
||||
iconColor = "KekColor",
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-01-01T00:00:00.000Z",
|
||||
addressEntries = entries.toList(),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class UpdateContactUseCaseTest {
|
|||
|
||||
@Test
|
||||
fun `update preserves id and persists signed changes without checking uniqueness`() = runTest {
|
||||
val existing = contact(name = "Alice")
|
||||
val existing = contact(name = "Alice", iconColor = "TestColor")
|
||||
val saved = slot<Contact>()
|
||||
coEvery { repository.saveContact(capture(saved)) } returns Unit
|
||||
|
||||
|
|
@ -77,6 +77,7 @@ class UpdateContactUseCaseTest {
|
|||
userWallet = userWallet,
|
||||
contact = existing,
|
||||
name = "Bob",
|
||||
iconColor = "TestColor",
|
||||
addressEntries = updatedEntries,
|
||||
)
|
||||
|
||||
|
|
@ -96,8 +97,9 @@ class UpdateContactUseCaseTest {
|
|||
|
||||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
contact = contact(name = "Alice"),
|
||||
contact = contact(name = "Alice", iconColor = "TestColor"),
|
||||
name = "Bob",
|
||||
iconColor = "TestColor",
|
||||
addressEntries = updatedEntries,
|
||||
)
|
||||
|
||||
|
|
@ -109,8 +111,9 @@ class UpdateContactUseCaseTest {
|
|||
fun `invalid name fails without persisting`() = runTest {
|
||||
val result = useCase(
|
||||
userWallet = userWallet,
|
||||
contact = contact(name = "Alice"),
|
||||
contact = contact(name = "Alice", iconColor = "TestColor"),
|
||||
name = "",
|
||||
iconColor = "TestColor",
|
||||
addressEntries = updatedEntries,
|
||||
)
|
||||
|
||||
|
|
@ -119,10 +122,12 @@ class UpdateContactUseCaseTest {
|
|||
coVerify(exactly = 0) { repository.saveContact(any()) }
|
||||
}
|
||||
|
||||
private fun contact(name: String): Contact = Contact(
|
||||
private fun contact(name: String, iconColor: String): Contact = Contact(
|
||||
id = ContactId("id-$name"),
|
||||
walletId = walletId,
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = iconColor,
|
||||
createdAt = originalTimestamp,
|
||||
updatedAt = originalTimestamp,
|
||||
addressEntries = listOf(
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ class ValidateContactNameUseCaseTest {
|
|||
id = ContactId("id-$name"),
|
||||
walletId = walletId,
|
||||
name = requireNotNull(ContactName(name).getOrNull()),
|
||||
icon = "",
|
||||
iconColor = "KekColor",
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-01-01T00:00:00.000Z",
|
||||
addressEntries = listOf(
|
||||
|
|
|
|||
|
|
@ -152,6 +152,8 @@ class VerifyAddressEntriesUseCaseTest {
|
|||
id = ContactId("contact-1"),
|
||||
walletId = UserWalletId("011"),
|
||||
name = requireNotNull(ContactName("Alice").getOrNull()),
|
||||
icon = "",
|
||||
iconColor = "KekColor",
|
||||
createdAt = "2026-01-01T00:00:00.000Z",
|
||||
updatedAt = "2026-01-01T00:00:00.000Z",
|
||||
addressEntries = entries.toList(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue