<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>SendBeacon CORS preflight test with cookie</title>
    <script src=/resources/testharness.js></script>
    <script src=/resources/testharnessreport.js></script>
  </head>
  <body>
    <script src="/common/utils.js"></script>
    <script src="/common/get-host-info.sub.js"></script>
    <script>
var RESOURCES_DIR = "/WebKit/beacon/resources/";

if (window.testRunner)
  testRunner.setAlwaysAcceptCookies(true);

function pollResult(test, id) {
  var checkUrl = RESOURCES_DIR + "beacon-preflight.py?cmd=get&id=" + id;

  return new Promise(resolve => {
    step_timeout(test.step_func(() => {
      fetch(checkUrl).then(response => {
        response.json().then(body => {
          resolve(body);
        });
      });
    }), 1000);
  });
}

function fetchCORSCookie(testBase, name, path) {
  return new Promise(resolve => {
    let frame = document.createElement("iframe");
    frame.src = testBase + "set-cookie.py?name=" + encodeURIComponent(name) + "&path=" + encodeURIComponent(path);
    frame.onload = function() { resolve(); };
    document.body.append(frame);
  });
}

function testCORSPreflightSuccessWithCookie(what) {
  var testBase = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR;
  var id = self.token();
  var testUrl = testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id; 

  promise_test(function(test) {
    return fetchCORSCookie(testBase, "testCookie", "/").then(() => {
      assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
      return pollResult(test, id).then(result => {
        assert_equals(result['preflight'], 1, "Received preflight")
        assert_equals(result['preflight_cookie_header'], "", "Preflight cookie header")
        assert_equals(result['beacon'], 1, "Received beacon")
        assert_equals(result['beacon_cookie_header'], "testCookie=1", "Beacon Cookie header")
      });
    });
  }, "CORS preflight success test");
}

function testCORSPreflightSuccessWithCookieAndRedirection(what) {
  var testBase = get_host_info().HTTP_ORIGIN_WITH_DIFFERENT_PORT + RESOURCES_DIR;
  var id = self.token();
  var target = testBase + "beacon-preflight.py?allowCors=1&cmd=put&id=" + id;
  var testUrl = get_host_info().HTTP_REMOTE_ORIGIN + RESOURCES_DIR + "redirect.py?redirect_status=307&location=" + target;

  promise_test(function(test) {
    return fetchCORSCookie(testBase, "testCookie", "/").then(() => {
      assert_true(navigator.sendBeacon(testUrl, what), "SendBeacon Succeeded");
      return pollResult(test, id).then(result => {
        assert_equals(result['preflight'], 1, "Received preflight")
        assert_equals(result['preflight_cookie_header'], "", "Preflight cookie header")
        assert_equals(result['beacon'], 1, "Received beacon")
        assert_equals(result['beacon_cookie_header'], "testCookie=1", "Beacon Cookie header")
      });
    });
  }, "CORS preflight success test with redirection");
}

let blob = new Blob(["123"], {type: "application/octet-stream"});
testCORSPreflightSuccessWithCookie(blob);
testCORSPreflightSuccessWithCookieAndRedirection(blob);
    </script>
  </body>
</html>
