diff --git a/library/build.gradle b/library/build.gradle index f86e3851..7fd3a307 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -50,4 +50,6 @@ dependencies { androidTestImplementation "androidx.test:runner:$testRunnerVersion" androidTestImplementation "androidx.test:rules:$testRulesVersion" androidTestImplementation "androidx.test:core:$testCoreVersion" + testImplementation "junit:junit:$junitVersion" + testImplementation "org.assertj:assertj-core:$assertjVersion" } \ No newline at end of file diff --git a/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt b/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt new file mode 100644 index 00000000..73497399 --- /dev/null +++ b/library/src/main/java/com/alexstyl/contactstore/ContactStoreDSL.kt @@ -0,0 +1,37 @@ +package com.alexstyl.contactstore + +suspend fun ContactStore.execute(request: SaveRequest.() -> Unit) { + execute(SaveRequest().apply(request)) +} + +fun SaveRequest.insert(builder: MutableContactBuilder.() -> Unit) { + val values = MutableContactBuilder().apply(builder) + insert(MutableContact().apply { + isStarred = values.isStarred + imageData = values.imageData + + prefix = values.prefix + firstName = values.firstName + middleName = values.middleName + lastName = values.lastName + suffix = values.suffix + + fullNameStyle = values.fullNameStyle + phoneticFirstName = values.phoneticFirstName + phoneticLastName = values.phoneticLastName + phoneticMiddleName = values.phoneticMiddleName + + nickname = values.nickname + note = values.note?.let { Note(it) } + + jobTitle = values.jobTitle + organization = values.organization + + phones.addAll(values.phones) + mails.addAll(values.mails) + events.addAll(values.events) + postalAddresses.addAll(values.postalAddresses) + webAddresses.addAll(values.webAddresses) + groups.addAll(values.groupMemberships) + }) +} diff --git a/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt b/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt index bd38ffa8..aada5727 100644 --- a/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt +++ b/library/src/main/java/com/alexstyl/contactstore/DataClasses.kt @@ -29,12 +29,12 @@ data class WebAddress(val raw: String) data class PostalAddress( val street: String, - val poBox: String, - val neighborhood: String, - val city: String, - val region: String, - val postCode: String, - val country: String + val poBox: String = "", + val neighborhood: String = "", + val city: String = "", + val region: String = "", + val postCode: String = "", + val country: String = "", ) @Suppress("MagicNumber") diff --git a/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt b/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt new file mode 100644 index 00000000..251c027c --- /dev/null +++ b/library/src/main/java/com/alexstyl/contactstore/MutableContactBuilder.kt @@ -0,0 +1,111 @@ +package com.alexstyl.contactstore + +import android.provider.ContactsContract + +data class MutableContactBuilder( + var prefix: String = "", + var firstName: String = "", + var middleName: String = "", + var lastName: String = "", + var suffix: String = "", + var fullNameStyle: Int = ContactsContract.FullNameStyle.UNDEFINED, + var phoneticNameStyle: Int = ContactsContract.PhoneticNameStyle.UNDEFINED, + var phoneticFirstName: String = "", + var phoneticMiddleName: String = "", + var phoneticLastName: String = "", + var nickname: String = "", + var note: String? = null, + var jobTitle: String = "", + var organization: String = "", + var imageData: ImageData? = null, + var isStarred: Boolean = false, +) { + private val _phones: MutableList> = mutableListOf() + val phones: List> + get() = _phones.toList() + + private val _mails: MutableList> = mutableListOf() + val mails: List> + get() = _mails.toList() + + private val _events: MutableList> = mutableListOf() + val events: List> + get() = _events.toList() + + private val _postalAddresses: MutableList> = mutableListOf() + val postalAddresses: List> + get() = _postalAddresses.toList() + + private val _webAddresses: MutableList> = mutableListOf() + val webAddresses: List> + get() = _webAddresses.toList() + + private val _groups: MutableList = mutableListOf() + val groupMemberships: List + get() = _groups.toList() + + fun phone( + number: String, + label: Label + ) { + _phones.add(LabeledValue(PhoneNumber(number), label)) + } + + fun mail( + address: String, + label: Label + ) { + _mails.add(LabeledValue(MailAddress(address), label)) + } + + fun event(dayOfMonth: Int, month: Int, year: Int? = null, label: Label) { + _events.add( + LabeledValue(EventDate(dayOfMonth = dayOfMonth, month = month, year = year), label) + ) + } + + fun postalAddress( + street: String, + poBox: String = "", + neighborhood: String = "", + city: String = "", + region: String = "", + postCode: String = "", + country: String = "", + label: Label + ) { + _postalAddresses.add( + LabeledValue( + value = PostalAddress( + street = street, + poBox = poBox, + neighborhood = neighborhood, + city = city, + region = region, + postCode = postCode, + country = country, + ), + label = label + ) + ) + } + + fun postalAddress(fullAddress: String, label: Label) { + _postalAddresses.add( + LabeledValue( + value = PostalAddress(fullAddress), + label = label + ) + ) + } + + fun webAddress(address: String, label: Label) { + _webAddresses.add(LabeledValue(WebAddress(address), label)) + } + + fun groupMembership(groupId: Long) { + _groups.add( + GroupMembership(groupId) + ) + } +} diff --git a/library/src/main/java/com/alexstyl/contactstore/SaveRequest.kt b/library/src/main/java/com/alexstyl/contactstore/SaveRequest.kt index 6faa588d..7f0085ee 100644 --- a/library/src/main/java/com/alexstyl/contactstore/SaveRequest.kt +++ b/library/src/main/java/com/alexstyl/contactstore/SaveRequest.kt @@ -35,4 +35,23 @@ class SaveRequest { fun delete(contactId: Long) { _requests.add(Delete(contactId)) } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as SaveRequest + + if (_requests != other._requests) return false + + return true + } + + override fun hashCode(): Int { + return _requests.hashCode() + } + + override fun toString(): String { + return "SaveRequest(_requests=$_requests)" + } } diff --git a/library/src/test/java/com/alexstyl/contactstore/ContactStoreDSLKtTest.kt b/library/src/test/java/com/alexstyl/contactstore/ContactStoreDSLKtTest.kt new file mode 100644 index 00000000..6ece6041 --- /dev/null +++ b/library/src/test/java/com/alexstyl/contactstore/ContactStoreDSLKtTest.kt @@ -0,0 +1,132 @@ +package com.alexstyl.contactstore + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test + +class ContactStoreDSLKtTest { + + @Test + fun insert(): Unit = runBlocking { + val store = contactStore() + store.execute { + insert { + prefix = "pref" + firstName = "Paolo" + middleName = "Mid" + lastName = "Melendez" + suffix = "Suf" + note = "Note to self" + jobTitle = "Job Title" + organization = "Org" + + imageData = ImageData("image data".toByteArray()) + isStarred = false + phone( + number = "555-11-23", + label = Label.LocationHome + ) + + mail( + address = "paolo@paolo.com", + label = Label.LocationWork + ) + event( + dayOfMonth = 3, + month = 12, + year = 2021, + label = Label.DateBirthday + ) + + postalAddress( + street = "85 Somewhere Str", + label = Label.LocationHome + ) + + webAddress( + address = "www.paolo.com", + label = Label.LocationWork + ) + groupMembership(groupId = 123) + } + } + assertThat(store.request).isEqualTo( + SaveRequest().apply { + insert(MutableContact().apply { + prefix = "pref" + firstName = "Paolo" + middleName = "Mid" + lastName = "Melendez" + suffix = "Suf" + note = Note("Note to self") + jobTitle = "Job Title" + organization = "Org" + + imageData = ImageData("image data".toByteArray()) + isStarred = false + phones.add( + LabeledValue( + value = PhoneNumber("555-11-23"), + label = Label.LocationHome + ) + ) + mails.add( + LabeledValue( + value = MailAddress("paolo@paolo.com"), + label = Label.LocationWork + ) + ) + events.add( + LabeledValue( + value = EventDate( + dayOfMonth = 3, + month = 12, + year = 2021, + ), + label = Label.DateBirthday + ) + ) + + postalAddresses.add( + LabeledValue( + PostalAddress(street = "85 Somewhere Str"), + Label.LocationHome + ) + ) + + webAddresses.add( + LabeledValue( + value = WebAddress("www.paolo.com"), + label = Label.LocationWork + ) + ) + groups.add( + GroupMembership(123) + ) + }) + } + ) + } + + private fun contactStore(): TestContactStore { + return TestContactStore() + } + + private class TestContactStore : ContactStore { + + var request: SaveRequest? = null + + override suspend fun execute(request: SaveRequest) { + this.request = request + } + + override fun fetchContacts( + predicate: ContactPredicate?, + columnsToFetch: List + ): Flow> { + return emptyFlow() + } + } +}