Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

Commit

Permalink
Issue #10836: Add Facts for Credit Card Autofill Feature
Browse files Browse the repository at this point in the history
  • Loading branch information
rocketsroger committed Aug 18, 2021
1 parent 2fb230c commit bcea682
Show file tree
Hide file tree
Showing 8 changed files with 226 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import mozilla.components.feature.prompts.dialog.Prompter
import mozilla.components.feature.prompts.dialog.SaveLoginDialogFragment
import mozilla.components.feature.prompts.dialog.TextPromptDialogFragment
import mozilla.components.feature.prompts.dialog.TimePickerDialogFragment
import mozilla.components.feature.prompts.facts.emitSuccessfulCreditCardAutofillFormDetectedFact
import mozilla.components.feature.prompts.file.FilePicker
import mozilla.components.feature.prompts.login.LoginExceptions
import mozilla.components.feature.prompts.login.LoginPicker
Expand Down Expand Up @@ -424,6 +425,7 @@ class PromptFeature private constructor(
is File -> filePicker.handleFileRequest(promptRequest)
is Share -> handleShareRequest(promptRequest, session)
is SelectCreditCard -> {
emitSuccessfulCreditCardAutofillFormDetectedFact()
if (isCreditCardAutofillEnabled() && promptRequest.creditCards.isNotEmpty()) {
creditCardPicker?.handleSelectCreditCardRequest(promptRequest)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import mozilla.components.concept.engine.prompt.CreditCard
import mozilla.components.concept.engine.prompt.PromptRequest
import mozilla.components.feature.prompts.concept.SelectablePromptView
import mozilla.components.feature.prompts.consumePromptFrom
import mozilla.components.feature.prompts.facts.emitCreditCardAutofillDismissedFact
import mozilla.components.feature.prompts.facts.emitCreditCardAutofillShownFact
import mozilla.components.support.base.log.logger.Logger

/**
Expand Down Expand Up @@ -84,6 +86,7 @@ class CreditCardPicker(
*/
@Suppress("TooGenericExceptionCaught")
fun dismissSelectCreditCardRequest(promptRequest: PromptRequest.SelectCreditCard? = null) {
emitCreditCardAutofillDismissedFact()
creditCardSelectBar.hidePrompt()

try {
Expand All @@ -106,6 +109,7 @@ class CreditCardPicker(
* @param request The [PromptRequest] containing the the credit card request data to be shown.
*/
internal fun handleSelectCreditCardRequest(request: PromptRequest.SelectCreditCard) {
emitCreditCardAutofillShownFact()
creditCardSelectBar.showPrompt(request.creditCards)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import androidx.recyclerview.widget.RecyclerView
import mozilla.components.concept.engine.prompt.CreditCard
import mozilla.components.feature.prompts.R
import mozilla.components.feature.prompts.concept.SelectablePromptView
import mozilla.components.feature.prompts.facts.emitCreditCardAutofillExpandedFact
import mozilla.components.feature.prompts.facts.emitSuccessfulCreditCardAutofillSuccessFact
import mozilla.components.support.ktx.android.view.hideKeyboard

/**
Expand All @@ -39,7 +41,10 @@ class CreditCardSelectBar @JvmOverloads constructor(
private var headerTextStyle: Int? = null

private val listAdapter = CreditCardsAdapter { creditCard ->
listener?.onOptionSelect(creditCard)
listener?.apply {
onOptionSelect(creditCard)
emitSuccessfulCreditCardAutofillSuccessFact()
}
}

override var listener: SelectablePromptView.Listener<CreditCard>? = null
Expand Down Expand Up @@ -131,6 +136,7 @@ class CreditCardSelectBar @JvmOverloads constructor(
expanderView?.rotation = ROTATE_180
headerView?.contentDescription =
context.getString(R.string.mozac_feature_prompts_collapse_credit_cards_content_description)
emitCreditCardAutofillExpandedFact()
} else {
expanderView?.rotation = 0F
headerView?.contentDescription =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ import mozilla.components.concept.storage.Login
import mozilla.components.concept.storage.LoginValidationDelegate.Result
import mozilla.components.feature.prompts.R
import mozilla.components.feature.prompts.ext.onDone
import mozilla.components.feature.prompts.facts.emitCancelFact
import mozilla.components.feature.prompts.facts.emitDisplayFact
import mozilla.components.feature.prompts.facts.emitNeverSaveFact
import mozilla.components.feature.prompts.facts.emitSaveFact
import mozilla.components.support.base.log.logger.Logger
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import mozilla.components.support.ktx.android.view.hideKeyboard
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* 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 mozilla.components.feature.prompts.facts

import mozilla.components.support.base.Component
import mozilla.components.support.base.facts.Action
import mozilla.components.support.base.facts.Fact
import mozilla.components.support.base.facts.collect

/**
* Facts emitted for telemetry related to the Autofill prompt feature for credit cards.
*/
class CreditCardAutofillDialogFacts {
/**
* Specific types of telemetry items.
*/
object Items {
const val AUTOFILL_CREDIT_CARD_FORM_DETECTED = "autofill_credit_card_form_detected"
const val AUTOFILL_CREDIT_CARD_SUCCESS = "autofill_credit_card_success"
const val AUTOFILL_CREDIT_CARD_PROMPT_SHOWN = "autofill_credit_card_prompt_shown"
const val AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED = "autofill_credit_card_prompt_expanded"
const val AUTOFILL_CREDIT_CARD_PROMPT_DISMISSED = "autofill_credit_card_prompt_dismissed"
}
}

private fun emitCreditCardAutofillDialogFact(
action: Action,
item: String,
value: String? = null,
metadata: Map<String, Any>? = null
) {
Fact(
Component.FEATURE_PROMPTS,
action,
item,
value,
metadata
).collect()
}

internal fun emitSuccessfulCreditCardAutofillFormDetectedFact() {
emitCreditCardAutofillDialogFact(
Action.INTERACTION,
CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_FORM_DETECTED
)
}

internal fun emitSuccessfulCreditCardAutofillSuccessFact() {
emitCreditCardAutofillDialogFact(
Action.INTERACTION,
CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_SUCCESS
)
}

internal fun emitCreditCardAutofillShownFact() {
emitCreditCardAutofillDialogFact(
Action.INTERACTION,
CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_SHOWN
)
}

internal fun emitCreditCardAutofillExpandedFact() {
emitCreditCardAutofillDialogFact(
Action.INTERACTION,
CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED
)
}

internal fun emitCreditCardAutofillDismissedFact() {
emitCreditCardAutofillDialogFact(
Action.INTERACTION,
CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_DISMISSED
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* 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 mozilla.components.feature.prompts.dialog
package mozilla.components.feature.prompts.facts

import mozilla.components.support.base.Component
import mozilla.components.support.base.facts.Action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,20 @@ import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.runBlocking
import mozilla.components.concept.engine.prompt.CreditCard
import mozilla.components.feature.prompts.R
import mozilla.components.feature.prompts.concept.SelectablePromptView
import mozilla.components.feature.prompts.facts.CreditCardAutofillDialogFacts
import mozilla.components.support.base.Component
import mozilla.components.support.base.facts.Action
import mozilla.components.support.base.facts.Fact
import mozilla.components.support.base.facts.FactProcessor
import mozilla.components.support.base.facts.Facts
import mozilla.components.support.test.ext.appCompatContext
import mozilla.components.support.test.mock
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
Expand Down Expand Up @@ -73,10 +81,17 @@ class CreditCardSelectBarTest {
}

@Test
fun `GIVEN a listener WHEN a credit card is selected THEN onOptionSelect is called`() {
fun `GIVEN a listener WHEN a credit card is selected THEN onOptionSelect is called`() = runBlocking {
val listener: SelectablePromptView.Listener<CreditCard> = mock()
creditCardSelectBar.listener = listener

val facts = mutableListOf<Fact>()
Facts.registerProcessor(object : FactProcessor {
override fun process(fact: Fact) {
facts.add(fact)
}
})

creditCardSelectBar.showPrompt(listOf(creditCard))

val adapter = creditCardSelectBar.findViewById<RecyclerView>(R.id.credit_cards_list).adapter as CreditCardsAdapter
Expand All @@ -85,18 +100,40 @@ class CreditCardSelectBarTest {

holder.itemView.performClick()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_SUCCESS, item)
}
verify(listener).onOptionSelect(creditCard)
}

@Test
fun `WHEN the header is clicked THEN view is expanded or collapsed`() {
val facts = mutableListOf<Fact>()
Facts.registerProcessor(object : FactProcessor {
override fun process(fact: Fact) {
facts.add(fact)
}
})

creditCardSelectBar.showPrompt(listOf(creditCard))

creditCardSelectBar.findViewById<AppCompatTextView>(R.id.select_credit_card_header).performClick()

assertTrue(creditCardSelectBar.findViewById<RecyclerView>(R.id.credit_cards_list).isVisible)
assertTrue(creditCardSelectBar.findViewById<AppCompatTextView>(R.id.manage_credit_cards).isVisible)

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED, item)
}

creditCardSelectBar.findViewById<AppCompatTextView>(R.id.select_credit_card_header).performClick()

assertFalse(creditCardSelectBar.findViewById<RecyclerView>(R.id.credit_cards_list).isVisible)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/* 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 mozilla.components.feature.prompts.facts

import mozilla.components.support.base.Component
import mozilla.components.support.base.facts.Action
import mozilla.components.support.base.facts.processor.CollectionProcessor
import org.junit.Assert.assertEquals
import org.junit.Test

class CreditCardAutofillDialogFactsTest {

@Test
fun `Emits facts for autofill form detected events`() {
CollectionProcessor.withFactCollection { facts ->

emitSuccessfulCreditCardAutofillFormDetectedFact()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_FORM_DETECTED, item)
}
}
}

@Test
fun `Emits facts for autofill success events`() {
CollectionProcessor.withFactCollection { facts ->

emitSuccessfulCreditCardAutofillSuccessFact()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_SUCCESS, item)
}
}
}

@Test
fun `Emits facts for autofill shown events`() {
CollectionProcessor.withFactCollection { facts ->

emitCreditCardAutofillShownFact()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_SHOWN, item)
}
}
}

@Test
fun `Emits facts for autofill expanded events`() {
CollectionProcessor.withFactCollection { facts ->

emitCreditCardAutofillExpandedFact()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_EXPANDED, item)
}
}
}

@Test
fun `Emits facts for autofill dismissed events`() {
CollectionProcessor.withFactCollection { facts ->

emitCreditCardAutofillDismissedFact()

assertEquals(1, facts.size)

facts[0].apply {
assertEquals(Component.FEATURE_PROMPTS, component)
assertEquals(Action.INTERACTION, action)
assertEquals(CreditCardAutofillDialogFacts.Items.AUTOFILL_CREDIT_CARD_PROMPT_DISMISSED, item)
}
}
}
}

0 comments on commit bcea682

Please sign in to comment.