| <!DOCTYPE html> |
| <!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> |
| <!-- Copyright (C) 2017 Apple Inc. All rights reserved. --> |
| <!-- FIXME: Upstream this test to web-platform-tests/payment-request/. --> |
| <meta charset="utf-8"> |
| <title>Tests for PaymentRequest.canMakePayment() method</title> |
| <link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method"> |
| <script src="/js-test-resources/ui-helper.js"></script> |
| <script src="/resources/payment-request.js"></script> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <script> |
| const applePay = Object.freeze({ |
| supportedMethods: "https://apple.com/apple-pay", |
| data: { |
| version: 2, |
| merchantIdentifier: "", |
| merchantCapabilities: ["supports3DS"], |
| supportedNetworks: ["visa", "masterCard"], |
| countryCode: "US", |
| } |
| }); |
| const invalidApplePay = Object.freeze({ |
| supportedMethods: "https://apple.com/apple-pay", |
| data: { |
| } |
| }); |
| const defaultMethods = Object.freeze([applePay]); |
| const defaultDetails = Object.freeze({ |
| total: { |
| label: "Total", |
| amount: { |
| currency: "USD", |
| value: "1.00", |
| }, |
| }, |
| }); |
| |
| promise_test(async t => { |
| const request = new PaymentRequest(defaultMethods, defaultDetails); |
| try { |
| assert_true( |
| await request.canMakePayment(), |
| `canMakePaymentPromise should be true` |
| ); |
| assert_true( |
| await request.canMakePayment(), |
| `canMakePaymentPromise should be true` |
| ); |
| } catch (err) { |
| assert_equals( |
| err.name, |
| "NotAllowedError", |
| "if it throws, then it must be a NotAllowedError." |
| ); |
| } |
| }, `If request.[[state]] is "created", then return a promise that resolves to true for known method.`); |
| |
| user_activation_test(async t => { |
| const request = new PaymentRequest(defaultMethods, defaultDetails); |
| const acceptPromise = request.show(); // Sets state to "interactive" |
| const canMakePaymentPromise = request.canMakePayment(); |
| try { |
| const result = await canMakePaymentPromise; |
| assert_true( |
| false, |
| `canMakePaymentPromise should have thrown InvalidStateError` |
| ); |
| } catch (err) { |
| await promise_rejects(t, "InvalidStateError", canMakePaymentPromise); |
| } finally { |
| await request.abort(); |
| await promise_rejects(t, "AbortError", acceptPromise); |
| } |
| // The state should be "closed" |
| await promise_rejects(t, "InvalidStateError", request.canMakePayment()); |
| }, `If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.`); |
| |
| user_activation_test(async t => { |
| const request = new PaymentRequest(defaultMethods, defaultDetails); |
| const acceptPromise = request.show(); // The state is now "interactive" |
| acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools. |
| await request.abort(); // The state is now "closed" |
| await promise_rejects(t, "InvalidStateError", request.canMakePayment()); |
| try { |
| const result = await request.canMakePayment(); |
| assert_true( |
| false, |
| `should have thrown InvalidStateError, but instead returned "${result}"` |
| ); |
| } catch (err) { |
| assert_equals( |
| err.name, |
| "InvalidStateError", |
| "must be an InvalidStateError." |
| ); |
| } |
| }, `If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.`); |
| |
| promise_test(async t => { |
| const request = new PaymentRequest(defaultMethods, defaultDetails); |
| assert_true(await request.canMakePayment(), "basic-card should be supported"); |
| }, `If payment method identifier and serialized parts are supported, resolve promise with true.`); |
| |
| promise_test(async t => { |
| const request = new PaymentRequest([invalidApplePay], defaultDetails); |
| assert_false(await request.canMakePayment(), "Apple Pay with invalid data should not be supported"); |
| }, `If a payment method identifier is supported but its serialized parts are not, resolve promise with false.`); |
| |
| promise_test(async t => { |
| const unsupportedMethods = [ |
| "this-is-not-supported", |
| "https://not.supported", |
| "e", |
| "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa", |
| "a-b-q-n-s-pw0", |
| "m-u", |
| "s-l5", |
| "k9-f", |
| "m-l", |
| "u4-n-t", |
| "i488jh6-g18-fck-yb-v7-i", |
| "x-x-t-t-c34-o", |
| "https://wpt", |
| "https://wpt.fyi/", |
| "https://wpt.fyi/payment", |
| "https://wpt.fyi/payment-request", |
| "https://wpt.fyi/payment-request?", |
| "https://wpt.fyi/payment-request?this=is", |
| "https://wpt.fyi/payment-request?this=is&totally", |
| "https://wpt.fyi:443/payment-request?this=is&totally", |
| "https://wpt.fyi:443/payment-request?this=is&totally#fine", |
| "https://:@wpt.fyi:443/payment-request?this=is&totally#👍", |
| " \thttps://wpt\n ", |
| "https://xn--c1yn36f", |
| "https://點看", |
| ]; |
| for (const method of unsupportedMethods) { |
| try { |
| const request = new PaymentRequest( |
| [{ supportedMethods: method }], |
| defaultDetails |
| ); |
| assert_false( |
| await request.canMakePayment(), |
| `method "${method}" must not be supported` |
| ); |
| } catch (err) { |
| assert_true( |
| false, |
| `Unexpected exception testing method ${method}, expected false. See error console.` |
| ); |
| } |
| } |
| }, `If payment method identifier is unknown, resolve promise with false.`); |
| |
| promise_test(async t => { |
| // This test might never actually hit its assertion, but that's allowed. |
| const request = new PaymentRequest(defaultMethods, defaultDetails); |
| for (let i = 0; i < 1000; i++) { |
| try { |
| await request.canMakePayment(); |
| } catch (err) { |
| assert_equals( |
| err.name, |
| "NotAllowedError", |
| "if it throws, then it must be a NotAllowedError." |
| ); |
| break; |
| } |
| } |
| for (let i = 0; i < 1000; i++) { |
| try { |
| await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment(); |
| } catch (err) { |
| assert_equals( |
| err.name, |
| "NotAllowedError", |
| "if it throws, then it must be a NotAllowedError." |
| ); |
| break; |
| } |
| } |
| }, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`); |
| </script> |