feat(test): Add more /force_auth functional tests.

Add for:
* Fx Desktop Sync v1
* OAuth
* OAuth web channel

Adding these tests to ensure force auth functionality does not regress with
Fennec related changes to how the brokers handle force auth.

issue #1933
issue #1934
This commit is contained in:
Shane Tomlinson 2015-09-29 20:35:55 +01:00
Родитель 16c9fd5496
Коммит 3afdc32bc7
10 изменённых файлов: 297 добавлений и 85 удалений

Просмотреть файл

@ -6,6 +6,7 @@ define([
'./functional/sign_in',
'./functional/sign_in_cached',
'./functional/sync_sign_in',
'./functional/sync_force_auth',
'./functional/sign_up',
'./functional/sign_up_coppa_input',
'./functional/complete_sign_up',

Просмотреть файл

@ -6,12 +6,12 @@ define([
'intern',
'intern!object',
'intern/chai!assert',
'require',
'intern/node_modules/dojo/node!xmlhttprequest',
'app/bower_components/fxa-js-client/fxa-client',
'tests/lib/helpers',
'tests/functional/lib/helpers'
], function (intern, registerSuite, assert, require, nodeXMLHttpRequest, FxaClient, TestHelpers, FunctionalHelpers) {
], function (intern, registerSuite, assert, nodeXMLHttpRequest, FxaClient,
TestHelpers, FunctionalHelpers) {
var config = intern.config;
var AUTH_SERVER_ROOT = config.fxaAuthRoot;
var FORCE_AUTH_URL = config.fxaContentRoot + 'force_auth';
@ -21,12 +21,8 @@ define([
var client;
function openFxa(context, email) {
return context.remote
.setFindTimeout(intern.config.pageLoadTimeout)
.get(require.toUrl(FORCE_AUTH_URL + '?email=' + email))
.findByCssSelector('#fxa-force-auth-header')
.end();
var url = FORCE_AUTH_URL + '?email=' + encodeURIComponent(email);
return FunctionalHelpers.openPage(context, url, '#fxa-force-auth-header');
}
function attemptSignIn(context) {
@ -62,7 +58,7 @@ define([
});
},
'sign in via force-auth': function () {
'sign in via force_auth': function () {
var self = this;
return openFxa(self, email)

Просмотреть файл

@ -8,11 +8,12 @@ define([
'tests/lib/restmail',
'tests/lib/helpers',
'intern/dojo/node!leadfoot/helpers/pollUntil',
'intern/node_modules/dojo/lang',
'intern/node_modules/dojo/node!url',
'intern/node_modules/dojo/node!querystring',
'intern/chai!assert'
], function (intern, require, restmail, TestHelpers, pollUntil,
Url, Querystring, assert) {
lang, Url, Querystring, assert) {
var config = intern.config;
var CONTENT_SERVER = config.fxaContentRoot;
var OAUTH_APP = config.fxaOauthApp;
@ -329,24 +330,41 @@ define([
return openFxaFromRp(context, page, urlSuffix, true);
}
function reOpenWithAdditionalQueryParams(context, additionalQueryParams, waitForSelector) {
return context.remote
.getCurrentUrl()
.then(function (url) {
var parsedUrl = Url.parse(url);
var currentQueryParams = Querystring.parse(parsedUrl.search);
var updatedQueryParams = lang.mixin({}, currentQueryParams, additionalQueryParams);
var urlToOpen = url + '?' + Querystring.stringify(updatedQueryParams);
return openPage(context, urlToOpen, waitForSelector);
});
}
function openFxaFromRp(context, page, urlSuffix, untrusted) {
var app = untrusted ? UNTRUSTED_OAUTH_APP : OAUTH_APP;
// force_auth does not have a button on 123done, instead this is
// only available programatically.
if (page === 'force_auth') {
return context.remote
.get(require.toUrl(app + 'api/force_auth' + urlSuffix))
.setFindTimeout(intern.config.pageLoadTimeout)
.findByCssSelector('#fxa-force-auth-header')
.end();
var additionalQueryParams;
if (urlSuffix) {
additionalQueryParams = Querystring.parse(urlSuffix.replace(/^\?/, ''));
}
return context.remote
.get(require.toUrl(app))
.setFindTimeout(intern.config.pageLoadTimeout)
// force_auth does not have a button on 123done, instead this is
// only available programatically. Load the force_auth page
// with only the email initially, then reload with the full passed
// in urlSuffix so things like the webChannelId are correctly passed.
if (page === 'force_auth') {
var email = additionalQueryParams.email;
var emailSearchString = '?' + Querystring.stringify({ email: email });
return openPage(context, app + 'api/force_auth' + emailSearchString, '#fxa-force-auth-header')
.then(function () {
return reOpenWithAdditionalQueryParams(context, additionalQueryParams, '#fxa-force-auth-header');
});
}
return openPage(context, app, '#splash .' + page)
.findByCssSelector('#splash .' + page)
.click()
.end()
@ -357,19 +375,10 @@ define([
.end()
.then(function () {
if (urlSuffix) {
return context.remote
.getCurrentUrl()
.then(function (url) {
url += urlSuffix;
return context.remote.get(require.toUrl(url));
});
if (additionalQueryParams) {
return reOpenWithAdditionalQueryParams(context, additionalQueryParams, '#fxa-' + page + '-header');
}
})
.findByCssSelector('#fxa-' + page + '-header')
.end();
});
}
function fillOutSignIn(context, email, password, alwaysLoad) {
@ -488,6 +497,24 @@ define([
.end();
}
function fillOutForceAuth(context, password) {
return context.remote
.setFindTimeout(intern.config.pageLoadTimeout)
.findByCssSelector('#fxa-force-auth-header')
.end()
.findByCssSelector('input[type=password]')
.click()
.type(password)
.end()
.findByCssSelector('button[type="submit"]')
.click()
.end();
}
function fillOutCompleteResetPassword(context, password, vpassword) {
return context.remote
.setFindTimeout(intern.config.pageLoadTimeout)
@ -666,6 +693,7 @@ define([
fillOutChangePassword: fillOutChangePassword,
fillOutCompleteResetPassword: fillOutCompleteResetPassword,
fillOutDeleteAccount: fillOutDeleteAccount,
fillOutForceAuth: fillOutForceAuth,
fillOutResetPassword: fillOutResetPassword,
fillOutSignIn: fillOutSignIn,
fillOutSignUp: fillOutSignUp,

Просмотреть файл

@ -0,0 +1,53 @@
/* 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/. */
/**
* Provides helpers for WebChannel tests
*/
define([
'intern/chai!assert',
'intern/node_modules/dojo/node!querystring',
'tests/functional/lib/helpers',
], function (assert, queryString, FunctionalHelpers) {
function openFxaFromRp(context, page, queryParams) {
queryParams = queryParams || {};
queryParams.webChannelId = 'test';
var searchString = '?' + queryString.stringify(queryParams);
return FunctionalHelpers.openFxaFromRp(context, page, searchString);
}
function testIsBrowserNotifiedOfLogin(context, options) {
options = options || {};
return FunctionalHelpers.testIsBrowserNotified(context, 'oauth_complete', function (data) {
assert.ok(data.redirect);
assert.ok(data.code);
assert.ok(data.state);
// None of these flows should produce encryption keys.
assert.notOk(data.keys);
assert.equal(data.closeWindow, options.shouldCloseTab);
});
}
function testIsBrowserNotifiedOfLoginWithKeys(context, options) {
options = options || {};
return FunctionalHelpers.testIsBrowserNotified(context, 'oauth_complete', function (data) {
assert.ok(data.redirect);
assert.ok(data.code);
assert.ok(data.state);
// All of these flows should produce encryption keys.
assert.ok(data.keys);
assert.equal(data.closeWindow, options.shouldCloseTab);
});
}
return {
openFxaFromRp: openFxaFromRp,
testIsBrowserNotifiedOfLogin: testIsBrowserNotifiedOfLogin,
testIsBrowserNotifiedOfLoginWithKeys: testIsBrowserNotifiedOfLoginWithKeys
};
});

Просмотреть файл

@ -11,8 +11,9 @@ define([
'app/bower_components/fxa-js-client/fxa-client',
'tests/lib/helpers',
'tests/functional/lib/helpers',
'tests/functional/lib/webchannel-helpers',
], function (intern, registerSuite, assert, require, nodeXMLHttpRequest,
FxaClient, TestHelpers, FunctionalHelpers) {
FxaClient, TestHelpers, FunctionalHelpers, WebChannelHelpers) {
var config = intern.config;
var AUTH_SERVER_ROOT = config.fxaAuthRoot;
@ -31,29 +32,11 @@ define([
* finish OAuth flows
*/
function testIsBrowserNotifiedOfLogin(context, options) {
options = options || {};
return FunctionalHelpers.testIsBrowserNotified(context, 'oauth_complete', function (data) {
assert.ok(data.redirect);
assert.ok(data.code);
assert.ok(data.state);
// None of these flows should produce encryption keys.
assert.notOk(data.keys);
assert.equal(data.closeWindow, options.shouldCloseTab);
});
}
function openFxaFromRp(context, page, additionalQueryParams) {
var queryParams = '&webChannelId=test';
for (var key in additionalQueryParams) {
queryParams += ('&' + key + '=' + additionalQueryParams[key]);
}
return FunctionalHelpers.openFxaFromRp(context, page, queryParams);
}
var testIsBrowserNotifiedOfLogin = WebChannelHelpers.testIsBrowserNotifiedOfLogin;
var openFxaFromRp = WebChannelHelpers.openFxaFromRp;
registerSuite({
name: 'oauth web channel',
name: 'oauth webchannel',
beforeEach: function () {
email = TestHelpers.createEmail();

Просмотреть файл

@ -0,0 +1,71 @@
/* 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([
'intern',
'intern!object',
'intern/node_modules/dojo/node!xmlhttprequest',
'app/bower_components/fxa-js-client/fxa-client',
'tests/lib/helpers',
'tests/functional/lib/helpers',
'tests/functional/lib/webchannel-helpers'
], function (intern, registerSuite, nodeXMLHttpRequest, FxaClient, TestHelpers,
FunctionalHelpers, WebChannelHelpers) {
var config = intern.config;
var AUTH_SERVER_ROOT = config.fxaAuthRoot;
var PASSWORD = 'password';
var email;
var client;
var testIsBrowserNotifiedOfLogin = WebChannelHelpers.testIsBrowserNotifiedOfLogin;
var openFxaFromRp = WebChannelHelpers.openFxaFromRp;
registerSuite({
name: 'oauth webchannel force_auth',
beforeEach: function () {
email = TestHelpers.createEmail();
client = new FxaClient(AUTH_SERVER_ROOT, {
xhr: nodeXMLHttpRequest.XMLHttpRequest
});
return FunctionalHelpers.clearBrowserState(this);
},
'verified': function () {
var self = this;
return client.signUp(email, PASSWORD, { preVerified: true })
.then(function () {
return openFxaFromRp(self, 'force_auth', { email: email })
.execute(FunctionalHelpers.listenForWebChannelMessage)
.then(function () {
return FunctionalHelpers.fillOutForceAuth(self, PASSWORD);
})
// the page does not transition, loop will close the screen
.findByCssSelector('#fxa-force-auth-header')
.end()
.then(testIsBrowserNotifiedOfLogin(self, { shouldCloseTab: true }));
});
},
'unverified': function () {
var self = this;
return client.signUp(email, PASSWORD, { preVerified: false})
.then(function () {
return openFxaFromRp(self, 'force_auth', { email: email })
.then(function () {
return FunctionalHelpers.fillOutForceAuth(self, PASSWORD);
})
.findByCssSelector('#fxa-confirm-header')
.end();
});
}
});
});

Просмотреть файл

@ -2,6 +2,12 @@
* 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/. */
/**
* This suite tests the WebChannel functionality for delivering encryption keys
* in the OAuth signin and signup cases. It uses a CustomEvent "WebChannelMessageToChrome"
* to finish OAuth flows
*/
define([
'intern',
'intern!object',
@ -11,9 +17,10 @@ define([
'app/bower_components/fxa-js-client/fxa-client',
'tests/lib/helpers',
'tests/functional/lib/helpers',
'tests/functional/lib/fx-desktop'
'tests/functional/lib/fx-desktop',
'tests/functional/lib/webchannel-helpers'
], function (intern, registerSuite, assert, require, nodeXMLHttpRequest,
FxaClient, TestHelpers, FunctionalHelpers, FxDesktopHelpers) {
FxaClient, TestHelpers, FunctionalHelpers, FxDesktopHelpers, WebChannelHelpers) {
var config = intern.config;
var AUTH_SERVER_ROOT = config.fxaAuthRoot;
var SYNC_URL = config.fxaContentRoot + 'signin?context=fx_desktop_v1&service=sync';
@ -29,37 +36,16 @@ define([
var listenForSyncCommands = FxDesktopHelpers.listenForFxaCommands;
var testIsBrowserNotifiedOfSyncLogin = FxDesktopHelpers.testIsBrowserNotifiedOfLogin;
var testIsBrowserNotifiedOfLogin = WebChannelHelpers.testIsBrowserNotifiedOfLoginWithKeys;
/**
* This suite tests the WebChannel functionality for delivering encryption keys
* in the OAuth signin and signup cases. It uses a CustomEvent "WebChannelMessageToChrome"
* to finish OAuth flows
*/
function testIsBrowserNotifiedOfLogin(context, options) {
options = options || {};
return FunctionalHelpers.testIsBrowserNotified(context, 'oauth_complete', function (data) {
assert.ok(data.redirect);
assert.ok(data.code);
assert.ok(data.state);
// All of these flows should produce encryption keys.
assert.ok(data.keys);
assert.equal(data.closeWindow, options.shouldCloseTab);
function openFxaFromRpAndRequestKeys(context, page) {
return WebChannelHelpers.openFxaFromRp(context, page, {
keys: true
});
}
function openFxaFromRpAndRequestKeys(context, page, additionalQueryParams) {
var queryParams = '&webChannelId=test&keys=true';
for (var key in additionalQueryParams) {
queryParams += ('&' + key + '=' + additionalQueryParams[key]);
}
return FunctionalHelpers.openFxaFromRp(context, page, queryParams);
}
registerSuite({
name: 'oauth web channel keys',
name: 'oauth webchannel keys',
beforeEach: function () {
email = TestHelpers.createEmail();

Просмотреть файл

@ -0,0 +1,93 @@
/* 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([
'intern',
'intern!object',
'intern/node_modules/dojo/node!xmlhttprequest',
'app/bower_components/fxa-js-client/fxa-client',
'tests/lib/helpers',
'tests/functional/lib/helpers',
'tests/functional/lib/fx-desktop'
], function (intern, registerSuite, nodeXMLHttpRequest, FxaClient, TestHelpers, FunctionalHelpers, FxDesktopHelpers) {
var config = intern.config;
var AUTH_SERVER_ROOT = config.fxaAuthRoot;
var FORCE_AUTH_URL = config.fxaContentRoot + 'force_auth?context=fx_desktop_v1&service=sync';
var PASSWORD = 'password';
var email;
var client;
var url;
var listenForFxaCommands = FxDesktopHelpers.listenForFxaCommands;
registerSuite({
name: 'Firefox Desktop Sync force_auth',
beforeEach: function () {
email = TestHelpers.createEmail();
url = FORCE_AUTH_URL + '&email=' + encodeURIComponent(email);
client = new FxaClient(AUTH_SERVER_ROOT, {
xhr: nodeXMLHttpRequest.XMLHttpRequest
});
return FunctionalHelpers.clearBrowserState(this);
},
'verified': function () {
var self = this;
return client.signUp(email, PASSWORD, { preVerified: true })
.then(function () {
return FunctionalHelpers.openPage(self, url, '#fxa-force-auth-header')
.execute(listenForFxaCommands)
.then(function () {
return FunctionalHelpers.fillOutForceAuth(self, PASSWORD);
})
// add a slight delay to ensure the page does not transition
.sleep(1000)
// the page does not transition.
.findByCssSelector('#fxa-force-auth-header')
.end()
.then(function () {
return FxDesktopHelpers.testIsBrowserNotifiedOfMessage(
self, 'can_link_account');
})
.then(function () {
return FxDesktopHelpers.testIsBrowserNotifiedOfMessage(
self, 'login');
});
});
},
'unverified': function () {
var self = this;
return client.signUp(email, PASSWORD, { preVerified: false})
.then(function () {
return FunctionalHelpers.openPage(self, url, '#fxa-force-auth-header')
.execute(listenForFxaCommands)
.then(function () {
return FunctionalHelpers.fillOutForceAuth(self, PASSWORD);
})
.findByCssSelector('#fxa-confirm-header')
.end()
.then(function () {
return FxDesktopHelpers.testIsBrowserNotifiedOfMessage(
self, 'can_link_account');
})
.then(function () {
return FxDesktopHelpers.testIsBrowserNotifiedOfMessage(
self, 'login');
});
});
}
});
});

Просмотреть файл

@ -8,9 +8,10 @@ define([
'./functional/oauth_sign_up_verification_redirect',
'./functional/oauth_reset_password',
'./functional/oauth_webchannel',
'./functional/oauth_webchannel_force_auth',
'./functional/oauth_webchannel_keys',
'./functional/oauth_preverified_sign_up',
'./functional/oauth_iframe',
'./functional/oauth_force_email',
'./functional/oauth_force_auth',
'./functional/oauth_permissions'
], function () {});