summaryrefslogtreecommitdiffstats
path: root/browser/components/payments/res/debugging.js
diff options
context:
space:
mode:
Diffstat (limited to 'browser/components/payments/res/debugging.js')
-rw-r--r--browser/components/payments/res/debugging.js664
1 files changed, 664 insertions, 0 deletions
diff --git a/browser/components/payments/res/debugging.js b/browser/components/payments/res/debugging.js
new file mode 100644
index 0000000000..fffc85dd11
--- /dev/null
+++ b/browser/components/payments/res/debugging.js
@@ -0,0 +1,664 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const paymentDialog = window.parent.document.querySelector("payment-dialog");
+// The requestStore should be manipulated for most changes but autofill storage changes
+// happen through setStateFromParent which includes some consistency checks.
+const requestStore = paymentDialog.requestStore;
+
+// keep the payment options checkboxes in sync w. actual state
+const paymentOptionsUpdater = {
+ stateChangeCallback(state) {
+ this.render(state);
+ },
+ render(state) {
+ let { completeStatus, paymentOptions } = state.request;
+
+ document.getElementById("setChangesPrevented").checked =
+ state.changesPrevented;
+
+ let paymentOptionInputs = document.querySelectorAll(
+ "#paymentOptions input[type='checkbox']"
+ );
+ for (let input of paymentOptionInputs) {
+ if (paymentOptions.hasOwnProperty(input.name)) {
+ input.checked = paymentOptions[input.name];
+ }
+ }
+
+ let completeStatusInputs = document.querySelectorAll(
+ "input[type='radio'][name='setCompleteStatus']"
+ );
+ for (let input of completeStatusInputs) {
+ input.checked = input.value == completeStatus;
+ }
+ },
+};
+
+let REQUEST_1 = {
+ tabId: 9,
+ topLevelPrincipal: { URI: { displayHost: "debugging.example.com" } },
+ requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
+ completeStatus: "",
+ paymentMethods: [],
+ paymentDetails: {
+ id: "",
+ totalItem: {
+ label: "Demo total",
+ amount: { currency: "EUR", value: "1.00" },
+ pending: false,
+ },
+ displayItems: [
+ {
+ label: "Square",
+ amount: {
+ currency: "USD",
+ value: "5",
+ },
+ },
+ ],
+ payerErrors: {},
+ paymentMethodErrors: {},
+ shippingAddressErrors: {},
+ shippingOptions: [
+ {
+ id: "std",
+ label: "Standard (3-5 business days)",
+ amount: {
+ currency: "USD",
+ value: 10,
+ },
+ selected: false,
+ },
+ {
+ id: "super-slow",
+ // Long to test truncation
+ label: "Ssssssssuuuuuuuuupppppeeeeeeerrrrr sssssllllllloooooowwwwww",
+ amount: {
+ currency: "USD",
+ value: 1.5,
+ },
+ selected: true,
+ },
+ ],
+ modifiers: null,
+ error: "",
+ },
+ paymentOptions: {
+ requestPayerName: true,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: true,
+ shippingType: "shipping",
+ },
+ shippingOption: "std",
+};
+
+let REQUEST_2 = {
+ tabId: 9,
+ topLevelPrincipal: { URI: { displayHost: "example.com" } },
+ requestId: "3797081f-a96b-c34b-a58b-1083c6e66e25",
+ completeStatus: "",
+ paymentMethods: [
+ {
+ supportedMethods: "basic-card",
+ data: {
+ supportedNetworks: ["amex", "discover", "mastercard", "visa"],
+ },
+ },
+ ],
+ paymentDetails: {
+ id: "",
+ totalItem: {
+ label: "",
+ amount: { currency: "CAD", value: "25.75" },
+ pending: false,
+ },
+ displayItems: [
+ {
+ label: "Triangle",
+ amount: {
+ currency: "CAD",
+ value: "3",
+ },
+ },
+ {
+ label: "Circle",
+ amount: {
+ currency: "EUR",
+ value: "10.50",
+ },
+ },
+ {
+ label: "Tax",
+ type: "tax",
+ amount: {
+ currency: "USD",
+ value: "1.50",
+ },
+ },
+ ],
+ payerErrors: {},
+ paymentMethoErrors: {},
+ shippingAddressErrors: {},
+ shippingOptions: [
+ {
+ id: "123",
+ label: "Fast (default)",
+ amount: {
+ currency: "USD",
+ value: 10,
+ },
+ selected: true,
+ },
+ {
+ id: "947",
+ label: "Slow",
+ amount: {
+ currency: "USD",
+ value: 1,
+ },
+ selected: false,
+ },
+ ],
+ modifiers: [
+ {
+ supportedMethods: "basic-card",
+ total: {
+ label: "Total",
+ amount: {
+ currency: "CAD",
+ value: "28.75",
+ },
+ pending: false,
+ },
+ additionalDisplayItems: [
+ {
+ label: "Credit card fee",
+ amount: {
+ currency: "CAD",
+ value: "1.50",
+ },
+ },
+ ],
+ data: {},
+ },
+ ],
+ error: "",
+ },
+ paymentOptions: {
+ requestPayerName: false,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: true,
+ shippingType: "shipping",
+ },
+ shippingOption: "123",
+};
+
+let ADDRESSES_1 = {
+ "48bnds6854t": {
+ "address-level1": "MI",
+ "address-level2": "Some City",
+ country: "US",
+ email: "foo@bar.com",
+ "family-name": "Smith",
+ "given-name": "John",
+ guid: "48bnds6854t",
+ name: "John Smith",
+ "postal-code": "90210",
+ "street-address": "123 Sesame Street,\nApt 40",
+ tel: "+1 519 555-5555",
+ timeLastUsed: 50000,
+ },
+ "68gjdh354j": {
+ "additional-name": "Z.",
+ "address-level1": "CA",
+ "address-level2": "Mountain View",
+ country: "US",
+ "family-name": "Doe",
+ "given-name": "Jane",
+ guid: "68gjdh354j",
+ name: "Jane Z. Doe",
+ "postal-code": "94041",
+ "street-address": "P.O. Box 123",
+ tel: "+1 650 555-5555",
+ timeLastUsed: 30000,
+ },
+ abcde12345: {
+ "address-level2": "Mountain View",
+ country: "US",
+ "family-name": "Fields",
+ "given-name": "Mrs.",
+ guid: "abcde12345",
+ name: "Mrs. Fields",
+ timeLastUsed: 70000,
+ },
+ german1: {
+ "additional-name": "Y.",
+ "address-level1": "",
+ "address-level2": "Berlin",
+ country: "DE",
+ email: "de@example.com",
+ "family-name": "Mouse",
+ "given-name": "Anon",
+ guid: "german1",
+ name: "Anon Y. Mouse",
+ organization: "Mozilla",
+ "postal-code": "10997",
+ "street-address": "Schlesische Str. 27",
+ tel: "+49 30 983333002",
+ timeLastUsed: 10000,
+ },
+ "missing-country": {
+ "address-level1": "ON",
+ "address-level2": "Toronto",
+ "family-name": "Bogard",
+ "given-name": "Kristin",
+ guid: "missing-country",
+ name: "Kristin Bogard",
+ "postal-code": "H0H 0H0",
+ "street-address": "123 Yonge Street\nSuite 2300",
+ tel: "+1 416 555-5555",
+ timeLastUsed: 90000,
+ },
+ TimBR: {
+ "given-name": "Timothy",
+ "additional-name": "João",
+ "family-name": "Berners-Lee",
+ organization: "World Wide Web Consortium",
+ "street-address": "Rua Adalberto Pajuaba, 404",
+ "address-level3": "Campos Elísios",
+ "address-level2": "Ribeirão Preto",
+ "address-level1": "SP",
+ "postal-code": "14055-220",
+ country: "BR",
+ tel: "+0318522222222",
+ email: "timbr@example.org",
+ timeLastUsed: 110000,
+ },
+};
+
+let DUPED_ADDRESSES = {
+ a9e830667189: {
+ "street-address": "Unit 1\n1505 Northeast Kentucky Industrial Parkway \n",
+ "address-level2": "Greenup",
+ "address-level1": "KY",
+ "postal-code": "41144",
+ country: "US",
+ email: "bob@example.com",
+ "family-name": "Smith",
+ "given-name": "Bob",
+ guid: "a9e830667189",
+ tel: "+19871234567",
+ name: "Bob Smith",
+ timeLastUsed: 10001,
+ },
+ "72a15aed206d": {
+ "street-address": "1 New St",
+ "address-level2": "York",
+ "address-level1": "SC",
+ "postal-code": "29745",
+ country: "US",
+ "given-name": "Mary Sue",
+ guid: "72a15aed206d",
+ tel: "+19871234567",
+ name: "Mary Sue",
+ "address-line1": "1 New St",
+ timeLastUsed: 10009,
+ },
+ "2b4dce0fbc1f": {
+ "street-address": "123 Park St",
+ "address-level2": "Springfield",
+ "address-level1": "OR",
+ "postal-code": "97403",
+ country: "US",
+ email: "rita@foo.com",
+ "family-name": "Foo",
+ "given-name": "Rita",
+ guid: "2b4dce0fbc1f",
+ name: "Rita Foo",
+ "address-line1": "123 Park St",
+ timeLastUsed: 10005,
+ },
+ "46b2635a5b26": {
+ "street-address": "432 Another St",
+ "address-level2": "Springfield",
+ "address-level1": "OR",
+ "postal-code": "97402",
+ country: "US",
+ email: "rita@foo.com",
+ "family-name": "Foo",
+ "given-name": "Rita",
+ guid: "46b2635a5b26",
+ name: "Rita Foo",
+ "address-line1": "432 Another St",
+ timeLastUsed: 10003,
+ },
+};
+
+let BASIC_CARDS_1 = {
+ "53f9d009aed2": {
+ billingAddressGUID: "68gjdh354j",
+ methodName: "basic-card",
+ "cc-number": "************5461",
+ guid: "53f9d009aed2",
+ version: 3,
+ timeCreated: 1505240896213,
+ timeLastModified: 1515609524588,
+ timeLastUsed: 10000,
+ timesUsed: 0,
+ "cc-name": "John Smith",
+ "cc-exp-month": 6,
+ "cc-exp-year": 2024,
+ "cc-type": "visa",
+ "cc-given-name": "John",
+ "cc-additional-name": "",
+ "cc-family-name": "Smith",
+ "cc-exp": "2024-06",
+ },
+ "9h5d4h6f4d1s": {
+ methodName: "basic-card",
+ "cc-number": "************0954",
+ guid: "9h5d4h6f4d1s",
+ version: 3,
+ timeCreated: 1517890536491,
+ timeLastModified: 1517890564518,
+ timeLastUsed: 50000,
+ timesUsed: 0,
+ "cc-name": "Jane Doe",
+ "cc-exp-month": 5,
+ "cc-exp-year": 2023,
+ "cc-type": "mastercard",
+ "cc-given-name": "Jane",
+ "cc-additional-name": "",
+ "cc-family-name": "Doe",
+ "cc-exp": "2023-05",
+ },
+ "123456789abc": {
+ methodName: "basic-card",
+ "cc-number": "************1234",
+ guid: "123456789abc",
+ version: 3,
+ timeCreated: 1517890536491,
+ timeLastModified: 1517890564518,
+ timeLastUsed: 90000,
+ timesUsed: 0,
+ "cc-name": "Jane Fields",
+ "cc-given-name": "Jane",
+ "cc-additional-name": "",
+ "cc-family-name": "Fields",
+ "cc-type": "discover",
+ },
+ "amex-card": {
+ methodName: "basic-card",
+ billingAddressGUID: "68gjdh354j",
+ "cc-number": "************1941",
+ guid: "amex-card",
+ version: 1,
+ timeCreated: 1517890536491,
+ timeLastModified: 1517890564518,
+ timeLastUsed: 70000,
+ timesUsed: 0,
+ "cc-name": "Capt America",
+ "cc-given-name": "Capt",
+ "cc-additional-name": "",
+ "cc-family-name": "America",
+ "cc-type": "amex",
+ "cc-exp-month": 6,
+ "cc-exp-year": 2023,
+ "cc-exp": "2023-06",
+ },
+ "missing-cc-name": {
+ methodName: "basic-card",
+ "cc-number": "************8563",
+ guid: "missing-cc-name",
+ version: 3,
+ timeCreated: 1517890536491,
+ timeLastModified: 1517890564518,
+ timeLastUsed: 30000,
+ timesUsed: 0,
+ "cc-exp-month": 8,
+ "cc-exp-year": 2024,
+ "cc-exp": "2024-08",
+ },
+};
+
+let buttonActions = {
+ debugFrame() {
+ let event = new CustomEvent("paymentContentToChrome", {
+ bubbles: true,
+ detail: {
+ messageType: "debugFrame",
+ },
+ });
+ document.dispatchEvent(event);
+ },
+
+ delete1Address() {
+ let savedAddresses = Object.assign(
+ {},
+ requestStore.getState().savedAddresses
+ );
+ delete savedAddresses[Object.keys(savedAddresses)[0]];
+ // Use setStateFromParent since it ensures there is no dangling
+ // `selectedShippingAddress` foreign key (FK) reference.
+ paymentDialog.setStateFromParent({
+ savedAddresses,
+ });
+ },
+
+ delete1Card() {
+ let savedBasicCards = Object.assign(
+ {},
+ requestStore.getState().savedBasicCards
+ );
+ delete savedBasicCards[Object.keys(savedBasicCards)[0]];
+ // Use setStateFromParent since it ensures there is no dangling
+ // `selectedPaymentCard` foreign key (FK) reference.
+ paymentDialog.setStateFromParent({
+ savedBasicCards,
+ });
+ },
+
+ logState() {
+ let state = requestStore.getState();
+ // eslint-disable-next-line no-console
+ console.log(state);
+ dump(`${JSON.stringify(state, null, 2)}\n`);
+ },
+
+ refresh() {
+ window.parent.location.reload(true);
+ },
+
+ rerender() {
+ requestStore.setState({});
+ },
+
+ saveVisibleForm() {
+ // Bypasses field validation which is useful to test error handling.
+ paymentDialog
+ .querySelector("#main-container > .page:not([hidden])")
+ .saveRecord();
+ },
+
+ setAddresses1() {
+ paymentDialog.setStateFromParent({ savedAddresses: ADDRESSES_1 });
+ },
+
+ setDupesAddresses() {
+ paymentDialog.setStateFromParent({ savedAddresses: DUPED_ADDRESSES });
+ },
+
+ setBasicCards1() {
+ paymentDialog.setStateFromParent({ savedBasicCards: BASIC_CARDS_1 });
+ },
+
+ setBasicCardErrors() {
+ let request = Object.assign({}, requestStore.getState().request);
+ request.paymentDetails = Object.assign(
+ {},
+ requestStore.getState().request.paymentDetails
+ );
+ request.paymentDetails.paymentMethodErrors = {
+ cardNumber: "",
+ cardholderName: "",
+ cardSecurityCode: "",
+ expiryMonth: "",
+ expiryYear: "",
+ billingAddress: {
+ addressLine:
+ "Can only buy from ROADS, not DRIVES, BOULEVARDS, or STREETS",
+ city: "Can only buy from CITIES, not TOWNSHIPS or VILLAGES",
+ country: "Can only buy from US, not CA",
+ dependentLocality: "Can only be SUBURBS, not NEIGHBORHOODS",
+ organization: "Can only buy from CORPORATIONS, not CONSORTIUMS",
+ phone: "Only allowed to buy from area codes that start with 9",
+ postalCode: "Only allowed to buy from postalCodes that start with 0",
+ recipient: "Can only buy from names that start with J",
+ region: "Can only buy from regions that start with M",
+ regionCode: "Regions must be 1 to 3 characters in length",
+ },
+ };
+ requestStore.setState({
+ request,
+ });
+ },
+
+ setChangesPrevented(evt) {
+ requestStore.setState({
+ changesPrevented: evt.target.checked,
+ });
+ },
+
+ setCompleteStatus() {
+ let input = document.querySelector("[name='setCompleteStatus']:checked");
+ let completeStatus = input.value;
+ let request = requestStore.getState().request;
+ paymentDialog.setStateFromParent({
+ request: Object.assign({}, request, { completeStatus }),
+ });
+ },
+
+ setPayerErrors() {
+ let request = Object.assign({}, requestStore.getState().request);
+ request.paymentDetails = Object.assign(
+ {},
+ requestStore.getState().request.paymentDetails
+ );
+ request.paymentDetails.payerErrors = {
+ email: "Only @mozilla.com emails are supported",
+ name: "Payer name must start with M",
+ phone: "Payer area codes must start with 1",
+ };
+ requestStore.setState({
+ request,
+ });
+ },
+
+ setPaymentOptions() {
+ let options = {};
+ let checkboxes = document.querySelectorAll(
+ "#paymentOptions input[type='checkbox']"
+ );
+ for (let input of checkboxes) {
+ options[input.name] = input.checked;
+ }
+ let req = Object.assign({}, requestStore.getState().request, {
+ paymentOptions: options,
+ });
+ requestStore.setState({ request: req });
+ },
+
+ setRequest1() {
+ paymentDialog.setStateFromParent({ request: REQUEST_1 });
+ },
+
+ setRequest2() {
+ paymentDialog.setStateFromParent({ request: REQUEST_2 });
+ },
+
+ setRequestPayerName() {
+ buttonActions.setPaymentOptions();
+ },
+ setRequestPayerEmail() {
+ buttonActions.setPaymentOptions();
+ },
+ setRequestPayerPhone() {
+ buttonActions.setPaymentOptions();
+ },
+ setRequestShipping() {
+ buttonActions.setPaymentOptions();
+ },
+
+ setShippingError() {
+ let request = Object.assign({}, requestStore.getState().request);
+ request.paymentDetails = Object.assign(
+ {},
+ requestStore.getState().request.paymentDetails
+ );
+ request.paymentDetails.error = "Shipping Error!";
+ request.paymentDetails.shippingOptions = [];
+ requestStore.setState({
+ request,
+ });
+ },
+
+ setShippingAddressErrors() {
+ let request = Object.assign({}, requestStore.getState().request);
+ request.paymentDetails = Object.assign(
+ {},
+ requestStore.getState().request.paymentDetails
+ );
+ request.paymentDetails.shippingAddressErrors = {
+ addressLine: "Can only ship to ROADS, not DRIVES, BOULEVARDS, or STREETS",
+ city: "Can only ship to CITIES, not TOWNSHIPS or VILLAGES",
+ country: "Can only ship to USA, not CA",
+ dependentLocality: "Can only be SUBURBS, not NEIGHBORHOODS",
+ organization: "Can only ship to CORPORATIONS, not CONSORTIUMS",
+ phone: "Only allowed to ship to area codes that start with 9",
+ postalCode: "Only allowed to ship to postalCodes that start with 0",
+ recipient: "Can only ship to names that start with J",
+ region: "Can only ship to regions that start with M",
+ regionCode: "Regions must be 1 to 3 characters in length",
+ };
+ requestStore.setState({
+ request,
+ });
+ },
+
+ toggleDirectionality() {
+ let body = paymentDialog.ownerDocument.body;
+ body.dir = body.dir == "rtl" ? "ltr" : "rtl";
+ },
+
+ toggleBranding() {
+ for (let container of paymentDialog.querySelectorAll("accepted-cards")) {
+ container.classList.toggle("branded");
+ }
+ },
+};
+
+window.addEventListener("click", function onButtonClick(evt) {
+ let id = evt.target.id || evt.target.name;
+ if (!id || typeof buttonActions[id] != "function") {
+ return;
+ }
+
+ buttonActions[id](evt);
+});
+
+window.addEventListener("DOMContentLoaded", function onDCL() {
+ if (window.location.protocol == "resource:") {
+ // Only show the debug frame button if we're running from a resource URI
+ // so it doesn't show during development over file: or http: since it won't work.
+ // Note that the button still won't work if resource://payments/paymentRequest.xhtml
+ // is manually loaded in a tab but will be shown.
+ document.getElementById("debugFrame").hidden = false;
+ }
+
+ requestStore.subscribe(paymentOptionsUpdater);
+ paymentOptionsUpdater.render(requestStore.getState());
+});