From 3afdc32bc7ff8b59e7a2ebd34c2fb5955d287d1c Mon Sep 17 00:00:00 2001 From: Shane Tomlinson Date: Tue, 29 Sep 2015 20:35:55 +0100 Subject: [PATCH] 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 --- tests/functional.js | 1 + tests/functional/force_auth.js | 14 +-- tests/functional/lib/helpers.js | 78 +++++++++++----- tests/functional/lib/webchannel-helpers.js | 53 +++++++++++ ...uth_force_email.js => oauth_force_auth.js} | 0 tests/functional/oauth_webchannel.js | 27 +----- .../functional/oauth_webchannel_force_auth.js | 71 ++++++++++++++ tests/functional/oauth_webchannel_keys.js | 42 +++------ tests/functional/sync_force_auth.js | 93 +++++++++++++++++++ tests/functional_oauth.js | 3 +- 10 files changed, 297 insertions(+), 85 deletions(-) create mode 100644 tests/functional/lib/webchannel-helpers.js rename tests/functional/{oauth_force_email.js => oauth_force_auth.js} (100%) create mode 100644 tests/functional/oauth_webchannel_force_auth.js create mode 100644 tests/functional/sync_force_auth.js diff --git a/tests/functional.js b/tests/functional.js index 19b202c26..fa0dde515 100644 --- a/tests/functional.js +++ b/tests/functional.js @@ -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', diff --git a/tests/functional/force_auth.js b/tests/functional/force_auth.js index 6b4ad6c0a..a11683fff 100644 --- a/tests/functional/force_auth.js +++ b/tests/functional/force_auth.js @@ -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) diff --git a/tests/functional/lib/helpers.js b/tests/functional/lib/helpers.js index 072e6ced8..7d6735eb6 100644 --- a/tests/functional/lib/helpers.js +++ b/tests/functional/lib/helpers.js @@ -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, diff --git a/tests/functional/lib/webchannel-helpers.js b/tests/functional/lib/webchannel-helpers.js new file mode 100644 index 000000000..23399bc8a --- /dev/null +++ b/tests/functional/lib/webchannel-helpers.js @@ -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 + }; +}); + diff --git a/tests/functional/oauth_force_email.js b/tests/functional/oauth_force_auth.js similarity index 100% rename from tests/functional/oauth_force_email.js rename to tests/functional/oauth_force_auth.js diff --git a/tests/functional/oauth_webchannel.js b/tests/functional/oauth_webchannel.js index cbe312e1a..37111edf2 100644 --- a/tests/functional/oauth_webchannel.js +++ b/tests/functional/oauth_webchannel.js @@ -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(); diff --git a/tests/functional/oauth_webchannel_force_auth.js b/tests/functional/oauth_webchannel_force_auth.js new file mode 100644 index 000000000..0a61faa46 --- /dev/null +++ b/tests/functional/oauth_webchannel_force_auth.js @@ -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(); + }); + } + }); +}); diff --git a/tests/functional/oauth_webchannel_keys.js b/tests/functional/oauth_webchannel_keys.js index 719a99fab..efec9106f 100644 --- a/tests/functional/oauth_webchannel_keys.js +++ b/tests/functional/oauth_webchannel_keys.js @@ -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(); diff --git a/tests/functional/sync_force_auth.js b/tests/functional/sync_force_auth.js new file mode 100644 index 000000000..e649354eb --- /dev/null +++ b/tests/functional/sync_force_auth.js @@ -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'); + }); + }); + } + }); +}); diff --git a/tests/functional_oauth.js b/tests/functional_oauth.js index d42626634..a7fce5c1e 100644 --- a/tests/functional_oauth.js +++ b/tests/functional_oauth.js @@ -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 () {});