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.
7 * Unit tests for host_controller.js.
14 /** @type {remoting.HostController} */
17 /** @type {sinon.Mock} */
18 var hostListMock
= null;
20 /** @type {sinon.TestStub} */
23 /** @type {remoting.MockHostDaemonFacade} */
24 var mockHostDaemonFacade
;
26 /** @type {sinon.TestStub} */
27 var hostDaemonFacadeCtorStub
;
29 /** @type {remoting.MockSignalStrategy} */
30 var mockSignalStrategy
;
32 /** @type {sinon.TestStub} */
33 var signalStrategyCreateStub
;
35 /** @type {sinon.TestStub|Function} */
36 var signalStrategyConnectStub
;
38 var FAKE_HOST_PIN
= '<FAKE_HOST_PIN>';
39 var FAKE_PIN_HASH
= '<FAKE_PIN_HASH>';
40 var FAKE_NEW_HOST_PIN
= '<FAKE_NEW_HOST_PIN>';
41 var FAKE_USER_EMAIL
= '<FAKE_USER_EMAIL>';
42 var FAKE_XMPP_LOGIN
= '<FAKE_XMPP_LOGIN>';
43 var FAKE_USER_NAME
= '<FAKE_USER_NAME>';
44 var FAKE_HOST_ID
= '0bad0bad-0bad-0bad-0bad-0bad0bad0bad';
45 var FAKE_DAEMON_VERSION
= '1.2.3.4';
46 var FAKE_HOST_NAME
= '<FAKE_HOST_NAME>';
47 var FAKE_PUBLIC_KEY
= '<FAKE_PUBLIC_KEY>';
48 var FAKE_PRIVATE_KEY
= '<FAKE_PRIVATE_KEY>';
49 var FAKE_AUTH_CODE
= '<FAKE_AUTH_CODE>';
50 var FAKE_REFRESH_TOKEN
= '<FAKE_REFRESH_TOKEN>';
51 var FAKE_HOST_CLIENT_ID
= '<FAKE_HOST_CLIENT_ID>';
52 var FAKE_CLIENT_JID
= '<FAKE_CLIENT_JID>';
53 var FAKE_CLIENT_BASE_JID
= '<FAKE_CLIENT_BASE_JID>';
54 var FAKE_IDENTITY_TOKEN
= '<FAKE_IDENTITY_TOKEN>';
56 /** @type {sinon.Spy|Function} */
57 var getCredentialsFromAuthCodeSpy
;
59 /** @type {sinon.Spy|Function} */
62 /** @type {sinon.Spy|Function} */
65 /** @type {sinon.Spy|Function} */
66 var updateDaemonConfigSpy
;
68 /** @type {sinon.Spy|Function} */
69 var clearPairedClientsSpy
;
71 /** @type {sinon.Spy} */
72 var unregisterHostByIdSpy
;
74 /** @type {sinon.Spy} */
75 var onLocalHostStartedSpy
;
77 /** @type {remoting.MockHostListApi} */
80 QUnit
.module('host_controller', {
81 beforeEach: function(/** QUnit.Assert */ assert
) {
82 chromeMocks
.identity
.mock
$setToken(FAKE_IDENTITY_TOKEN
);
83 remoting
.settings
= new remoting
.Settings();
84 remoting
.identity
= new remoting
.Identity();
85 mockHostListApi
= new remoting
.MockHostListApi
;
86 mockHostListApi
.authCodeFromRegister
= FAKE_AUTH_CODE
;
87 mockHostListApi
.emailFromRegister
= '';
88 mockHostListApi
.hostIdFromRegister
= FAKE_HOST_ID
;
89 remoting
.HostListApi
.setInstance(mockHostListApi
);
90 console
.assert(remoting
.oauth2
=== null, '|oauth2| already exists.');
91 remoting
.oauth2
= new remoting
.OAuth2();
92 console
.assert(remoting
.hostList
=== null, '|hostList| already exists.');
93 remoting
.hostList
= /** @type {remoting.HostList} */
94 (Object
.create(remoting
.HostList
.prototype));
96 // When the HostList's unregisterHostById method is called, make
97 // sure the argument is correct.
98 unregisterHostByIdSpy
=
99 sinon
.stub(remoting
.hostList
, 'unregisterHostById', function(
100 /** string */ hostId
, /** Function */ onDone
) {
101 assert
.equal(hostId
, FAKE_HOST_ID
);
107 // When the HostList's onLocalHostStarted method is called, make
108 // sure the arguments are correct.
109 onLocalHostStartedSpy
=
111 remoting
.hostList
, 'onLocalHostStarted', function(
112 /** string */ hostName
,
113 /** string */ newHostId
,
114 /** string */ publicKey
) {
115 assert
.equal(hostName
, FAKE_HOST_NAME
);
116 assert
.equal(newHostId
, FAKE_HOST_ID
);
117 assert
.equal(publicKey
, FAKE_PUBLIC_KEY
);
120 mockSignalStrategy
= new remoting
.MockSignalStrategy(
121 FAKE_CLIENT_JID
+ '/extra_junk',
122 remoting
.SignalStrategy
.Type
.XMPP
);
123 signalStrategyCreateStub
= sinon
.stub(remoting
.SignalStrategy
, 'create');
124 signalStrategyCreateStub
.returns(mockSignalStrategy
);
126 hostDaemonFacadeCtorStub
= sinon
.stub(remoting
, 'HostDaemonFacade');
127 mockHostDaemonFacade
= new remoting
.MockHostDaemonFacade();
128 hostDaemonFacadeCtorStub
.returns(mockHostDaemonFacade
);
129 generateUuidStub
= sinon
.stub(base
, 'generateUuid');
130 generateUuidStub
.returns(FAKE_HOST_ID
);
131 getCredentialsFromAuthCodeSpy
= sinon
.spy(
132 mockHostDaemonFacade
, 'getCredentialsFromAuthCode');
133 getPinHashSpy
= sinon
.spy(mockHostDaemonFacade
, 'getPinHash');
134 startDaemonSpy
= sinon
.spy(mockHostDaemonFacade
, 'startDaemon');
135 updateDaemonConfigSpy
=
136 sinon
.spy(mockHostDaemonFacade
, 'updateDaemonConfig');
137 clearPairedClientsSpy
=
138 sinon
.spy(mockHostDaemonFacade
, 'clearPairedClients');
140 // Set up successful responses from mockHostDaemonFacade.
141 // Individual tests override these values to create errors.
142 mockHostDaemonFacade
.features
=
143 [remoting
.HostController
.Feature
.OAUTH_CLIENT
];
144 mockHostDaemonFacade
.daemonVersion
= FAKE_DAEMON_VERSION
;
145 mockHostDaemonFacade
.hostName
= FAKE_HOST_NAME
;
146 mockHostDaemonFacade
.privateKey
= FAKE_PRIVATE_KEY
;
147 mockHostDaemonFacade
.publicKey
= FAKE_PUBLIC_KEY
;
148 mockHostDaemonFacade
.hostClientId
= FAKE_HOST_CLIENT_ID
;
149 mockHostDaemonFacade
.userEmail
= FAKE_XMPP_LOGIN
;
150 mockHostDaemonFacade
.refreshToken
= FAKE_REFRESH_TOKEN
;
151 mockHostDaemonFacade
.pinHashFunc
= fakePinHashFunc
;
152 mockHostDaemonFacade
.startDaemonResult
=
153 remoting
.HostController
.AsyncResult
.OK
;
154 mockHostDaemonFacade
.stopDaemonResult
=
155 remoting
.HostController
.AsyncResult
.OK
;
156 mockHostDaemonFacade
.daemonConfig
= {
157 host_id
: FAKE_HOST_ID
,
158 xmpp_login
: FAKE_XMPP_LOGIN
160 mockHostDaemonFacade
.updateDaemonConfigResult
=
161 remoting
.HostController
.AsyncResult
.OK
;
162 mockHostDaemonFacade
.daemonState
=
163 remoting
.HostController
.State
.STARTED
;
165 sinon
.stub(remoting
.identity
, 'getEmail').returns(
166 Promise
.resolve(FAKE_USER_EMAIL
));
167 sinon
.stub(remoting
.oauth2
, 'getRefreshToken').returns(
170 controller
= new remoting
.HostController();
173 afterEach: function() {
175 getCredentialsFromAuthCodeSpy
.restore();
176 generateUuidStub
.restore();
177 hostDaemonFacadeCtorStub
.restore();
178 signalStrategyCreateStub
.restore();
179 remoting
.hostList
= null;
180 remoting
.oauth2
= null;
181 remoting
.HostListApi
.setInstance(null);
182 remoting
.identity
= null;
187 * @param {string} hostId
188 * @param {string} pin
191 function fakePinHashFunc(hostId
, pin
) {
192 return '<FAKE_PIN:' + hostId
+ ':' + pin
+ '>';
196 * @param {boolean} successful
198 function stubSignalStrategyConnect(successful
) {
199 sinon
.stub(mockSignalStrategy
, 'connect', function() {
200 Promise
.resolve().then(function() {
201 mockSignalStrategy
.setStateForTesting(
203 remoting
.SignalStrategy
.State
.CONNECTED
:
204 remoting
.SignalStrategy
.State
.FAILED
);
209 // Check what happens when the HostDaemonFacade's getHostName method
211 QUnit
.test('start with getHostName failure', function(assert
) {
212 mockHostDaemonFacade
.hostName
= null;
213 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
215 }, function(/** remoting.Error */ e
) {
216 assert
.equal(e
.getDetail(), 'getHostName');
217 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
218 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
219 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
220 assert
.equal(startDaemonSpy
.callCount
, 0);
224 // Check what happens when the HostDaemonFacade's generateKeyPair
226 QUnit
.test('start with generateKeyPair failure', function(assert
) {
227 mockHostDaemonFacade
.publicKey
= null;
228 mockHostDaemonFacade
.privateKey
= null;
229 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
231 }, function(/** remoting.Error */ e
) {
232 assert
.equal(e
.getDetail(), 'generateKeyPair');
233 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
234 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
235 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
236 assert
.equal(startDaemonSpy
.callCount
, 0);
240 // Check what happens when the HostDaemonFacade's getHostClientId
242 QUnit
.test('start with getHostClientId failure', function(assert
) {
243 mockHostDaemonFacade
.hostClientId
= null;
244 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
246 }, function(/** remoting.Error */ e
) {
247 assert
.equal(e
.getDetail(), 'getHostClientId');
248 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
249 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
250 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
251 assert
.equal(startDaemonSpy
.callCount
, 0);
255 // Check what happens when the registry returns an HTTP when we try to
257 QUnit
.test('start with host registration failure', function(assert
) {
258 mockHostListApi
.authCodeFromRegister
= null;
259 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
261 }, function(/** remoting.Error */ e
) {
262 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.REGISTRATION_FAILED
);
263 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
264 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
265 assert
.equal(startDaemonSpy
.callCount
, 0);
269 // Check what happens when the HostDaemonFacade's
270 // getCredentialsFromAuthCode method fails.
271 QUnit
.test('start with getCredentialsFromAuthCode failure', function(assert
) {
272 mockHostDaemonFacade
.useEmail
= null;
273 mockHostDaemonFacade
.refreshToken
= null;
274 return controller
.start(FAKE_HOST_PIN
, true).then(function(result
) {
276 }, function(/** remoting.Error */ e
) {
277 assert
.equal(e
.getDetail(), 'getCredentialsFromAuthCode');
278 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
279 assert
.equal(getCredentialsFromAuthCodeSpy
.callCount
, 1);
280 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
281 assert
.equal(startDaemonSpy
.callCount
, 0);
285 // Check what happens when the SignalStrategy fails to connect.
286 QUnit
.test('start with signalStrategy failure', function(assert
) {
287 stubSignalStrategyConnect(false);
288 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
290 }, function(/** remoting.Error */ e
) {
291 assert
.equal(e
.getDetail(), 'setStateForTesting');
292 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
293 assert
.equal(unregisterHostByIdSpy
.callCount
, 1);
297 // Check what happens when the HostDaemonFacade's startDaemon method
298 // fails and calls its onError argument.
299 // TODO(jrw): Should startDaemon even have an onError callback?
300 QUnit
.test('start with startDaemon failure', function(assert
) {
301 stubSignalStrategyConnect(true);
302 mockHostDaemonFacade
.startDaemonResult
= null;
303 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
305 }, function(/** remoting.Error */ e
) {
306 assert
.equal(e
.getDetail(), 'startDaemon');
307 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
308 assert
.equal(unregisterHostByIdSpy
.callCount
, 1);
309 assert
.equal(unregisterHostByIdSpy
.args
[0][0], FAKE_HOST_ID
);
310 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
314 // Check what happens when the HostDaemonFacade's startDaemon method
315 // calls is onDone method with a CANCELLED error code.
316 QUnit
.test('start with startDaemon cancelled', function(assert
) {
317 stubSignalStrategyConnect(true);
318 mockHostDaemonFacade
.startDaemonResult
=
319 remoting
.HostController
.AsyncResult
.CANCELLED
;
320 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
322 }, function(/** remoting.Error */ e
) {
323 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.CANCELLED
);
324 assert
.equal(unregisterHostByIdSpy
.callCount
, 1);
325 assert
.equal(unregisterHostByIdSpy
.args
[0][0], FAKE_HOST_ID
);
326 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
330 // Check what happens when the HostDaemonFacade's startDaemon method
331 // calls is onDone method with an async error code.
332 QUnit
.test('start with startDaemon returning failure code', function(assert
) {
333 stubSignalStrategyConnect(true);
334 mockHostDaemonFacade
.startDaemonResult
=
335 remoting
.HostController
.AsyncResult
.FAILED
;
336 return controller
.start(FAKE_HOST_PIN
, true).then(function() {
338 }, function(/** remoting.Error */ e
) {
339 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
340 assert
.equal(unregisterHostByIdSpy
.callCount
, 1);
341 assert
.equal(onLocalHostStartedSpy
.callCount
, 0);
345 // Check what happens when the entire host registration process
347 [false, true].forEach(function(/** boolean */ consent
) {
348 QUnit
.test('start with consent=' + consent
, function(assert
) {
350 var fakePinHash
= fakePinHashFunc(FAKE_HOST_ID
, FAKE_HOST_PIN
);
351 stubSignalStrategyConnect(true);
352 return controller
.start(FAKE_HOST_PIN
, consent
).then(function() {
353 assert
.equal(getCredentialsFromAuthCodeSpy
.callCount
, 1);
355 getCredentialsFromAuthCodeSpy
.args
[0][0],
357 assert
.equal(getPinHashSpy
.callCount
, 1);
359 getPinHashSpy
.args
[0].slice(0, 2),
360 [FAKE_HOST_ID
, FAKE_HOST_PIN
]);
361 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
362 assert
.equal(onLocalHostStartedSpy
.callCount
, 1);
363 assert
.equal(startDaemonSpy
.callCount
, 1);
364 var expectedConfig
= {
365 xmpp_login
: FAKE_XMPP_LOGIN
,
366 oauth_refresh_token
: FAKE_REFRESH_TOKEN
,
367 host_owner
: FAKE_CLIENT_JID
.toLowerCase(),
368 host_owner_email
: FAKE_USER_EMAIL
,
369 host_name
: FAKE_HOST_NAME
,
370 host_secret_hash
: fakePinHash
,
371 private_key
: FAKE_PRIVATE_KEY
373 expectedConfig
['host_id'] = FAKE_HOST_ID
;
375 startDaemonSpy
.args
[0].slice(0, 2),
376 [expectedConfig
, consent
]);
381 // Check what happens when stopDaemon calls onError.
382 // TODO(jrw): Should stopDaemon even have an onError callback?
383 QUnit
.test('stop with stopDaemon failure', function(assert
) {
384 mockHostDaemonFacade
.stopDaemonResult
= null;
385 return new Promise(function(resolve
, reject
) {
386 controller
.stop(function() {
387 reject('test failed');
388 }, function(/** remoting.Error */ e
) {
389 assert
.equal(e
.getDetail(), 'stopDaemon');
390 // TODO(jrw): Is it really desirable to leave the host registered?
391 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
397 // Check what happens when stopDaemon returns FAILED.
398 QUnit
.test('stop with stopDaemon cancelled', function(assert
) {
399 mockHostDaemonFacade
.stopDaemonResult
=
400 remoting
.HostController
.AsyncResult
.FAILED
;
401 return new Promise(function(resolve
, reject
) {
402 controller
.stop(function() {
403 reject('test failed');
404 }, function(/** remoting.Error */ e
) {
405 // TODO(jrw): Is it really desirable to leave the host registered?
406 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
407 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
413 // Check what happens when stopDaemon returns CANCELLED.
414 QUnit
.test('stop with stopDaemon cancelled', function(assert
) {
415 mockHostDaemonFacade
.stopDaemonResult
=
416 remoting
.HostController
.AsyncResult
.CANCELLED
;
417 return new Promise(function(resolve
, reject
) {
418 controller
.stop(function() {
419 reject('test failed');
420 }, function(/** remoting.Error */ e
) {
421 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.CANCELLED
);
422 assert
.equal(unregisterHostByIdSpy
.callCount
, 0);
428 // Check what happens when stopDaemon succeeds.
429 QUnit
.test('stop succeeds', function(assert
) {
430 sinon
.stub(controller
, 'getLocalHostId').callsArgWith(0, FAKE_HOST_ID
);
431 return new Promise(function(resolve
, reject
) {
432 controller
.stop(function() {
433 assert
.equal(unregisterHostByIdSpy
.callCount
, 1);
434 assert
.equal(unregisterHostByIdSpy
.args
[0][0], FAKE_HOST_ID
);
440 // Check what happens when the host reports an invalid config.
441 QUnit
.test('updatePin where config is invalid', function(assert
) {
442 mockHostDaemonFacade
.daemonConfig
= {};
443 return new Promise(function(resolve
, reject
) {
444 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
445 reject('test failed');
446 }, function(/** remoting.Error */ e
) {
447 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
448 assert
.equal(clearPairedClientsSpy
.callCount
, 0);
454 // Check what happens when getDaemonConfig calls onError.
455 QUnit
.test('updatePin where getDaemonConfig fails', function(assert
) {
456 mockHostDaemonFacade
.daemonConfig
= null;
457 return new Promise(function(resolve
, reject
) {
458 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
459 reject('test failed');
460 }, function(/** remoting.Error */ e
) {
461 assert
.equal(e
.getDetail(), 'getDaemonConfig');
462 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
463 assert
.equal(clearPairedClientsSpy
.callCount
, 0);
469 // Check what happens when updateDaemonConfig calls onError.
470 // TODO(jrw): Should updateDaemonConfig even have an onError callback?
471 QUnit
.test('updatePin where updateDaemonConfig calls onError', function(
473 mockHostDaemonFacade
.updateDaemonConfigResult
= null;
474 return new Promise(function(resolve
, reject
) {
475 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
476 reject('test failed');
477 }, function(/** remoting.Error */ e
) {
478 assert
.equal(e
.getDetail(), 'updateDaemonConfig');
479 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
480 assert
.equal(clearPairedClientsSpy
.callCount
, 0);
486 // Check what happens when updateDaemonConfig returns CANCELLED.
487 QUnit
.test('updatePin where updateDaemonConfig is cancelled', function(
489 mockHostDaemonFacade
.updateDaemonConfigResult
=
490 remoting
.HostController
.AsyncResult
.CANCELLED
;
491 return new Promise(function(resolve
, reject
) {
492 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
493 reject('test failed');
494 }, function(/** remoting.Error */ e
) {
495 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.CANCELLED
);
496 assert
.equal(clearPairedClientsSpy
.callCount
, 0);
502 // Check what happens when updateDaemonConfig returns FAILED.
503 QUnit
.test('updatePin where updateDaemonConfig is returns failure', function(
505 mockHostDaemonFacade
.updateDaemonConfigResult
=
506 remoting
.HostController
.AsyncResult
.FAILED
;
507 return new Promise(function(resolve
, reject
) {
508 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
509 reject('test failed');
510 }, function(/** remoting.Error */ e
) {
511 assert
.equal(e
.getTag(), remoting
.Error
.Tag
.UNEXPECTED
);
512 assert
.equal(clearPairedClientsSpy
.callCount
, 0);
518 // Check what happens when updatePin succeeds.
519 QUnit
.test('updatePin succeeds', function(assert
) {
520 mockHostDaemonFacade
.pairedClients
= [];
522 var fakePinHash
= fakePinHashFunc(FAKE_HOST_ID
, FAKE_NEW_HOST_PIN
);
523 return new Promise(function(resolve
, reject
) {
524 controller
.updatePin(FAKE_NEW_HOST_PIN
, function() {
525 assert
.equal(getPinHashSpy
.callCount
, 1);
526 assert
.equal(getPinHashSpy
.args
[0][0], FAKE_HOST_ID
);
527 assert
.equal(getPinHashSpy
.args
[0][1], FAKE_NEW_HOST_PIN
);
528 assert
.equal(updateDaemonConfigSpy
.callCount
, 1);
530 updateDaemonConfigSpy
.args
[0][0], {
531 host_secret_hash
: fakePinHash
533 assert
.equal(clearPairedClientsSpy
.callCount
, 1);
539 // Check what happens when getLocalHostState fails.
540 QUnit
.test('getLocalHostState with error', function(assert
) {
541 mockHostDaemonFacade
.daemonState
= null;
542 return new Promise(function(resolve
, reject
) {
543 controller
.getLocalHostState(function(
544 /** remoting.HostController.State */ state
) {
545 assert
.equal(state
, remoting
.HostController
.State
.UNKNOWN
);
551 // Check what happens when getLocalHostState reports no plugin.
552 QUnit
.test('getLocalHostState with no plugin', function(assert
) {
553 sinon
.stub(mockHostDaemonFacade
, 'getDaemonState').returns(
554 Promise
.reject(new remoting
.Error(remoting
.Error
.Tag
.MISSING_PLUGIN
)));
555 return new Promise(function(resolve
, reject
) {
556 controller
.getLocalHostState(function(
557 /** remoting.HostController.State */ state
) {
558 assert
.equal(state
, remoting
.HostController
.State
.NOT_INSTALLED
);
564 // Check what happens when getLocalHostState succeeds.
565 QUnit
.test('getLocalHostState succeeds', function(assert
) {
566 return new Promise(function(resolve
, reject
) {
567 controller
.getLocalHostState(function(
568 /** remoting.HostController.State */ state
) {
569 assert
.equal(state
, remoting
.HostController
.State
.STARTED
);
575 // Check what happens to getLocalHostId when getDaemonConfig
576 // returns an invalid config.
577 QUnit
.test('getLocalHostId with invalid daemon config', function(assert
) {
578 mockHostDaemonFacade
.daemonConfig
= {};
579 return new Promise(function(resolve
, reject
) {
580 controller
.getLocalHostId(function(/** ?string */ id
) {
581 assert
.strictEqual(id
, null);
587 // Check what happens to getLocalHostId when getDaemonConfig fails.
588 QUnit
.test('getLocalHostId with getDaemonConfig failure', function(assert
) {
589 mockHostDaemonFacade
.daemonConfig
= null;
590 return new Promise(function(resolve
, reject
) {
591 controller
.getLocalHostId(function(/** ?string */ id
) {
592 assert
.strictEqual(id
, null);
598 // Check what happens when getLocalHostId succeeds.
599 QUnit
.test('getLocalHostId succeeds', function(assert
) {
600 return new Promise(function(resolve
, reject
) {
601 controller
.getLocalHostId(function(/** ?string */ id
) {
602 assert
.equal(id
, FAKE_HOST_ID
);
608 // Tests omitted for hasFeature, getPairedClients, deletePairedClient,
609 // and clearPairedClients because they simply call through to