1 // Copyright 2015 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.
9 var ControllableSignalStrategy = function(jid, type, stateChangeCallback) {
12 this.stateChangeCallback_ = stateChangeCallback;
14 this.onIncomingStanzaCallback = function() {};
15 this.dispose = sinon.spy();
16 this.connect = sinon.spy();
17 this.sendMessage = sinon.spy();
18 this.sendConnectionSetupResults = sinon.spy();
21 ControllableSignalStrategy.prototype.setStateChangedCallback = function(
22 onStateChangedCallback) {
23 this.onStateChangedCallback =
24 onStateChangedCallback ? onStateChangedCallback : function() {};
27 ControllableSignalStrategy.prototype.setIncomingStanzaCallback =
28 function(onIncomingStanzaCallback) {
29 this.onIncomingStanzaCallback =
30 onIncomingStanzaCallback ? onIncomingStanzaCallback
34 ControllableSignalStrategy.prototype.getState = function(message) {
38 ControllableSignalStrategy.prototype.getError = function(message) {
39 return remoting.Error.UNKNOWN;
42 ControllableSignalStrategy.prototype.getJid = function(message) {
46 ControllableSignalStrategy.prototype.getType = function(message) {
50 ControllableSignalStrategy.prototype.setExternalCallbackForTesting =
51 function(externalCallback) {
52 this.externalCallback_ = externalCallback;
55 ControllableSignalStrategy.prototype.setStateForTesting =
56 function(state, expectExternalCallback) {
58 this.externalCallback_.reset();
59 this.onStateChangedCallback(state);
60 if (expectExternalCallback) {
61 equal(this.externalCallback_.callCount, 1);
62 ok(this.externalCallback_.calledWith(state));
63 equal(strategy.getState(), state);
65 ok(!this.externalCallback_.called);
69 var MockLogToServer = function() {
70 this.logSignalStrategyProgress = sinon.spy();
73 MockLogToServer.prototype.assertProgress = function() {
74 equal(this.logSignalStrategyProgress.callCount * 2, arguments.length);
75 for (var i = 0; i < this.logSignalStrategyProgress.callCount; ++i) {
76 equal(this.logSignalStrategyProgress.getCall(i).args[0], arguments[2 * i]);
77 equal(this.logSignalStrategyProgress.getCall(i).args[1],
78 arguments[2 * i + 1]);
82 var onStateChange = null;
83 var onIncomingStanzaCallback = null;
87 var logToServer = null;
89 module('fallback_signal_strategy', {
91 onStateChange = sinon.spy();
92 onIncomingStanzaCallback = sinon.spy();
93 strategy = new remoting.FallbackSignalStrategy(
94 new ControllableSignalStrategy('primary-jid',
95 remoting.SignalStrategy.Type.XMPP),
96 new ControllableSignalStrategy('secondary-jid',
97 remoting.SignalStrategy.Type.WCS));
98 strategy.setStateChangedCallback(onStateChange);
99 strategy.setIncomingStanzaCallback(onIncomingStanzaCallback);
100 primary = strategy.primary_;
101 secondary = strategy.secondary_;
102 logToServer = new MockLogToServer();
103 primary.setExternalCallbackForTesting(onStateChange);
104 secondary.setExternalCallbackForTesting(onStateChange);
106 teardown: function() {
107 onStateChange = null;
108 onIncomingStanzaCallback = null;
116 test('primary succeeds; send & receive routed to it',
118 ok(!onStateChange.called);
119 ok(!primary.connect.called);
120 strategy.connect('server', 'username', 'authToken');
121 ok(primary.connect.calledWith('server', 'username', 'authToken'));
123 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
125 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
126 primary.setStateForTesting(remoting.SignalStrategy.State.HANDSHAKE, true);
128 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTED, true);
129 equal(strategy.getJid(), 'primary-jid');
131 strategy.sendConnectionSetupResults(logToServer);
132 logToServer.assertProgress(
133 remoting.SignalStrategy.Type.XMPP,
134 remoting.FallbackSignalStrategy.Progress.SUCCEEDED);
136 ok(!onIncomingStanzaCallback.called);
137 primary.onIncomingStanzaCallback('test-receive-primary');
138 secondary.onIncomingStanzaCallback('test-receive-secondary');
139 ok(onIncomingStanzaCallback.calledOnce);
140 ok(onIncomingStanzaCallback.calledWith('test-receive-primary'));
142 ok(!primary.sendMessage.called);
143 strategy.sendMessage('test-send');
144 ok(primary.sendMessage.calledOnce);
145 ok(primary.sendMessage.calledWith('test-send'));
147 ok(!primary.dispose.called);
148 ok(!secondary.dispose.called);
149 primary.setStateForTesting(remoting.SignalStrategy.State.CLOSED, true);
151 ok(primary.dispose.calledOnce);
152 ok(secondary.dispose.calledOnce);
156 test('primary fails; secondary succeeds; send & receive routed to it',
158 ok(!onStateChange.called);
159 ok(!primary.connect.called);
160 strategy.connect('server', 'username', 'authToken');
161 ok(primary.connect.calledWith('server', 'username', 'authToken'));
163 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
165 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
167 ok(!secondary.connect.called);
168 primary.setStateForTesting(remoting.SignalStrategy.State.FAILED, false);
169 ok(secondary.connect.calledWith('server', 'username', 'authToken'));
171 secondary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
173 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING,
175 secondary.setStateForTesting(remoting.SignalStrategy.State.HANDSHAKE, true);
177 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTED, true);
178 equal(strategy.getJid(), 'secondary-jid');
180 strategy.sendConnectionSetupResults(logToServer);
181 logToServer.assertProgress(
182 remoting.SignalStrategy.Type.XMPP,
183 remoting.FallbackSignalStrategy.Progress.FAILED,
184 remoting.SignalStrategy.Type.WCS,
185 remoting.FallbackSignalStrategy.Progress.SUCCEEDED);
187 ok(!onIncomingStanzaCallback.called);
188 primary.onIncomingStanzaCallback('test-receive-primary');
189 secondary.onIncomingStanzaCallback('test-receive-secondary');
190 ok(onIncomingStanzaCallback.calledOnce);
191 ok(onIncomingStanzaCallback.calledWith('test-receive-secondary'));
193 ok(!secondary.sendMessage.called);
194 strategy.sendMessage('test-send');
195 ok(!primary.sendMessage.called);
196 ok(secondary.sendMessage.calledOnce);
197 ok(secondary.sendMessage.calledWith('test-send'));
201 test('primary fails; secondary fails',
203 ok(!onStateChange.called);
204 ok(!primary.connect.called);
205 strategy.connect('server', 'username', 'authToken');
206 ok(primary.connect.calledWith('server', 'username', 'authToken'));
208 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
210 ok(!secondary.connect.called);
211 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
212 primary.setStateForTesting(remoting.SignalStrategy.State.FAILED, false);
213 ok(secondary.connect.calledWith('server', 'username', 'authToken'));
214 secondary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
216 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, false);
217 secondary.setStateForTesting(remoting.SignalStrategy.State.FAILED, true);
221 test('primary times out; secondary succeeds',
223 ok(!onStateChange.called);
224 ok(!primary.connect.called);
225 strategy.connect('server', 'username', 'authToken');
226 ok(primary.connect.calledWith('server', 'username', 'authToken'));
228 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
230 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
231 this.clock.tick(strategy.PRIMARY_CONNECT_TIMEOUT_MS_ - 1);
232 ok(!secondary.connect.called);
234 ok(secondary.connect.calledWith('server', 'username', 'authToken'));
235 secondary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
237 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING,
239 secondary.setStateForTesting(remoting.SignalStrategy.State.HANDSHAKE, true);
240 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTED, true);
241 strategy.sendConnectionSetupResults(logToServer);
243 secondary.setStateForTesting(remoting.SignalStrategy.State.CLOSED, true);
244 primary.setStateForTesting(remoting.SignalStrategy.State.FAILED, false);
246 logToServer.assertProgress(
247 remoting.SignalStrategy.Type.XMPP,
248 remoting.FallbackSignalStrategy.Progress.TIMED_OUT,
249 remoting.SignalStrategy.Type.WCS,
250 remoting.FallbackSignalStrategy.Progress.SUCCEEDED,
251 remoting.SignalStrategy.Type.XMPP,
252 remoting.FallbackSignalStrategy.Progress.FAILED_LATE);
256 test('primary times out; secondary fails',
258 ok(!onStateChange.called);
259 ok(!primary.connect.called);
260 strategy.connect('server', 'username', 'authToken');
261 ok(primary.connect.calledWith('server', 'username', 'authToken'));
263 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
265 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
266 this.clock.tick(strategy.PRIMARY_CONNECT_TIMEOUT_MS_ - 1);
267 ok(!secondary.connect.called);
269 ok(secondary.connect.calledWith('server', 'username', 'authToken'));
270 secondary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
272 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING,
274 secondary.setStateForTesting(remoting.SignalStrategy.State.FAILED, true);
278 test('primary times out; secondary succeeds; primary succeeds late',
280 ok(!onStateChange.called);
281 ok(!primary.connect.called);
282 strategy.connect('server', 'username', 'authToken');
283 ok(primary.connect.calledWith('server', 'username', 'authToken'));
285 primary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
287 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING, true);
288 this.clock.tick(strategy.PRIMARY_CONNECT_TIMEOUT_MS_);
289 ok(secondary.connect.calledWith('server', 'username', 'authToken'));
290 secondary.setStateForTesting(remoting.SignalStrategy.State.NOT_CONNECTED,
292 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTING,
294 secondary.setStateForTesting(remoting.SignalStrategy.State.HANDSHAKE, true);
295 secondary.setStateForTesting(remoting.SignalStrategy.State.CONNECTED, true);
296 strategy.sendConnectionSetupResults(logToServer);
298 primary.setStateForTesting(remoting.SignalStrategy.State.HANDSHAKE, false);
299 primary.setStateForTesting(remoting.SignalStrategy.State.CONNECTED, false);
301 logToServer.assertProgress(
302 remoting.SignalStrategy.Type.XMPP,
303 remoting.FallbackSignalStrategy.Progress.TIMED_OUT,
304 remoting.SignalStrategy.Type.WCS,
305 remoting.FallbackSignalStrategy.Progress.SUCCEEDED,
306 remoting.SignalStrategy.Type.XMPP,
307 remoting.FallbackSignalStrategy.Progress.SUCCEEDED_LATE);