Skip to content
This repository was archived by the owner on Aug 21, 2025. It is now read-only.

Commit 8d20527

Browse files
committed
VCard - FN should containt displayName/nickname
1 parent 682ac7c commit 8d20527

File tree

2 files changed

+7
-54
lines changed
  • homeUi/src
    • main/kotlin/com/gravatar/app/homeUi/presentation/home/share/model
    • test/kotlin/com/gravatar/app/homeUi/presentation/home/share/model

2 files changed

+7
-54
lines changed

homeUi/src/main/kotlin/com/gravatar/app/homeUi/presentation/home/share/model/VCard.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,14 @@ internal class VCard private constructor(
1919

2020
val firstName = firstName.orEmpty()
2121
val lastName = lastName.orEmpty()
22-
val nickname = nickname.orEmpty()
2322
if (firstName.isNotEmpty() || lastName.isNotEmpty()) {
2423
contentBuilder.append("N:${lastName.escaped()};${firstName.escaped()};;;\n")
25-
.append(
26-
"FN:${("${firstName.escaped()} ${lastName.escaped()}".trim()).ifEmpty { nickname.escaped() }}\n"
27-
)
2824
}
29-
val calculatedNickname = nickname.ifEmpty { "$firstName $lastName".trim() }.escaped()
30-
31-
calculatedNickname.takeIf { it.isNotEmpty() }?.let { contentBuilder.append("NICKNAME:${it.escaped()}\n") }
25+
nickname?.takeIf { it.isNotEmpty() }?.let {
26+
contentBuilder
27+
.append("NICKNAME:${it.escaped()}\n")
28+
.append("FN:${it.escaped()}\n")
29+
}
3230
organization?.takeIf { it.isNotEmpty() }?.let { contentBuilder.append("ORG:${it.escaped()}\n") }
3331
title?.takeIf { it.isNotEmpty() }?.let { contentBuilder.append("TITLE:${it.escaped()}\n") }
3432
profileUrl?.takeIf { it.isNotEmpty() }?.let { contentBuilder.append("URL:${it.escaped()}\n") }

homeUi/src/test/kotlin/com/gravatar/app/homeUi/presentation/home/share/model/VCardTest.kt

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class VCardTest {
2626
assertTrue(vCardString.contains("VERSION:3.0"))
2727
assertTrue(vCardString.contains("PRODID:Gravatar Android"))
2828
assertTrue(vCardString.contains("N:Doe;John;;;"))
29-
assertTrue(vCardString.contains("FN:John Doe"))
29+
assertTrue(vCardString.contains("FN:Johnny"))
3030
assertTrue(vCardString.contains("NICKNAME:Johnny"))
3131
assertTrue(vCardString.contains("ORG:Gravatar"))
3232
assertTrue(vCardString.contains("TITLE:Developer"))
@@ -51,8 +51,6 @@ class VCardTest {
5151
assertTrue(vCardString.contains("VERSION:3.0"))
5252
assertTrue(vCardString.contains("PRODID:Gravatar Android"))
5353
assertTrue(vCardString.contains("N:;Jane;;;")) // Last name is empty
54-
assertTrue(vCardString.contains("FN:Jane")) // FN falls back to first name
55-
assertTrue(vCardString.contains("NICKNAME:Jane")) // Nickname falls back to FN
5654
assertTrue(vCardString.contains("ORG:Automattic"))
5755
assertTrue(vCardString.contains("EMAIL:jane.doe@example.com"))
5856
assertTrue(vCardString.endsWith("END:VCARD"))
@@ -78,49 +76,6 @@ class VCardTest {
7876
)
7977
}
8078

81-
@Test
82-
fun `FN and NICKNAME fall back correctly when names or nickname are empty`() {
83-
// Case 1: Only first name
84-
var vCard = VCard.Builder().firstName("Solo").build()
85-
var vCardString = vCard.toString()
86-
assertTrue(vCardString.contains("N:;Solo;;;"))
87-
assertTrue(vCardString.contains("FN:Solo"))
88-
assertTrue(vCardString.contains("NICKNAME:Solo"))
89-
90-
// Case 2: Only last name
91-
vCard = VCard.Builder().lastName("OnlyLastName").build()
92-
vCardString = vCard.toString()
93-
assertTrue(vCardString.contains("N:OnlyLastName;;;;"))
94-
assertTrue(vCardString.contains("FN:OnlyLastName"))
95-
assertTrue(vCardString.contains("NICKNAME:OnlyLastName"))
96-
97-
// Case 3: First name, last name, but empty nickname
98-
vCard = VCard.Builder().firstName("First").lastName("Last").nickname("").build()
99-
vCardString = vCard.toString()
100-
assertTrue(vCardString.contains("N:Last;First;;;"))
101-
assertTrue(vCardString.contains("FN:First Last"))
102-
assertTrue(vCardString.contains("NICKNAME:First Last")) // Falls back to FN
103-
104-
// Case 4: Only nickname
105-
vCard = VCard.Builder().nickname("JustNickname").build()
106-
vCardString = vCard.toString()
107-
assertEquals(
108-
"BEGIN:VCARD\n" +
109-
"VERSION:3.0\n" +
110-
"PRODID:Gravatar Android\n" +
111-
"NICKNAME:JustNickname\n" +
112-
"END:VCARD",
113-
vCardString
114-
)
115-
116-
// Case 5: First name, last name, and nickname (nickname should take precedence for NICKNAME field)
117-
vCard = VCard.Builder().firstName("Official").lastName("Name").nickname("PreferredNick").build()
118-
vCardString = vCard.toString()
119-
assertTrue(vCardString.contains("N:Name;Official;;;"))
120-
assertTrue(vCardString.contains("FN:Official Name"))
121-
assertTrue(vCardString.contains("NICKNAME:PreferredNick"))
122-
}
123-
12479
@Test
12580
fun `builder handles null inputs gracefully`() {
12681
val vCard = VCard.Builder()
@@ -186,7 +141,7 @@ class VCardTest {
186141
val vCardString = vCard.toString()
187142

188143
assertTrue(vCardString.contains("N:Last Name;First Name;;;"))
189-
assertTrue(vCardString.contains("FN:First Name Last Name"))
144+
assertTrue(vCardString.contains("FN:Nick Name"))
190145
assertTrue(vCardString.contains("NICKNAME:Nick Name"))
191146
assertTrue(vCardString.contains("ORG:Org Name"))
192147
assertTrue(vCardString.contains("TITLE:Job Title"))

0 commit comments

Comments
 (0)