1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5(function() {
6
7'use strict';
8
9var appLauncher = null;
10var hangoutPort = null;
11var webappPort = null;
12var helperChannel = null;
13var disconnectCallback = null;
14
15module('It2MeHelperChannel', {
16  setup: function() {
17    // App Launcher.
18    appLauncher = {
19      launch: function () {
20        return promiseResolveSynchronous('tabId');
21      },
22      close: function () {}
23    };
24    appLauncher.launch = sinon.spy(appLauncher, 'launch');
25    appLauncher.close = sinon.spy(appLauncher, 'close');
26
27    // HangoutPort.
28    hangoutPort = new chromeMocks.runtime.Port();
29    hangoutPort.postMessage = sinon.spy(hangoutPort, 'postMessage');
30    hangoutPort.disconnect = sinon.spy(hangoutPort, 'disconnect');
31
32    // WebappPort.
33    webappPort = new chromeMocks.runtime.Port();
34    webappPort.sender = {
35      tab : {
36        id : 'tabId'
37      }
38    };
39    webappPort.postMessage = sinon.spy(webappPort, 'postMessage');
40    webappPort.disconnect = sinon.spy(webappPort, 'disconnect');
41
42    // disconnect callback
43    disconnectCallback = sinon.spy();
44
45    // HelperChannel.
46    helperChannel = new remoting.It2MeHelperChannel(
47        appLauncher, hangoutPort, disconnectCallback);
48    helperChannel.init();
49    hangoutPort.onMessage.mock$fire({
50      method: remoting.It2MeHelperChannel.HangoutMessageTypes.CONNECT,
51      accessCode: "123412341234"
52    });
53  },
54});
55
56function promiseResolveSynchronous(value) {
57  return {
58    then: function(callback) {
59      callback('tabId');
60    }
61  };
62}
63
64test('onHangoutMessage_("hello") should return supportedFeatures', function() {
65  hangoutPort.onMessage.mock$fire(
66      { method: remoting.It2MeHelperChannel.HangoutMessageTypes.HELLO });
67
68  sinon.assert.calledWith(hangoutPort.postMessage, {
69    method: remoting.It2MeHelperChannel.HangoutMessageTypes.HELLO_RESPONSE,
70    supportedFeatures: base.values(remoting.It2MeHelperChannel.Features)
71  });
72});
73
74test('onHangoutMessage_(|connect|) should launch the webapp',
75    function() {
76  sinon.assert.called(appLauncher.launch);
77  QUnit.equal(helperChannel.instanceId(), 'tabId');
78});
79
80test('onWebappMessage() should forward messages to hangout', function() {
81  // Execute.
82  helperChannel.onWebappConnect(webappPort);
83  webappPort.onMessage.mock$fire({
84    method:'sessionStateChanged',
85    state:remoting.ClientSession.State.CONNECTING
86  });
87  webappPort.onMessage.mock$fire({
88    method:'sessionStateChanged',
89    state:remoting.ClientSession.State.CONNECTED
90  });
91
92  // Verify events are forwarded.
93  sinon.assert.calledWith(hangoutPort.postMessage, {
94    method:'sessionStateChanged',
95    state:remoting.ClientSession.State.CONNECTING
96  });
97
98  sinon.assert.calledWith(hangoutPort.postMessage, {
99    method:'sessionStateChanged',
100    state:remoting.ClientSession.State.CONNECTED
101  });
102});
103
104test('should notify hangout when the webapp crashes', function() {
105  // Execute.
106  helperChannel.onWebappConnect(webappPort);
107  webappPort.onDisconnect.mock$fire();
108
109  // Verify events are forwarded.
110  sinon.assert.calledWith(hangoutPort.postMessage, {
111    method:'sessionStateChanged',
112    state: remoting.ClientSession.State.FAILED
113  });
114  sinon.assert.called(hangoutPort.disconnect);
115  sinon.assert.calledOnce(disconnectCallback);
116});
117
118test('should notify hangout when the session is ended', function() {
119  // Execute.
120  helperChannel.onWebappConnect(webappPort);
121  webappPort.onMessage.mock$fire({
122    method:'sessionStateChanged',
123    state:remoting.ClientSession.State.CLOSED
124  });
125
126  webappPort.onDisconnect.mock$fire();
127
128  // Verify events are forwarded.
129  sinon.assert.calledWith(hangoutPort.postMessage, {
130    method:'sessionStateChanged',
131    state:remoting.ClientSession.State.CLOSED
132  });
133  sinon.assert.called(hangoutPort.disconnect);
134  sinon.assert.calledOnce(disconnectCallback);
135});
136
137test('should notify hangout when the session has error', function() {
138  helperChannel.onWebappConnect(webappPort);
139  webappPort.onMessage.mock$fire({
140    method:'sessionStateChanged',
141    state:remoting.ClientSession.State.FAILED
142  });
143
144  webappPort.onDisconnect.mock$fire();
145
146  // Verify events are forwarded.
147  sinon.assert.calledWith(hangoutPort.postMessage, {
148    method:'sessionStateChanged',
149    state:remoting.ClientSession.State.FAILED
150  });
151  sinon.assert.called(hangoutPort.disconnect);
152  sinon.assert.calledOnce(disconnectCallback);
153});
154
155
156test('onHangoutMessages_(disconnect) should close the webapp', function() {
157  // Execute.
158  helperChannel.onWebappConnect(webappPort);
159  hangoutPort.onMessage.mock$fire({
160    method: remoting.It2MeHelperChannel.HangoutMessageTypes.DISCONNECT
161  });
162
163  sinon.assert.calledOnce(appLauncher.close);
164
165  // Webapp will respond by disconnecting the port
166  webappPort.onDisconnect.mock$fire();
167
168  // Verify events are forwarded.
169  sinon.assert.calledWith(hangoutPort.postMessage, {
170    method:'sessionStateChanged',
171    state:remoting.ClientSession.State.CLOSED
172  });
173  sinon.assert.called(webappPort.disconnect);
174  sinon.assert.called(hangoutPort.disconnect);
175});
176
177test('should close the webapp when hangout crashes', function() {
178  // Execute.
179  helperChannel.onWebappConnect(webappPort);
180  hangoutPort.onDisconnect.mock$fire();
181
182  sinon.assert.calledOnce(appLauncher.close);
183  sinon.assert.calledOnce(disconnectCallback);
184
185  sinon.assert.called(hangoutPort.disconnect);
186  sinon.assert.called(webappPort.disconnect);
187});
188
189})();
190