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

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: 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 {remoting.HostController} */
11 var controller = null;
12
13 /** @type {sinon.Mock} */
14 var hostListMock = null;
15
16 /** @type {sinon.TestStub} */
17 var generateUuidStub;
18
19 /** @type {remoting.MockHostDaemonFacade} */
20 var mockHostDaemonFacade;
21
22 /** @type {sinon.TestStub} */
23 var hostDaemonFacadeCtorStub;
24
25 var FAKE_HOST_PIN = '<FAKE_HOST_PIN>';
26 var FAKE_USER_EMAIL = '<FAKE_USER_EMAIL>';
27 var FAKE_USER_NAME = '<FAKE_USER_NAME>';
28 var FAKE_UUID = '0bad0bad-0bad-0bad-0bad-0bad0bad0bad';
29 var FAKE_DAEMON_VERSION = '1.2.3.4';
30 var FAKE_HOST_NAME = '<FAKE_HOST_NAME>';
31 var FAKE_PUBLIC_KEY = '<FAKE_PUBLIC_KEY>';
32 var FAKE_PRIVATE_KEY = '<FAKE_PRIVATE_KEY>';
33 var FAKE_AUTH_CODE = '<FAKE_AUTH_CODE>';
34 var FAKE_REFRESH_TOKEN = '<FAKE_REFRESH_TOKEN>';
35 var FAKE_PIN_HASH = '<FAKE_PIN_HASH>';
36
37 /** @type {sinon.Spy|Function} */
38 var getCredentialsFromAuthCodeSpy;
39
40 /** @type {sinon.Spy|Function} */
41 var getPinHashSpy;
42
43 /** @type {sinon.Spy|Function} */
44 var startDaemonSpy;
45
46 /** @type {sinon.Spy} */
47 var unregisterHostByIdSpy;
48
49 /** @type {sinon.Spy} */
50 var onLocalHostStartedSpy;
51
52 QUnit.module('host_controller', {
53 beforeEach: function(/** QUnit.Assert */ assert) {
54 chromeMocks.activate(['identity', 'runtime']);
55 chromeMocks.identity.mock$setToken('my_token');
56 remoting.identity = new remoting.Identity();
57 remoting.MockXhr.activate();
58 base.debug.assert(remoting.oauth2 === null);
59 remoting.oauth2 = new remoting.OAuth2();
60 base.debug.assert(remoting.hostList === null);
61 remoting.hostList = /** @type {remoting.HostList} */
62 (Object.create(remoting.HostList.prototype));
63
64 // When the HostList's unregisterHostById method is called, make
65 // sure the argument is correct.
66 unregisterHostByIdSpy =
67 sinon.stub(remoting.hostList, 'unregisterHostById', function(
68 /** string */ hostId) {
69 assert.equal(hostId, FAKE_UUID);
70 });
71
72 // When the HostList's onLocalHostStarted method is called, make
73 // sure the arguments are correct.
74 onLocalHostStartedSpy =
75 sinon.stub(
76 remoting.hostList, 'onLocalHostStarted', function(
77 /** string */ hostName,
78 /** string */ newHostId,
79 /** string */ publicKey) {
80 assert.equal(hostName, FAKE_HOST_NAME);
81 assert.equal(newHostId, FAKE_UUID);
82 assert.equal(publicKey, FAKE_PUBLIC_KEY);
83 });
84
85 hostDaemonFacadeCtorStub = sinon.stub(remoting, 'HostDaemonFacade');
86 mockHostDaemonFacade = new remoting.MockHostDaemonFacade();
87 hostDaemonFacadeCtorStub.returns(mockHostDaemonFacade);
88 generateUuidStub = sinon.stub(base, 'generateUuid');
89 generateUuidStub.returns(FAKE_UUID);
90 getCredentialsFromAuthCodeSpy = sinon.spy(
91 mockHostDaemonFacade, 'getCredentialsFromAuthCode');
92 getPinHashSpy = sinon.spy(mockHostDaemonFacade, 'getPinHash');
93 startDaemonSpy = sinon.spy(mockHostDaemonFacade, 'startDaemon');
94 },
95 afterEach: function() {
Jamie 2015/04/07 01:13:12 Blank line before afterEach for readability.
John Williams 2015/04/07 20:10:26 Done.
96 controller = null;
97 getCredentialsFromAuthCodeSpy.restore();
98 generateUuidStub.restore();
99 hostDaemonFacadeCtorStub.restore();
100 remoting.hostList = null;
101 remoting.oauth2 = null;
102 remoting.MockXhr.restore();
103 chromeMocks.restore();
104 remoting.identity = null;
105 }
106 });
107
108 // Check that hasFeature returns false by default.
109 QUnit.test('hasFeature returns false', function(assert) {
110 controller = new remoting.HostController();
Jamie 2015/04/07 01:13:12 Can this be moved into beforeEach (for symmetry wi
John Williams 2015/04/07 20:10:25 Made local.
111 return new Promise(function(resolve, reject) {
112 controller.hasFeature(
113 remoting.HostController.Feature.PAIRING_REGISTRY,
114 resolve);
115 }).then(function(/** boolean */ result) {
116 assert.equal(result, false);
117 });
118 });
119
120 // Check what happens when the HostDaemonFacade's getHostName method
121 // fails.
122 QUnit.test('start with getHostName failure', function(assert) {
123 controller = new remoting.HostController();
124 return new Promise(function(resolve, reject) {
125 controller.start(FAKE_HOST_PIN, true, function() {
126 reject(null);
127 }, function(/** remoting.Error */ e) {
128 assert.equal(e.getDetail(), 'getHostName');
129 resolve(null);
130 });
131 });
132 });
133
134 // Prepare the to execute HostController.start up to the point where
Jamie 2015/04/07 01:13:12 Prepare the what? (here and below)
John Williams 2015/04/07 20:10:25 The word "the" wasn't supposed to be there.
135 // the hostname is retreived.
136 function initThroughHostName() {
Jamie 2015/04/07 01:13:12 Using "through" to mean "until" is idiomatic to US
John Williams 2015/04/07 20:10:26 News to me. I'll keep that in mind.
137 mockHostDaemonFacade.daemonVersion = FAKE_DAEMON_VERSION;
138 mockHostDaemonFacade.hostName = FAKE_HOST_NAME;
139 };
140
141 // Check what happens when the HostDaemonFacade's generateKeyPair
142 // method fails.
143 QUnit.test('start with generateKeyPair failure', function(assert) {
144 initThroughHostName();
145 controller = new remoting.HostController();
146 return new Promise(function(resolve, reject) {
147 controller.start(FAKE_HOST_PIN, true, function() {
148 reject(null);
149 }, function(/** remoting.Error */ e) {
150 assert.equal(e.getDetail(), 'generateKeyPair');
Jamie 2015/04/07 01:13:12 Check the tag as well?
John Williams 2015/04/07 20:10:26 Seems redundant since it's always UNEXPECTED and t
Jamie 2015/04/08 00:16:14 It's only UNEXPECTED if the code is bug-free :) If
John Williams 2015/04/08 20:20:09 Done.
151 resolve(null);
152 });
153 });
154 });
155
156 // Prepare the to execute HostController.start up to the point where
157 // a key pair is generated.
158 function initThroughPublicPrivateKey() {
159 initThroughHostName();
160 mockHostDaemonFacade.privateKey = FAKE_PRIVATE_KEY;
161 mockHostDaemonFacade.publicKey = FAKE_PUBLIC_KEY;
162 }
163
164 // Check what happens when the HostDaemonFacade's getHostClientId
165 // method fails.
166 QUnit.test('start with getHostClientId failure', function(assert) {
167 initThroughPublicPrivateKey();
168 mockHostDaemonFacade.features = [
169 remoting.HostController.Feature.OAUTH_CLIENT
Jamie 2015/04/07 01:13:12 Is there a reason why you don't want this Feature
John Williams 2015/04/07 20:10:25 Minimalism again. I want the tests to demonstrate
170 ];
171 controller = new remoting.HostController();
172 return new Promise(function(resolve, reject) {
173 controller.start(FAKE_HOST_PIN, true, function() {
174 reject(null);
175 }, function(/** remoting.Error */ e) {
176 assert.equal(e.getDetail(), 'getHostClientId');
177 resolve(null);
178 });
179 });
180 });
181
182 // Check what happens when the registry returns an HTTP when we try to
183 // register a host.
184 QUnit.test('start with host registration failure', function(assert) {
185 initThroughPublicPrivateKey();
186 controller = new remoting.HostController();
187 remoting.MockXhr.setEmptyResponseFor(
188 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', 500);
189 return new Promise(function(resolve, reject) {
190 controller.start(FAKE_HOST_PIN, true, function() {
191 reject(null);
192 }, function(/** remoting.Error */ e) {
193 assert.equal(e.getTag(), remoting.Error.Tag.REGISTRATION_FAILED);
194 resolve(null);
195 });
196 });
197 });
198
199 // Check what happens when the HostDaemonFacade's
200 // getCredentialsFromAuthCode method fails.
201 QUnit.test('start with getCredentialsFromAuthCode failure', function(assert) {
202 initThroughPublicPrivateKey();
203 remoting.MockXhr.setTextResponseFor(
204 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', JSON.stringify({
205 data: {
206 authorizationCode: FAKE_AUTH_CODE
207 }
208 }));
209 controller = new remoting.HostController();
210 return new Promise(function(resolve, reject) {
211 controller.start(FAKE_HOST_PIN, true, function() {
212 reject(null);
213 }, function(/** remoting.Error */ e) {
214 assert.equal(e.getDetail(), 'getCredentialsFromAuthCode');
215 resolve(null);
216 });
217 });
218 });
219
220 // Prepare the to execute HostController.start up to the point where
221 // a refresh token is generated.
222 function initThroughRefreshToken() {
223 initThroughPublicPrivateKey();
224 sinon.stub(remoting.identity, 'getEmail').returns(
225 Promise.resolve(FAKE_USER_EMAIL));
226 sinon.stub(remoting.oauth2, 'getRefreshToken').returns(
227 FAKE_REFRESH_TOKEN);
228 mockHostDaemonFacade.userEmail = FAKE_USER_EMAIL;
229 mockHostDaemonFacade.refreshToken = FAKE_REFRESH_TOKEN;
230 }
231
232 // Check what happens when the HostDaemonFacade's getPinHash method
233 // fails, and verify that getPinHash is called when the registry
234 // does't return an auth code.
235 QUnit.test('start with getRefreshToken+getPinHash failure', function(assert) {
236 initThroughRefreshToken();
237 remoting.MockXhr.setTextResponseFor(
238 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', '{}');
239 controller = new remoting.HostController();
240 return new Promise(function(resolve, reject) {
241 controller.start(FAKE_HOST_PIN, true, function() {
242 reject(null);
243 }, function(/** remoting.Error */ e) {
244 assert.equal(unregisterHostByIdSpy.callCount, 0);
245 assert.equal(e.getDetail(), 'getPinHash');
246 resolve(null);
247 });
248 });
249 });
250
251 // Check what happens when the HostController's getClientBaseJid_
252 // method fails.
253 QUnit.test('start with getClientBaseJid_ failure', function(assert) {
254 initThroughRefreshToken();
255 remoting.MockXhr.setTextResponseFor(
256 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', JSON.stringify({
257 data: {
258 authorizationCode: FAKE_AUTH_CODE
259 }
260 }));
261 controller = new remoting.HostController();
262 sinon.stub(controller, 'getClientBaseJid_').
263 callsArgWith(1, remoting.Error.unexpected('getClientBaseJid_'));
264 return new Promise(function(resolve, reject) {
265 controller.start(FAKE_HOST_PIN, true, function() {
266 reject(null);
267 }, function(/** remoting.Error */ e) {
268 assert.equal(unregisterHostByIdSpy.callCount, 1);
269 assert.equal(e.getDetail(), 'getClientBaseJid_');
270 resolve(null);
271 });
272 });
273 });
274
275 // Prepare the to execute HostController.start up to the point where a
276 // PIN hash is generated. This function also installs a check to
277 // ensure that the registry is updated correctly.
278 function initThroughPinHash(/** QUnit.Assert */ assert) {
279 initThroughRefreshToken();
280 remoting.MockXhr.setResponseFor(
281 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts',
282 function(/** remoting.MockXhr */ xhr) {
283 assert.deepEqual(
284 xhr.params.jsonContent,
285 { data: {
286 hostId: FAKE_UUID,
287 hostName: FAKE_HOST_NAME,
288 publicKey: FAKE_PUBLIC_KEY
289 } });
290 xhr.setTextResponse(200, JSON.stringify({
291 data: {
292 authorizationCode: FAKE_AUTH_CODE
293 }
294 }));
295 });
296 mockHostDaemonFacade.pinHash = FAKE_PIN_HASH;
297 };
298
299 // Check what happens when the HostDaemonFacade's startDaemon method
300 // fails and calls its onError argument.
301 QUnit.test('start with startDaemon failure', function(assert) {
302 initThroughPinHash(assert);
303 controller = new remoting.HostController();
304 sinon.stub(controller, 'getClientBaseJid_').callsArgWith(0, FAKE_USER_EMAIL);
305 return new Promise(function(resolve, reject) {
306 controller.start(FAKE_HOST_PIN, true, function() {
307 reject(null);
308 }, function(/** remoting.Error */ e) {
309 assert.equal(unregisterHostByIdSpy.callCount, 1);
310 assert.equal(e.getDetail(), 'startDaemon');
311 resolve(null);
312 });
313 });
314 });
315
316 // Check what happens when the HostDaemonFacade's startDaemon method
317 // calls is onDone method with an async error code.
318 QUnit.test('start with startDaemon cancelled', function(assert) {
319 initThroughPinHash(assert);
320 mockHostDaemonFacade.startDaemonResult =
321 remoting.HostController.AsyncResult.CANCELLED;
322 controller = new remoting.HostController();
323 sinon.stub(controller, 'getClientBaseJid_').callsArgWith(0, FAKE_USER_EMAIL);
324 return new Promise(function(resolve, reject) {
325 controller.start(FAKE_HOST_PIN, true, function() {
326 reject(null);
327 }, function(/** remoting.Error */ e) {
328 assert.equal(unregisterHostByIdSpy.callCount, 1);
329 assert.equal(e.getTag(), remoting.Error.Tag.CANCELLED);
330 resolve(null);
331 });
332 });
333 });
334
335 // Check what happens when the entire host registration process
336 // succeeds.
337 [false, true].forEach(function(/** boolean */ consent) {
338 QUnit.test('start succeeds with consent=' + consent, function(assert) {
339 initThroughPinHash(assert);
340 mockHostDaemonFacade.startDaemonResult =
341 remoting.HostController.AsyncResult.OK;
342 controller = new remoting.HostController();
343 sinon.stub(controller, 'getClientBaseJid_').
344 callsArgWith(0, FAKE_USER_EMAIL);
345 return new Promise(function(resolve, reject) {
346 controller.start(FAKE_HOST_PIN, consent, function() {
347 assert.equal(getCredentialsFromAuthCodeSpy.callCount, 1);
348 assert.deepEqual(
349 getCredentialsFromAuthCodeSpy.args[0][0],
350 FAKE_AUTH_CODE);
351 assert.equal(getPinHashSpy.callCount, 1);
352 assert.deepEqual(
353 getPinHashSpy.args[0].slice(0, 2),
354 [FAKE_UUID, FAKE_HOST_PIN]);
355
356 assert.equal(unregisterHostByIdSpy.callCount, 0);
357 assert.equal(onLocalHostStartedSpy.callCount, 1);
358 assert.equal(startDaemonSpy.callCount, 1);
359 assert.deepEqual(
360 startDaemonSpy.args[0].slice(0, 2),
361 [{
362 xmpp_login: FAKE_USER_EMAIL,
363 oauth_refresh_token: FAKE_REFRESH_TOKEN,
364 host_id: FAKE_UUID,
365 host_name: FAKE_HOST_NAME,
366 host_secret_hash: FAKE_PIN_HASH,
367 private_key: FAKE_PRIVATE_KEY
368 }, consent]);
369 resolve(null);
370 }, reject);
371 });
372 });
373 });
374
375 // TODO(jrw): Add tests for |stop| method.
376 // TODO(jrw): Add tests for |updatePin| method.
377 // TODO(jrw): Add tests for |getLocalHostState| method.
378 // TODO(jrw): Add tests for |getLocalHostId| method.
379 // TODO(jrw): Add tests for |getPairedClients| method.
380 // TODO(jrw): Add tests for |deletePairedClient| method.
381 // TODO(jrw): Add tests for |clearPairedClients| method.
382 // TODO(jrw): Make sure getClientBaseJid_ method is tested.
383
384 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698