<!DOCTYPE html>
<!--
  Copyright 2022 The Cobalt Authors. All Rights Reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!--
  This is a basic test of the getRegistrations() for service workers.
-->

<html>
<head>
  <title>Cobalt Service Worker getRegistrations() Test</title>
  <script src='black_box_js_test_utils.js'></script>
</head>
<body>
  <script>
    h5vcc.storage.clearServiceWorkerCache();

    // TODO: check multiple registrations.
    const unregisterAll = () => navigator.serviceWorker.getRegistrations().then(registrations =>
        Promise.all(registrations.map(r => r.unregister())));
    const fail = msg => {
      if (msg) {
        console.error(msg);
      }
      unregisterAll().then(notReached);
    };
    const timeoutId = window.setTimeout(fail, 10000);
    const success = () => unregisterAll().then(() => {
      clearTimeout(timeoutId);
      onEndTest();
    });
    const assertEquals = (expected, actual, msg) => {
      if (expected !== actual) {
        const errorMessage = `Expected: '${expected}', but was '${actual}'`;
        fail(msg ? `${msg}(${errorMessage})` : errorMessage);
      }
    };
    const workerPostMessage = message => navigator.serviceWorker.getRegistrations()
      .then(registrations => {
        let sent = false;
        registrations.forEach(registration => {
          if (registration.active) {
            registration.active.postMessage(message);
            sent = true;
          }
        });
        if (!sent) {
          fail('Unable to post message to active service worker.');
        }
      });
    let activeServiceWorker = null;
    navigator.serviceWorker.onmessage = event => {
      if (event.data === 'check-get-registrations') {
        navigator.serviceWorker.getRegistrations().then(registrations => {
          assertEquals(1, registrations.length);
          console.log(JSON.stringify(registrations[0]));
          workerPostMessage('check-get-registrations-ok');
        });
        return;
      }
      if (event.data === 'end-test') {
        success();
        return;
      }
      fail();
    };

    unregisterAll()
      .then(() => navigator.serviceWorker.getRegistrations())
      .then(registrations => {
        assertEquals(0, registrations.length);
      })
      .then(() => navigator.serviceWorker.register('service_worker_get_registrations_test.js'))
      .catch(fail);

    navigator.serviceWorker.ready.then(() => {
      workerPostMessage('start-test');
    });

    setupFinished();
  </script>
</body>
</html>
