From e3bbf3edd895a0d96996016b4811f0e1fbc2565c Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Wed, 20 Mar 2024 20:15:39 -0400 Subject: [PATCH 1/5] Add accessible fields --- .../java/com/paypal/messages/config/modal/ModalCloseButton.kt | 2 ++ library/src/main/java/com/paypal/messages/io/ApiMessageData.kt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt b/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt index 6100c121..c727baa1 100644 --- a/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt +++ b/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt @@ -15,4 +15,6 @@ data class ModalCloseButton( val color: String, @SerializedName("color_type") val colorType: String, + @SerializedName("alternative_text") + val alternativeText: String, ) diff --git a/library/src/main/java/com/paypal/messages/io/ApiMessageData.kt b/library/src/main/java/com/paypal/messages/io/ApiMessageData.kt index 696e0171..1eadc858 100644 --- a/library/src/main/java/com/paypal/messages/io/ApiMessageData.kt +++ b/library/src/main/java/com/paypal/messages/io/ApiMessageData.kt @@ -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?, ) From f90a8a7147255ac4416224690a78ca4e752ee1fa Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:52:02 -0400 Subject: [PATCH 2/5] Add text for modal close button --- .../java/com/paypal/messages/ModalFragment.kt | 1 + .../messages/config/modal/ModalCloseButton.kt | 26 +++++++++++++------ .../paypal_message_modal_sheet_layout.xml | 2 +- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/paypal/messages/ModalFragment.kt b/library/src/main/java/com/paypal/messages/ModalFragment.kt index f922aa7c..70eb75a5 100644 --- a/library/src/main/java/com/paypal/messages/ModalFragment.kt +++ b/library/src/main/java/com/paypal/messages/ModalFragment.kt @@ -105,6 +105,7 @@ internal class ModalFragment( val rootView = inflator.inflate(R.layout.paypal_message_modal_sheet_layout, container, false) val closeButton = rootView.findViewById(R.id.ModalCloseButton) + closeButton.contentDescription = closeButtonData?.alternativeText closeButton.layoutParams.height = TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, diff --git a/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt b/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt index c727baa1..3dba4962 100644 --- a/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt +++ b/library/src/main/java/com/paypal/messages/config/modal/ModalCloseButton.kt @@ -4,17 +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") - val alternativeText: String, -) + 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" + } +} diff --git a/library/src/main/res/layout/paypal_message_modal_sheet_layout.xml b/library/src/main/res/layout/paypal_message_modal_sheet_layout.xml index 3f836aa0..165f4655 100644 --- a/library/src/main/res/layout/paypal_message_modal_sheet_layout.xml +++ b/library/src/main/res/layout/paypal_message_modal_sheet_layout.xml @@ -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" /> From 39dffe3f617247e7e356bd79fb7a6975dbf08dde Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:53:35 -0400 Subject: [PATCH 3/5] Add a11y text to message view --- .../java/com/paypal/messages/PayPalMessageView.kt | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/library/src/main/java/com/paypal/messages/PayPalMessageView.kt b/library/src/main/java/com/paypal/messages/PayPalMessageView.kt index 2884302b..94ffb6df 100644 --- a/library/src/main/java/com/paypal/messages/PayPalMessageView.kt +++ b/library/src/main/java/com/paypal/messages/PayPalMessageView.kt @@ -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 @@ -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( From b9dc3e5ea6bf773976035e8cd6de1cb8f5c85c2a Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:56:18 -0400 Subject: [PATCH 4/5] Fix tests --- .../main/java/com/paypal/messages/ModalFragment.kt | 2 +- .../messages/config/modal/ModalCloseButtonTest.kt | 5 ++++- .../java/com/paypal/messages/io/ApiHashDataTest.kt | 5 +++-- .../com/paypal/messages/io/ApiMessageDataTest.kt | 12 +++++++----- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/library/src/main/java/com/paypal/messages/ModalFragment.kt b/library/src/main/java/com/paypal/messages/ModalFragment.kt index 70eb75a5..d1d1905a 100644 --- a/library/src/main/java/com/paypal/messages/ModalFragment.kt +++ b/library/src/main/java/com/paypal/messages/ModalFragment.kt @@ -368,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 diff --git a/library/src/test/java/com/paypal/messages/config/modal/ModalCloseButtonTest.kt b/library/src/test/java/com/paypal/messages/config/modal/ModalCloseButtonTest.kt index f2f8a463..d3097241 100644 --- a/library/src/test/java/com/paypal/messages/config/modal/ModalCloseButtonTest.kt +++ b/library/src/test/java/com/paypal/messages/config/modal/ModalCloseButtonTest.kt @@ -12,6 +12,7 @@ class ModalCloseButtonTest { availableHeight = 200, color = "#FFFFFF", colorType = "solid", + alternativeText = "test_alternative_text", ) @Test @@ -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 @@ -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"}""", ) } } diff --git a/library/src/test/java/com/paypal/messages/io/ApiHashDataTest.kt b/library/src/test/java/com/paypal/messages/io/ApiHashDataTest.kt index 51d77773..364729dd 100644 --- a/library/src/test/java/com/paypal/messages/io/ApiHashDataTest.kt +++ b/library/src/test/java/com/paypal/messages/io/ApiHashDataTest.kt @@ -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"}}""", ) } @@ -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"}""") } } diff --git a/library/src/test/java/com/paypal/messages/io/ApiMessageDataTest.kt b/library/src/test/java/com/paypal/messages/io/ApiMessageDataTest.kt index bd792b77..f31d00bd 100644 --- a/library/src/test/java/com/paypal/messages/io/ApiMessageDataTest.kt +++ b/library/src/test/java/com/paypal/messages/io/ApiMessageDataTest.kt @@ -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) @@ -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) } @@ -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 @@ -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) } From 8c306a2ee49e89885ed466342b673941f0898d30 Mon Sep 17 00:00:00 2001 From: "Merlin (they/them)" <421960+merlinpatt@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:59:27 -0400 Subject: [PATCH 5/5] Fix instrumentation test --- .../java/com/paypal/messages/PayPalMessageViewTest.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/src/androidTest/java/com/paypal/messages/PayPalMessageViewTest.kt b/library/src/androidTest/java/com/paypal/messages/PayPalMessageViewTest.kt index cd780e44..828ddcb4 100644 --- a/library/src/androidTest/java/com/paypal/messages/PayPalMessageViewTest.kt +++ b/library/src/androidTest/java/com/paypal/messages/PayPalMessageViewTest.kt @@ -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, @@ -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 = ""), ), )