Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: remoting/webapp/crd/js/host_controller_unittest.js

Issue 1065733004: Added partial unit tests for host_controller.js. More to come. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hdf-unittest
Patch Set: added licenses to satisfy presubmit Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 /**
6 * @fileoverview
7 * Unit tests for host_controller.js.
8 */
9
10 (function() {
11
12 'use strict';
13
14 /** @type {remoting.HostController} */
15 var controller;
16
17 /** @type {sinon.Mock} */
18 var hostListMock = null;
19
20 /** @type {sinon.TestStub} */
21 var generateUuidStub;
22
23 /** @type {remoting.MockHostDaemonFacade} */
24 var mockHostDaemonFacade;
25
26 /** @type {sinon.TestStub} */
27 var hostDaemonFacadeCtorStub;
28
29 var FAKE_HOST_PIN = '<FAKE_HOST_PIN>';
30 var FAKE_USER_EMAIL = '<FAKE_USER_EMAIL>';
31 var FAKE_USER_NAME = '<FAKE_USER_NAME>';
32 var FAKE_UUID = '0bad0bad-0bad-0bad-0bad-0bad0bad0bad';
33 var FAKE_DAEMON_VERSION = '1.2.3.4';
34 var FAKE_HOST_NAME = '<FAKE_HOST_NAME>';
35 var FAKE_PUBLIC_KEY = '<FAKE_PUBLIC_KEY>';
36 var FAKE_PRIVATE_KEY = '<FAKE_PRIVATE_KEY>';
37 var FAKE_AUTH_CODE = '<FAKE_AUTH_CODE>';
38 var FAKE_REFRESH_TOKEN = '<FAKE_REFRESH_TOKEN>';
39 var FAKE_PIN_HASH = '<FAKE_PIN_HASH>';
40 var FAKE_HOST_CLIENT_ID = '<FAKE_HOST_CLIENT_ID>';
41 var FAKE_CLIENT_BASE_JID = '<FAKE_CLIENT_BASE_JID>';
42
43 /** @type {sinon.Spy|Function} */
44 var getCredentialsFromAuthCodeSpy;
45
46 /** @type {sinon.Spy|Function} */
47 var getPinHashSpy;
48
49 /** @type {sinon.Spy|Function} */
50 var startDaemonSpy;
51
52 /** @type {sinon.Spy} */
53 var unregisterHostByIdSpy;
54
55 /** @type {sinon.Spy} */
56 var onLocalHostStartedSpy;
57
58 QUnit.module('host_controller', {
59 beforeEach: function(/** QUnit.Assert */ assert) {
60 chromeMocks.activate(['identity', 'runtime']);
61 chromeMocks.identity.mock$setToken('my_token');
62 remoting.identity = new remoting.Identity();
63 remoting.MockXhr.activate();
64 base.debug.assert(remoting.oauth2 === null);
65 remoting.oauth2 = new remoting.OAuth2();
66 base.debug.assert(remoting.hostList === null);
67 remoting.hostList = /** @type {remoting.HostList} */
68 (Object.create(remoting.HostList.prototype));
69
70 // When the HostList's unregisterHostById method is called, make
71 // sure the argument is correct.
72 unregisterHostByIdSpy =
73 sinon.stub(remoting.hostList, 'unregisterHostById', function(
74 /** string */ hostId) {
75 assert.equal(hostId, FAKE_UUID);
76 });
77
78 // When the HostList's onLocalHostStarted method is called, make
79 // sure the arguments are correct.
80 onLocalHostStartedSpy =
81 sinon.stub(
82 remoting.hostList, 'onLocalHostStarted', function(
83 /** string */ hostName,
84 /** string */ newHostId,
85 /** string */ publicKey) {
86 assert.equal(hostName, FAKE_HOST_NAME);
87 assert.equal(newHostId, FAKE_UUID);
88 assert.equal(publicKey, FAKE_PUBLIC_KEY);
89 });
90
91 hostDaemonFacadeCtorStub = sinon.stub(remoting, 'HostDaemonFacade');
92 mockHostDaemonFacade = new remoting.MockHostDaemonFacade();
93 hostDaemonFacadeCtorStub.returns(mockHostDaemonFacade);
94 generateUuidStub = sinon.stub(base, 'generateUuid');
95 generateUuidStub.returns(FAKE_UUID);
96 getCredentialsFromAuthCodeSpy = sinon.spy(
97 mockHostDaemonFacade, 'getCredentialsFromAuthCode');
98 getPinHashSpy = sinon.spy(mockHostDaemonFacade, 'getPinHash');
99 startDaemonSpy = sinon.spy(mockHostDaemonFacade, 'startDaemon');
100
101 // Set up successful responses from mockHostDaemonFacade.
102 // Individual tests override these values to create errors.
103 mockHostDaemonFacade.features =
104 [remoting.HostController.Feature.OAUTH_CLIENT];
105 mockHostDaemonFacade.daemonVersion = FAKE_DAEMON_VERSION;
106 mockHostDaemonFacade.hostName = FAKE_HOST_NAME;
107 mockHostDaemonFacade.privateKey = FAKE_PRIVATE_KEY;
108 mockHostDaemonFacade.publicKey = FAKE_PUBLIC_KEY;
109 mockHostDaemonFacade.hostClientId = FAKE_HOST_CLIENT_ID;
110 mockHostDaemonFacade.userEmail = FAKE_USER_EMAIL;
111 mockHostDaemonFacade.refreshToken = FAKE_REFRESH_TOKEN;
112 mockHostDaemonFacade.pinHash = FAKE_PIN_HASH;
113 mockHostDaemonFacade.startDaemonResult =
114 remoting.HostController.AsyncResult.OK;
115
116 sinon.stub(remoting.identity, 'getEmail').returns(
117 Promise.resolve(FAKE_USER_EMAIL));
118 sinon.stub(remoting.oauth2, 'getRefreshToken').returns(
119 FAKE_REFRESH_TOKEN);
120
121 controller = new remoting.HostController();
122 },
123
124 afterEach: function() {
125 controller = null;
126 getCredentialsFromAuthCodeSpy.restore();
127 generateUuidStub.restore();
128 hostDaemonFacadeCtorStub.restore();
129 remoting.hostList = null;
130 remoting.oauth2 = null;
131 remoting.MockXhr.restore();
132 chromeMocks.restore();
133 remoting.identity = null;
134 }
135 });
136
137 /**
138 * Install an HTTP response for requests to the registry.
139 * @param {QUnit.Assert} assert
140 * @param {boolean} withAuthCode
141 */
142 function queueRegistryResponse(assert, withAuthCode) {
143 var responseJson = {
144 data: {
145 authorizationCode: FAKE_AUTH_CODE
146 }
147 };
148 if (!withAuthCode) {
149 delete responseJson.data.authorizationCode;
150 }
151
152 remoting.MockXhr.setResponseFor(
153 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts',
154 function(/** remoting.MockXhr */ xhr) {
155 assert.deepEqual(
156 xhr.params.jsonContent,
157 { data: {
158 hostId: FAKE_UUID,
159 hostName: FAKE_HOST_NAME,
160 publicKey: FAKE_PUBLIC_KEY
161 } });
162 xhr.setTextResponse(200, JSON.stringify(responseJson));
163 });
164 }
165
166 function mockGetClientBaseJid() {
167 sinon.stub(controller, 'getClientBaseJid_').
168 callsArgWith(0, FAKE_CLIENT_BASE_JID);
169 };
170
171 // Check that hasFeature returns false for missing features.
172 QUnit.test('hasFeature returns false', function(assert) {
173 return new Promise(function(resolve, reject) {
174 controller.hasFeature(
175 remoting.HostController.Feature.PAIRING_REGISTRY,
176 resolve);
177 }).then(function(/** boolean */ result) {
178 assert.equal(result, false);
179 });
180 });
181
182 // Check that hasFeature returns true for supported features.
183 QUnit.test('hasFeature returns true', function(assert) {
184 return new Promise(function(resolve, reject) {
185 controller.hasFeature(
186 remoting.HostController.Feature.OAUTH_CLIENT,
187 resolve);
188 }).then(function(/** boolean */ result) {
189 assert.equal(result, true);
190 });
191 });
192
193 // Check what happens when the HostDaemonFacade's getHostName method
194 // fails.
195 QUnit.test('start with getHostName failure', function(assert) {
196 mockHostDaemonFacade.hostName = null;
197 return new Promise(function(resolve, reject) {
198 controller.start(FAKE_HOST_PIN, true, function() {
199 reject('test failed');
200 }, function(/** remoting.Error */ e) {
201 assert.equal(e.getDetail(), 'getHostName');
202 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
203 assert.equal(unregisterHostByIdSpy.callCount, 0);
204 assert.equal(onLocalHostStartedSpy.callCount, 0);
205 assert.equal(startDaemonSpy.callCount, 0);
206 resolve(null);
207 });
208 });
209 });
210
211 // Check what happens when the HostDaemonFacade's generateKeyPair
212 // method fails.
213 QUnit.test('start with generateKeyPair failure', function(assert) {
214 mockHostDaemonFacade.publicKey = null;
215 mockHostDaemonFacade.privateKey = null;
216 return new Promise(function(resolve, reject) {
217 controller.start(FAKE_HOST_PIN, true, function() {
218 reject('test failed');
219 }, function(/** remoting.Error */ e) {
220 assert.equal(e.getDetail(), 'generateKeyPair');
221 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
222 assert.equal(unregisterHostByIdSpy.callCount, 0);
223 assert.equal(onLocalHostStartedSpy.callCount, 0);
224 assert.equal(startDaemonSpy.callCount, 0);
225 resolve(null);
226 });
227 });
228 });
229
230 // Check what happens when the HostDaemonFacade's getHostClientId
231 // method fails.
232 QUnit.test('start with getHostClientId failure', function(assert) {
233 mockHostDaemonFacade.hostClientId = null;
234 return new Promise(function(resolve, reject) {
235 controller.start(FAKE_HOST_PIN, true, function() {
236 reject('test failed');
237 }, function(/** remoting.Error */ e) {
238 assert.equal(e.getDetail(), 'getHostClientId');
239 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
240 assert.equal(unregisterHostByIdSpy.callCount, 0);
241 assert.equal(onLocalHostStartedSpy.callCount, 0);
242 assert.equal(startDaemonSpy.callCount, 0);
243 resolve(null);
244 });
245 });
246 });
247
248 // Check what happens when the registry returns an HTTP when we try to
249 // register a host.
250 QUnit.test('start with host registration failure', function(assert) {
251 remoting.MockXhr.setEmptyResponseFor(
252 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', 500);
253 return new Promise(function(resolve, reject) {
254 controller.start(FAKE_HOST_PIN, true, function() {
255 reject('test failed');
256 }, function(/** remoting.Error */ e) {
257 assert.equal(e.getTag(), remoting.Error.Tag.REGISTRATION_FAILED);
258 assert.equal(unregisterHostByIdSpy.callCount, 0);
259 assert.equal(onLocalHostStartedSpy.callCount, 0);
260 assert.equal(startDaemonSpy.callCount, 0);
261 resolve(null);
262 });
263 });
264 });
265
266 // Check what happens when the HostDaemonFacade's
267 // getCredentialsFromAuthCode method fails.
268 QUnit.test('start with getCredentialsFromAuthCode failure', function(assert) {
269 mockHostDaemonFacade.useEmail = null;
270 mockHostDaemonFacade.refreshToken = null;
271 queueRegistryResponse(assert, true);
272 return new Promise(function(resolve, reject) {
273 controller.start(FAKE_HOST_PIN, true, function() {
274 reject('test failed');
275 }, function(/** remoting.Error */ e) {
276 assert.equal(e.getDetail(), 'getCredentialsFromAuthCode');
277 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
278 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 1);
279 assert.equal(unregisterHostByIdSpy.callCount, 0);
280 assert.equal(onLocalHostStartedSpy.callCount, 0);
281 assert.equal(startDaemonSpy.callCount, 0);
282 resolve(null);
283 });
284 });
285 });
286
287 // Check what happens when the HostDaemonFacade's getPinHash method
288 // fails, and verify that getPinHash is called when the registry
289 // does't return an auth code.
290 QUnit.test('start with getRefreshToken+getPinHash failure', function(assert) {
291 mockHostDaemonFacade.pinHash = null;
292 queueRegistryResponse(assert, false);
293 return new Promise(function(resolve, reject) {
294 controller.start(FAKE_HOST_PIN, true, function() {
295 reject('test failed');
296 }, function(/** remoting.Error */ e) {
297 assert.equal(e.getDetail(), 'getPinHash');
298 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
299 assert.equal(unregisterHostByIdSpy.callCount, 0);
300 assert.equal(onLocalHostStartedSpy.callCount, 0);
301 assert.equal(startDaemonSpy.callCount, 0);
302 resolve(null);
303 });
304 });
305 });
306
307 // Check what happens when the HostController's getClientBaseJid_
308 // method fails.
309 QUnit.test('start with getClientBaseJid_ failure', function(assert) {
310 queueRegistryResponse(assert, true);
311 sinon.stub(controller, 'getClientBaseJid_').
312 callsArgWith(1, remoting.Error.unexpected('getClientBaseJid_'));
313 return new Promise(function(resolve, reject) {
314 controller.start(FAKE_HOST_PIN, true, function() {
315 reject('test failed');
316 }, function(/** remoting.Error */ e) {
317 assert.equal(e.getDetail(), 'getClientBaseJid_');
318 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
319 assert.equal(unregisterHostByIdSpy.callCount, 1);
320 resolve(null);
321 });
322 });
323 });
324
325 // Check what happens when the HostDaemonFacade's startDaemon method
326 // fails and calls its onError argument.
327 QUnit.test('start with startDaemon failure', function(assert) {
328 queueRegistryResponse(assert, true);
329 mockGetClientBaseJid();
330 mockHostDaemonFacade.startDaemonResult = null;
331 return new Promise(function(resolve, reject) {
332 controller.start(FAKE_HOST_PIN, true, function() {
333 reject('test failed');
334 }, function(/** remoting.Error */ e) {
335 assert.equal(e.getDetail(), 'startDaemon');
336 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
337 assert.equal(unregisterHostByIdSpy.callCount, 1);
338 assert.equal(onLocalHostStartedSpy.callCount, 0);
339 resolve(null);
340 });
341 });
342 });
343
344 // Check what happens when the HostDaemonFacade's startDaemon method
345 // calls is onDone method with a CANCELLED error code.
346 QUnit.test('start with startDaemon cancelled', function(assert) {
347 queueRegistryResponse(assert, true);
348 mockGetClientBaseJid();
349 mockHostDaemonFacade.startDaemonResult =
350 remoting.HostController.AsyncResult.CANCELLED;
351 return new Promise(function(resolve, reject) {
352 controller.start(FAKE_HOST_PIN, true, function() {
353 reject('test failed');
354 }, function(/** remoting.Error */ e) {
355 assert.equal(e.getTag(), remoting.Error.Tag.CANCELLED);
356 assert.equal(unregisterHostByIdSpy.callCount, 1);
357 assert.equal(onLocalHostStartedSpy.callCount, 0);
358 resolve(null);
359 });
360 });
361 });
362
363 // Check what happens when the HostDaemonFacade's startDaemon method
364 // calls is onDone method with an async error code.
365 QUnit.test('start with startDaemon returning failure code', function(assert) {
366 queueRegistryResponse(assert, true);
367 mockGetClientBaseJid();
368 mockHostDaemonFacade.startDaemonResult =
369 remoting.HostController.AsyncResult.FAILED;
370 return new Promise(function(resolve, reject) {
371 controller.start(FAKE_HOST_PIN, true, function() {
372 reject('test failed');
373 }, function(/** remoting.Error */ e) {
374 assert.equal(e.getTag(), remoting.Error.Tag.UNEXPECTED);
375 assert.equal(unregisterHostByIdSpy.callCount, 1);
376 assert.equal(onLocalHostStartedSpy.callCount, 0);
377 resolve(null);
378 });
379 });
380 });
381
382 // Check what happens when the entire host registration process
383 // succeeds.
384 [false, true].forEach(function(/** boolean */ consent) {
385 QUnit.test('start succeeds with consent=' + consent, function(assert) {
386 queueRegistryResponse(assert, true);
387 mockGetClientBaseJid();
388 return new Promise(function(resolve, reject) {
389 controller.start(FAKE_HOST_PIN, consent, function() {
390 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 1);
391 assert.deepEqual(
392 getCredentialsFromAuthCodeSpy.args[0][0],
393 FAKE_AUTH_CODE);
394 assert.equal(getPinHashSpy.callCount, 1);
395 assert.deepEqual(
396 getPinHashSpy.args[0].slice(0, 2),
397 [FAKE_UUID, FAKE_HOST_PIN]);
398
399 assert.equal(unregisterHostByIdSpy.callCount, 0);
400 assert.equal(onLocalHostStartedSpy.callCount, 1);
401 assert.equal(startDaemonSpy.callCount, 1);
402 assert.deepEqual(
403 startDaemonSpy.args[0].slice(0, 2),
404 [{
405 xmpp_login: FAKE_USER_EMAIL,
406 oauth_refresh_token: FAKE_REFRESH_TOKEN,
407 host_owner: FAKE_CLIENT_BASE_JID,
408 host_owner_email: FAKE_USER_EMAIL,
409 host_id: FAKE_UUID,
410 host_name: FAKE_HOST_NAME,
411 host_secret_hash: FAKE_PIN_HASH,
412 private_key: FAKE_PRIVATE_KEY
413 }, consent]);
414 resolve(null);
415 }, reject);
416 });
417 });
418 });
419
420 // TODO(jrw): Add tests for |stop| method.
421 // TODO(jrw): Add tests for |updatePin| method.
422 // TODO(jrw): Add tests for |getLocalHostState| method.
423 // TODO(jrw): Add tests for |getLocalHostId| method.
424 // TODO(jrw): Add tests for |getPairedClients| method.
425 // TODO(jrw): Add tests for |deletePairedClient| method.
426 // TODO(jrw): Add tests for |clearPairedClients| method.
427 // TODO(jrw): Make sure getClientBaseJid_ method is tested.
428
429 })();
OLDNEW
« no previous file with comments | « remoting/webapp/crd/js/host_controller.js ('k') | remoting/webapp/crd/js/mock_host_daemon_facade.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698