Merge pull request #7037 from farhan787/issue-#7033 r=@shane-tomlinson
fix(auth_broker): fx-desktop-v1 merged into fx-ios-v1
This commit is contained in:
Коммит
e978dc4ae0
|
@ -1,96 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* V1 of the broker to communicate with Fx Desktop when signing in to Sync.
|
|
||||||
*/
|
|
||||||
|
|
||||||
define(function (require, exports, module) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const _ = require('underscore');
|
|
||||||
const FxDesktopChannel = require('../../lib/channels/fx-desktop-v1');
|
|
||||||
const FxSyncChannelAuthenticationBroker = require('../auth_brokers/fx-sync-channel');
|
|
||||||
const HaltBehavior = require('../../views/behaviors/halt');
|
|
||||||
const Url = require('../../lib/url');
|
|
||||||
|
|
||||||
var proto = FxSyncChannelAuthenticationBroker.prototype;
|
|
||||||
|
|
||||||
var FxDesktopV1AuthenticationBroker = FxSyncChannelAuthenticationBroker.extend({
|
|
||||||
type: 'fx-desktop-v1',
|
|
||||||
|
|
||||||
commands: {
|
|
||||||
CAN_LINK_ACCOUNT: 'can_link_account',
|
|
||||||
CHANGE_PASSWORD: 'change_password',
|
|
||||||
DELETE_ACCOUNT: 'delete_account',
|
|
||||||
LOADED: 'loaded',
|
|
||||||
LOGIN: 'login'
|
|
||||||
},
|
|
||||||
|
|
||||||
defaultBehaviors: _.extend({}, proto.defaultBehaviors, {
|
|
||||||
// about:accounts displays its own screen after sign in, no need
|
|
||||||
// to show anything.
|
|
||||||
afterForceAuth: new HaltBehavior(),
|
|
||||||
// about:accounts displays its own screen after password reset, no
|
|
||||||
// need to show anything.
|
|
||||||
afterResetPasswordConfirmationPoll: new HaltBehavior(),
|
|
||||||
// about:accounts displays its own screen after sign in, no need
|
|
||||||
// to show anything.
|
|
||||||
afterSignIn: new HaltBehavior(),
|
|
||||||
// about:accounts displays its own screen after sign in, no need
|
|
||||||
// to show anything.
|
|
||||||
afterSignInConfirmationPoll: new HaltBehavior(),
|
|
||||||
// about:accounts displays its own screen after sign in, no need
|
|
||||||
// to show anything.
|
|
||||||
afterSignUpConfirmationPoll: new HaltBehavior()
|
|
||||||
}),
|
|
||||||
|
|
||||||
createChannel () {
|
|
||||||
var channel = new FxDesktopChannel();
|
|
||||||
|
|
||||||
channel.initialize({
|
|
||||||
// Fx Desktop browser will send messages with an origin of the string
|
|
||||||
// `null`. These messages are trusted by the channel by default.
|
|
||||||
//
|
|
||||||
// 1) Fx on iOS and functional tests will send messages from the
|
|
||||||
// content server itself. Accept messages from the content
|
|
||||||
// server to handle these cases.
|
|
||||||
// 2) Fx 18 (& FxOS 1.*) do not support location.origin. Build the origin from location.href
|
|
||||||
origin: this.window.location.origin || Url.getOrigin(this.window.location.href),
|
|
||||||
window: this.window
|
|
||||||
});
|
|
||||||
|
|
||||||
channel.on('error', this.trigger.bind(this, 'error'));
|
|
||||||
|
|
||||||
return channel;
|
|
||||||
},
|
|
||||||
|
|
||||||
afterResetPasswordConfirmationPoll (account) {
|
|
||||||
// We wouldn't expect `customizeSync` to be set when completing
|
|
||||||
// a password reset, but the field must be present for the login
|
|
||||||
// message to be sent. false is the default value set in
|
|
||||||
// lib/fxa-client.js if the value is not present.
|
|
||||||
// See #5528
|
|
||||||
if (! account.has('customizeSync')) {
|
|
||||||
account.set('customizeSync', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only fx-desktop-v1 based integrations send a login message
|
|
||||||
// after reset password complete, assuming the user verifies
|
|
||||||
// in the same browser. fx-desktop-v1 based integrations
|
|
||||||
// do not support WebChannels, and the login message must be
|
|
||||||
// sent within about:accounts for the browser to receive it.
|
|
||||||
// Integrations that support WebChannel messages will send
|
|
||||||
// the login message from the verification tab, and for users
|
|
||||||
// of either integration that verify in a different browser,
|
|
||||||
// they will be asked to signin in this browser using the
|
|
||||||
// new password.
|
|
||||||
return this._notifyRelierOfLogin(account)
|
|
||||||
.then(() => proto.afterResetPasswordConfirmationPoll.call(this, account));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = FxDesktopV1AuthenticationBroker;
|
|
||||||
});
|
|
||||||
|
|
|
@ -11,19 +11,88 @@ define(function (require, exports, module) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const _ = require('underscore');
|
const _ = require('underscore');
|
||||||
const FxDesktopV1AuthenticationBroker = require('../auth_brokers/fx-desktop-v1');
|
const FxDesktopChannel = require('../../lib/channels/fx-desktop-v1');
|
||||||
|
const FxSyncChannelAuthenticationBroker = require('../auth_brokers/fx-sync-channel');
|
||||||
|
const HaltBehavior = require('../../views/behaviors/halt');
|
||||||
const NavigateBehavior = require('../../views/behaviors/navigate');
|
const NavigateBehavior = require('../../views/behaviors/navigate');
|
||||||
const UserAgent = require('../../lib/user-agent');
|
const UserAgent = require('../../lib/user-agent');
|
||||||
|
|
||||||
const proto = FxDesktopV1AuthenticationBroker.prototype;
|
const proto = FxSyncChannelAuthenticationBroker.prototype;
|
||||||
|
|
||||||
|
const FxiOSV1AuthenticationBroker = FxSyncChannelAuthenticationBroker.extend({
|
||||||
|
type: 'fx-ios-v1',
|
||||||
|
|
||||||
|
commands: {
|
||||||
|
CAN_LINK_ACCOUNT: 'can_link_account',
|
||||||
|
CHANGE_PASSWORD: 'change_password',
|
||||||
|
DELETE_ACCOUNT: 'delete_account',
|
||||||
|
LOADED: 'loaded',
|
||||||
|
LOGIN: 'login'
|
||||||
|
},
|
||||||
|
|
||||||
|
defaultBehaviors: _.extend({}, proto.defaultBehaviors, {
|
||||||
|
// about:accounts displays its own screen after sign in, no need
|
||||||
|
// to show anything.
|
||||||
|
afterForceAuth: new HaltBehavior(),
|
||||||
|
// about:accounts displays its own screen after password reset, no
|
||||||
|
// need to show anything.
|
||||||
|
afterResetPasswordConfirmationPoll: new HaltBehavior(),
|
||||||
|
// about:accounts displays its own screen after sign in, no need
|
||||||
|
// to show anything.
|
||||||
|
afterSignIn: new HaltBehavior(),
|
||||||
|
// about:accounts display the "Signin confirmed" screen after
|
||||||
|
// the user signin is successful
|
||||||
|
afterSignInConfirmationPoll: new NavigateBehavior('signin_confirmed'),
|
||||||
|
// about:accounts display the "Signup complete!" screen after
|
||||||
|
// the users verify their email
|
||||||
|
afterSignUpConfirmationPoll: new NavigateBehavior('signup_confirmed')
|
||||||
|
}),
|
||||||
|
|
||||||
const FxiOSV1AuthenticationBroker = FxDesktopV1AuthenticationBroker.extend({
|
|
||||||
defaultCapabilities: _.extend({}, proto.defaultCapabilities, {
|
defaultCapabilities: _.extend({}, proto.defaultCapabilities, {
|
||||||
chooseWhatToSyncCheckbox: false,
|
chooseWhatToSyncCheckbox: false,
|
||||||
chooseWhatToSyncWebV1: true,
|
chooseWhatToSyncWebV1: true,
|
||||||
convertExternalLinksToText: true
|
convertExternalLinksToText: true
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
createChannel () {
|
||||||
|
var channel = new FxDesktopChannel();
|
||||||
|
|
||||||
|
channel.initialize({
|
||||||
|
// Fx on iOS and functional tests will send messages from the
|
||||||
|
// content server itself. Accept messages from the content
|
||||||
|
// server to handle these cases.
|
||||||
|
origin: this.window.location.origin,
|
||||||
|
window: this.window
|
||||||
|
});
|
||||||
|
|
||||||
|
channel.on('error', this.trigger.bind(this, 'error'));
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
},
|
||||||
|
|
||||||
|
afterResetPasswordConfirmationPoll (account) {
|
||||||
|
// We wouldn't expect `customizeSync` to be set when completing
|
||||||
|
// a password reset, but the field must be present for the login
|
||||||
|
// message to be sent. false is the default value set in
|
||||||
|
// lib/fxa-client.js if the value is not present.
|
||||||
|
// See #5528
|
||||||
|
if (! account.has('customizeSync')) {
|
||||||
|
account.set('customizeSync', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fx-ios-v1 send a login message after reset password complete,
|
||||||
|
// assuming the user verifies in the same browser. fx-ios-v1
|
||||||
|
// do not support WebChannels, and the login message must be
|
||||||
|
// sent within about:accounts for the browser to receive it.
|
||||||
|
// Integrations that support WebChannel messages will send
|
||||||
|
// the login message from the verification tab, and for users
|
||||||
|
// of either integration that verify in a different browser,
|
||||||
|
// they will be asked to signin in this browser using the
|
||||||
|
// new password.
|
||||||
|
return this._notifyRelierOfLogin(account)
|
||||||
|
.then(() => proto.afterResetPasswordConfirmationPoll.call(this, account));
|
||||||
|
},
|
||||||
|
|
||||||
initialize (options = {}) {
|
initialize (options = {}) {
|
||||||
proto.initialize.call(this, options);
|
proto.initialize.call(this, options);
|
||||||
|
|
||||||
|
@ -36,15 +105,6 @@ define(function (require, exports, module) {
|
||||||
if (! this._supportsChooseWhatToSync(version)) {
|
if (! this._supportsChooseWhatToSync(version)) {
|
||||||
this.setCapability('chooseWhatToSyncWebV1', false);
|
this.setCapability('chooseWhatToSyncWebV1', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fx for iOS allows the user to see the "confirm your email" screen,
|
|
||||||
// but never takes it away after the user verifies. Allow the poll
|
|
||||||
// so that the user sees the "Signup complete!" screen after they
|
|
||||||
// verify their email.
|
|
||||||
this.setBehavior(
|
|
||||||
'afterSignInConfirmationPoll', new NavigateBehavior('signin_confirmed'));
|
|
||||||
this.setBehavior(
|
|
||||||
'afterSignUpConfirmationPoll', new NavigateBehavior('signup_confirmed'));
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
define(function (require, exports, module) {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const chai = require('chai');
|
|
||||||
const FxDesktopV1AuthenticationBroker = require('models/auth_brokers/fx-desktop-v1');
|
|
||||||
const NullChannel = require('lib/channels/null');
|
|
||||||
const sinon = require('sinon');
|
|
||||||
const User = require('models/user');
|
|
||||||
const WindowMock = require('../../../mocks/window');
|
|
||||||
|
|
||||||
var assert = chai.assert;
|
|
||||||
|
|
||||||
describe('models/auth_brokers/fx-desktop-v1', function () {
|
|
||||||
var account;
|
|
||||||
var broker;
|
|
||||||
var channelMock;
|
|
||||||
var user;
|
|
||||||
var windowMock;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
windowMock = new WindowMock();
|
|
||||||
channelMock = new NullChannel();
|
|
||||||
channelMock.send = sinon.spy(function () {
|
|
||||||
return Promise.resolve();
|
|
||||||
});
|
|
||||||
|
|
||||||
user = new User();
|
|
||||||
account = user.initAccount({
|
|
||||||
email: 'testuser@testuser.com',
|
|
||||||
keyFetchToken: 'key-fetch-token',
|
|
||||||
uid: 'uid',
|
|
||||||
unwrapBKey: 'unwrap-b-key'
|
|
||||||
});
|
|
||||||
|
|
||||||
broker = new FxDesktopV1AuthenticationBroker({
|
|
||||||
channel: channelMock,
|
|
||||||
window: windowMock
|
|
||||||
});
|
|
||||||
sinon.stub(broker, '_hasRequiredLoginFields').callsFake(() => true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('has the expected capabilities', () => {
|
|
||||||
assert.isTrue(broker.hasCapability('signup'));
|
|
||||||
assert.isTrue(broker.hasCapability('handleSignedInNotification'));
|
|
||||||
assert.isTrue(broker.hasCapability('emailVerificationMarketingSnippet'));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('createChannel', function () {
|
|
||||||
it('creates a channel', function () {
|
|
||||||
assert.ok(broker.createChannel());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('channel errors', function () {
|
|
||||||
it('are propagated outwards', function () {
|
|
||||||
var channel = broker.createChannel();
|
|
||||||
|
|
||||||
var errorSpy = sinon.spy();
|
|
||||||
broker.on('error', errorSpy);
|
|
||||||
|
|
||||||
var error = new Error('malformed message');
|
|
||||||
channel.trigger('error', error);
|
|
||||||
assert.isTrue(errorSpy.calledWith(error));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterLoaded', function () {
|
|
||||||
it('sends a `loaded` message', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
return broker.afterLoaded()
|
|
||||||
.then(function () {
|
|
||||||
assert.isTrue(broker.send.calledWith('loaded'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterSignIn', function () {
|
|
||||||
it('notifies the channel of login, halts by default', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
return broker.afterSignIn(account)
|
|
||||||
.then(function (result) {
|
|
||||||
assert.isTrue(broker.send.calledWith('login'));
|
|
||||||
assert.isTrue(result.halt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterSignInConfirmationPoll', () => {
|
|
||||||
it('halts by default', () => {
|
|
||||||
return broker.afterSignInConfirmationPoll(account)
|
|
||||||
.then((result) => {
|
|
||||||
assert.isTrue(result.halt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('beforeSignUpConfirmationPoll', function () {
|
|
||||||
it('notifies the channel of login', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
return broker.beforeSignUpConfirmationPoll(account)
|
|
||||||
.then((result) => {
|
|
||||||
assert.isTrue(broker.send.calledWith('login'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterSignUpConfirmationPoll', () => {
|
|
||||||
it('halts by default', () => {
|
|
||||||
return broker.afterSignUpConfirmationPoll(account)
|
|
||||||
.then((result) => {
|
|
||||||
assert.isTrue(result.halt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterResetPasswordConfirmationPoll', function () {
|
|
||||||
it('notifies the channel of login, halts by default', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
// customizeSync is required to send the `login` message, but
|
|
||||||
// it won't be set because the user hasn't visited the signup/in
|
|
||||||
// page.
|
|
||||||
account.unset('customizeSync');
|
|
||||||
|
|
||||||
return broker.afterResetPasswordConfirmationPoll(account)
|
|
||||||
.then(function (result) {
|
|
||||||
assert.isTrue(broker.send.calledWith('login'));
|
|
||||||
assert.isTrue(broker.send.calledOnce);
|
|
||||||
const loginData = broker.send.args[0][1];
|
|
||||||
assert.isFalse(loginData.customizeSync);
|
|
||||||
|
|
||||||
assert.isTrue(result.halt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterChangePassword', function () {
|
|
||||||
it('notifies the channel of change_password with the new login info', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
return broker.afterChangePassword(account)
|
|
||||||
.then(function () {
|
|
||||||
assert.isTrue(broker.send.calledWith('change_password'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('afterDeleteAccount', function () {
|
|
||||||
it('notifies the channel of delete_account', function () {
|
|
||||||
sinon.spy(broker, 'send');
|
|
||||||
|
|
||||||
account.set('uid', 'uid');
|
|
||||||
|
|
||||||
return broker.afterDeleteAccount(account)
|
|
||||||
.then(function () {
|
|
||||||
assert.isTrue(broker.send.calledWith('delete_account'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -5,23 +5,24 @@
|
||||||
define(function (require, exports, module) {
|
define(function (require, exports, module) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Account = require('models/account');
|
|
||||||
const { assert } = require('chai');
|
const { assert } = require('chai');
|
||||||
const FxiOSAuthenticationBroker = require('models/auth_brokers/fx-ios-v1');
|
const FxiOSAuthenticationBroker = require('models/auth_brokers/fx-ios-v1');
|
||||||
const FxDesktopV1AuthenticationBroker = require('models/auth_brokers/fx-desktop-v1');
|
|
||||||
const NullChannel = require('lib/channels/null');
|
const NullChannel = require('lib/channels/null');
|
||||||
const Relier = require('models/reliers/relier');
|
const Relier = require('models/reliers/relier');
|
||||||
const sinon = require('sinon');
|
const sinon = require('sinon');
|
||||||
|
const User = require('models/user');
|
||||||
const WindowMock = require('../../../mocks/window');
|
const WindowMock = require('../../../mocks/window');
|
||||||
|
|
||||||
const IMMEDIATE_UNVERIFIED_LOGIN_UA_STRING = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/6.1 Mobile/12F69 Safari/600.1.4'; //eslint-disable-line max-len
|
const IMMEDIATE_UNVERIFIED_LOGIN_UA_STRING = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/6.1 Mobile/12F69 Safari/600.1.4'; //eslint-disable-line max-len
|
||||||
const CHOOSE_WHAT_TO_SYNC_UA_STRING = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/11.0 Mobile/12F69 Safari/600.1.4'; //eslint-disable-line max-len
|
const CHOOSE_WHAT_TO_SYNC_UA_STRING = 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/11.0 Mobile/12F69 Safari/600.1.4'; //eslint-disable-line max-len
|
||||||
|
|
||||||
describe('models/auth_brokers/fx-ios-v1', () => {
|
describe('models/auth_brokers/fx-ios-v1', () => {
|
||||||
|
let account;
|
||||||
let broker;
|
let broker;
|
||||||
let channel;
|
let channel;
|
||||||
const loginMessageDelayMS = 250;
|
const loginMessageDelayMS = 250;
|
||||||
let relier;
|
let relier;
|
||||||
|
let user;
|
||||||
let windowMock;
|
let windowMock;
|
||||||
let sandbox;
|
let sandbox;
|
||||||
|
|
||||||
|
@ -33,6 +34,14 @@ define(function (require, exports, module) {
|
||||||
relier: relier,
|
relier: relier,
|
||||||
window: windowMock
|
window: windowMock
|
||||||
});
|
});
|
||||||
|
|
||||||
|
user = new User();
|
||||||
|
account = user.initAccount({
|
||||||
|
email: 'testuser@testuser.com',
|
||||||
|
keyFetchToken: 'key-fetch-token',
|
||||||
|
uid: 'uid',
|
||||||
|
unwrapBKey: 'unwrap-b-key'
|
||||||
|
});
|
||||||
sandbox.stub(broker, '_hasRequiredLoginFields').callsFake(() => true);
|
sandbox.stub(broker, '_hasRequiredLoginFields').callsFake(() => true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,15 +89,10 @@ define(function (require, exports, module) {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('_notifyRelierOfLogin', () => {
|
describe('_notifyRelierOfLogin', () => {
|
||||||
let account;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sandbox.stub(broker, 'send').callsFake(() => Promise.resolve());
|
sandbox.stub(broker, 'send').callsFake(() => Promise.resolve());
|
||||||
sandbox.spy(windowMock, 'setTimeout');
|
sandbox.spy(windowMock, 'setTimeout');
|
||||||
sandbox.spy(windowMock, 'clearTimeout');
|
sandbox.spy(windowMock, 'clearTimeout');
|
||||||
account = new Account({
|
|
||||||
uid: 'uid'
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function testLoginSent(triggerLoginCB) {
|
function testLoginSent(triggerLoginCB) {
|
||||||
|
@ -126,23 +130,137 @@ define(function (require, exports, module) {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('afterCompleteSignInWithCode', () => {
|
describe('afterCompleteSignInWithCode', () => {
|
||||||
let account;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
sandbox.spy(broker, 'afterCompleteSignInWithCode');
|
sandbox.spy(broker, 'afterCompleteSignInWithCode');
|
||||||
sandbox.spy(broker, '_notifyRelierOfLogin');
|
sandbox.spy(broker, '_notifyRelierOfLogin');
|
||||||
sandbox.spy(FxDesktopV1AuthenticationBroker.prototype, 'afterCompleteSignInWithCode');
|
sandbox.spy(FxiOSAuthenticationBroker.prototype, 'afterCompleteSignInWithCode');
|
||||||
account = new Account({
|
|
||||||
uid: 'uid'
|
|
||||||
});
|
|
||||||
return broker.afterCompleteSignInWithCode(account);
|
return broker.afterCompleteSignInWithCode(account);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('broker calls correct methods', () => {
|
it('broker calls correct methods', () => {
|
||||||
assert.isTrue(FxDesktopV1AuthenticationBroker.prototype.afterCompleteSignInWithCode.called);
|
assert.isTrue(broker.afterCompleteSignInWithCode.called);
|
||||||
assert.isTrue(broker._notifyRelierOfLogin.called);
|
assert.isTrue(broker._notifyRelierOfLogin.called);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('createChannel', () => {
|
||||||
|
it('creates a channel', () => {
|
||||||
|
assert.ok(broker.createChannel());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('channel errors', () => {
|
||||||
|
it('are propagated outwards', () => {
|
||||||
|
var channel = broker.createChannel();
|
||||||
|
|
||||||
|
var errorSpy = sinon.spy();
|
||||||
|
broker.on('error', errorSpy);
|
||||||
|
|
||||||
|
var error = new Error('malformed message');
|
||||||
|
channel.trigger('error', error);
|
||||||
|
assert.isTrue(errorSpy.calledWith(error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterLoaded', () => {
|
||||||
|
it('sends a `loaded` message', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
return broker.afterLoaded()
|
||||||
|
.then(() => {
|
||||||
|
assert.isTrue(broker.send.calledWith('loaded'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterSignIn', () => {
|
||||||
|
it('notifies the channel of login, halts by default', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
return broker.afterSignIn(account)
|
||||||
|
.then((result) => {
|
||||||
|
assert.isTrue(broker.send.calledWith('login'));
|
||||||
|
assert.isTrue(result.halt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterSignInConfirmationPoll', () => {
|
||||||
|
it('navigates to `signin_confirmed` by default', () => {
|
||||||
|
return broker.afterSignInConfirmationPoll(account)
|
||||||
|
.then(() => {
|
||||||
|
assert.equal(broker.getBehavior('afterSignInConfirmationPoll').type, 'navigate');
|
||||||
|
assert.equal(broker.getBehavior('afterSignInConfirmationPoll').endpoint, 'signin_confirmed');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('beforeSignUpConfirmationPoll', () => {
|
||||||
|
it('notifies the channel of login', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
return broker.beforeSignUpConfirmationPoll(account)
|
||||||
|
.then(() => {
|
||||||
|
assert.isTrue(broker.send.calledWith('login'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterSignUpConfirmationPoll', () => {
|
||||||
|
it('navigates to `signup_confirmed` by default', () => {
|
||||||
|
return broker.afterSignUpConfirmationPoll(account)
|
||||||
|
.then(() => {
|
||||||
|
assert.equal(broker.getBehavior('afterSignUpConfirmationPoll').type, 'navigate');
|
||||||
|
assert.equal(broker.getBehavior('afterSignUpConfirmationPoll').endpoint, 'signup_confirmed');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterResetPasswordConfirmationPoll', () => {
|
||||||
|
it('notifies the channel of login, halts by default', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
// customizeSync is required to send the `login` message, but
|
||||||
|
// it won't be set because the user hasn't visited the signup/in
|
||||||
|
// page.
|
||||||
|
account.unset('customizeSync');
|
||||||
|
|
||||||
|
return broker.afterResetPasswordConfirmationPoll(account)
|
||||||
|
.then((result) => {
|
||||||
|
assert.isTrue(broker.send.calledWith('login'));
|
||||||
|
assert.isTrue(broker.send.calledOnce);
|
||||||
|
const loginData = broker.send.args[0][1];
|
||||||
|
assert.isFalse(loginData.customizeSync);
|
||||||
|
|
||||||
|
assert.isTrue(result.halt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterChangePassword', () => {
|
||||||
|
it('notifies the channel of change_password with the new login info', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
return broker.afterChangePassword(account)
|
||||||
|
.then(() => {
|
||||||
|
assert.isTrue(broker.send.calledWith('change_password'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('afterDeleteAccount', () => {
|
||||||
|
it('notifies the channel of delete_account', () => {
|
||||||
|
sinon.spy(broker, 'send');
|
||||||
|
|
||||||
|
account.set('uid', 'uid');
|
||||||
|
|
||||||
|
return broker.afterDeleteAccount(account)
|
||||||
|
.then(() => {
|
||||||
|
assert.isTrue(broker.send.calledWith('delete_account'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -84,7 +84,6 @@ require('./spec/lib/xss');
|
||||||
require('./spec/models/account');
|
require('./spec/models/account');
|
||||||
require('./spec/models/attached-clients');
|
require('./spec/models/attached-clients');
|
||||||
require('./spec/models/auth_brokers/base');
|
require('./spec/models/auth_brokers/base');
|
||||||
require('./spec/models/auth_brokers/fx-desktop-v1');
|
|
||||||
require('./spec/models/auth_brokers/fx-desktop-v2');
|
require('./spec/models/auth_brokers/fx-desktop-v2');
|
||||||
require('./spec/models/auth_brokers/fx-desktop-v3');
|
require('./spec/models/auth_brokers/fx-desktop-v3');
|
||||||
require('./spec/models/auth_brokers/fx-fennec-v1');
|
require('./spec/models/auth_brokers/fx-fennec-v1');
|
||||||
|
|
Загрузка…
Ссылка в новой задаче