tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_currency_amount_validation.html (8075B)


      1 <!DOCTYPE HTML>
      2 <meta charset="utf-8">
      3 <!--
      4 https://bugzilla.mozilla.org/show_bug.cgi?id=1367669
      5 https://bugzilla.mozilla.org/show_bug.cgi?id=1388661
      6 -->
      7 <title>Test for PaymentRequest API currency amount validation</title>
      8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
      9 <script src="/tests/SimpleTest/SimpleTest.js"></script>
     10 <script>
     11 "use strict";
     12 SimpleTest.waitForExplicitFinish();
     13 
     14 const gUrl = SimpleTest.getTestFileURL(
     15  "CurrencyAmountValidationChromeScript.js"
     16 );
     17 const gScript = SpecialPowers.loadChromeScript(gUrl);
     18 
     19 function testFailHandler(message) {
     20  ok(false, message);
     21 }
     22 gScript.addMessageListener("test-fail", testFailHandler);
     23 
     24 const defaultMethods = [
     25  {
     26    supportedMethods: "basic-card",
     27  },
     28 ];
     29 const defaultDetails = {
     30  total: {
     31    label: "total",
     32    amount: {
     33      currency: "usd",
     34      value: "1.00",
     35    },
     36  },
     37 };
     38 
     39 const specialAmountDetails = {
     40  total: {
     41    label: "total",
     42    amount: {
     43      currency: "usd",
     44      value: {
     45        toString() {
     46          throw "42";
     47        },
     48      },
     49    },
     50  },
     51 };
     52 
     53 const wellFormedCurrencyCodes = [
     54  "BOB",
     55  "EUR",
     56  "usd", // currency codes are case-insensitive
     57  "XdR",
     58  "xTs",
     59 ];
     60 
     61 const invalidCurrencyCodes = [
     62  "",
     63  "€",
     64  "$",
     65  "SFr.",
     66  "DM",
     67  "KR₩",
     68  "702",
     69  "ßP",
     70  "ınr",
     71  "invalid",
     72  "in",
     73  "123",
     74 ];
     75 
     76 const updatedInvalidCurrencyDetails = {
     77  total: {
     78    label: "Total",
     79    amount: {
     80      currency: "Invalid",
     81      value: "1.00",
     82    },
     83  },
     84 };
     85 
     86 const updatedInvalidAmountDetails = {
     87  total: {
     88    label: "Total",
     89    amount: {
     90      currency: "USD",
     91      value: "-1.00",
     92    },
     93  },
     94 };
     95 
     96 const invalidAmounts = [
     97  "-",
     98  "notdigits",
     99  "ALSONOTDIGITS",
    100  "10.",
    101  ".99",
    102  "-10.",
    103  "-.99",
    104  "10-",
    105  "1-0",
    106  "1.0.0",
    107  "1/3",
    108  "",
    109  null,
    110  " 1.0  ",
    111  " 1.0 ",
    112  "1.0 ",
    113  "USD$1.0",
    114  "$1.0",
    115  {
    116    toString() {
    117      return " 1.0";
    118    },
    119  },
    120  undefined,
    121 ];
    122 const invalidTotalAmounts = invalidAmounts.concat([
    123  "-1",
    124  "-1.0",
    125  "-1.00",
    126  "-1000.000",
    127 ]);
    128 
    129 function updateWithInvalidAmount() {
    130  return new Promise((resolve, reject) => {
    131    resolve(updatedInvalidAmountDetails);
    132  });
    133 }
    134 
    135 async function testWithLowerCaseCurrency() {
    136  const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
    137  return new Promise(resolve => {
    138    gScript.addMessageListener(
    139      "check-complete",
    140      function checkCompleteHandler() {
    141        gScript.removeMessageListener("check-complete", checkCompleteHandler);
    142        resolve();
    143      }
    144    );
    145    gScript.sendAsyncMessage("check-lower-case-currency");
    146  });
    147 }
    148 
    149 function testWithWellFormedCurrencyCodes() {
    150  for (const currency of wellFormedCurrencyCodes) {
    151    const details = {
    152      total: {
    153        label: "Well Formed Currency",
    154        amount: {
    155          currency,
    156          value: "1.00",
    157        },
    158      },
    159    };
    160    try {
    161      const payRequest = new PaymentRequest(defaultMethods, details);
    162    } catch (e) {
    163      const msg = `Unexpected error while creating payment request with well-formed currency (${currency}) ${
    164        e.name
    165      }`;
    166      ok(false, msg);
    167    }
    168  }
    169 }
    170 
    171 function testWithInvalidCurrencyCodes() {
    172  for (const invalidCurrency of invalidCurrencyCodes) {
    173    const invalidDetails = {
    174      total: {
    175        label: "Invalid Currency",
    176        amount: {
    177          currency: invalidCurrency,
    178          value: "1.00",
    179        },
    180      },
    181    };
    182    try {
    183      const payRequest = new PaymentRequest(defaultMethods, invalidDetails);
    184      ok(
    185        false,
    186        `Creating a Payment Request with invalid currency (${invalidCurrency}) must throw.`
    187      );
    188    } catch (e) {
    189      is(
    190        e.name,
    191        "RangeError",
    192        `Expected rejected with 'RangeError', but got '${e.name}'.`
    193      );
    194    }
    195  }
    196 }
    197 
    198 async function testUpdateWithInvalidCurrency() {
    199  const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(
    200    true
    201  );
    202  gScript.sendAsyncMessage("set-update-with-invalid-details-ui-service");
    203  const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
    204  payRequest.addEventListener("shippingaddresschange", event => {
    205    event.updateWith(Promise.resolve(updatedInvalidCurrencyDetails));
    206  });
    207  payRequest.addEventListener("shippingoptionchange", event => {
    208    event.updateWith(updatedInvalidCurrencyDetails);
    209  });
    210  try {
    211    await payRequest.show();
    212    ok(false, "Should have rejected with 'RangeError'");
    213  } catch (err) {
    214    is(
    215      err.name,
    216      "RangeError",
    217      `Should be rejected with 'RangeError', but got '${err.name}'.`
    218    );
    219  }
    220  handler.destruct();
    221 }
    222 
    223 async function testUpdateWithInvalidAmount() {
    224  const handler = SpecialPowers.getDOMWindowUtils(window).setHandlingUserInput(
    225    true
    226  );
    227  gScript.sendAsyncMessage("set-update-with-invalid-details-ui-service");
    228  const payRequest = new PaymentRequest(defaultMethods, defaultDetails);
    229  payRequest.addEventListener("shippingaddresschange", event => {
    230    event.updateWith(updateWithInvalidAmount());
    231  });
    232  payRequest.addEventListener("shippingoptionchange", event => {
    233    event.updateWith(updateWithInvalidAmount());
    234  });
    235  try {
    236    await payRequest.show();
    237    ok(false, "Should be rejected with 'TypeError'");
    238  } catch (err) {
    239    is(
    240      err.name,
    241      "TypeError",
    242      `Should be rejected with 'TypeError', but got ${err.name}.`
    243    );
    244  }
    245  handler.destruct();
    246 }
    247 
    248 function testSpecialAmount() {
    249  try {
    250    new PaymentRequest(defaultMethods, specialAmountDetails);
    251    ok(false, "Should throw '42', but got resolved.");
    252  } catch (e) {
    253    is(e, "42", "Expected throw '42'. but got " + e);
    254  }
    255 }
    256 
    257 function testInvalidTotalAmounts() {
    258  for (const invalidAmount of invalidTotalAmounts) {
    259    try {
    260      const invalidDetails = {
    261        total: {
    262          label: "",
    263          amount: {
    264            currency: "USD",
    265            value: invalidAmount,
    266          },
    267        },
    268      };
    269      new PaymentRequest(defaultMethods, invalidDetails);
    270      ok(false, "Should throw 'TypeError', but got resolved.");
    271    } catch (err) {
    272      is(err.name, "TypeError", `Expected 'TypeError', but got '${err.name}'`);
    273    }
    274  }
    275 }
    276 
    277 function testInvalidAmounts() {
    278  for (const invalidAmount of invalidAmounts) {
    279    try {
    280      new PaymentRequest(defaultMethods, {
    281        total: {
    282          label: "",
    283          amount: {
    284            currency: "USD",
    285            value: "1.00",
    286          },
    287        },
    288        displayItems: [
    289          {
    290            label: "",
    291            amount: {
    292              currency: "USD",
    293              value: invalidAmount,
    294            },
    295          },
    296        ],
    297      });
    298      ok(false, "Should throw 'TypeError', but got resolved.");
    299    } catch (err) {
    300      is(err.name, "TypeError", `Expected 'TypeError', but got '${err.name}'.`);
    301    }
    302  }
    303 }
    304 
    305 function teardown() {
    306  return new Promise(resolve => {
    307    gScript.addMessageListener(
    308      "teardown-complete",
    309      function teardownCompleteHandler() {
    310        gScript.removeMessageListener(
    311          "teardown-complete",
    312          teardownCompleteHandler
    313        );
    314        gScript.removeMessageListener("test-fail", testFailHandler);
    315        gScript.destroy();
    316        SimpleTest.finish();
    317        resolve();
    318      }
    319    );
    320    gScript.sendAsyncMessage("teardown");
    321  });
    322 }
    323 
    324 async function runTests() {
    325  try {
    326    testInvalidTotalAmounts();
    327    testSpecialAmount();
    328    testInvalidAmounts();
    329    testWithWellFormedCurrencyCodes();
    330    testWithInvalidCurrencyCodes();
    331    await testUpdateWithInvalidAmount();
    332    await testUpdateWithInvalidCurrency();
    333    await testWithLowerCaseCurrency();
    334    await teardown();
    335  } catch (e) {
    336    console.error(e);
    337    ok(false, "Unexpected error: " + e.name);
    338    SimpleTest.finish();
    339  }
    340 }
    341 
    342 window.addEventListener("load", () => {
    343  SpecialPowers.pushPrefEnv(
    344    {
    345      set: [["dom.payments.request.enabled", true]],
    346    },
    347    runTests
    348  );
    349 });
    350 </script>
    351 <body>
    352 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1367669">Mozilla Bug 1367669</a>
    353 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1388661">Mozilla Bug 1388661</a>