16e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
26e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
36e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// found in the LICENSE file.
46e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)(function() {
66e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
76e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)'use strict';
86e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var appLauncher = null;
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var hangoutPort = null;
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var webappPort = null;
126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var helperChannel = null;
136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)var disconnectCallback = null;
146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)module('It2MeHelperChannel', {
166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  setup: function() {
176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // App Launcher.
186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    appLauncher = {
196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      launch: function () {
206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        return promiseResolveSynchronous('tabId');
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      },
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      close: function () {}
236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    };
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    appLauncher.launch = sinon.spy(appLauncher, 'launch');
256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    appLauncher.close = sinon.spy(appLauncher, 'close');
266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // HangoutPort.
286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    hangoutPort = new chromeMocks.runtime.Port();
296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    hangoutPort.postMessage = sinon.spy(hangoutPort, 'postMessage');
306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    hangoutPort.disconnect = sinon.spy(hangoutPort, 'disconnect');
316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // WebappPort.
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    webappPort = new chromeMocks.runtime.Port();
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    webappPort.sender = {
356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      tab : {
366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        id : 'tabId'
376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      }
386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    };
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    webappPort.postMessage = sinon.spy(webappPort, 'postMessage');
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    webappPort.disconnect = sinon.spy(webappPort, 'disconnect');
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // disconnect callback
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    disconnectCallback = sinon.spy();
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // HelperChannel.
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    helperChannel = new remoting.It2MeHelperChannel(
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        appLauncher, hangoutPort, disconnectCallback);
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    helperChannel.init();
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    hangoutPort.onMessage.mock$fire({
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      method: remoting.It2MeHelperChannel.HangoutMessageTypes.CONNECT,
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      accessCode: "123412341234"
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    });
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  },
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)function promiseResolveSynchronous(value) {
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return {
586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    then: function(callback) {
596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      callback('tabId');
606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  };
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)test('onHangoutMessage_("hello") should return supportedFeatures', function() {
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  hangoutPort.onMessage.mock$fire(
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      { method: remoting.It2MeHelperChannel.HangoutMessageTypes.HELLO });
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    method: remoting.It2MeHelperChannel.HangoutMessageTypes.HELLO_RESPONSE,
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    supportedFeatures: base.values(remoting.It2MeHelperChannel.Features)
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  });
7203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)});
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('onHangoutMessage_(|connect|) should launch the webapp',
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    function() {
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(appLauncher.launch);
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  QUnit.equal(helperChannel.instanceId(), 'tabId');
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('onWebappMessage() should forward messages to hangout', function() {
816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Execute.
826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onMessage.mock$fire({
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CONNECTING
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onMessage.mock$fire({
886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CONNECTED
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify events are forwarded.
936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CONNECTING
966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CONNECTED
1016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('should notify hangout when the webapp crashes', function() {
1056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Execute.
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onDisconnect.mock$fire();
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify events are forwarded.
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state: remoting.ClientSession.State.FAILED
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(hangoutPort.disconnect);
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(disconnectCallback);
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('should notify hangout when the session is ended', function() {
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Execute.
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onMessage.mock$fire({
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CLOSED
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onDisconnect.mock$fire();
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify events are forwarded.
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CLOSED
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(hangoutPort.disconnect);
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(disconnectCallback);
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('should notify hangout when the session has error', function() {
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onMessage.mock$fire({
1406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.FAILED
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onDisconnect.mock$fire();
1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify events are forwarded.
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.FAILED
1506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(hangoutPort.disconnect);
1526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(disconnectCallback);
1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('onHangoutMessages_(disconnect) should close the webapp', function() {
1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Execute.
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  hangoutPort.onMessage.mock$fire({
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method: remoting.It2MeHelperChannel.HangoutMessageTypes.DISCONNECT
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(appLauncher.close);
1646e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Webapp will respond by disconnecting the port
1666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  webappPort.onDisconnect.mock$fire();
1676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Verify events are forwarded.
1696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledWith(hangoutPort.postMessage, {
1706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    method:'sessionStateChanged',
1716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    state:remoting.ClientSession.State.CLOSED
1726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  });
1736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(webappPort.disconnect);
1746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(hangoutPort.disconnect);
1756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)test('should close the webapp when hangout crashes', function() {
1786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Execute.
1796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  helperChannel.onWebappConnect(webappPort);
1806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  hangoutPort.onDisconnect.mock$fire();
1816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(appLauncher.close);
1836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.calledOnce(disconnectCallback);
1846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(hangoutPort.disconnect);
1866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  sinon.assert.called(webappPort.disconnect);
1876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)});
1886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)})();
190