<!doctype html>
<html>
  <head>
    <title>Notifications: the fetch handler handles the request for the icon.</title>
    <script src="../resources/testharness.js"></script>
    <script src="../resources/testharnessreport.js"></script>
    <script src="../serviceworker/resources/test-helpers.js"></script>
    <script src="resources/test-helpers.js"></script>
  </head>
  <body>
    <script>
      // Tests that the request for the notification icon is handled by the fetch event handler for
      // a persistent notification shown by the document.
      promise_test(test => {
          var scope = './';
          var script = 'instrumentation-service-worker.js';
          var port;
          var iconPath = '/resources/square20.png';

          testRunner.setPermission('notifications', 'granted', location.origin, location.origin);

          return getActiveServiceWorkerWithMessagePort(test, script, scope).then(info => {
              port = info.port;
              assert_true(!!navigator.serviceWorker.controller, 'The page must be controlled.');
              // (1) Display a persistent notification from a document context.
              return info.registration.showNotification('Title', { icon: iconPath });
          }).then(() => {
              return sendCommand(port, { command: 'get-fetch-history' });
          }).then(data => {
              // (2) Confirm that the icon request passed through the fetch event handler.
              assert_equals(data.fetchHistory.length, 1);
              assert_equals(data.fetchHistory[0], location.origin + iconPath);
          });
      }, 'The request for the notification icon is handled by the fetch event handler.');
    </script>
  </body>
</html>
