summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/merchant-validation/constructor.tentative.https.html
blob: cab7b10236210a179a98763866724311eb4716b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<!DOCTYPE html>
<!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). -->
<meta charset="utf-8">
<title>Test for MerchantValidationEvent Constructor</title>
<link rel="help" href="https://w3c.github.io/browser-payment-api/#merchantvalidationevent-constructor">
<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: 3,
    merchantIdentifier: "merchant.com.example",
    countryCode: "US",
    merchantCapabilities: ["supports3DS"],
    supportedNetworks: ["visa"],
  }
});
const examplePay = Object.freeze({ supportedMethods: "https://example.com/pay" });
const defaultMethods = Object.freeze([examplePay, applePay]);
const defaultDetails = Object.freeze({
  total: {
    label: "Total",
    amount: {
      currency: "USD",
      value: "1.00",
    },
  },
});

test(() => {
  new MerchantValidationEvent("test");
}, "MerchantValidationEvent can be constructed in secure-context.");

test(() => {
  const ev = new MerchantValidationEvent("test", {
    bubbles: true,
    cancelable: true,
    composed: true,
  });
  assert_false(ev.isTrusted, "constructed in script, so not trusted");
  assert_true(ev.bubbles, "set by EventInitDict");
  assert_true(ev.cancelable, "set by EventInitDict");
  assert_true(ev.composed, "set by EventInitDict");
  assert_equals(ev.target, null, "initially null");
  assert_equals(ev.type, "test");
}, "MerchantValidationEvent can be constructed with an EventInitDict, even if not trusted.");

test(() => {
  const request = new PaymentRequest(defaultMethods, defaultDetails);
  const ev = new MerchantValidationEvent("test");
  request.addEventListener("test", evt => {
    assert_equals(ev, evt);
  });
  request.dispatchEvent(ev);
}, "MerchantValidationEvent can be dispatched, even if not trusted.");

test(() => {
  const validationURL = "https://pass.com";
  const event = new MerchantValidationEvent("test", { validationURL });
  assert_idl_attribute(event, "validationURL");
  assert_equals(event.validationURL, "https://pass.com/");
}, "Must have a validationURL IDL attribute, which is initialized with to the validationURL dictionary value.");

test(() => {
  const validationURL = "http://\u005B"; // invalid URL
  assert_throws_js(TypeError, () => {
    new MerchantValidationEvent("test", { validationURL });
  });
}, "Must throw TypeError if initialized with an invalid URL.");

test(() => {
  const validationURL = "";
  const relativePaths = ["", ".", "/test"];
  for (const path of relativePaths) {
    const event = new MerchantValidationEvent("test", { validationURL: path });
    const expected = new URL(path, document.location.href).href;
    assert_equals(event.validationURL, expected);
  }
}, "Relative validationURLs use the document as the base.");

test(() => {
  const validationURL = "pass";
  const base = document.createElement("base");
  base.href = "https://pass.com";
  document.head.append(base);
  const event = new MerchantValidationEvent("test", { validationURL });
  try {
    assert_idl_attribute(event, "validationURL");
    assert_equals(event.validationURL, "https://pass.com/pass");
  } finally {
    base.remove();
  }
}, "Relative validationURLs use the document.baseURI as the base.");

test(() => {
  const methodName = "https://pass.com";
  const event = new MerchantValidationEvent("test", { methodName });
  assert_idl_attribute(event, "methodName");
  assert_equals(event.methodName, "https://pass.com");
}, "Must have a methodName IDL attribute, which is initialized with to the methodName dictionary value.");

test(() => {
  const event = new MerchantValidationEvent("test", {});
  assert_equals(event.methodName, "");
}, "When no methodName is passed, methodName attribute defaults to the empty string");

test(() => {
  const validPMIs = [
    "https://example.com/pay",
    "https://example.com/pay?version=1",
    "https://example.com/pay/version/1",
    "secure-payment-confirmation",
    "https://apple.com/apple-pay",
    // special case for as default value
    "",
  ];
  for (const methodName of validPMIs) {
    const event = new MerchantValidationEvent("test", { methodName });
    assert_equals(event.methodName, methodName);
  }
}, "MerchantValidationEvent can be constructed with valid PMIs");

test(() => {
  const invalidPMIs = [
    // ❌ Contains Unicode character outside the valid ranges.
    "secure-💳",
    // ❌ Contains uppercase characters.
    "Secure-Payment-Confirmation",
    // ❌ Contains Unicode characters outside the valid ranges.
    "¡secure-*-payment-confirmation!",
    // ❌ Uses http://, a username, and a password.
    "http://username:password@example.com/pay",
    // ❌ Uses unknown URI scheme.
    "unknown://example.com/pay",
  ];
  for (const methodName of invalidPMIs) {
    assert_throws_js(
      RangeError,
      () => {
        const event = new MerchantValidationEvent("test", { methodName });
      },
      `expected to throw when constructed with invalid PMI: '${methodName}'`
    );
  }
}, "MerchantValidationEvent can't be constructed with invalid PMIs");
</script>