diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 2af114e..ca2dc86 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -11,7 +11,7 @@ android { compileSdk = 33 defaultConfig { - minSdk = 21 // Android 5 + minSdk = 23 // Android 6 aarMetadata { minCompileSdk = 29 diff --git a/lib/src/androidTest/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilderTest.kt b/lib/src/androidTest/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilderTest.kt index 4b34629..444821c 100644 --- a/lib/src/androidTest/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilderTest.kt +++ b/lib/src/androidTest/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilderTest.kt @@ -7,6 +7,11 @@ package at.bitfire.vcard4android.contactrow import android.net.Uri import android.provider.ContactsContract.CommonDataKinds.StructuredName import at.bitfire.vcard4android.Contact +import at.bitfire.vcard4android.LabeledProperty +import ezvcard.property.Email +import ezvcard.property.Nickname +import ezvcard.property.Organization +import ezvcard.property.Telephone import org.junit.Assert.assertEquals import org.junit.Test @@ -18,7 +23,73 @@ class StructuredNameBuilderTest { assertEquals(0, result.size) } } - + + @Test + fun testSkipWhenOnly_Email() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "test@example.com" + emails.add(LabeledProperty(Email("test@example.com"))) + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + + @Test + fun testSkipWhenOnly_Nickname() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "Foo" + nickName = LabeledProperty(Nickname().apply { + values.add("Foo") + }) + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + + @Test + fun testSkipWhenOnly_Org() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "Only A Company" + organization = Organization().apply { + values.add("Only A Company") + } + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + + @Test + fun testSkipWhenOnly_OrgJoined() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "Only / A / Company" + organization = Organization().apply { + values.addAll(arrayOf("Only", "A", "Company")) + } + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + + @Test + fun testSkipWhenOnly_PhoneNumber() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "+12345" + phoneNumbers.add(LabeledProperty(Telephone("+12345"))) + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + + @Test + fun testSkipWhenOnly_Uid() { + StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { + displayName = "e6d19ebc-992a-4fef-9a56-84eab8b3bd9c" + uid = "e6d19ebc-992a-4fef-9a56-84eab8b3bd9c" + }, false).build().also { result -> + assertEquals(0, result.size) + } + } + @Test fun testValues() { StructuredNameBuilder(Uri.EMPTY, null, Contact().apply { diff --git a/lib/src/main/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilder.kt b/lib/src/main/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilder.kt index 9363ef8..56b744a 100644 --- a/lib/src/main/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilder.kt +++ b/lib/src/main/java/at/bitfire/vcard4android/contactrow/StructuredNameBuilder.kt @@ -20,16 +20,24 @@ class StructuredNameBuilder(dataRowUri: Uri, rawContactId: Long?, contact: Conta contact.phoneticGivenName != null || contact.phoneticMiddleName != null || contact.phoneticFamilyName != null // no structured name info - if (contact.displayName == null && !hasStructuredComponents) + val displayName = contact.displayName + if (displayName == null && !hasStructuredComponents) return emptyList() - // only displayname and it's equivalent to the organization → - // don't create structured name row because it would split the organization into given/family name - if (contact.displayName != null && contact.displayName == contact.organization?.values?.firstOrNull() && !hasStructuredComponents) + // only displayName and it's equivalent to one of the values in ContactWriter.addFormattedName → + // don't create structured name row because it wouldn't add information but split the organization into given/family name + if (displayName != null && !hasStructuredComponents && ( + contact.organization?.values?.contains(displayName) == true || + contact.organization?.values?.joinToString(" / ") == displayName || + contact.nickName?.property?.values?.contains(displayName) == true || + contact.emails.any { it.property.value == displayName } || + contact.phoneNumbers.any { it.property.text == displayName } || + contact.uid == displayName + )) return emptyList() return listOf(newDataRow().apply { - withValue(StructuredName.DISPLAY_NAME, contact.displayName) + withValue(StructuredName.DISPLAY_NAME, displayName) withValue(StructuredName.PREFIX, contact.prefix) withValue(StructuredName.GIVEN_NAME, contact.givenName) withValue(StructuredName.MIDDLE_NAME, contact.middleName)