Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
for #24931: create address label and description based on available data
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewTighe committed May 6, 2022
1 parent aa78f10 commit 9087b72
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 3 deletions.
7 changes: 6 additions & 1 deletion app/src/main/java/org/mozilla/fenix/compose/list/ListItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private val ICON_SIZE = 24.dp
* @param label The label in the list item.
* @param modifier [Modifier] to be applied to the layout.
* @param description An optional description text below the label.
* @param maxDescriptionLines An optional maximum number of lines for the description text to span.
* @param onClick Called when the user clicks on the item.
* @param iconPainter [Painter] used to display a [ListItemIcon] after the list item.
* @param iconDescription Content description of the icon.
Expand All @@ -51,6 +52,7 @@ fun TextListItem(
label: String,
modifier: Modifier = Modifier,
description: String? = null,
maxDescriptionLines: Int = 1,
onClick: (() -> Unit)? = null,
iconPainter: Painter? = null,
iconDescription: String? = null,
Expand All @@ -60,6 +62,7 @@ fun TextListItem(
label = label,
modifier = modifier,
description = description,
maxDescriptionLines,
onClick = onClick,
afterListAction = {
iconPainter?.let {
Expand Down Expand Up @@ -172,6 +175,7 @@ fun IconListItem(
* @param label The label in the list item.
* @param modifier [Modifier] to be applied to the layout.
* @param description An optional description text below the label.
* @param maxDescriptionLines An optional maximum number of lines for the description text to span.
* @param onClick Called when the user clicks on the item.
* @param beforeListAction Optional Composable for adding UI before the list item.
* @param afterListAction Optional Composable for adding UI to the end of the list item.
Expand All @@ -181,6 +185,7 @@ private fun ListItem(
label: String,
modifier: Modifier = Modifier,
description: String? = null,
maxDescriptionLines: Int = 1,
onClick: (() -> Unit)? = null,
beforeListAction: @Composable RowScope.() -> Unit = {},
afterListAction: @Composable RowScope.() -> Unit = {},
Expand Down Expand Up @@ -211,7 +216,7 @@ private fun ListItem(
SecondaryText(
text = description,
fontSize = 14.sp,
maxLines = 1,
maxLines = maxDescriptionLines,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.settings.address.ext

import androidx.annotation.VisibleForTesting
import mozilla.components.concept.storage.Address

/**
* Generate a label item text for an [Address]. The combination of names is based on desktop code
* found here:
* https://searchfox.org/mozilla-central/rev/d989c65584ded72c2de85cb40bede7ac2f176387/toolkit/components/formautofill/FormAutofillNameUtils.jsm#400
*/
fun Address.getFullName(): String = listOf(givenName, additionalName, familyName)
.filter { it.isNotEmpty() }
.joinToString(" ")

/**
* Generate a description item text for an [Address]. The element ordering is based on the
* priorities defined by the desktop code found here:
* https://searchfox.org/mozilla-central/rev/d989c65584ded72c2de85cb40bede7ac2f176387/toolkit/components/formautofill/FormAutofillUtils.jsm#323
*/
fun Address.getAddressLabel(): String = listOf(
streetAddress.toOneLineAddress(),
addressLevel3,
addressLevel2,
organization,
addressLevel1,
country,
postalCode,
tel,
email
).filter { it.isNotEmpty() }.joinToString(", ")

@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun String.toOneLineAddress(): String =
this.split("\n").joinToString(separator = " ") { it.trim() }
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import mozilla.components.concept.storage.Address
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.list.IconListItem
import org.mozilla.fenix.compose.list.TextListItem
import org.mozilla.fenix.settings.address.ext.getAddressLabel
import org.mozilla.fenix.settings.address.ext.getFullName
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme

Expand All @@ -38,9 +40,10 @@ fun AddressList(
LazyColumn {
items(addresses) { address ->
TextListItem(
label = address.givenName + " " + address.familyName,
label = address.getFullName(),
modifier = Modifier.padding(start = 56.dp),
description = address.streetAddress,
description = address.getAddressLabel(),
maxDescriptionLines = 2,
onClick = { onAddressClick(address) },
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.fenix.settings.address.ext

import mozilla.components.concept.storage.Address
import org.junit.Assert.assertEquals
import org.junit.Test

class AddressTest {
@Test
fun `WHEN all names are populated THEN label includes all names`() {
val addr = generateAddress()

val label = addr.getFullName()

assertEquals("${addr.givenName} ${addr.additionalName} ${addr.familyName}", label)
}

@Test
fun `WHEN middle name is missing THEN label is given and family combined`() {
val addr = generateAddress(additionalName = "")

val label = addr.getFullName()

assertEquals("${addr.givenName} ${addr.familyName}", label)
}

@Test
fun `WHEN only family and middle name are available THEN label is middle and family combined`() {
val addr = generateAddress(givenName = "")

val label = addr.getFullName()

assertEquals("${addr.additionalName} ${addr.familyName}", label)
}

@Test
fun `WHEN only family name is available THEN label is family name`() {
val addr = generateAddress(givenName = "", additionalName = "")

val label = addr.getFullName()

assertEquals(addr.familyName, label)
}

@Test
fun `WHEN all properties are present THEN all properties present in description`() {
val addr = generateAddress()

val description = addr.getAddressLabel()

val expected = "${addr.streetAddress}, ${addr.addressLevel3}, ${addr.addressLevel2}, " +
"${addr.organization}, ${addr.addressLevel1}, ${addr.country}, " +
"${addr.postalCode}, ${addr.tel}, ${addr.email}"

assertEquals(expected, description)
}

@Test
fun `WHEN any properties are missing THEN description includes only present`() {
val addr = generateAddress(
addressLevel3 = "",
organization = "",
email = "",
)

val description = addr.getAddressLabel()

val expected = "${addr.streetAddress}, ${addr.addressLevel2}, ${addr.addressLevel1}, " +
"${addr.country}, ${addr.postalCode}, ${addr.tel}"
assertEquals(expected, description)
}

@Test
fun `WHEN everything is missing THEN description is empty`() {
val addr = generateAddress(
givenName = "",
additionalName = "",
familyName = "",
organization = "",
streetAddress = "",
addressLevel3 = "",
addressLevel2 = "",
addressLevel1 = "",
postalCode = "",
country = "",
tel = "",
email = ""
)

val description = addr.getAddressLabel()

assertEquals("", description)
}

@Test
fun `GIVEN multiline street address THEN joined as single line`() {
val streetAddress = """
line1
line2
line3
""".trimIndent()

val result = streetAddress.toOneLineAddress()

assertEquals("line1 line2 line3", result)
}

private fun generateAddress(
givenName: String = "Firefox",
additionalName: String = "The",
familyName: String = "Browser",
organization: String = "Mozilla",
streetAddress: String = "street",
addressLevel3: String = "3",
addressLevel2: String = "2",
addressLevel1: String = "1",
postalCode: String = "code",
country: String = "country",
tel: String = "tel",
email: String = "email",
) = Address(
guid = "",
givenName = givenName,
additionalName = additionalName,
familyName = familyName,
organization = organization,
streetAddress = streetAddress,
addressLevel3 = addressLevel3,
addressLevel2 = addressLevel2,
addressLevel1 = addressLevel1,
postalCode = postalCode,
country = country,
tel = tel,
email = email,
timeCreated = 1,
timeLastUsed = 1,
timeLastModified = 1,
timesUsed = 1,
)
}

0 comments on commit 9087b72

Please sign in to comment.