setup({ explicit_done: true, explicit_timeout: true });

const validMethod = Object.freeze({
  supportedMethods: "basic-card",
});

const validMethods = Object.freeze([validMethod]);

const validAmount = Object.freeze({
  currency: "USD",
  value: "1.00",
});

const validTotal = Object.freeze({
  label: "Valid total",
  amount: validAmount,
});
const validDetails = {
  total: validTotal,
};

test(() => {
  try {
    new PaymentRequest(validMethods, validDetails);
  } catch (err) {
    done();
    throw err;
  }
}, "Can construct a payment request (smoke test).");

/**
 * Pops up a payment sheet, allowing options to be
 * passed in if particular values are needed.
 *
 * @param PaymentOptions options
 */
async function getPaymentResponse(options, id) {
  const { response } = await getPaymentRequestResponse(options, id);
  return response;
}

/**
 * Creates a payment request and response pair.
 * It also shows the payment sheet.
 *
 * @param {PaymentOptions?} options
 * @param {String?} id
 */
async function getPaymentRequestResponse(options, id) {
  const methods = [{ supportedMethods: "basic-card" }];
  const details = {
    id,
    total: {
      label: "Total due",
      amount: { currency: "USD", value: "1.0" },
    },
    shippingOptions: [
      {
        id: "fail1",
        label: "Fail option 1",
        amount: { currency: "USD", value: "5.00" },
        selected: false,
      },
      {
        id: "pass",
        label: "Pass option",
        amount: { currency: "USD", value: "5.00" },
        selected: true,
      },
      {
        id: "fail2",
        label: "Fail option 2",
        amount: { currency: "USD", value: "5.00" },
        selected: false,
      },
    ],
  };
  const request = new PaymentRequest(methods, details, options);
  request.onshippingaddresschange = ev => ev.updateWith(details);
  request.onshippingoptionchange = ev => ev.updateWith(details);
  const response = await request.show();
  return { request, response };
}

/**
 * Runs a manual test for payment
 *
 * @param {HTMLButtonElement} button The HTML button.
 * @param {PaymentOptions?} options.
 * @param {Object} expected What property values are expected to pass the test.
 * @param {String?} id And id for the request/response pair.
 */
async function runManualTest(button, options, expected = {}, id = undefined) {
  button.disabled = true;
  const { request, response } = await getPaymentRequestResponse(options, id);
  await response.complete();
  test(() => {
    assert_idl_attribute(
      response,
      "requestId",
      "Expected requestId to be an IDL attribute."
    );
    assert_equals(response.requestId, request.id, `Expected ids to match`);
    for (const [attribute, value] of Object.entries(expected)) {
      assert_idl_attribute(
        response,
        attribute,
        `Expected ${attribute} to be an IDL attribute.`
      );
      assert_equals(
        response[attribute],
        value,
        `Expected response ${attribute} attribute to be ${value}`
      );
    }
    assert_idl_attribute(response, "details");
    assert_equals(typeof response.details, "object", "Expected an object");
    // Testing that this does not throw:
    response.toJSON();
    if (options && options.requestShipping) {
      assert_equals(
        response.shippingOption,
        "pass",
        "request.shippingOption must be 'pass'"
      );
    } else {
      assert_equals(
        request.shippingOption,
        null,
        "If requestShipping is falsy, request.shippingOption must be null"
      );
      assert_equals(
        response.shippingOption,
        null,
        "request.shippingOption must be null"
      );
    }
  }, button.textContent.trim());
}
