summaryrefslogtreecommitdiffstats
path: root/dom/payments/test/test_currency_amount_validation.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/payments/test/test_currency_amount_validation.html')
-rw-r--r--dom/payments/test/test_currency_amount_validation.html353
1 files changed, 353 insertions, 0 deletions
diff --git a/dom/payments/test/test_currency_amount_validation.html b/dom/payments/test/test_currency_amount_validation.html
new file mode 100644
index 0000000000..bf8284f37a
--- /dev/null
+++ b/dom/payments/test/test_currency_amount_validation.html
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1367669
+https://bugzilla.mozilla.org/show_bug.cgi?id=1388661
+-->
+<title>Test for PaymentRequest API currency amount validation</title>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script>
+"use strict";
+SimpleTest.waitForExplicitFinish();
+
+const gUrl = SimpleTest.getTestFileURL(
+ "CurrencyAmountValidationChromeScript.js"
+);
+const gScript = SpecialPowers.loadChromeScript(gUrl);
+
+function testFailHandler(message) {
+ ok(false, message);
+}
+gScript.addMessageListener("test-fail", testFailHandler);
+
+const defaultMethods = [
+ {
+ supportedMethods: "basic-card",
+ },
+];
+const defaultDetails = {
+ total: {
+ label: "total",
+ amount: {
+ currency: "usd",
+ value: "1.00",
+ },
+ },
+};
+
+const specialAmountDetails = {
+ total: {
+ label: "total",
+ amount: {
+ currency: "usd",
+ value: {
+ toString() {
+ throw "42";
+ },
+ },
+ },
+ },
+};
+
+const wellFormedCurrencyCodes = [
+ "BOB",
+ "EUR",
+ "usd", // currency codes are case-insensitive
+ "XdR",
+ "xTs",
+];
+
+const invalidCurrencyCodes = [
+ "",
+ "€",
+ "$",
+ "SFr.",
+ "DM",
+ "KR₩",
+ "702",
+ "ßP",
+ "ınr",
+ "invalid",
+ "in",
+ "123",
+];
+
+const updatedInvalidCurrencyDetails = {
+ total: {
+ label: "Total",
+ amount: {
+ currency: "Invalid",
+ value: "1.00",
+ },
+ },
+};
+
+const updatedInvalidAmountDetails = {
+ total: {
+ label: "Total",
+ amount: {
+ currency: "USD",
+ value: "-1.00",
+ },
+ },
+};
+
+const invalidAmounts = [
+ "-",
+ "notdigits",
+ "ALSONOTDIGITS",
+ "10.",
+ ".99",
+ "-10.",
+ "-.99",
+ "10-",
+ "1-0",
+ "1.0.0",
+ "1/3",
+ "",
+ null,
+ " 1.0 ",
+ " 1.0 ",
+ "1.0 ",
+ "USD$1.0",
+ "$1.0",
+ {
+ toString() {
+ return " 1.0";
+ },
+ },
+ undefined,
+];
+const invalidTotalAmounts = invalidAmounts.concat([
+ "-1",
+ "-1.0",
+ "-1.00",
+ "-1000.000",
+]);
+
+function updateWithInvalidAmount() {
+ return new Promise((resolve, reject) => {
+ resolve(updatedInvalidAmountDetails);
+ });
+}
+
+async function testWithLowerCaseCurrency() {
+ const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
+ return new Promise(resolve => {
+ gScript.addMessageListener(
+ "check-complete",
+ function checkCompleteHandler() {
+ gScript.removeMessageListener("check-complete", checkCompleteHandler);
+ resolve();
+ }
+ );
+ gScript.sendAsyncMessage("check-lower-case-currency");
+ });
+}
+
+function testWithWellFormedCurrencyCodes() {
+ for (const currency of wellFormedCurrencyCodes) {
+ const details = {
+ total: {
+ label: "Well Formed Currency",
+ amount: {
+ currency,
+ value: "1.00",
+ },
+ },
+ };
+ try {
+ const payRequest = new PaymentRequest(defaultMethods, details);
+ } catch (e) {
+ const msg = `Unexpected error while creating payment request with well-formed currency (${currency}) ${
+ e.name
+ }`;
+ ok(false, msg);
+ }
+ }
+}
+
+function testWithInvalidCurrencyCodes() {
+ for (const invalidCurrency of invalidCurrencyCodes) {
+ const invalidDetails = {
+ total: {
+ label: "Invalid Currency",
+ amount: {
+ currency: invalidCurrency,
+ value: "1.00",
+ },
+ },
+ };
+ try {
+ const payRequest = new PaymentRequest(defaultMethods, invalidDetails);
+ ok(
+ false,
+ `Creating a Payment Request with invalid currency (${invalidCurrency}) must throw.`
+ );
+ } catch (e) {
+ is(
+ e.name,
+ "RangeError",
+ `Expected rejected with 'RangeError', but got '${e.name}'.`
+ );
+ }
+ }
+}
+
+async function testUpdateWithInvalidCurrency() {
+ const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(
+ true
+ );
+ gScript.sendAsyncMessage("set-update-with-invalid-details-ui-service");
+ const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
+ payRequest.addEventListener("shippingaddresschange", event => {
+ event.updateWith(Promise.resolve(updatedInvalidCurrencyDetails));
+ });
+ payRequest.addEventListener("shippingoptionchange", event => {
+ event.updateWith(updatedInvalidCurrencyDetails);
+ });
+ try {
+ await payRequest.show();
+ ok(false, "Should have rejected with 'RangeError'");
+ } catch (err) {
+ is(
+ err.name,
+ "RangeError",
+ `Should be rejected with 'RangeError', but got '${err.name}'.`
+ );
+ }
+ handler.destruct();
+}
+
+async function testUpdateWithInvalidAmount() {
+ const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(
+ true
+ );
+ gScript.sendAsyncMessage("set-update-with-invalid-details-ui-service");
+ const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
+ payRequest.addEventListener("shippingaddresschange", event => {
+ event.updateWith(updateWithInvalidAmount());
+ });
+ payRequest.addEventListener("shippingoptionchange", event => {
+ event.updateWith(updateWithInvalidAmount());
+ });
+ try {
+ await payRequest.show();
+ ok(false, "Should be rejected with 'TypeError'");
+ } catch (err) {
+ is(
+ err.name,
+ "TypeError",
+ `Should be rejected with 'TypeError', but got ${err.name}.`
+ );
+ }
+ handler.destruct();
+}
+
+function testSpecialAmount() {
+ try {
+ new PaymentRequest(defaultMethods, specialAmountDetails);
+ ok(false, "Should throw '42', but got resolved.");
+ } catch (e) {
+ is(e, "42", "Expected throw '42'. but got " + e);
+ }
+}
+
+function testInvalidTotalAmounts() {
+ for (const invalidAmount of invalidTotalAmounts) {
+ try {
+ const invalidDetails = {
+ total: {
+ label: "",
+ amount: {
+ currency: "USD",
+ value: invalidAmount,
+ },
+ },
+ };
+ new PaymentRequest(defaultMethods, invalidDetails);
+ ok(false, "Should throw 'TypeError', but got resolved.");
+ } catch (err) {
+ is(err.name, "TypeError", `Expected 'TypeError', but got '${err.name}'`);
+ }
+ }
+}
+
+function testInvalidAmounts() {
+ for (const invalidAmount of invalidAmounts) {
+ try {
+ new PaymentRequest(defaultMethods, {
+ total: {
+ label: "",
+ amount: {
+ currency: "USD",
+ value: "1.00",
+ },
+ },
+ displayItems: [
+ {
+ label: "",
+ amount: {
+ currency: "USD",
+ value: invalidAmount,
+ },
+ },
+ ],
+ });
+ ok(false, "Should throw 'TypeError', but got resolved.");
+ } catch (err) {
+ is(err.name, "TypeError", `Expected 'TypeError', but got '${err.name}'.`);
+ }
+ }
+}
+
+function teardown() {
+ return new Promise(resolve => {
+ gScript.addMessageListener(
+ "teardown-complete",
+ function teardownCompleteHandler() {
+ gScript.removeMessageListener(
+ "teardown-complete",
+ teardownCompleteHandler
+ );
+ gScript.removeMessageListener("test-fail", testFailHandler);
+ gScript.destroy();
+ SimpleTest.finish();
+ resolve();
+ }
+ );
+ gScript.sendAsyncMessage("teardown");
+ });
+}
+
+async function runTests() {
+ try {
+ testInvalidTotalAmounts();
+ testSpecialAmount();
+ testInvalidAmounts();
+ testWithWellFormedCurrencyCodes();
+ testWithInvalidCurrencyCodes();
+ await testUpdateWithInvalidAmount();
+ await testUpdateWithInvalidCurrency();
+ await testWithLowerCaseCurrency();
+ await teardown();
+ } catch (e) {
+ console.error(e);
+ ok(false, "Unexpected error: " + e.name);
+ SimpleTest.finish();
+ }
+}
+
+window.addEventListener("load", () => {
+ SpecialPowers.pushPrefEnv(
+ {
+ set: [["dom.payments.request.enabled", true]],
+ },
+ runTests
+ );
+});
+</script>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1367669">Mozilla Bug 1367669</a>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1388661">Mozilla Bug 1388661</a>