if (self.importScripts) {
  importScripts('/resources/testharness.js');
  importScripts('../resources/test-helpers.js');
  importScripts('/common/utils.js');
}

// We perform the same tests on put, add, addAll. Parameterise the tests to
// reduce repetition.
const methodsToTest = {
  put: async (cache, request) => {
    const response = await fetch(request);
    return cache.put(request, response);
  },
  add: async (cache, request) => cache.add(request),
  addAll: async (cache, request) => cache.addAll([request]),
};

for (const method in methodsToTest) {
  const perform = methodsToTest[method];

  cache_test(async (cache, test) => {
    const controller = new AbortController();
    const signal = controller.signal;
    controller.abort();
    const request = new Request('../resources/simple.txt', { signal });
    return promise_rejects_dom(test, 'AbortError', perform(cache, request),
                          `${method} should reject`);
  }, `${method}() on an already-aborted request should reject with AbortError`);

  cache_test(async (cache, test) => {
    const controller = new AbortController();
    const signal = controller.signal;
    const request = new Request('../resources/simple.txt', { signal });
    const promise = perform(cache, request);
    controller.abort();
    return promise_rejects_dom(test, 'AbortError', promise,
                          `${method} should reject`);
  }, `${method}() synchronously followed by abort should reject with ` +
     `AbortError`);

  cache_test(async (cache, test) => {
    const controller = new AbortController();
    const signal = controller.signal;
    const stateKey = token();
    const abortKey = token();
    const request = new Request(
        `../../../fetch/api/resources/infinite-slow-response.py?stateKey=${stateKey}&abortKey=${abortKey}`,
        { signal });

    const promise = perform(cache, request);

    // Wait for the server to start sending the response body.
    let opened = false;
    do {
      // Normally only one fetch to 'stash-take' is needed, but the fetches
      // will be served in reverse order sometimes
      // (i.e., 'stash-take' gets served before 'infinite-slow-response').

      const response =
            await fetch(`../../../fetch/api/resources/stash-take.py?key=${stateKey}`);
      const body = await response.json();
      if (body === 'open') opened = true;
    } while (!opened);

    // Sadly the above loop cannot guarantee that the browser has started
    // processing the response body. This delay is needed to make the test
    // failures non-flaky in Chrome version 66. My deepest apologies.
    await new Promise(resolve => setTimeout(resolve, 250));

    controller.abort();

    await promise_rejects_dom(test, 'AbortError', promise,
                          `${method} should reject`);

    // infinite-slow-response.py doesn't know when to stop.
    return fetch(`../../../fetch/api/resources/stash-put.py?key=${abortKey}`);
  }, `${method}() followed by abort after headers received should reject ` +
     `with AbortError`);
}

done();
