Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: accessibility #31

Merged
merged 5 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class PayPalMessageViewTest {

private val defaultMain = "Test main"
private val defaultDisclaimer = "Test disclaimer"
private val defaultMainAlternative = "Test main alternative"
private val response = ApiMessageData.Response(
meta = ApiMessageData.Metadata(
creditProductGroup = ProductGroup.PAYPAL_CREDIT,
Expand All @@ -51,8 +52,8 @@ class PayPalMessageViewTest {
originatingInstanceId = UUID.randomUUID(),
),
content = ApiMessageData.ContentOptions(
default = ApiMessageData.ContentDetails(main = defaultMain, disclaimer = defaultDisclaimer),
generic = ApiMessageData.ContentDetails(main = "", disclaimer = ""),
default = ApiMessageData.ContentDetails(main = defaultMain, mainAlternative = defaultMainAlternative, disclaimer = defaultDisclaimer),
generic = ApiMessageData.ContentDetails(main = "", mainAlternative = "", disclaimer = ""),
),
)

Expand Down
3 changes: 2 additions & 1 deletion library/src/main/java/com/paypal/messages/ModalFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ internal class ModalFragment(
val rootView =
inflator.inflate(R.layout.paypal_message_modal_sheet_layout, container, false)
val closeButton = rootView.findViewById<ImageButton>(R.id.ModalCloseButton)
closeButton.contentDescription = closeButtonData?.alternativeText

closeButton.layoutParams.height = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
Expand Down Expand Up @@ -367,7 +368,7 @@ internal class ModalFragment(
*/
@JavascriptInterface
fun paypalMessageModalCallbackHandler(passedParams: String) {
val params = if (passedParams != "") passedParams else "{\"name\": \"\", \"args\": [{}]"
val params = if (passedParams != "") passedParams else """{"name": "", "args": [{}]} """
val nameAndArgs = JsonParser.parseString(params).asJsonObject
val name = nameAndArgs.get("name").asString
val args = nameAndArgs.get("args").asJsonArray[0].asJsonObject
Expand Down
15 changes: 13 additions & 2 deletions library/src/main/java/com/paypal/messages/PayPalMessageView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.core.content.res.getFloatOrThrow
import androidx.core.content.res.getIntOrThrow
import androidx.core.content.res.use
import com.paypal.messages.config.PayPalEnvironment
import com.paypal.messages.config.ProductGroup
import com.paypal.messages.config.modal.ModalConfig
import com.paypal.messages.config.modal.ModalEvents
import com.paypal.messages.io.Api
Expand Down Expand Up @@ -516,12 +517,22 @@ class PayPalMessageView @JvmOverloads constructor(
logoType: LogoType,
): String {
val builder = StringBuilder()
val messageContent = response.content?.default?.main
val mainContent = response.content?.default?.main
val logoTag = response.meta?.variables?.logoPlaceholder
val disclaimer = response.content?.default?.disclaimer

val productGroup = response.meta?.creditProductGroup
val brandingText = if (productGroup == ProductGroup.PAYPAL_CREDIT) "PayPal Credit" else "PayPal"

val alternativeText = response.content?.default?.mainAlternative
?: response.content?.generic?.mainAlternative
?: logoTag?.let { mainContent?.replace(it, brandingText) ?: "" }
val leadText = if (mainContent?.contains("$logoTag") == false) "$brandingText -" else ""
val accessibilityText = "$leadText $alternativeText $disclaimer".trim()
messageTextView.contentDescription = accessibilityText

// Append message content if it exists
messageContent?.let { content ->
mainContent?.let { content ->
// Append LogoTag if logotype is PRIMARY or ALTERNATIVE and tag is not present
logoTag?.let { tag ->
if (logoType in listOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@ import com.google.gson.annotations.SerializedName

data class ModalCloseButton(
@SerializedName("width")
val width: Int,
var width: Int? = null,
@SerializedName("height")
val height: Int,
var height: Int? = null,
@SerializedName("available_width")
val availableWidth: Int,
var availableWidth: Int? = null,
@SerializedName("available_height")
val availableHeight: Int,
var availableHeight: Int? = null,
@SerializedName("color")
val color: String,
var color: String? = null,
@SerializedName("color_type")
val colorType: String,
)
var colorType: String? = null,
@SerializedName("alternative_text")
var alternativeText: String? = null,
) {
init {
width = width ?: 26
height = height ?: 26
availableWidth = availableWidth ?: 60
availableHeight = availableHeight ?: 60
color = color ?: "#001435"
colorType = colorType ?: "dark"
alternativeText = alternativeText ?: "PayPal learn more modal close"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ object ApiMessageData {
data class ContentDetails(
@SerializedName("main")
val main: String?,
@SerializedName("main_alternative")
val mainAlternative: String?,
@SerializedName("disclaimer")
val disclaimer: String?,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@
android:layout_marginEnd="12dip"
android:background="@drawable/ic_close"
android:scaleType="center"
android:contentDescription="Close modal" />
android:contentDescription="PayPal learn more modal close" />
</RelativeLayout>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class ModalCloseButtonTest {
availableHeight = 200,
color = "#FFFFFF",
colorType = "solid",
alternativeText = "test_alternative_text",
)

@Test
Expand All @@ -22,6 +23,7 @@ class ModalCloseButtonTest {
assertEquals(modalCloseButton.availableHeight, 200)
assertEquals(modalCloseButton.color, "#FFFFFF")
assertEquals(modalCloseButton.colorType, "solid")
assertEquals(modalCloseButton.alternativeText, "test_alternative_text")
}

@Test
Expand All @@ -31,7 +33,8 @@ class ModalCloseButtonTest {

assertEquals(
json,
"{\"width\":100,\"height\":100,\"available_width\":200,\"available_height\":200,\"color\":\"#FFFFFF\",\"color_type\":\"solid\"}",
@Suppress("ktlint:standard:max-line-length")
"""{"width":100,"height":100,"available_width":200,"available_height":200,"color":"#FFFFFF","color_type":"solid","alternative_text":"test_alternative_text"}""",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class ApiHashDataTest {
val json = gson.toJson(response)
assertEquals(
json,
"{\"cache_flow_disabled\":true,\"ttl_soft\":1000,\"ttl_hard\":2000,\"merchant_profile\":{\"hash\":\"test_merchant_profile_hash\"}}",
@Suppress("ktlint:standard:max-line-length")
"""{"cache_flow_disabled":true,"ttl_soft":1000,"ttl_hard":2000,"merchant_profile":{"hash":"test_merchant_profile_hash"}}""",
)
}

Expand All @@ -44,6 +45,6 @@ class ApiHashDataTest {
@Test
fun testMerchantProfileSerialization() {
val json = gson.toJson(merchantProfile)
assertEquals(json, "{\"hash\":\"test_merchant_profile_hash\"}")
assertEquals(json, """{"hash":"test_merchant_profile_hash"}""")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ class ApiMessageDataTest {
)

private val main = "test_main"
private val mainAlternative = "test_alternative"
private val disclaimer = "test_disclaimer"
private val contentDetails = ApiMessageData.ContentDetails(main, disclaimer)
private val contentDetails = ApiMessageData.ContentDetails(main, mainAlternative, disclaimer)
private val contentOptions = ApiMessageData.ContentOptions(contentDetails, contentDetails)
private val response = ApiMessageData.Response(metadata, contentOptions)

Expand All @@ -65,7 +66,7 @@ class ApiMessageDataTest {
val json = gson.toJson(response)

@Suppress("ktlint:standard:max-line-length")
val expectedJson = """{"meta":{"credit_product_group":"PAYPAL_CREDIT","offer_country_code":"US","offer_type":"PAY_LATER_SHORT_TERM","message_type":"OFFER","modal_close_button":{"width":100,"height":100,"available_width":200,"available_height":200,"color":"#FFFFFF","color_type":"solid"},"variables":{"inline_logo_placeholder":"test_logo_placeholder"},"merchant_country_code":"US","credit_product_identifiers":["test_credit_product_identifier"],"debug_id":"test_debug_id","fdata":"test_fdata","tracking_keys":["test_tracking_key"],"originating_instance_id":"350e8400-e29b-41d4-a716-446655440000"},"content":{"default":{"main":"test_main","disclaimer":"test_disclaimer"},"generic":{"main":"test_main","disclaimer":"test_disclaimer"}}}"""
val expectedJson = """{"meta":{"credit_product_group":"PAYPAL_CREDIT","offer_country_code":"US","offer_type":"PAY_LATER_SHORT_TERM","message_type":"OFFER","modal_close_button":{"width":100,"height":100,"available_width":200,"available_height":200,"color":"#FFFFFF","color_type":"solid","alternative_text":"PayPal learn more modal close"},"variables":{"inline_logo_placeholder":"test_logo_placeholder"},"merchant_country_code":"US","credit_product_identifiers":["test_credit_product_identifier"],"debug_id":"test_debug_id","fdata":"test_fdata","tracking_keys":["test_tracking_key"],"originating_instance_id":"350e8400-e29b-41d4-a716-446655440000"},"content":{"default":{"main":"test_main","main_alternative":"test_alternative","disclaimer":"test_disclaimer"},"generic":{"main":"test_main","main_alternative":"test_alternative","disclaimer":"test_disclaimer"}}}"""
assertEquals(expectedJson, json)
}

Expand All @@ -80,20 +81,21 @@ class ApiMessageDataTest {
val json = gson.toJson(contentOptions)

@Suppress("ktlint:standard:max-line-length")
val expectedJson = """{"default":{"main":"test_main","disclaimer":"test_disclaimer"},"generic":{"main":"test_main","disclaimer":"test_disclaimer"}}"""
val expectedJson = """{"default":{"main":"test_main","main_alternative":"test_alternative","disclaimer":"test_disclaimer"},"generic":{"main":"test_main","main_alternative":"test_alternative","disclaimer":"test_disclaimer"}}"""
assertEquals(expectedJson, json)
}

@Test
fun testContentDetailsConstructor() {
assertEquals(main, contentDetails.main)
assertEquals(mainAlternative, contentDetails.mainAlternative)
assertEquals(disclaimer, contentDetails.disclaimer)
}

@Test
fun testContentDetailsSerialization() {
val json = gson.toJson(contentDetails)
assertEquals(json, """{"main":"test_main","disclaimer":"test_disclaimer"}""")
assertEquals(json, """{"main":"test_main","main_alternative":"test_alternative","disclaimer":"test_disclaimer"}""")
}

@Test
Expand All @@ -117,7 +119,7 @@ class ApiMessageDataTest {
val json = gson.toJson(metadata)

@Suppress("ktlint:standard:max-line-length")
val expectedJson = """{"credit_product_group":"PAYPAL_CREDIT","offer_country_code":"US","offer_type":"PAY_LATER_SHORT_TERM","message_type":"OFFER","modal_close_button":{"width":100,"height":100,"available_width":200,"available_height":200,"color":"#FFFFFF","color_type":"solid"},"variables":{"inline_logo_placeholder":"test_logo_placeholder"},"merchant_country_code":"US","credit_product_identifiers":["test_credit_product_identifier"],"debug_id":"test_debug_id","fdata":"test_fdata","tracking_keys":["test_tracking_key"],"originating_instance_id":"350e8400-e29b-41d4-a716-446655440000"}"""
val expectedJson = """{"credit_product_group":"PAYPAL_CREDIT","offer_country_code":"US","offer_type":"PAY_LATER_SHORT_TERM","message_type":"OFFER","modal_close_button":{"width":100,"height":100,"available_width":200,"available_height":200,"color":"#FFFFFF","color_type":"solid","alternative_text":"PayPal learn more modal close"},"variables":{"inline_logo_placeholder":"test_logo_placeholder"},"merchant_country_code":"US","credit_product_identifiers":["test_credit_product_identifier"],"debug_id":"test_debug_id","fdata":"test_fdata","tracking_keys":["test_tracking_key"],"originating_instance_id":"350e8400-e29b-41d4-a716-446655440000"}"""
assertEquals(expectedJson, json)
}

Expand Down
Loading