1setup({ explicit_done: true, explicit_timeout: true });
2
3const validMethod = Object.freeze({
4 supportedMethods: "https://apple.com/apple-pay",
5 data: {
6 version: 2,
7 merchantIdentifier: '',
8 merchantCapabilities: ['supports3DS'],
9 supportedNetworks: ['visa', 'masterCard'],
10 countryCode: 'US',
11 },
12});
13
14const validMethods = Object.freeze([validMethod]);
15
16const validAmount = Object.freeze({
17 currency: "USD",
18 value: "1.00",
19});
20
21const validTotal = Object.freeze({
22 label: "Valid total",
23 amount: validAmount,
24});
25const validDetails = {
26 total: validTotal,
27};
28
29test(() => {
30 try {
31 new PaymentRequest(validMethods, validDetails);
32 } catch (err) {
33 done();
34 throw err;
35 }
36}, "Can construct a payment request (smoke test).");
37
38/**
39 * Pops up a payment sheet, allowing options to be
40 * passed in if particular values are needed.
41 *
42 * @param PaymentOptions options
43 */
44async function getPaymentResponse(options, id) {
45 const { response } = getPaymentRequestResponse(options, id);
46 return response;
47}
48
49/**
50 * Creates a payment request and response pair.
51 * It also shows the payment sheet.
52 *
53 * @param {PaymentOptions?} options
54 * @param {String?} id
55 */
56async function getPaymentRequestResponse(options, id) {
57 const methods = [{
58 supportedMethods: "https://apple.com/apple-pay",
59 data: {
60 version: 2,
61 merchantIdentifier: '',
62 merchantCapabilities: ['supports3DS'],
63 supportedNetworks: ['visa', 'masterCard'],
64 countryCode: 'US',
65 },
66 }];
67 const details = {
68 id,
69 total: {
70 label: "Total due",
71 amount: { currency: "USD", value: "1.0" },
72 },
73 shippingOptions: [
74 {
75 id: "fail1",
76 label: "Fail option 1",
77 amount: { currency: "USD", value: "5.00" },
78 selected: false,
79 },
80 {
81 id: "pass",
82 label: "Pass option",
83 amount: { currency: "USD", value: "5.00" },
84 selected: true,
85 },
86 {
87 id: "fail2",
88 label: "Fail option 2",
89 amount: { currency: "USD", value: "5.00" },
90 selected: false,
91 },
92 ],
93 };
94 const request = new PaymentRequest(methods, details, options);
95 request.onshippingaddresschange = ev => ev.updateWith(details);
96 request.onshippingoptionchange = ev => ev.updateWith(details);
97 request.onapplepayvalidatemerchant = ev => ev.complete({});
98 const response = await request.show();
99 return { request, response };
100}
101
102/**
103 * Runs a manual test for payment
104 *
105 * @param {HTMLButtonElement} button The HTML button.
106 * @param {PaymentOptions?} options.
107 * @param {Object} expected What property values are expected to pass the test.
108 * @param {String?} id And id for the request/response pair.
109 */
110async function runTest(button, options, expected = {}, id = undefined) {
111 button.disabled = true;
112 const { request, response } = await getPaymentRequestResponse(options, id);
113 await response.complete();
114 test(() => {
115 assert_idl_attribute(
116 response,
117 "requestId",
118 "Expected requestId to be an IDL attribute."
119 );
120 assert_equals(response.requestId, request.id, `Expected ids to match`);
121 for (const [attribute, value] of Object.entries(expected)) {
122 assert_idl_attribute(
123 response,
124 attribute,
125 `Expected ${attribute} to be an IDL attribute.`
126 );
127 assert_equals(
128 response[attribute],
129 value,
130 `Expected response ${attribute} attribute to be ${value}`
131 );
132 }
133 assert_idl_attribute(response, "details");
134 assert_equals(typeof response.details, "object", "Expected an object");
135 // Testing that this does not throw:
136 response.toJSON();
137 if (options && options.requestShipping) {
138 assert_equals(
139 response.shippingOption,
140 "pass",
141 "request.shippingOption must be 'pass'"
142 );
143 } else {
144 assert_equals(
145 request.shippingOption,
146 null,
147 "If requestShipping is falsy, request.shippingOption must be null"
148 );
149 assert_equals(
150 response.shippingOption,
151 null,
152 "request.shippingOption must be null"
153 );
154 }
155 }, button.textContent.trim());
156}