diff options
author | jrw <jrw@chromium.org> | 2015-04-17 19:10:28 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-18 02:10:37 +0000 |
commit | 300af59814b6cf34dd54b9f9490313c58d5ddcb6 (patch) | |
tree | f0c456af1a4d2e4f2eed0e6c3267ae3f304675d2 /remoting | |
parent | f00854bf70866a011757ee946f13d95ece449bfe (diff) | |
download | chromium_src-300af59814b6cf34dd54b9f9490313c58d5ddcb6.zip chromium_src-300af59814b6cf34dd54b9f9490313c58d5ddcb6.tar.gz chromium_src-300af59814b6cf34dd54b9f9490313c58d5ddcb6.tar.bz2 |
Moved some host registration logic into HostListApiImpl because it will
be completely different with GCD.
BUG=471928
Review URL: https://codereview.chromium.org/1098563002
Cr-Commit-Position: refs/heads/master@{#325759}
Diffstat (limited to 'remoting')
-rw-r--r-- | remoting/remoting_webapp_files.gypi | 3 | ||||
-rw-r--r-- | remoting/webapp/crd/js/host_controller.js | 59 | ||||
-rw-r--r-- | remoting/webapp/crd/js/host_controller_unittest.js | 51 | ||||
-rw-r--r-- | remoting/webapp/crd/js/host_list_api.js | 9 | ||||
-rw-r--r-- | remoting/webapp/crd/js/host_list_api_impl.js | 35 | ||||
-rw-r--r-- | remoting/webapp/crd/js/host_list_api_impl_unittest.js | 102 | ||||
-rw-r--r-- | remoting/webapp/crd/js/mock_host_list_api.js | 18 |
7 files changed, 191 insertions, 86 deletions
diff --git a/remoting/remoting_webapp_files.gypi b/remoting/remoting_webapp_files.gypi index e327d72..5e56650 100644 --- a/remoting/remoting_webapp_files.gypi +++ b/remoting/remoting_webapp_files.gypi @@ -81,6 +81,7 @@ 'webapp/crd/js/gcd_client_with_mock_xhr_unittest.js', 'webapp/crd/js/host_controller_unittest.js', 'webapp/crd/js/host_daemon_facade_unittest.js', + 'webapp/crd/js/host_list_api_impl_unittest.js', 'webapp/crd/js/host_table_entry_unittest.js', 'webapp/crd/js/identity_unittest.js', 'webapp/crd/js/l10n_unittest.js', @@ -96,6 +97,8 @@ # Some proto files can be repurposed as simple mocks for the unittests. # Note that some defs in chrome_proto are overwritten by chrome_mocks. 'webapp/crd/js/mock_host_daemon_facade.js', + 'webapp/crd/js/mock_host_list_api.js', + 'webapp/crd/js/mock_identity.js', 'webapp/crd/js/mock_signal_strategy.js', 'webapp/js_proto/chrome_proto.js', 'webapp/js_proto/chrome_mocks.js', diff --git a/remoting/webapp/crd/js/host_controller.js b/remoting/webapp/crd/js/host_controller.js index cde869a..8df1614 100644 --- a/remoting/webapp/crd/js/host_controller.js +++ b/remoting/webapp/crd/js/host_controller.js @@ -156,7 +156,6 @@ remoting.HostController.prototype.start = function(hostPin, consent) { var hasOauthPromise = this.hasFeature(remoting.HostController.Feature.OAUTH_CLIENT); var keyPairPromise = this.hostDaemonFacade_.generateKeyPair(); - var oauthTokenPromise = remoting.identity.getToken(); var hostClientIdPromise = hasOauthPromise.then(function(hasOauth) { if (hasOauth) { return that.hostDaemonFacade_.getHostClientId(); @@ -167,57 +166,27 @@ remoting.HostController.prototype.start = function(hostPin, consent) { var newHostId = base.generateUuid(); var pinHashPromise = this.hostDaemonFacade_.getPinHash(newHostId, hostPin); - // Try to register the host. - /** @type {!Promise<!remoting.Xhr.Response>} */ - var registrationResultPromise = Promise.all([ + /** @type {boolean} */ + var hostRegistered = false; + + // Register the host and extract an optional auth code from the host + // response. The absence of an auth code is represented by an empty + // string. + /** @type {!Promise<string>} */ + var authCodePromise = Promise.all([ hostClientIdPromise, hostNamePromise, - oauthTokenPromise, keyPairPromise ]).then(function(/** Array */ a) { var hostClientId = /** @type {string} */ (a[0]); var hostName = /** @type {string} */ (a[1]); - var oauthToken = /** @type {string} */ (a[2]); - var keyPair = /** @type {remoting.KeyPair} */ (a[3]); - - var newHostDetails = { data: { - hostId: newHostId, - hostName: hostName, - publicKey: keyPair.publicKey - } }; - - return new remoting.Xhr({ - method: 'POST', - url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts', - urlParams: { - hostClientId: hostClientId - }, - jsonContent: newHostDetails, - oauthToken: oauthToken - }).start(); - }); + var keyPair = /** @type {remoting.KeyPair} */ (a[2]); - /** @type {boolean} */ - var hostRegistered = false; - - // Extract an optional auth code from the host response. The - // absence of an auth code is represented by an empty string. - /** @type {!Promise<string>} */ - var authCodePromise = registrationResultPromise.then(function(response) { - if (response.status == 200) { - hostRegistered = true; - var result = base.jsonParseSafe(response.getText()); - if (result['data']) { - return base.getStringAttr(result['data'], 'authorizationCode', ''); - } else { - return ''; - } - } else { - console.log( - 'Failed to register the host. Status: ' + response.status + - ' response: ' + response.getText()); - throw new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED); - } + return remoting.hostListApi.register( + newHostId, hostName, keyPair.publicKey, hostClientId); + }).then(function(/** string */ authCode) { + hostRegistered = true; + return authCode; }); // Get XMPP creditials. diff --git a/remoting/webapp/crd/js/host_controller_unittest.js b/remoting/webapp/crd/js/host_controller_unittest.js index bddbbf47..daa41d8 100644 --- a/remoting/webapp/crd/js/host_controller_unittest.js +++ b/remoting/webapp/crd/js/host_controller_unittest.js @@ -71,13 +71,18 @@ var unregisterHostByIdSpy; /** @type {sinon.Spy} */ var onLocalHostStartedSpy; +/** @type {remoting.MockHostListApi} */ +var mockHostListApi; + QUnit.module('host_controller', { beforeEach: function(/** QUnit.Assert */ assert) { chromeMocks.activate(['identity', 'runtime']); chromeMocks.identity.mock$setToken(FAKE_IDENTITY_TOKEN); remoting.settings = new remoting.Settings(); remoting.identity = new remoting.Identity(); - remoting.MockXhr.activate(); + mockHostListApi = new remoting.MockHostListApi; + mockHostListApi.registerResult = FAKE_AUTH_CODE; + remoting.hostListApi = mockHostListApi; base.debug.assert(remoting.oauth2 === null); remoting.oauth2 = new remoting.OAuth2(); base.debug.assert(remoting.hostList === null); @@ -167,8 +172,8 @@ QUnit.module('host_controller', { signalStrategyCreateStub.restore(); remoting.hostList = null; remoting.oauth2 = null; - remoting.MockXhr.restore(); chromeMocks.restore(); + remoting.hostListApi = null; remoting.identity = null; } }); @@ -183,35 +188,6 @@ function fakePinHashFunc(hostId, pin) { } /** - * Install an HTTP response for requests to the registry. - * @param {QUnit.Assert} assert - * @param {boolean} withAuthCode - */ -function queueRegistryResponse(assert, withAuthCode) { - var responseJson = { - data: { - authorizationCode: FAKE_AUTH_CODE - } - }; - if (!withAuthCode) { - delete responseJson.data.authorizationCode; - } - - remoting.MockXhr.setResponseFor( - 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', - function(/** remoting.MockXhr */ xhr) { - assert.deepEqual( - xhr.params.jsonContent, - { data: { - hostId: FAKE_HOST_ID, - hostName: FAKE_HOST_NAME, - publicKey: FAKE_PUBLIC_KEY - } }); - xhr.setTextResponse(200, JSON.stringify(responseJson)); - }); -} - -/** * @param {boolean} successful */ function stubSignalStrategyConnect(successful) { @@ -274,8 +250,7 @@ QUnit.test('start with getHostClientId failure', function(assert) { // Check what happens when the registry returns an HTTP when we try to // register a host. QUnit.test('start with host registration failure', function(assert) { - remoting.MockXhr.setEmptyResponseFor( - 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', 500); + mockHostListApi.registerResult = null; return controller.start(FAKE_HOST_PIN, true).then(function() { throw 'test failed'; }, function(/** remoting.Error */ e) { @@ -291,7 +266,6 @@ QUnit.test('start with host registration failure', function(assert) { QUnit.test('start with getCredentialsFromAuthCode failure', function(assert) { mockHostDaemonFacade.useEmail = null; mockHostDaemonFacade.refreshToken = null; - queueRegistryResponse(assert, true); return controller.start(FAKE_HOST_PIN, true).then(function() { throw 'test failed'; }, function(/** remoting.Error */ e) { @@ -308,7 +282,7 @@ QUnit.test('start with getCredentialsFromAuthCode failure', function(assert) { // does't return an auth code. QUnit.test('start with getRefreshToken+getPinHash failure', function(assert) { mockHostDaemonFacade.pinHashFunc = null; - queueRegistryResponse(assert, false); + mockHostListApi.registerResult = ''; return controller.start(FAKE_HOST_PIN, true).then(function() { throw 'test failed'; }, function(/** remoting.Error */ e) { @@ -321,7 +295,6 @@ QUnit.test('start with getRefreshToken+getPinHash failure', function(assert) { // Check what happens when the SignalStrategy fails to connect. QUnit.test('start with signalStrategy failure', function(assert) { - queueRegistryResponse(assert, true); stubSignalStrategyConnect(false); return controller.start(FAKE_HOST_PIN, true).then(function() { throw 'test failed'; @@ -336,7 +309,6 @@ QUnit.test('start with signalStrategy failure', function(assert) { // fails and calls its onError argument. // TODO(jrw): Should startDaemon even have an onError callback? QUnit.test('start with startDaemon failure', function(assert) { - queueRegistryResponse(assert, true); stubSignalStrategyConnect(true); mockHostDaemonFacade.startDaemonResult = null; return controller.start(FAKE_HOST_PIN, true).then(function() { @@ -353,7 +325,6 @@ QUnit.test('start with startDaemon failure', function(assert) { // Check what happens when the HostDaemonFacade's startDaemon method // calls is onDone method with a CANCELLED error code. QUnit.test('start with startDaemon cancelled', function(assert) { - queueRegistryResponse(assert, true); stubSignalStrategyConnect(true); mockHostDaemonFacade.startDaemonResult = remoting.HostController.AsyncResult.CANCELLED; @@ -370,7 +341,6 @@ QUnit.test('start with startDaemon cancelled', function(assert) { // Check what happens when the HostDaemonFacade's startDaemon method // calls is onDone method with an async error code. QUnit.test('start with startDaemon returning failure code', function(assert) { - queueRegistryResponse(assert, true); stubSignalStrategyConnect(true); mockHostDaemonFacade.startDaemonResult = remoting.HostController.AsyncResult.FAILED; @@ -389,7 +359,6 @@ QUnit.test('start with startDaemon returning failure code', function(assert) { QUnit.test('start with auth code, consent=' + consent, function(assert) { /** @const */ var fakePinHash = fakePinHashFunc(FAKE_HOST_ID, FAKE_HOST_PIN); - queueRegistryResponse(assert, true); stubSignalStrategyConnect(true); return controller.start(FAKE_HOST_PIN, consent).then(function() { assert.equal(getCredentialsFromAuthCodeSpy.callCount, 1); @@ -425,7 +394,7 @@ QUnit.test('start with startDaemon returning failure code', function(assert) { QUnit.test('start without auth code, consent=' + consent, function(assert) { /** @const */ var fakePinHash = fakePinHashFunc(FAKE_HOST_ID, FAKE_HOST_PIN); - queueRegistryResponse(assert, false); + mockHostListApi.registerResult = ''; stubSignalStrategyConnect(true); return controller.start(FAKE_HOST_PIN, consent).then(function() { assert.equal(getCredentialsFromAuthCodeSpy.callCount, 0); diff --git a/remoting/webapp/crd/js/host_list_api.js b/remoting/webapp/crd/js/host_list_api.js index 3a2524d..acdff97 100644 --- a/remoting/webapp/crd/js/host_list_api.js +++ b/remoting/webapp/crd/js/host_list_api.js @@ -17,6 +17,15 @@ remoting.HostListApi = function() { }; /** + * @param {string} newHostId + * @param {string} hostName + * @param {string} publicKey + * @param {?string} hostClientId + * @return {!Promise<string>} An OAuth2 auth code or the empty string. + */ +remoting.HostListApi.prototype.register; + +/** * Fetch the list of hosts for a user. * * @param {function(Array<remoting.Host>):void} onDone diff --git a/remoting/webapp/crd/js/host_list_api_impl.js b/remoting/webapp/crd/js/host_list_api_impl.js index 9484a02..55b4868 100644 --- a/remoting/webapp/crd/js/host_list_api_impl.js +++ b/remoting/webapp/crd/js/host_list_api_impl.js @@ -21,6 +21,41 @@ var remoting = remoting || {}; remoting.HostListApiImpl = function() { }; +/** @override */ +remoting.HostListApiImpl.prototype.register = function( + newHostId, hostName, publicKey, hostClientId) { + var newHostDetails = { data: { + hostId: newHostId, + hostName: hostName, + publicKey: publicKey + } }; + + return new remoting.Xhr({ + method: 'POST', + url: remoting.settings.DIRECTORY_API_BASE_URL + '/@me/hosts', + urlParams: { + hostClientId: hostClientId + }, + jsonContent: newHostDetails, + acceptJson: true, + useIdentity: true + }).start().then(function(response) { + if (response.status == 200) { + var result = response.getJson(); + if (result['data']) { + return base.getStringAttr(result['data'], 'authorizationCode', ''); + } else { + return ''; + } + } else { + console.log( + 'Failed to register the host. Status: ' + response.status + + ' response: ' + response.getText()); + throw new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED); + } + }); +}; + /** * Fetch the list of hosts for a user. * diff --git a/remoting/webapp/crd/js/host_list_api_impl_unittest.js b/remoting/webapp/crd/js/host_list_api_impl_unittest.js new file mode 100644 index 0000000..3fe3432 --- /dev/null +++ b/remoting/webapp/crd/js/host_list_api_impl_unittest.js @@ -0,0 +1,102 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * @fileoverview + * Unit tests for host_controller.js. + */ + +(function() { + +'use strict'; + +var FAKE_HOST_ID = '0bad0bad-0bad-0bad-0bad-0bad0bad0bad'; +var FAKE_HOST_NAME = '<FAKE_HOST_NAME>'; +var FAKE_PUBLIC_KEY = '<FAKE_PUBLIC_KEY>'; +var FAKE_HOST_CLIENT_ID = '<FAKE_HOST_CLIENT_ID>'; +var FAKE_AUTH_CODE = '<FAKE_AUTH_CODE>'; + +QUnit.module('host_list_api_impl', { + beforeEach: function(/** QUnit.Assert */ assert) { + remoting.settings = new remoting.Settings(); + remoting.MockXhr.activate(); + }, + afterEach: function(/** QUnit.Assert */ assert) { + remoting.MockXhr.restore(); + remoting.settings = null; + } +}); + +/** + * Install an HTTP response for requests to the registry. + * @param {QUnit.Assert} assert + * @param {boolean} withAuthCode + */ +function queueRegistryResponse(assert, withAuthCode) { + var responseJson = { + data: { + authorizationCode: FAKE_AUTH_CODE + } + }; + if (!withAuthCode) { + delete responseJson.data.authorizationCode; + } + + remoting.MockXhr.setResponseFor( + 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', + function(/** remoting.MockXhr */ xhr) { + assert.deepEqual( + xhr.params.jsonContent, + { data: { + hostId: FAKE_HOST_ID, + hostName: FAKE_HOST_NAME, + publicKey: FAKE_PUBLIC_KEY + } }); + xhr.setJsonResponse(200, responseJson); + }); +} + +QUnit.test('register with auth code', function(assert) { + var impl = new remoting.HostListApiImpl(); + queueRegistryResponse(assert, true); + return impl.register( + FAKE_HOST_ID, + FAKE_HOST_NAME, + FAKE_PUBLIC_KEY, + FAKE_HOST_CLIENT_ID + ). then(function(authCode) { + assert.equal(authCode, FAKE_AUTH_CODE); + }); +}); + +QUnit.test('register without auth code', function(assert) { + var impl = new remoting.HostListApiImpl(); + queueRegistryResponse(assert, false); + return impl.register( + FAKE_HOST_ID, + FAKE_HOST_NAME, + FAKE_PUBLIC_KEY, + FAKE_HOST_CLIENT_ID + ). then(function(authCode) { + assert.equal(authCode, ''); + }); +}); + +QUnit.test('register failure', function(assert) { + var impl = new remoting.HostListApiImpl(); + remoting.MockXhr.setEmptyResponseFor( + 'POST', 'DIRECTORY_API_BASE_URL/@me/hosts', 500); + return impl.register( + FAKE_HOST_ID, + FAKE_HOST_NAME, + FAKE_PUBLIC_KEY, + FAKE_HOST_CLIENT_ID + ).then(function(authCode) { + throw 'test failed'; + }, function(/** remoting.Error */ e) { + assert.equal(e.getTag(), remoting.Error.Tag.REGISTRATION_FAILED); + }); +}); + +})();
\ No newline at end of file diff --git a/remoting/webapp/crd/js/mock_host_list_api.js b/remoting/webapp/crd/js/mock_host_list_api.js index 87e5fa9..7d1516c 100644 --- a/remoting/webapp/crd/js/mock_host_list_api.js +++ b/remoting/webapp/crd/js/mock_host_list_api.js @@ -17,6 +17,13 @@ var remoting = remoting || {}; * @implements {remoting.HostListApi} */ remoting.MockHostListApi = function() { + /** + * The auth code for the |register| method to return, or null if it + * should fail. + * @type {?string} + */ + this.registerResult = null; + /** @type {Array<remoting.Host>} */ this.hosts = [ { @@ -40,6 +47,17 @@ remoting.MockHostListApi = function() { ]; }; +/** @override */ +remoting.MockHostListApi.prototype.register = function( + newHostId, hostName, publicKey, hostClientId) { + if (this.registerResult === null) { + return Promise.reject( + new remoting.Error(remoting.Error.Tag.REGISTRATION_FAILED)); + } else { + return Promise.resolve(this.registerResult); + } +}; + /** * @param {function(Array<remoting.Host>):void} onDone * @param {function(!remoting.Error):void} onError |