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

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: for review 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 /**
2 * @fileoverview
3 * Unit tests for host_controller.js.
4 */
5
6 (function() {
7
8 'use strict';
9
10 /** @type {sinon.Mock} */
11 var hostListMock = null;
12
13 /** @type {sinon.TestStub} */
14 var generateUuidStub;
15
16 /** @type {remoting.MockHostDaemonFacade} */
17 var mockHostDaemonFacade;
18
19 /** @type {sinon.TestStub} */
20 var hostDaemonFacadeCtorStub;
21
22 var FAKE_HOST_PIN = '<FAKE_HOST_PIN>';
23 var FAKE_USER_EMAIL = '<FAKE_USER_EMAIL>';
24 var FAKE_USER_NAME = '<FAKE_USER_NAME>';
25 var FAKE_UUID = '0bad0bad-0bad-0bad-0bad-0bad0bad0bad';
26 var FAKE_DAEMON_VERSION = '1.2.3.4';
27 var FAKE_HOST_NAME = '<FAKE_HOST_NAME>';
28 var FAKE_PUBLIC_KEY = '<FAKE_PUBLIC_KEY>';
29 var FAKE_PRIVATE_KEY = '<FAKE_PRIVATE_KEY>';
30 var FAKE_AUTH_CODE = '<FAKE_AUTH_CODE>';
31 var FAKE_REFRESH_TOKEN = '<FAKE_REFRESH_TOKEN>';
32 var FAKE_PIN_HASH = '<FAKE_PIN_HASH>';
33 var FAKE_HOST_CLIENT_ID = '<FAKE_HOST_CLIENT_ID>';
34 var FAKE_CLIENT_BASE_JID = '<FAKE_CLIENT_BASE_JID>';
35
36 /** @type {sinon.Spy|Function} */
37 var getCredentialsFromAuthCodeSpy;
38
39 /** @type {sinon.Spy|Function} */
40 var getPinHashSpy;
41
42 /** @type {sinon.Spy|Function} */
43 var startDaemonSpy;
44
45 /** @type {sinon.Spy} */
46 var unregisterHostByIdSpy;
47
48 /** @type {sinon.Spy} */
49 var onLocalHostStartedSpy;
50
51 QUnit.module('host_controller', {
52 beforeEach: function(/** QUnit.Assert */ assert) {
53 chromeMocks.activate(['identity', 'runtime']);
54 chromeMocks.identity.mock$setToken('my_token');
55 remoting.identity = new remoting.Identity();
56 remoting.MockXhr.activate();
57 base.debug.assert(remoting.oauth2 === null);
58 remoting.oauth2 = new remoting.OAuth2();
59 base.debug.assert(remoting.hostList === null);
60 remoting.hostList = /** @type {remoting.HostList} */
61 (Object.create(remoting.HostList.prototype));
62
63 // When the HostList's unregisterHostById method is called, make
64 // sure the argument is correct.
65 unregisterHostByIdSpy =
66 sinon.stub(remoting.hostList, 'unregisterHostById', function(
67 /** string */ hostId) {
68 assert.equal(hostId, FAKE_UUID);
69 });
70
71 // When the HostList's onLocalHostStarted method is called, make
72 // sure the arguments are correct.
73 onLocalHostStartedSpy =
74 sinon.stub(
75 remoting.hostList, 'onLocalHostStarted', function(
76 /** string */ hostName,
77 /** string */ newHostId,
78 /** string */ publicKey) {
79 assert.equal(hostName, FAKE_HOST_NAME);
80 assert.equal(newHostId, FAKE_UUID);
81 assert.equal(publicKey, FAKE_PUBLIC_KEY);
82 });
83
84 hostDaemonFacadeCtorStub = sinon.stub(remoting, 'HostDaemonFacade');
85 mockHostDaemonFacade = new remoting.MockHostDaemonFacade();
86 hostDaemonFacadeCtorStub.returns(mockHostDaemonFacade);
87 generateUuidStub = sinon.stub(base, 'generateUuid');
88 generateUuidStub.returns(FAKE_UUID);
89 getCredentialsFromAuthCodeSpy = sinon.spy(
90 mockHostDaemonFacade, 'getCredentialsFromAuthCode');
91 getPinHashSpy = sinon.spy(mockHostDaemonFacade, 'getPinHash');
92 startDaemonSpy = sinon.spy(mockHostDaemonFacade, 'startDaemon');
93
94 // Set up successful responses from mockHostDaemonFacade.
95 // Individual tests override these values to create errors.
96 mockHostDaemonFacade.features =
97 [remoting.HostController.Feature.OAUTH_CLIENT];
98 mockHostDaemonFacade.daemonVersion = FAKE_DAEMON_VERSION;
99 mockHostDaemonFacade.hostName = FAKE_HOST_NAME;
100 mockHostDaemonFacade.privateKey = FAKE_PRIVATE_KEY;
101 mockHostDaemonFacade.publicKey = FAKE_PUBLIC_KEY;
102 mockHostDaemonFacade.hostClientId = FAKE_HOST_CLIENT_ID;
103 mockHostDaemonFacade.userEmail = FAKE_USER_EMAIL;
104 mockHostDaemonFacade.refreshToken = FAKE_REFRESH_TOKEN;
105 mockHostDaemonFacade.pinHash = FAKE_PIN_HASH;
106 mockHostDaemonFacade.startDaemonResult =
107 remoting.HostController.AsyncResult.OK;
108
109 sinon.stub(remoting.identity, 'getEmail').returns(
110 Promise.resolve(FAKE_USER_EMAIL));
111 sinon.stub(remoting.oauth2, 'getRefreshToken').returns(
112 FAKE_REFRESH_TOKEN);
113 },
114
115 afterEach: function() {
116 getCredentialsFromAuthCodeSpy.restore();
117 generateUuidStub.restore();
118 hostDaemonFacadeCtorStub.restore();
119 remoting.hostList = null;
120 remoting.oauth2 = null;
121 remoting.MockXhr.restore();
122 chromeMocks.restore();
123 remoting.identity = null;
124 }
125 });
126
127 /**
128 * Install
Jamie 2015/04/08 00:16:15 The comment doesn't seem to have any relation to t
John Williams 2015/04/08 20:20:09 Must've typed errant ^K while I was thinking about
129 * @param {QUnit.Assert} assert
130 * @param {boolean} withAuthCode
131 */
132 function queueRegistryResponse(assert, withAuthCode) {
133 var responseJson = {
134 data: {
135 authorizationCode: FAKE_AUTH_CODE
136 }
137 };
138 if (!withAuthCode) {
139 delete responseJson.data.authorizationCode;
140 }
141
142 remoting.MockXhr.setResponseFor(
143 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts',
144 function(/** remoting.MockXhr */ xhr) {
145 assert.deepEqual(
146 xhr.params.jsonContent,
147 { data: {
148 hostId: FAKE_UUID,
149 hostName: FAKE_HOST_NAME,
150 publicKey: FAKE_PUBLIC_KEY
151 } });
152 xhr.setTextResponse(200, JSON.stringify(responseJson));
153 });
154 }
155
156 /**
157 * @param {remoting.HostController} controller
158 */
159 function mockGetClientBaseJid(controller) {
160 sinon.stub(controller, 'getClientBaseJid_').
161 callsArgWith(0, FAKE_CLIENT_BASE_JID);
162 };
163
164 // Check that hasFeature returns false for missing features.
165 QUnit.test('hasFeature returns false', function(assert) {
166 var controller = new remoting.HostController();
167 return new Promise(function(resolve, reject) {
168 controller.hasFeature(
169 remoting.HostController.Feature.PAIRING_REGISTRY,
170 resolve);
171 }).then(function(/** boolean */ result) {
172 assert.equal(result, false);
173 });
174 });
175
176 // Check that hasFeature returns true for supported features.
177 QUnit.test('hasFeature returns true', function(assert) {
178 var controller = new remoting.HostController();
179 return new Promise(function(resolve, reject) {
180 controller.hasFeature(
181 remoting.HostController.Feature.OAUTH_CLIENT,
182 resolve);
183 }).then(function(/** boolean */ result) {
184 assert.equal(result, true);
185 });
186 });
187
188 // Check what happens when the HostDaemonFacade's getHostName method
189 // fails.
190 QUnit.test('start with getHostName failure', function(assert) {
191 mockHostDaemonFacade.hostName = null;
192 var controller = new remoting.HostController();
Jamie 2015/04/08 00:16:14 Is the code from here on common to all tests? Can
John Williams 2015/04/08 20:20:09 Done.
Jamie 2015/04/08 22:29:29 IIRC, the controller used to be global and you opt
John Williams 2015/04/08 23:19:55 Right, I did. I misunderstood the comment, but I
Jamie 2015/04/08 23:28:42 Acknowledged.
193 return new Promise(function(resolve, reject) {
194 controller.start(FAKE_HOST_PIN, true, function() {
195 reject('test failed');
196 }, function(/** remoting.Error */ e) {
197 assert.equal(e.getDetail(), 'getHostName');
198 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0);
Jamie 2015/04/08 00:16:14 Should it be a test failure if this was called? We
John Williams 2015/04/08 20:20:09 Good point. Changed.
199 assert.equal(unregisterHostByIdSpy.callCount, 0);
200 assert.equal(onLocalHostStartedSpy.callCount, 0);
201 assert.equal(startDaemonSpy.callCount, 0);
202 resolve(null);
203 });
204 });
205 });
206
207 // Check what happens when the HostDaemonFacade's generateKeyPair
208 // method fails.
209 QUnit.test('start with generateKeyPair failure', function(assert) {
210 mockHostDaemonFacade.publicKey = null;
211 mockHostDaemonFacade.privateKey = null;
212 var controller = new remoting.HostController();
213 return new Promise(function(resolve, reject) {
214 controller.start(FAKE_HOST_PIN, true, function() {
215 reject('test failed');
216 }, function(/** remoting.Error */ e) {
217 assert.equal(e.getDetail(), 'generateKeyPair');
218 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0);
219 assert.equal(unregisterHostByIdSpy.callCount, 0);
220 assert.equal(onLocalHostStartedSpy.callCount, 0);
221 assert.equal(startDaemonSpy.callCount, 0);
222 resolve(null);
223 });
224 });
225 });
226
227 // Check what happens when the HostDaemonFacade's getHostClientId
228 // method fails.
229 QUnit.test('start with getHostClientId failure', function(assert) {
230 var controller = new remoting.HostController();
231 mockHostDaemonFacade.hostClientId = null;
232 return new Promise(function(resolve, reject) {
233 controller.start(FAKE_HOST_PIN, true, function() {
234 reject('test failed');
235 }, function(/** remoting.Error */ e) {
236 assert.equal(e.getDetail(), 'getHostClientId');
237 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0);
238 assert.equal(unregisterHostByIdSpy.callCount, 0);
239 assert.equal(onLocalHostStartedSpy.callCount, 0);
240 assert.equal(startDaemonSpy.callCount, 0);
241 resolve(null);
242 });
243 });
244 });
245
246 // Check what happens when the registry returns an HTTP when we try to
247 // register a host.
248 QUnit.test('start with host registration failure', function(assert) {
249 var controller = new remoting.HostController();
250 remoting.MockXhr.setEmptyResponseFor(
251 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', 500);
252 return new Promise(function(resolve, reject) {
253 controller.start(FAKE_HOST_PIN, true, function() {
254 reject('test failed');
255 }, function(/** remoting.Error */ e) {
256 assert.equal(e.getTag(), remoting.Error.Tag.REGISTRATION_FAILED);
257 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0);
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 var controller = new remoting.HostController();
270 mockHostDaemonFacade.useEmail = null;
271 mockHostDaemonFacade.refreshToken = null;
272 queueRegistryResponse(assert, true);
273 return new Promise(function(resolve, reject) {
274 controller.start(FAKE_HOST_PIN, true, function() {
275 reject('test failed');
276 }, function(/** remoting.Error */ e) {
277 assert.equal(e.getDetail(), 'getCredentialsFromAuthCode');
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 var controller = new remoting.HostController();
292 mockHostDaemonFacade.pinHash = null;
293 queueRegistryResponse(assert, false);
294 return new Promise(function(resolve, reject) {
295 controller.start(FAKE_HOST_PIN, true, function() {
296 reject('test failed');
297 }, function(/** remoting.Error */ e) {
298 assert.equal(e.getDetail(), 'getPinHash');
299 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0);
300 assert.equal(unregisterHostByIdSpy.callCount, 0);
301 assert.equal(onLocalHostStartedSpy.callCount, 0);
302 assert.equal(startDaemonSpy.callCount, 0);
303 resolve(null);
304 });
305 });
306 });
307
308 // Check what happens when the HostController's getClientBaseJid_
309 // method fails.
310 QUnit.test('start with getClientBaseJid_ failure', function(assert) {
311 var controller = new remoting.HostController();
312 queueRegistryResponse(assert, true);
313 sinon.stub(controller, 'getClientBaseJid_').
314 callsArgWith(1, remoting.Error.unexpected('getClientBaseJid_'));
315 return new Promise(function(resolve, reject) {
316 controller.start(FAKE_HOST_PIN, true, function() {
317 reject('test failed');
318 }, function(/** remoting.Error */ e) {
319 assert.equal(e.getDetail(), 'getClientBaseJid_');
320 assert.equal(unregisterHostByIdSpy.callCount, 1);
321 resolve(null);
322 });
323 });
324 });
325
326 // Check what happens when the HostDaemonFacade's startDaemon method
327 // fails and calls its onError argument.
328 QUnit.test('start with startDaemon failure', function(assert) {
329 var controller = new remoting.HostController();
330 queueRegistryResponse(assert, true);
331 mockGetClientBaseJid(controller);
332 mockHostDaemonFacade.startDaemonResult = null;
Jamie 2015/04/08 00:16:14 Why not FAILED/FAILED_DIRECTORY?
John Williams 2015/04/08 20:20:09 Added this as a separate case, but there are two d
Jamie 2015/04/08 22:29:29 Yuck. That sounds like something worth cleaning up
John Williams 2015/04/08 23:19:55 SGTM. When I work on legacy code I usually end up
Jamie 2015/04/08 23:28:42 Acknowledged.
333 return new Promise(function(resolve, reject) {
334 controller.start(FAKE_HOST_PIN, true, function() {
335 reject('test failed');
336 }, function(/** remoting.Error */ e) {
337 assert.equal(e.getDetail(), 'startDaemon');
338 assert.equal(unregisterHostByIdSpy.callCount, 1);
339 assert.equal(onLocalHostStartedSpy.callCount, 0);
340 resolve(null);
341 });
342 });
343 });
344
345 // Check what happens when the HostDaemonFacade's startDaemon method
346 // calls is onDone method with an async error code.
347 QUnit.test('start with startDaemon cancelled', function(assert) {
348 var controller = new remoting.HostController();
349 queueRegistryResponse(assert, true);
350 mockGetClientBaseJid(controller);
351 mockHostDaemonFacade.startDaemonResult =
352 remoting.HostController.AsyncResult.CANCELLED;
353 return new Promise(function(resolve, reject) {
354 controller.start(FAKE_HOST_PIN, true, function() {
355 reject('test failed');
356 }, function(/** remoting.Error */ e) {
357 assert.equal(e.getTag(), remoting.Error.Tag.CANCELLED);
358 assert.equal(unregisterHostByIdSpy.callCount, 1);
359 assert.equal(onLocalHostStartedSpy.callCount, 0);
360 resolve(null);
361 });
362 });
363 });
364
365 // Check what happens when the entire host registration process
366 // succeeds.
367 [false, true].forEach(function(/** boolean */ consent) {
368 QUnit.test('start succeeds with consent=' + consent, function(assert) {
369 var controller = new remoting.HostController();
370 queueRegistryResponse(assert, true);
371 mockGetClientBaseJid(controller);
372 return new Promise(function(resolve, reject) {
373 controller.start(FAKE_HOST_PIN, consent, function() {
374 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 1);
375 assert.deepEqual(
376 getCredentialsFromAuthCodeSpy.args[0][0],
377 FAKE_AUTH_CODE);
378 assert.equal(getPinHashSpy.callCount, 1);
379 assert.deepEqual(
380 getPinHashSpy.args[0].slice(0, 2),
381 [FAKE_UUID, FAKE_HOST_PIN]);
382
383 assert.equal(unregisterHostByIdSpy.callCount, 0);
384 assert.equal(onLocalHostStartedSpy.callCount, 1);
385 assert.equal(startDaemonSpy.callCount, 1);
386 assert.deepEqual(
387 startDaemonSpy.args[0].slice(0, 2),
388 [{
389 xmpp_login: FAKE_USER_EMAIL,
390 oauth_refresh_token: FAKE_REFRESH_TOKEN,
391 host_owner: FAKE_CLIENT_BASE_JID,
392 host_owner_email: FAKE_USER_EMAIL,
393 host_id: FAKE_UUID,
394 host_name: FAKE_HOST_NAME,
395 host_secret_hash: FAKE_PIN_HASH,
396 private_key: FAKE_PRIVATE_KEY
397 }, consent]);
398 resolve(null);
399 }, reject);
400 });
401 });
402 });
403
404 // TODO(jrw): Add tests for |stop| method.
405 // TODO(jrw): Add tests for |updatePin| method.
406 // TODO(jrw): Add tests for |getLocalHostState| method.
407 // TODO(jrw): Add tests for |getLocalHostId| method.
408 // TODO(jrw): Add tests for |getPairedClients| method.
409 // TODO(jrw): Add tests for |deletePairedClient| method.
410 // TODO(jrw): Add tests for |clearPairedClients| method.
411 // TODO(jrw): Make sure getClientBaseJid_ method is tested.
412
413 })();
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