<!DOCTYPE html>
<title>Tests that postMessage works during and after terminating a service worker</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.js"></script>
<script>
function send_ping(worker) {
  return new Promise(function(resolve) {
      var channel = new MessageChannel();
      channel.port1.onmessage = function(message) {
        resolve(message.data);
      };
      worker.postMessage({port: channel.port2}, [channel.port2]);
    });
}

function delay(ms) {
  return new Promise(function(resolve) {
      window.setTimeout(resolve, ms);
    });
}

promise_test(function(test) {
    var worker = 'resources/ping-worker.js';
    var scope = 'resources/blank.html';
    var sw;
    return service_worker_unregister_and_register(test, worker, scope)
      .then(function(registration) {
          sw = registration.installing;
          return send_ping(sw);
        })
      .then(function(reply) {
          assert_equals(reply, 0);
          return internals.terminateServiceWorker(sw);
        })
      .then(function() {
          return send_ping(sw);
        })
      .then(function(reply) {
          assert_equals(reply, 0);
          return send_ping(sw);
        })
      .then(function(reply) {
          assert_equals(reply, 1);
          return service_worker_unregister_and_done(test, scope);
      });
  }, 'postMessage to a terminated service worker.');

async_test(function(t) {
    var worker_script = 'resources/postmessage-worker.js';
    var scope = 'resources/postmessage-worker-scope';
    var worker;
    var registration;
    var port;

    service_worker_unregister_and_register(
        t, worker_script, scope)
      .then(function(r) {
          registration = r;
          return wait_for_state(t, r.installing, 'activated');
        })
      .then(function() {
          worker = registration.active;
          return internals.terminateServiceWorker(worker);
        })
      .then(function() {
          var messageChannel = new MessageChannel();
          port = messageChannel.port1;
          port.onmessage = t.step_func(on_message);
          port.postMessage({value: 0});
          worker.postMessage({port: messageChannel.port2},
                             [messageChannel.port2]);
          port.postMessage({value: 1});
          // Asynchronously sending more messages gives chrome a chance to be in
          // a slightly different state, so wait a minimal amount of time.
          return delay(1);
        })
      .then(function() {
          port.postMessage({value: 2});
          port.postMessage({done: true});
        })
      .catch(unreached_rejection(t));

    var result = [];
    var expected = [
      'Acking value: 0',
      'Acking value: 1',
      'Acking value: 2',
    ];

    function on_message(e) {
      var message = e.data;
      if (message === 'quit') {
        assert_array_equals(result, expected,
                            'Worker should post back expected values.');
        service_worker_unregister_and_done(t, scope);
      } else {
        result.push(message);
      }
    }
  }, 'postMessage on a port that was sent to a terminated service worker');

async_test(function(t) {
    var worker_script = 'resources/postmessage-port-worker.js';
    var scope = 'resources/postmessage-port-worker-scope';
    var worker;
    var registration;
    var port;

    service_worker_unregister_and_register(
        t, worker_script, scope)
      .then(function(r) {
          registration = r;
          return wait_for_state(t, r.installing, 'activated');
        })
      .then(function() {
          worker = registration.active;
          return internals.terminateServiceWorker(worker);
        })
      .then(function() {
          var innerChannel = new MessageChannel();
          var outerChannel = new MessageChannel();
          port = innerChannel.port1;
          port.onmessage = t.step_func(on_message);
          port.postMessage({value: 0});
          outerChannel.port1.postMessage({port: innerChannel.port2},
                                         [innerChannel.port2]);
          worker.postMessage({port: outerChannel.port2}, [outerChannel.port2]);
          port.postMessage({value: 1});
          // Asynchronously sending more messages gives chrome a chance to be in
          // a slightly different state, so wait a minimal amount of time.
          return delay(1);
        })
      .then(function() {
          port.postMessage({value: 2});
          port.postMessage({done: true});
        })
      .catch(unreached_rejection(t));

    var result = [];
    var expected = [
      'Acking value: 0',
      'Acking value: 1',
      'Acking value: 2',
    ];

    function on_message(e) {
      var message = e.data;
      if (message === 'quit') {
        assert_array_equals(result, expected,
                            'Worker should post back expected values.');
        service_worker_unregister_and_done(t, scope);
      } else {
        result.push(message);
      }
    }
  }, 'postMessage on a port that was sent on a port that was sent to a terminated service worker');
</script>
