Closed Bug 1429198 Opened 6 years ago Closed 5 years ago

Account for supportedNetworks in payment modifiers

Categories

(Firefox :: WebPayments UI, enhancement, P1)

enhancement

Tracking

()

RESOLVED FIXED
Firefox 66
Tracking Status
firefox66 --- fixed

People

(Reporter: MattN, Assigned: dpino, NeedInfo)

References

()

Details

(Whiteboard: [webpayments-reserve])

Attachments

(2 files, 9 obsolete files)

305.71 KB, image/png
Details
7.38 KB, patch
MattN
: review+
Details | Diff | Splinter Review
Priority: P3 → P2
Whiteboard: [webpayments]
Product: Toolkit → Firefox
Summary: Only allow users to selected payments cards of the requested supportedTypes (credit/debit/prepaid) and supportedNetworks → Only allow users to select payments cards of the requested supportedTypes (credit/debit/prepaid) and supportedNetworks
Priority: P2 → P3
Whiteboard: [webpayments] → [webpayments-reserve]
Summary: Only allow users to select payments cards of the requested supportedTypes (credit/debit/prepaid) and supportedNetworks → Communicate supportedTypes (credit/debit/prepaid) to the user and only allow user to select cards of the supportedNetworks
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → DUPLICATE
Whiteboard: [webpayments-reserve]
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Summary: Communicate supportedTypes (credit/debit/prepaid) to the user and only allow user to select cards of the supportedNetworks → Account for supportedNetworks in payment modifiers
Whiteboard: [webpayments-reserve]
Status: REOPENED → NEW
Line 247 should use this.getBasicCards to include temp. cards
Around line 257 we should compare the card's network to the supportedNetworks for the modifiers.

Spec issues at https://github.com/w3c/payment-request/issues/684#issuecomment-405612400 and https://github.com/w3c/payment-method-basic-card/issues/60 talk about first vs. last matching.

https://searchfox.org/mozilla-central/rev/55895c49f55073d82d977cb74ec1d3a71ae4b25f/browser/components/payments/res/paymentRequest.js#247,257
I modified `test_order_details.html` since it was failing. In the test, a card object didn't have a guid attribute, which is an expected attribute on calling `getBasicCards > _sortObjectsByTimeLastUsed`.
Attachment #9026679 - Flags: review?(MattN+bmo)
Assignee: nobody → dpino
Status: NEW → ASSIGNED
Priority: P3 → P1
Comment on attachment 9026679 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9026679 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks!

::: browser/components/payments/res/paymentRequest.js
@@ +257,4 @@
>      let modifier = modifiers.find(m => {
>        // take the first matching modifier
> +      return m.supportedMethods == "basic-card" &&
> +             acceptedNetworks.includes(method["cc-type"]);

I think there is a bit of confusion… You need to be matching the selected payment methods' cc-type to the supportedNetworks of modifier.data
Attachment #9026679 - Flags: review?(MattN+bmo)
I don't see any WPT for supportedNetworks in modifiers, is this correct? It seems like a significant thing to test.
Flags: needinfo?(mcaceres)
(In reply to Matthew N. [:MattN] (PM me if requests are blocking you) from comment #6)
> I don't see any WPT for supportedNetworks in modifiers, is this correct? 

Yeah, they were added before my time :( That's why "Modifiers and [[serializedModifierData]] not actually used anywhere": 
https://github.com/w3c/payment-request/issues/753

(and similarly with the ordering issue you raised)

> It seems like a significant thing to test.

I'll add them when I fix #735.
Flags: needinfo?(mcaceres)
I dumped a modifier at that point in code and the properties I see are:

```
additionalDisplayItems: [object Object]
supportedMethods: basic-card
total: [object Object]
```

There's no data, although PaymentDetailsModifier features that attribute https://searchfox.org/mozilla-central/source/dom/payments/PaymentRequestData.cpp#165.
https://rsolomakhin.github.io/pr/ is a test page with a mastercard discount (unfortunately it also tests supportedTypes which was dropped from the spec).

The following code works for me fine:
```js
    let modifier = modifiers.find(m => {
      // m.supportedMethods is a string despite the plural name kept for backwards-compat from when it was an sequence.                                                           
      if (m.supportedMethods && m.supportedMethods != method.methodName) {
        return false;
      }

      // XXX                                                                                                                                                                      
      if (m.data.supportedTypes) {
       	return false;
      }

      if (m.data.supportedNetworks && !m.data.supportedNetworks.includes(method["cc-type"])) {
        return false;
      }

      return true;
    });
```

We should also be applying the same technique as https://searchfox.org/mozilla-central/rev/8f89901f2d69d9783f946a7458a6d7ee70635a94/browser/components/payments/content/paymentDialogWrapper.js#395-397 to temporary cards in paymentDialogWrapper so that we don't need to hard-code "basic-card" in getModifierForPaymentMethod and can instead compare `m.supportedMethods == method.methodName`

Thanks
Thanks for the feedback. I incorporated the changes suggested, although I dropped the check for `supportedTypes` (rsolomakhin/pr works either way without that check).

Regarding the missing `data` field I couldn't find, the reason was that I was testing `test_order_details.html` and that field was not defined in the data samples, so I further modified the test.
Attachment #9026679 - Attachment is obsolete: true
Attachment #9026992 - Flags: review?(MattN+bmo)
Comment on attachment 9026992 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9026992 [details] [diff] [review]:
-----------------------------------------------------------------

::: browser/components/payments/res/paymentRequest.js
@@ +310,5 @@
> +    for (let card of Object.values(state.tempBasicCards)) {
> +      if (!card.methodName) {
> +        card.methodName = "basic-card";
> +      }
> +    }

As I mentioned in comment 9, I think this should be in paymentDialogWrapper so it's consistent with the persistent records

::: browser/components/payments/test/mochitest/test_order_details.html
@@ +186,4 @@
>      }],
>    });
>    requestStore.setState({request});
>    await asyncElementRendered();

Can you add test cases that ensure that supportedNetworks is actually being honored?
Attachment #9026992 - Flags: review?(MattN+bmo) → feedback+
I addressed the comments in previous review:

* Added a method `fetchTempPaymentCards` in `paymentDialogWrapper` that ensures cards have a method name.
* Modified existing test `test_modified_total` adding only one card in `supportedNetworks`. That's necessary to pass the test otherwise the modifier is not applied.
* Added a new test `test_non_supported_network()` that tries to apply a modifier but cannot apply it because the card's network is not supported.
* Modified `test_constructor.html` adding `data.supportedNetworks`. Not strictly necessary for this patch.
Attachment #9026992 - Attachment is obsolete: true
Attachment #9027876 - Flags: review?(MattN+bmo)
Flags: qe-verify+
QA Contact: hani.yacoub
Comment on attachment 9027876 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9027876 [details] [diff] [review]:
-----------------------------------------------------------------

Marcos, FYI that I feel that how `supportedNetworks: []` is handled for modifiers isn't clearly defined in the specs.

::: browser/components/payments/content/paymentDialogWrapper.js
@@ +515,5 @@
>        isPrivate,
>      });
>    },
>  
> +  fetchTempPaymentCards() {

Nit: Can you move this near `fetchSavedPaymentCards`

::: browser/components/payments/res/paymentRequest.js
@@ +258,5 @@
> +      if (m.supportedMethods && m.supportedMethods != method.methodName) {
> +        return false;
> +      }
> +      if (m.data && m.data.supportedNetworks &&
> +          !m.data.supportedNetworks.includes(method["cc-type"])) {

I think you need to add a check (and test) for `supportedNetworks: []` (`… && m.data.supportedNetworks.length > 0`) since I think an empty array means that the modifier should apply.

https://w3c.github.io/payment-method-basic-card/#steps-to-check-if-an-instrument-is-supported

::: browser/components/payments/test/mochitest/test_order_details.html
@@ +178,5 @@
>          amount: { currency: "USD", value: "3.5" },
>        },
> +      data: {
> +        supportedNetworks: ["visa"],
> +      },

> * Modified existing test `test_modified_total` adding only one card in `supportedNetworks`. That's necessary to pass the test otherwise the modifier is not applied.

I don't understand why this is necessary. If there is no `data.supportedNetworks` on a modifier then I thought it applied to all networks and having test coverage for that is good.
Attachment #9027876 - Flags: review?(MattN+bmo) → feedback?(mcaceres)
Comment on attachment 9027876 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9027876 [details] [diff] [review]:
-----------------------------------------------------------------

Sorry for the delay. I'm still inching my way to fixing the modifier part of the spec (agree, that part is a mess).
Attachment #9027876 - Flags: feedback?(mcaceres) → feedback+
Addressed comments in the latest review.

Regarding the modified test, I wasn't aware that if supportedNetworks wasn't defined the modifier should apply anyway, but I see that's in line with:

https://www.w3.org/TR/payment-method-basic-card/#dfn-steps-to-check-if-an-instrument-is-supported

OTOH, I wonder if I should remove the changes in dom/payments/test/ConstructorChromeScript.js too.
Attachment #9027876 - Attachment is obsolete: true
Attachment #9031674 - Flags: review?(MattN+bmo)
Comment on attachment 9031674 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9031674 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks.

(In reply to Diego Pino from comment #15)
> OTOH, I wonder if I should remove the changes in
> dom/payments/test/ConstructorChromeScript.js too.

Yeah, I think that makes sense to revert too.

::: browser/components/payments/res/paymentRequest.js
@@ +240,5 @@
>     * @returns {object?} the applicable modifier for the payment method
>     */
>    getModifierForPaymentMethod(state, methodID) {
> +    let basicCards = this.getBasicCards(state);
> +    let method = basicCards[methodID] || null;

Nit: could you rename `methodID` to `selectedMethodID` and `method` to `selectedMethod` in order to make the `.find` callback easier to read?

@@ +250,5 @@
>        return null;
>      }
>      let modifier = modifiers.find(m => {
>        // take the first matching modifier
> +      if (m.supportedMethods && m.supportedMethods != method.methodName) {

Since we have two relevant words starting with "m" here, could you also rename `m` to `modifier` to help readability.
Attachment #9031674 - Flags: review?(MattN+bmo) → review+
Addressed comments in last review.
Attachment #9031674 - Attachment is obsolete: true
Attachment #9032088 - Flags: review?(MattN+bmo)
Comment on attachment 9032088 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032088 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks
Attachment #9032088 - Flags: review?(MattN+bmo) → review+
Keywords: checkin-needed
Pushed by ebalazs@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/3fcc7597cd8d
Account for supportedNetworks in payment modifiers. r=MattN
Keywords: checkin-needed
Comment on attachment 9032088 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032088 [details] [diff] [review]:
-----------------------------------------------------------------

::: browser/components/payments/res/paymentRequest.js
@@ +248,5 @@
>      let modifiers = state.request.paymentDetails.modifiers;
>      if (!modifiers || !modifiers.length) {
>        return null;
>      }
> +    let modifier = modifiers.find(modifier => {

I guess we should rename the `modifier` on the left to `appliedModifier`
Attachment #9032088 - Attachment is obsolete: true
Flags: needinfo?(dpino)
Fixed lint error.
Attachment #9032143 - Attachment is obsolete: true
Attachment #9032387 - Flags: review?(MattN+bmo)
Comment on attachment 9032387 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032387 [details] [diff] [review]:
-----------------------------------------------------------------

Note that Phabricator runs the linters for you but you can also run them locally.

You can mark checkin-needed without another review next with the fix below.

::: browser/components/payments/res/paymentRequest.js
@@ +251,5 @@
> +    let basicCards = this.getBasicCards(state);
> +    let selectedMethod = basicCards[selectedMethodID] || null;
> +    if (selectedMethod && selectedMethod.methodName !== "basic-card") {
> +      throw new Error(`${selectedMethod.methodName} (${selectedMethodID})` +
> +                      `is not a supported payment method`);

You're missing a space character between the two lines.
Attachment #9032387 - Flags: review?(MattN+bmo) → review+
Comment on attachment 9032387 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032387 [details] [diff] [review]:
-----------------------------------------------------------------

Actually, why did you revert to `tempBasicCards: this.temporaryStore.creditCards.getAll(),` in the one place?

Is that to address the test failure of comment 24?
No, I think I didn't reintroduce `tempBasicCards: this.temporaryStore.creditCards.getAll()`. AFAICT, there are still two replacements of `this.temporaryStore.creditCards.getAll()` for `this.fetchTempPaymentCards()` in https://bugzilla.mozilla.org/attachment.cgi?id=9032387.

The only change I intended to introduce in https://bugzilla.mozilla.org/show_bug.cgi?id=1429198#c25 was the lint error pointed in https://bugzilla.mozilla.org/show_bug.cgi?id=1429198#c27.
Attachment #9032387 - Attachment is obsolete: true
Comment on attachment 9032440 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032440 [details] [diff] [review]:
-----------------------------------------------------------------

r=me assuming you addressed the test failure from comment 24
Attachment #9032440 - Flags: review+
Fixes error in browser_total.js.

The issue was that for some tests `selectedMethod` can be null (https://searchfox.org/mozilla-central/source/browser/components/payments/test/browser/browser_total.js#18) so the existence of `selectedMethod` has to be checked before accessing its methodName or cc-type.
Attachment #9032440 - Attachment is obsolete: true
Comment on attachment 9032639 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032639 [details] [diff] [review]:
-----------------------------------------------------------------

::: browser/components/payments/res/paymentRequest.js
@@ +265,5 @@
> +        return false;
> +      }
> +      let supportedNetworks = modifier.data && modifier.data.supportedNetworks || [];
> +      return supportedNetworks.length == 0 ||
> +             selectedMethod && supportedNetworks.includes(selectedMethod["cc-type"]);

IIUC, this means that we would apply a method with no supportedNetworks even if no method is selected because we wouldn't return above. To make this simpler and play-it-safe, I think we should return null in the `if` statement above:
```js
if (!selectedMethod || !modifiers || !modifiers.length) {
  return null;
}
```
Return null if selectedMethod is null.
Attachment #9032639 - Attachment is obsolete: true
Attachment #9032693 - Flags: review?(MattN+bmo)
Comment on attachment 9032693 [details] [diff] [review]
Bug-1429198-Account-for-supportedNetworks-in-payment.patch

Review of attachment 9032693 [details] [diff] [review]:
-----------------------------------------------------------------

r=me assuming tests still pass locally: ./mach test browser/components/payments/
Attachment #9032693 - Flags: review?(MattN+bmo) → review+
Keywords: checkin-needed
Pushed by cbrindusan@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/08e83023e7e8
Account for supportedNetworks in payment modifiers. r=MattN
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/08e83023e7e8
Status: ASSIGNED → RESOLVED
Closed: 6 years ago5 years ago
Resolution: --- → FIXED
Target Milestone: --- → Firefox 66

Given the "qe-verify+" tag, can someone help with some way to verify this bug? Thanks.

Flags: needinfo?(dpino)

Removing the "qe-verify+" tag since this feature is disabled.

Flags: qe-verify+

Removing the "qe-verify+" tag since this feature is disabled.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: