[Payment Request] Crash in PaymentRequest::canMakePayment() when Apple Pay payment...
[WebKit-https.git] / LayoutTests / http / tests / paymentrequest / payment-request-canmakepayment-method.https.html
1 <!DOCTYPE html>
2 <!--  Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang).  -->
3 <!--  Copyright (C) 2017 Apple Inc. All rights reserved.  -->
4 <!-- FIXME: Upstream this test to web-platform-tests/payment-request/. -->
5 <meta charset="utf-8">
6 <title>Tests for PaymentRequest.canMakePayment() method</title>
7 <link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
8 <script src="/js-test-resources/ui-helper.js"></script>
9 <script src="/resources/payment-request.js"></script>
10 <script src="/resources/testharness.js"></script>
11 <script src="/resources/testharnessreport.js"></script>
12 <script>
13 const applePay = Object.freeze({
14     supportedMethods: "https://apple.com/apple-pay",
15     data: {
16         version: 2,
17         merchantIdentifier: "",
18         merchantCapabilities: ["supports3DS"],
19         supportedNetworks: ["visa", "masterCard"],
20         countryCode: "US",
21     }
22 });
23 const invalidApplePay = Object.freeze({
24     supportedMethods: "https://apple.com/apple-pay",
25     data: {
26     }
27 });
28 const defaultMethods = Object.freeze([applePay]);
29 const defaultDetails = Object.freeze({
30   total: {
31     label: "Total",
32     amount: {
33       currency: "USD",
34       value: "1.00",
35     },
36   },
37 });
38
39 promise_test(async t => {
40   const request = new PaymentRequest(defaultMethods, defaultDetails);
41   try {
42     assert_true(
43       await request.canMakePayment(),
44       `canMakePaymentPromise should be true`
45     );
46     assert_true(
47       await request.canMakePayment(),
48       `canMakePaymentPromise should be true`
49     );
50   } catch (err) {
51     assert_equals(
52       err.name,
53       "NotAllowedError",
54       "if it throws, then it must be a NotAllowedError."
55     );
56   }
57 }, `If request.[[state]] is "created", then return a promise that resolves to true for known method.`);
58
59 user_activation_test(async t => {
60   const request = new PaymentRequest(defaultMethods, defaultDetails);
61   const acceptPromise = request.show(); // Sets state to "interactive"
62   const canMakePaymentPromise = request.canMakePayment();
63   try {
64     const result = await canMakePaymentPromise;
65     assert_true(
66       false,
67       `canMakePaymentPromise should have thrown InvalidStateError`
68     );
69   } catch (err) {
70     await promise_rejects(t, "InvalidStateError", canMakePaymentPromise);
71   } finally {
72     await request.abort();
73     await promise_rejects(t, "AbortError", acceptPromise);
74   }
75   // The state should be "closed"
76   await promise_rejects(t, "InvalidStateError", request.canMakePayment());
77 }, `If request.[[state]] is "interactive", then return a promise rejected with an "InvalidStateError" DOMException.`);
78
79 user_activation_test(async t => {
80   const request = new PaymentRequest(defaultMethods, defaultDetails);
81   const acceptPromise = request.show(); // The state is now "interactive"
82   acceptPromise.catch(() => {}); // no-op, just to silence unhandled rejection in devtools.
83   await request.abort(); // The state is now "closed"
84   await promise_rejects(t, "InvalidStateError", request.canMakePayment());
85   try {
86     const result = await request.canMakePayment();
87     assert_true(
88       false,
89       `should have thrown InvalidStateError, but instead returned "${result}"`
90     );
91   } catch (err) {
92     assert_equals(
93       err.name,
94       "InvalidStateError",
95       "must be an InvalidStateError."
96     );
97   }
98 }, `If request.[[state]] is "closed", then return a promise rejected with an "InvalidStateError" DOMException.`);
99
100 promise_test(async t => {
101   const request = new PaymentRequest(defaultMethods, defaultDetails);
102   assert_true(await request.canMakePayment(), "basic-card should be supported");
103 }, `If payment method identifier and serialized parts are supported, resolve promise with true.`);
104
105 promise_test(async t => {
106   const request = new PaymentRequest([invalidApplePay], defaultDetails);
107   assert_false(await request.canMakePayment(), "Apple Pay with invalid data should not be supported");
108 }, `If a payment method identifier is supported but its serialized parts are not, resolve promise with false.`);
109
110 promise_test(async t => {
111   const unsupportedMethods = [
112     "this-is-not-supported",
113     "https://not.supported",
114     "e",
115     "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa",
116     "a-b-q-n-s-pw0",
117     "m-u",
118     "s-l5",
119     "k9-f",
120     "m-l",
121     "u4-n-t",
122     "i488jh6-g18-fck-yb-v7-i",
123     "x-x-t-t-c34-o",
124     "https://wpt",
125     "https://wpt.fyi/",
126     "https://wpt.fyi/payment",
127     "https://wpt.fyi/payment-request",
128     "https://wpt.fyi/payment-request?",
129     "https://wpt.fyi/payment-request?this=is",
130     "https://wpt.fyi/payment-request?this=is&totally",
131     "https://wpt.fyi:443/payment-request?this=is&totally",
132     "https://wpt.fyi:443/payment-request?this=is&totally#fine",
133     "https://:@wpt.fyi:443/payment-request?this=is&totally#👍",
134     " \thttps://wpt\n ",
135     "https://xn--c1yn36f",
136     "https://點看",
137   ];
138   for (const method of unsupportedMethods) {
139     try {
140       const request = new PaymentRequest(
141         [{ supportedMethods: method }],
142         defaultDetails
143       );
144       assert_false(
145         await request.canMakePayment(),
146         `method "${method}" must not be supported`
147       );
148     } catch (err) {
149       assert_true(
150         false,
151         `Unexpected exception testing method ${method}, expected false. See error console.`
152       );
153     }
154   }
155 }, `If payment method identifier is unknown, resolve promise with false.`);
156
157 promise_test(async t => {
158   // This test might never actually hit its assertion, but that's allowed.
159   const request = new PaymentRequest(defaultMethods, defaultDetails);
160   for (let i = 0; i < 1000; i++) {
161     try {
162       await request.canMakePayment();
163     } catch (err) {
164       assert_equals(
165         err.name,
166         "NotAllowedError",
167         "if it throws, then it must be a NotAllowedError."
168       );
169       break;
170     }
171   }
172   for (let i = 0; i < 1000; i++) {
173     try {
174       await new PaymentRequest(defaultMethods, defaultDetails).canMakePayment();
175     } catch (err) {
176       assert_equals(
177         err.name,
178         "NotAllowedError",
179         "if it throws, then it must be a NotAllowedError."
180       );
181       break;
182     }
183   }
184 }, `Optionally, at the user agent's discretion, return a promise rejected with a "NotAllowedError" DOMException.`);
185 </script>