<!DOCTYPE html>
<title>Service Worker: CSS's base URL must be the response URL</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
<script>
const SCOPE = 'resources/fetch-request-css-base-url-iframe.html';
const SCRIPT = 'resources/fetch-request-css-base-url-worker.js';
let worker;

var signalMessage;
function getNextMessage() {
  return new Promise(resolve => { signalMessage = resolve; });
}

promise_test(async (t) => {
  const registration = await service_worker_unregister_and_register(
      t, SCRIPT, SCOPE);
  worker = registration.installing;
  await wait_for_state(t, worker, 'activated');
}, 'global setup');

// Creates a test concerning the base URL of a stylesheet. It loads a
// stylesheet from a controlled page. The stylesheet makes a subresource
// request for an image. The service worker messages back the details of the
// image request in order to test the base URL.
//
// The request URL for the stylesheet is under "resources/request-url-path/".
// The service worker may respond in a way such that the response URL is
// different to the request URL.
function base_url_test(params) {
  promise_test(async (t) => {
    let frame;
    t.add_cleanup(() => {
      if (frame)
        frame.remove();
    });

    // Ask the service worker to message this page once it gets the request
    // for the image.
    let channel = new MessageChannel();
    const sawPong = getNextMessage();
    channel.port1.onmessage = (event) => {
      signalMessage(event.data);
    };
    worker.postMessage({port:channel.port2},[channel.port2]);

    // It sends a pong back immediately. This ping/pong protocol helps deflake
    // the test for browsers where message/fetch ordering isn't guaranteed.
    assert_equals('pong', await sawPong);

    // Load the frame which will load the stylesheet that makes the image
    // request.
    const sawResult = getNextMessage();
    frame = await with_iframe(params.framePath);
    const result = await sawResult;

    // Test the image request.
    const base = new URL('.', document.location).href;
    assert_equals(result.url,
                  base + params.expectImageRequestPath,
                  'request');
    assert_equals(result.referrer,
                  base + params.expectImageRequestReferrer,
                  'referrer');
  }, params.description);
}

const cssFile = 'fetch-request-css-base-url-style.css';

base_url_test({
  framePath: SCOPE + '?fetch',
  expectImageRequestPath: 'resources/dummy.png',
  expectImageRequestReferrer: `resources/${cssFile}?fetch`,
  description: 'base URL when service worker does respondWith(fetch(responseUrl)).'});

base_url_test({
  framePath: SCOPE + '?newResponse',
  expectImageRequestPath: 'resources/request-url-path/dummy.png',
  expectImageRequestReferrer: `resources/request-url-path/${cssFile}?newResponse`,
  description: 'base URL when service worker does respondWith(new Response()).'});

// Cleanup step: this must be the last promise_test.
promise_test(async (t) => {
  return service_worker_unregister(t, SCOPE);
}, 'cleanup global state');
</script>
