<!doctype html>
<meta charset="utf8">
<link rel="help" href="https://www.w3.org/TR/payment-request/#paymentaddress-interface">
<title>
  PaymentResponse.prototype.shippingAddress
</title>
<script src="/js-test-resources/ui-helper.js"></script>
<script src="/resources/payment-request.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/helpers.js"></script>
<script>
setUpAndSmokeTest({ explicit_done: true, explicit_timeout: true });
const options = { requestShipping: true };
function runTest(button, expected = {}) {
  button.disabled = true;
  promise_test(async () => {
    const { response } = await getPaymentRequestResponse(options);
    await response.complete();
    assert_idl_attribute(response, "shippingAddress");
    const { shippingAddress: addr } = response;
    assert_true(
      addr instanceof PaymentAddress,
      "Expect instance of PaymentAddress"
    );
    // An [ISO3166] alpha-2 code. The canonical form is upper case.
    const { country } = addr;
    assert_equals(country.length, 2, "Expected length is 2");
    assert_true(/^[A-Z]{2}$/.test(country), "Canonical form is upper case");
    assert_true(
      addr.addressLine instanceof Array,
      "Expected addressLine to be an array"
    );
    assert_throws_js(
      TypeError,
      () => {
        addr.addressLine.push("this must throw");
      },
      "Array must be frozen"
    );
    const expectedEntries = Object.entries(expected);
    for (let [attr, expectedValue] of expectedEntries) {
      assert_idl_attribute(addr, attr);
      const msg = `Expected paymentAddress.${attr} to equal ${expectedValue}.`;
      //.toString() flattens array addressLine,
      //.toLowerCase() because case can't be enforced for some attributes
      const actualValue = addr[attr].toString().toLowerCase();
      expectedValue = expectedValue.toString().toLowerCase();
      assert_equals(actualValue, expectedValue, msg);
    }
    // Check toJSON result
    const jsonAddress = addr.toJSON();
    const jsonAddressEntries = Object.entries(jsonAddress);
    for (let [prop, jsonValue] of jsonAddressEntries) {
      const actualValue = jsonValue.toString().toLowerCase();
      const expectedValue = expected[prop].toString().toLowerCase();
      const msg = `Expected JSON ${prop} to be ${expectedValue}`;
      assert_equals(actualValue, expectedValue, msg);
    }
    assert_equals(jsonAddressEntries.length, expectedEntries.length);
    // Check that .toJSON() created a frozen array
    assert_throws_js(
      TypeError,
      () => {
        jsonAddress.addressLine.push("this must throw");
      },
    );
  }, button.textContent.trim());
  done();
}
</script>
<ol>
  <li>
    <button id="button">
      If the requestShipping member is true, then shippingAddress's PaymentAddress must match the expected values.
    </button>
  </li>
</ol>
<script>
    const address = {
        countryCode: 'AF',
        addressLines: ['1 wpt street'],
        locality: 'Kabul',
        postalCode: '1001',
        localizedName: 'web platform test',
        phoneNumber: '+93555555555',
    };
    internals.mockPaymentCoordinator.setShippingAddress(address);

    const expectedAddress = {
        country: address.countryCode,
        addressLine: address.addressLines,
        region: '',
        city: address.locality,
        dependentLocality: '',
        postalCode: address.postalCode,
        sortingCode: '',
        organization: '',
        recipient: address.localizedName,
        phone: address.phoneNumber,
    };
    runTest(document.getElementById("button"), expectedAddress);
</script>
