<!DOCTYPE html>
<title>Service Worker: Redirected response</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
// Tests redirect behavior. It calls fetch_method(url, fetch_option) and tests
// the resulting response against the expected values. It also adds the
// response to |cache| and checks the cached response matches the expected
// values.
//
// |options|: a dictionary of parameters for the test
// |options.url|: the URL to fetch
// |options.fetch_option|: the options passed to |fetch_method|
// |options.fetch_method|: the method used to fetch. Useful for testing an
//                         iframe's fetch() vs. this page's fetch().
// |options.expected_type|: The value of response.type
// |options.expected_redirected|: The value of response.redirected
// |options.expected_intercepted_urls|: The list of intercepted request URLs.
function redirected_test(options) {
  return options.fetch_method.call(null, options.url, options.fetch_option).then(response => {
        let cloned_response = response.clone();
        assert_equals(
            response.type, options.expected_type,
            'The response type of response must match. URL: ' + options.url);
        assert_equals(
            cloned_response.type, options.expected_type,
            'The response type of cloned response must match. URL: ' + options.url);
        assert_equals(
            response.redirected, options.expected_redirected,
            'The redirected flag of response must match. URL: ' + options.url);
        assert_equals(
            cloned_response.redirected, options.expected_redirected,
            'The redirected flag of cloned response must match. URL: ' + options.url);
        if (options.expected_response_url) {
            assert_equals(
                cloned_response.url, options.expected_response_url,
                'The URL does not meet expectation. URL: ' + options.url);
        }
        return cache.put(options.url, response);
      })
    .then(_ => cache.match(options.url))
    .then(response => {
        assert_equals(
            response.type, options.expected_type,
            'The response type of response in CacheStorage must match. ' +
            'URL: ' + options.url);
        assert_equals(
            response.redirected, options.expected_redirected,
            'The redirected flag of response in CacheStorage must match. ' +
            'URL: ' + options.url);
        return check_intercepted_urls(options.expected_intercepted_urls);
      });
}

async function take_intercepted_urls() {
  const message = new Promise((resolve) => {
    let channel = new MessageChannel();
    channel.port1.onmessage = msg => { resolve(msg.data.requestInfos); };
    worker.postMessage({command: 'getRequestInfos', port: channel.port2},
                       [channel.port2]);
  });
  const request_infos = await message;
  return request_infos.map(info => { return info.url; });
}

function check_intercepted_urls(expected_urls) {
  return take_intercepted_urls().then((urls) => {
      assert_object_equals(urls, expected_urls, 'Intercepted URLs matching.');
    });
}

function setup_and_clean() {
  // To prevent interference from previous tests, take the intercepted URLs from
  // the service worker.
  return setup.then(() => take_intercepted_urls());
}


let host_info = get_host_info();
const REDIRECT_URL = host_info['HTTPS_ORIGIN'] + base_path() +
                     'resources/redirect.py?Redirect=';
const TARGET_URL = host_info['HTTPS_ORIGIN'] + base_path() +
                   'resources/simple.txt?';
const REDIRECT_TO_TARGET_URL = REDIRECT_URL + encodeURIComponent(TARGET_URL);
let frame;
let cache;
let setup;
let worker;

promise_test(t => {
    const SCOPE = 'resources/blank.html?redirected-response';
    const SCRIPT = 'resources/redirect-worker.js';
    const CACHE_NAME = 'service-workers/service-worker/redirected-response';
    setup = service_worker_unregister_and_register(t, SCRIPT, SCOPE)
      .then(registration => {
          promise_test(
              () => registration.unregister(),
              'restore global state (service worker registration)');
          worker = registration.installing;
          return wait_for_state(t, registration.installing, 'activated');
        })
      .then(_ => self.caches.open(CACHE_NAME))
      .then(c => {
          cache = c;
          promise_test(
            () => self.caches.delete(CACHE_NAME),
            'restore global state (caches)');
          return with_iframe(SCOPE);
        })
      .then(f => {
          frame = f;
          add_completion_callback(() => f.remove());
          return check_intercepted_urls(
              [host_info['HTTPS_ORIGIN'] + base_path() + SCOPE]);
        });
      return setup;
  }, 'initialize global state (service worker registration and caches)');

// ===============================================================
// Tests for requests that are out-of-scope of the service worker.
// ===============================================================
promise_test(t => setup_and_clean()
  .then(() => redirected_test({url: TARGET_URL,
                               fetch_option: {},
                               fetch_method: self.fetch,
                               expected_type: 'basic',
                               expected_redirected: false,
                               expected_intercepted_urls: []})),
  'mode: "follow", non-intercepted request, no server redirect');

promise_test(t => setup_and_clean()
  .then(() => redirected_test({url: REDIRECT_TO_TARGET_URL,
                               fetch_option: {},
                               fetch_method: self.fetch,
                               expected_type: 'basic',
                               expected_redirected: true,
                               expected_intercepted_urls: []})),
  'mode: "follow", non-intercepted request');

promise_test(t => setup_and_clean()
  .then(() => redirected_test({url: REDIRECT_TO_TARGET_URL + '&manual',
                               fetch_option: {redirect: 'manual'},
                               fetch_method: self.fetch,
                               expected_type: 'opaqueredirect',
                               expected_redirected: false,
                               expected_intercepted_urls: []})),
  'mode: "manual", non-intercepted request');

promise_test(t => setup_and_clean()
    .then(() => promise_rejects(
                   t, new TypeError(),
                   self.fetch(REDIRECT_TO_TARGET_URL + '&error',
                              {redirect:'error'}),
                   'The redirect response from the server should be treated as' +
                   ' an error when the redirect flag of request was \'error\'.'))
    .then(() => check_intercepted_urls([])),
  'mode: "error", non-intercepted request');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = TARGET_URL + '&sw=fetch';
      return redirected_test({url: url,
                              fetch_option: {},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'basic',
                              expected_redirected: false,
                              expected_intercepted_urls: [url]})
    }),
  'mode: "follow", no mode change, no server redirect');

// =======================================================
// Tests for requests that are in-scope of the service worker. The service
// worker returns a redirected response.
// =======================================================
promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=follow&sw=fetch';
      return redirected_test({url: url,
                              fetch_option: {redirect: 'follow'},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'basic',
                              expected_redirected: true,
                              expected_intercepted_urls: [url]})
    }),
  'mode: "follow", no mode change');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=error&sw=follow';
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(url, {redirect: 'error'}),
          'The redirected response from the service worker should be ' +
          'treated as an error when the redirect flag of request was ' +
          '\'error\'.')
        .then(() => check_intercepted_urls([url]));
    }),
  'mode: "error", mode change: "follow"');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=manual&sw=follow';
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(url, {redirect: 'manual'}),
          'The redirected response from the service worker should be ' +
          'treated as an error when the redirect flag of request was ' +
          '\'manual\'.')
        .then(() => check_intercepted_urls([url]));
    }),
  'mode: "manual", mode change: "follow"');

// =======================================================
// Tests for requests that are in-scope of the service worker. The service
// worker returns an opaqueredirect response.
// =======================================================
promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=follow&sw=manual';
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(url, {redirect: 'follow'}),
          'The opaqueredirect response from the service worker should ' +
          'be treated as an error when the redirect flag of request was' +
          ' \'follow\'.')
        .then(() => check_intercepted_urls([url]));
    }),
  'mode: "follow", mode change: "manual"');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=error&sw=manual';
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(url, {redirect: 'error'}),
          'The opaqueredirect response from the service worker should ' +
          'be treated as an error when the redirect flag of request was' +
          ' \'error\'.')
        .then(() => check_intercepted_urls([url]));
    }),
  'mode: "error", mode change: "manual"');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = REDIRECT_TO_TARGET_URL +
                  '&original-redirect-mode=manual&sw=manual';
      return redirected_test({url: url,
                              fetch_option: {redirect: 'manual'},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'opaqueredirect',
                              expected_redirected: false,
                              expected_intercepted_urls: [url]});
    }),
  'mode: "manual", no mode change');

// =======================================================
// Tests for requests that are in-scope of the service worker. The service
// worker returns a generated redirect response.
// =======================================================
promise_test(t => setup_and_clean()
    .then(() => {
      const url = host_info['HTTPS_ORIGIN'] + base_path() +
                  'dummy?url=' + encodeURIComponent(TARGET_URL) +
                  '&original-redirect-mode=follow&sw=gen';
      return redirected_test({url: url,
                              fetch_option: {redirect: 'follow'},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'basic',
                              expected_redirected: true,
                              expected_intercepted_urls: [url, TARGET_URL]})
    }),
  'mode: "follow", generated redirect response');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = host_info['HTTPS_ORIGIN'] + base_path() +
                  'dummy?url=' + encodeURIComponent(TARGET_URL) +
                  '&original-redirect-mode=error&sw=gen';
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(url, {redirect: 'error'}),
          'The generated redirect response from the service worker should ' +
          'be treated as an error when the redirect flag of request was' +
          ' \'error\'.')
        .then(() => check_intercepted_urls([url]));
    }),
  'mode: "error", generated redirect response');

promise_test(t => setup_and_clean()
    .then(() => {
      const url = host_info['HTTPS_ORIGIN'] + base_path() +
                  'dummy?url=' + encodeURIComponent(TARGET_URL) +
                  '&original-redirect-mode=follow&sw=gen';
      return redirected_test({url: url,
                              fetch_option: {redirect: 'manual'},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'opaqueredirect',
                              expected_redirected: false,
                              expected_intercepted_urls: [url]})
    }),
  'mode: "manual", generated redirect response');

// =======================================================
// Tests for requests that are in-scope of the service worker. The service
// worker returns a generated redirect response. And the fetch follows the
// redirection multiple times.
// =======================================================
promise_test(t => setup_and_clean()
    .then(() => {
      // The Fetch spec says: "If request’s redirect count is twenty, return a
      // network error." https://fetch.spec.whatwg.org/#http-redirect-fetch
      // So fetch can follow the redirect response 20 times.
      let urls = [TARGET_URL];
      for (let i = 0; i < 20; ++i) {
        urls.unshift(host_info['HTTPS_ORIGIN'] + '/dummy?sw=gen&url=' +
                    encodeURIComponent(urls[0]));

      }
      return redirected_test({url: urls[0],
                              fetch_option: {redirect: 'follow'},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'basic',
                              expected_redirected: true,
                              expected_intercepted_urls: urls})
    }),
  'Fetch should follow the redirect response 20 times');

promise_test(t => setup_and_clean()
    .then(() => {
      let urls = [TARGET_URL];
      // The Fetch spec says: "If request’s redirect count is twenty, return a
      // network error." https://fetch.spec.whatwg.org/#http-redirect-fetch
      // So fetch can't follow the redirect response 21 times.
      for (let i = 0; i < 21; ++i) {
        urls.unshift(host_info['HTTPS_ORIGIN'] + '/dummy?sw=gen&url=' +
                    encodeURIComponent(urls[0]));

      }
      return promise_rejects(
          t, new TypeError(),
          frame.contentWindow.fetch(urls[0], {redirect: 'follow'}),
          'Fetch should not follow the redirect response 21 times.')
        .then(() => {
          urls.pop();
          return check_intercepted_urls(urls)
        });
    }),
  'Fetch should not follow the redirect response 21 times.');

// =======================================================
// A test for verifying the url of a service-worker-redirected request is
// propagated to the outer response.
// =======================================================
promise_test(t => setup_and_clean()
    .then(() => {
      const url = host_info['HTTPS_ORIGIN'] + base_path() + 'dummy?url=' +
                  encodeURIComponent(TARGET_URL) +'&sw=fetch-url';
      return redirected_test({url: url,
                              fetch_option: {},
                              fetch_method: frame.contentWindow.fetch,
                              expected_type: 'basic',
                              expected_redirected: false,
                              expected_intercepted_urls: [url],
                              expected_response_url: TARGET_URL});
    }),
  'The URL for the service worker redirected request should be propagated to ' +
  'response.');
</script>
