blob: 55ce092eafe601708162a8a0e5931bd6d36ff4b1 [file] [log] [blame]
// 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.
(function() {
'use strict';
/** @type {MockConsent} */
var consentDialog = null;
/** @type {sinon.Spy | Function} */
var promptForConsent = null;
/** @type {sinon.Spy | Function} */
var getAuthToken = null;
/** @type {remoting.Identity} */
var identity = null;
/**
* @param {QUnit.Assert} assert
* @constructor
* @implements {remoting.Identity.ConsentDialog}
*/
var MockConsent = function(assert) {
/** @type {boolean} */
this.grantConsent = true;
/** @private {QUnit.Assert} */
this.assert_ = assert;
};
MockConsent.prototype.show = function() {
// The consent dialog should only be shown if a previous call to getAuthToken
// with {interactive: false} failed, and it should occur before any call with
// {interactive: true}.
this.assert_.ok(getAuthToken.calledOnce);
this.assert_.ok(getAuthToken.calledWith(
{'interactive': false, scopes: undefined}));
getAuthToken.reset();
if (this.grantConsent) {
chromeMocks.identity.mock$setToken('token');
}
return Promise.resolve();
};
QUnit.module('Identity', {
beforeEach: function(/** QUnit.Assert*/ assert) {
chromeMocks.identity.mock$clearToken();
consentDialog = new MockConsent(assert);
promptForConsent = sinon.spy(consentDialog, 'show');
identity = new remoting.Identity(consentDialog);
getAuthToken = sinon.spy(chromeMocks.identity, 'getAuthToken');
},
afterEach: function() {
getAuthToken.restore();
}
});
QUnit.test('consent is requested only on first invocation', function(assert) {
assert.ok(!promptForConsent.called);
return identity.getToken().then(
function(/** string */ token) {
assert.ok(promptForConsent.called);
assert.ok(getAuthToken.calledOnce);
assert.ok(getAuthToken.calledWith(
{'interactive': true, 'scopes': undefined}));
// Request another token.
promptForConsent.reset();
getAuthToken.reset();
return identity.getToken();
}).then(function(/** string */ token) {
assert.ok(!promptForConsent.called);
assert.ok(getAuthToken.calledOnce);
assert.ok(getAuthToken.calledWith({
'interactive': true, 'scopes': undefined}));
assert.equal(token, 'token');
});
});
QUnit.test('requesting an explicit scope works', function(assert) {
assert.ok(!promptForConsent.called);
return identity.getToken().then(
function() {
// Request a token with an explicit scope.
promptForConsent.reset();
getAuthToken.reset();
return identity.getToken(['scope']);
}).then(function(/** string */ token) {
assert.ok(!promptForConsent.called);
assert.ok(getAuthToken.calledOnce);
assert.ok(getAuthToken.calledWith({
'interactive': true, 'scopes': ['scope']}));
assert.equal(token, 'token["scope"]');
});
});
QUnit.test('multiple concurrent outstanding requests are handled correctly',
function(assert) {
assert.ok(!promptForConsent.called);
return identity.getToken().then(
function() {
// Request a token with an explicit scope and another without.
promptForConsent.reset();
getAuthToken.reset();
var withScope = identity.getToken(['scope']);
var withoutScope = identity.getToken();
return Promise.all([withScope, withoutScope]);
}).then(function(/** Array<string> */ tokens) {
assert.ok(!promptForConsent.called);
assert.ok(getAuthToken.calledTwice);
assert.ok(getAuthToken.calledWith({
'interactive': true, 'scopes': ['scope']}));
assert.ok(getAuthToken.calledWith({
'interactive': true, 'scopes': undefined}));
assert.equal(tokens.length, 2);
assert.equal(tokens[0], 'token["scope"]');
assert.equal(tokens[1], 'token');
});
});
QUnit.test('cancellations are reported correctly', function(assert) {
consentDialog.grantConsent = false;
chromeMocks.runtime.lastError.message = 'The user did not approve access.';
return identity.getToken().then(
function(/** string */ token) {
assert.ok(false, 'expected getToken() to fail');
}).catch(function(/** remoting.Error */ error) {
assert.equal(error.getTag(), remoting.Error.Tag.CANCELLED);
});
});
QUnit.test('other errors are reported correctly', function(assert) {
consentDialog.grantConsent = false;
chromeMocks.runtime.lastError.message = '<some other error message>';
return identity.getToken().then(
function(/** string */ token) {
assert.ok(false, 'expected getToken() to fail');
}).catch(function(/** remoting.Error */ error) {
assert.equal(error.getTag(), remoting.Error.Tag.NOT_AUTHENTICATED);
});
});
}());