diff --git a/app/scripts/router.js b/app/scripts/router.js index a10d25c55..6459bd1a1 100644 --- a/app/scripts/router.js +++ b/app/scripts/router.js @@ -15,9 +15,6 @@ define([ 'views/settings', 'views/tos', 'views/pp', - 'views/age', - 'views/birthday', - 'views/create_account', 'views/cannot_create_account', 'views/complete_sign_up', 'views/reset_password', @@ -26,7 +23,7 @@ define([ 'views/reset_password_complete', 'transit' ], -function ($, Backbone, _, IntroView, SignInView, SignUpView, ConfirmView, SettingsView, TosView, PpView, AgeView, BirthdayView, CreateAccountView, CannotCreateAccountView, CompleteSignUpView, ResetPasswordView, ConfirmResetPasswordView, CompleteResetPasswordView, ResetPasswordCompleteView) { +function ($, Backbone, _, IntroView, SignInView, SignUpView, ConfirmView, SettingsView, TosView, PpView, CannotCreateAccountView, CompleteSignUpView, ResetPasswordView, ConfirmResetPasswordView, CompleteResetPasswordView, ResetPasswordCompleteView) { var Router = Backbone.Router.extend({ routes: { '': 'showSignUp', @@ -36,9 +33,6 @@ function ($, Backbone, _, IntroView, SignInView, SignUpView, ConfirmView, Settin 'settings': 'showSettings', 'tos': 'showTos', 'pp': 'showPp', - 'age': 'showAge', - 'birthday': 'showBirthday', - 'create_account': 'showCreateAccount', 'cannot_create_account': 'showCannotCreateAccount', 'verify_email': 'showCompleteSignUp', 'reset_password': 'showResetPassword', @@ -81,18 +75,6 @@ function ($, Backbone, _, IntroView, SignInView, SignUpView, ConfirmView, Settin this.showView(new PpView()); }, - showAge: function () { - this.showView(new AgeView()); - }, - - showBirthday: function () { - this.showView(new BirthdayView()); - }, - - showCreateAccount: function () { - this.showView(new CreateAccountView()); - }, - showCannotCreateAccount: function () { this.showView(new CannotCreateAccountView()); }, @@ -127,12 +109,17 @@ function ($, Backbone, _, IntroView, SignInView, SignUpView, ConfirmView, Settin // Make the stage transparent this.$stage.css({ opacity: 0 }); - // Render the new view - this.$stage.html(this.currentView.render().el); + // render will return false if the view could not be + // rendered for any reason, including if the view was + // automatically redirected. + if (this.currentView.render()) { + // Render the new view + this.$stage.html(this.currentView.el); - // Fade the stage back in - this.$stage.transition({ opacity: 100 }, - _.bind(this.currentView.afterVisible, this.currentView)); + // Fade the stage back in + this.$stage.transition({ opacity: 100 }, + _.bind(this.currentView.afterVisible, this.currentView)); + } }, watchAnchors: function () { diff --git a/app/scripts/templates/age.mustache b/app/scripts/templates/age.mustache deleted file mode 100644 index 85cf0adb4..000000000 --- a/app/scripts/templates/age.mustache +++ /dev/null @@ -1,33 +0,0 @@ -
-

{{#t}}Firefox Accounts{{/t}}

- -

{{#t}}When were you born?{{/t}}

-
- -
-
- -
-
- -
- -
- -
-
-
diff --git a/app/scripts/templates/birthday.mustache b/app/scripts/templates/birthday.mustache deleted file mode 100644 index a265c7973..000000000 --- a/app/scripts/templates/birthday.mustache +++ /dev/null @@ -1,68 +0,0 @@ -
-

{{#t}}Firefox Accounts{{/t}}

- -

{{#t}}When is your birthday?{{/t}}

-
- -
-
- -
-
- - - -
- -
- -
-
-
diff --git a/app/scripts/templates/cannot_create_account.mustache b/app/scripts/templates/cannot_create_account.mustache index c580a46af..e6601a5b6 100644 --- a/app/scripts/templates/cannot_create_account.mustache +++ b/app/scripts/templates/cannot_create_account.mustache @@ -1,7 +1,14 @@

{{#t}}Firefox Accounts{{/t}}

+

{{#t}}Cannot create account{{/t}}

-
-

We are unable to create an account for you.

+
+

+ {{#t}}You must meet certain age requirements to create a Firefox Account.{{/t}} +

+ +
diff --git a/app/scripts/templates/create_account.mustache b/app/scripts/templates/create_account.mustache deleted file mode 100644 index 78a995e54..000000000 --- a/app/scripts/templates/create_account.mustache +++ /dev/null @@ -1,9 +0,0 @@ -
-

{{#t}}Firefox Accounts{{/t}}

-
- -
-
- -
{{#t}}Please wait...{{/t}}
-
diff --git a/app/scripts/templates/sign_up.mustache b/app/scripts/templates/sign_up.mustache index 4c31ab7a3..d8fb5ce6e 100644 --- a/app/scripts/templates/sign_up.mustache +++ b/app/scripts/templates/sign_up.mustache @@ -16,6 +16,25 @@ +
+ + +
+ diff --git a/app/scripts/views/age.js b/app/scripts/views/age.js deleted file mode 100644 index 5aea24ea4..000000000 --- a/app/scripts/views/age.js +++ /dev/null @@ -1,74 +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/. */ - -'use strict'; - -define([ - 'views/base', - 'stache!templates/age' -], -function (BaseView, AgeTemplate) { - var now = new Date(); - - var VERIFICATION_AGE = 13; - var NEEDS_VERIFICATION_YEAR = now.getFullYear() - VERIFICATION_AGE; - - var AgeView = BaseView.extend({ - template: AgeTemplate, - className: 'age', - - events: { - 'submit form': 'age', - 'keyup select': 'enableButtonWhenValid', - 'change select': 'enableButtonWhenValid' - }, - - age: function (event) { - event.preventDefault(); - - if (! this._validateYear()) { - return; - } - - var year = parseInt(this.$('#fxa-age-year').val(), 10); - - var nextStep = this._getNextStep(year); - - router.navigate(nextStep, { trigger: true }); - }, - - isValid: function () { - return this._validateYear(); - }, - - _validateYear: function () { - var year = this.$('#fxa-age-year').val(); - return year !== 'none'; - }, - - _getNextStep: function (year) { - var nextStep = 'cannot_create_account'; - - if (this._requiresMoreVerification(year)) { - nextStep = 'birthday'; - } else if (this._canCreateAccount(year)) { - nextStep = 'create_account'; - } - - return nextStep; - }, - - _requiresMoreVerification: function (year) { - return year === NEEDS_VERIFICATION_YEAR; - }, - - _canCreateAccount: function (year) { - return year < NEEDS_VERIFICATION_YEAR; - } - - }); - - return AgeView; -}); - diff --git a/app/scripts/views/base.js b/app/scripts/views/base.js index 6d7b6f6df..1baae1600 100644 --- a/app/scripts/views/base.js +++ b/app/scripts/views/base.js @@ -20,7 +20,9 @@ function(_, Backbone, jQuery) { }, render: function() { - this.beforeRender(); + if ( ! this.beforeRender()) { + return false; + } this.destroySubviews(); @@ -50,7 +52,10 @@ function(_, Backbone, jQuery) { }, beforeRender: function() { - // Implement in subclasses + // Implement in subclasses. If returns false, then the view is not + // rendered. Useful if the view must immediately redirect to another + // view. + return true; }, afterRender: function() { diff --git a/app/scripts/views/birthday.js b/app/scripts/views/birthday.js deleted file mode 100644 index 8d06d518a..000000000 --- a/app/scripts/views/birthday.js +++ /dev/null @@ -1,76 +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/. */ - -'use strict'; - -define([ - 'views/base', - 'stache!templates/birthday' -], -function (BaseView, BirthdayTemplate) { - var BirthdayView = BaseView.extend({ - template: BirthdayTemplate, - className: 'birthday', - - events: { - 'submit form': 'birthday', - 'change select': 'enableButtonWhenValid' - }, - - birthday: function (event) { - event.preventDefault(); - - if (!this.isValid()) { - return; - } - - var month = this._getMonth(); - var day = this._getDay(); - - var nextStep = this._getNextStep(month, day); - - router.navigate(nextStep, { trigger: true }); - }, - - isValid: function () { - return !(isNaN(this._getMonth()) || isNaN(this._getDay())); - }, - - _getMonth: function () { - var val = this.$('#fxa-month').val(); - return parseInt(val, 10); - }, - - _getDay: function () { - var val = this.$('#fxa-day').val(); - return parseInt(val, 10); - }, - - _getNextStep: function (month, day) { - if (this._canCreateAccount(month, day)) { - return 'create_account'; - } - - return 'cannot_create_account'; - }, - - _canCreateAccount: function (month, day) { - // Make the assumption that the user is 13 during this calendar year. - // Find out whether they are 12 or 13 now. - // - // JS months go from 0-11. The months in the form go from 1-12 to be - // comprehensible to humans. - month = month - 1; - var today = new Date(); - var todayMonth = today.getMonth(); - var todayDay = today.getDate(); - - return ((month < todayMonth) || - (month === todayMonth && day <= todayDay)); - } - }); - - return BirthdayView; -}); - diff --git a/app/scripts/views/create_account.js b/app/scripts/views/create_account.js deleted file mode 100644 index 246de2caf..000000000 --- a/app/scripts/views/create_account.js +++ /dev/null @@ -1,55 +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/. */ - -'use strict'; - -define([ - 'views/base', - 'stache!templates/create_account', - 'lib/session', - 'lib/fxa-client' -], -function (BaseView, CreateAccountTemplate, Session, FxaClient) { - var CreateAccountView = BaseView.extend({ - template: CreateAccountTemplate, - className: 'create_account', - - context: function () { - return { - email: Session.email - }; - }, - - initialize: function () { - var email = Session.email; - var password = Session.password; - - if (email && password) { - this._createAccount(email, password); - } - }, - - _createAccount: function (email, password) { - var client = new FxaClient(); - client.signUp(email, password) - .done(function (accountData) { - // This info will be sent to the channel in the confirm screen. - Session.sessionToken = accountData.sessionToken; - Session.keyFetchToken = accountData.keyFetchToken; - Session.unwrapBKey = accountData.unwrapBKey; - Session.uid = accountData.uid; - - router.navigate('confirm', { trigger: true }); - }, - function (err) { - this.$('.spinner').hide(); - this.$('.error').html(err.message); - - console.error('Error?', err); - }.bind(this)); - } - }); - - return CreateAccountView; -}); diff --git a/app/scripts/views/sign_up.js b/app/scripts/views/sign_up.js index 1f65a7ce1..59813fcdd 100644 --- a/app/scripts/views/sign_up.js +++ b/app/scripts/views/sign_up.js @@ -5,36 +5,70 @@ 'use strict'; define([ + 'underscore', 'views/base', 'stache!templates/sign_up', - 'lib/session' + 'lib/session', + 'lib/fxa-client' ], -function (BaseView, SignUpTemplate, Session) { +function (_, BaseView, SignUpTemplate, Session, FxaClient) { + var now = new Date(); + + // If COPPA says 13, why 14 here? To make UX simpler, we only ask + // for their year of birth, we do not ask for month and day. + // To make this safe and ensure we do not let *any* 12 year olds pass, + // we are saying that it is acceptable for some 13 year olds to be + // caught in the snare. + // This is written on 2014-01-16. 13 years ago is 2001-01-16. Somebody born + // in 2001-01-15 is now 13. Somebody born 2001-01-17 is still only 12. + // To avoid letting the 12 year old in, add an extra year. + var TOO_YOUNG_YEAR = now.getFullYear() - 14; + var SignUpView = BaseView.extend({ + initialize: function (options) { + options = options || {}; + this.router = options.router || window.router; + }, + + beforeRender: function () { + if (document.cookie.indexOf('tooyoung') > -1) { + this.router.navigate('cannot_create_account', { trigger: true }); + return false; + } + + return true; + }, + template: SignUpTemplate, className: 'sign-up', events: { - 'submit form': 'signUp', - 'keyup input': 'enableButtonWhenValid', - 'change input': 'enableButtonWhenValid' + 'submit form': 'onSubmit', + 'keyup form': 'enableButtonWhenValid', + 'change form': 'enableButtonWhenValid' }, - signUp: function (event) { + onSubmit: function (event) { event.preventDefault(); + this.signUp(); + }, + signUp: function () { if (! (this.isValid())) { return; } - Session.email = this.$('.email').val(); - Session.password = this.$('.password').val(); + if (! this._isUserOldEnough()) { + return this._cannotCreateAccount(); + } - router.navigate('age', { trigger: true }); + this._createAccount(); }, isValid: function () { - return this._validateEmail() && this._validatePassword(); + return !! (this._validateEmail() && + this._validatePassword() && + this._validateYear()); }, _validateEmail: function () { @@ -43,7 +77,58 @@ function (BaseView, SignUpTemplate, Session) { _validatePassword: function () { return this.isElementValid('.password'); + }, + + _validateYear: function () { + return ! isNaN(this._getYear()); + }, + + _getYear: function () { + return this.$('#fxa-age-year').val(); + }, + + _isUserOldEnough: function () { + var year = parseInt(this._getYear(), 10); + + return year <= TOO_YOUNG_YEAR; + }, + + _cannotCreateAccount: function () { + // this is a session cookie. It will go away once: + // 1. the user closes the tab + // and + // 2. the user closes the browser + // Both of these have to happen or else the cookie + // hangs around like a bad smell. + document.cookie = 'tooyoung=1;'; + + this.router.navigate('cannot_create_account', { trigger: true }); + }, + + _createAccount: function () { + var email = this.$('.email').val(); + var password = this.$('.password').val(); + + var client = new FxaClient(); + client.signUp(email, password) + .done(_.bind(function (accountData) { + // This info will be sent to the channel in the confirm screen. + Session.email = email; + Session.sessionToken = accountData.sessionToken; + Session.keyFetchToken = accountData.keyFetchToken; + Session.unwrapBKey = accountData.unwrapBKey; + Session.uid = accountData.uid; + + this.router.navigate('confirm', { trigger: true }); + }, this), + _.bind(function (err) { + this.$('.spinner').hide(); + this.$('.error').html(err.message); + + console.error('Error?', err); + }, this)); } + }); return SignUpView; diff --git a/app/styles/main.css b/app/styles/main.css index 3b9cd9188..4fc529716 100644 --- a/app/styles/main.css +++ b/app/styles/main.css @@ -217,6 +217,10 @@ section p { margin-top: 20px; } +.cannot-create-account-content { + margin-top: 105px; +} + .spinner { -webkit-animation: 0.9s spin infinite linear; -moz-animation: 0.9s spin infinite linear; diff --git a/app/tests/main.js b/app/tests/main.js index 531279158..4bc93902e 100644 --- a/app/tests/main.js +++ b/app/tests/main.js @@ -53,13 +53,20 @@ require([ '../tests/spec/lib/xss', '../tests/spec/lib/url', '../tests/spec/lib/fxa-client', - '../tests/spec/views/base' + '../tests/spec/views/base', + '../tests/spec/views/sign_up' ], function (Mocha) { + // Use a mock for the translator + window.translator = { + get: function (key) { + return key; + } + }; + var runner = Mocha.run(); runner.on('end', function () { - // This is our hook to the Selenium tests that run // the mocha tests as part of the CI build. // The selenium test will wait until the #total-failures element exists diff --git a/app/tests/mocks/router.js b/app/tests/mocks/router.js index d0755bc4f..22da52330 100644 --- a/app/tests/mocks/router.js +++ b/app/tests/mocks/router.js @@ -6,17 +6,22 @@ 'use strict'; -define([], function () { +define([ + 'underscore', + 'backbone' +], function (_, Backbone) { function RouterMock() { // nothing to do here. } - RouterMock.prototype = { + _.extend(RouterMock.prototype, Backbone.Events, { navigate: function(page, opts) { this.page = page; this.opts = opts; + + this.trigger('navigate'); } - }; + }); return RouterMock; }); diff --git a/app/tests/spec/views/sign_up.js b/app/tests/spec/views/sign_up.js new file mode 100644 index 000000000..e6561c72d --- /dev/null +++ b/app/tests/spec/views/sign_up.js @@ -0,0 +1,146 @@ +/* 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/. */ + +'use strict'; + + +define([ + 'mocha', + 'chai', + 'underscore', + 'jquery', + 'views/sign_up', + '../../mocks/router' +], +function (mocha, chai, _, $, View, RouterMock) { + var assert = chai.assert; + + describe('views/sign_up', function () { + var view, router, email; + + beforeEach(function() { + email = 'testuser.' + Math.random() + '@testuser.com'; + document.cookie = 'tooyoung=1; expires=Thu, 01-Jan-1970 00:00:01 GMT'; + sessionStorage.removeItem('tooYoung'); + router = new RouterMock(); + view = new View({ + router: router + }); + view.render(); + + $('body').append(view.el); + }); + + afterEach(function() { + $(view.el).remove(); + view.destroy(); + view = null; + router = null; + document.cookie = 'tooyoung=1; expires=Thu, 01-Jan-1970 00:00:01 GMT'; + }); + + describe('isValid', function() { + it('returns true if email, password, and age are all valid', function() { + $('.email').val(email); + $('.password').val('password'); + $('#fxa-age-year').val('1960'); + + assert.isTrue(view.isValid()); + }); + + it('returns false if email is empty', function() { + $('.password').val('password'); + $('#fxa-age-year').val('1960'); + + assert.isFalse(view.isValid()); + }); + + it('returns false if email is not an email address', function() { + $('.email').val('testuser') + $('.password').val('password'); + $('#fxa-age-year').val('1960'); + + assert.isFalse(view.isValid()); + }); + + it('returns false if password is empty', function() { + $('.email').val(email); + $('#fxa-age-year').val('1960'); + + assert.isFalse(view.isValid()); + }); + + it('returns false if password is invalid', function() { + $('.email').val(email); + $('.password').val('passwor'); + $('#fxa-age-year').val('1960'); + + assert.isFalse(view.isValid()); + }); + + it('returns false if age is invalid', function() { + $('.email').val(email); + $('.password').val('password'); + + assert.isFalse(view.isValid()); + }); + }); + + describe('signUp', function() { + it('sends the user to confirm screen if form filled out, >= 14 years ago', function(done) { + $('.email').val(email); + $('.password').val('password'); + + var nowYear = (new Date()).getFullYear(); + $('#fxa-age-year').val(nowYear - 14); + + router.on('navigate', function() { + assert.equal(router.page, 'confirm'); + done(); + }); + view.signUp(); + }); + + it('sends the user to cannot_create_account screen if user selects <= 13 years ago', function(done) { + $('.email').val(email); + $('.password').val('password'); + + var nowYear = (new Date()).getFullYear(); + $('#fxa-age-year').val(nowYear - 13); + + router.on('navigate', function() { + assert.equal(router.page, 'cannot_create_account'); + done(); + }); + view.signUp(); + }); + + it('a user who retries to enter the signUp screen after already going to cannot_create_account is automatically sent to cannot_create_account', function(done) { + $('.email').val(email); + $('.password').val('password'); + + var nowYear = (new Date()).getFullYear(); + $('#fxa-age-year').val(nowYear - 13); + + view.signUp(); + assert.equal(router.page, 'cannot_create_account'); + + // simulate user re-visiting the /signup page after being rejected + var revisitRouter = new RouterMock(); + + revisitRouter.on('navigate', function() { + assert.equal(revisitRouter.page, 'cannot_create_account'); + done(); + }); + + var revisitView = new View({ + router: revisitRouter + }); + revisitView.render(); + }); + }); + }); +}); + + diff --git a/tests/functional.js b/tests/functional.js index f752c9ae2..92855b887 100644 --- a/tests/functional.js +++ b/tests/functional.js @@ -8,8 +8,6 @@ define([ './functional/complete_sign_up', './functional/tos', './functional/pp', - './functional/age', - './functional/birthday', './functional/confirm', './functional/reset_password', './functional/confirm_reset_password', diff --git a/tests/functional/age.js b/tests/functional/age.js deleted file mode 100644 index 8855a803b..000000000 --- a/tests/functional/age.js +++ /dev/null @@ -1,102 +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([ - 'intern!object', - 'intern/chai!assert', - 'require' -], function (registerSuite, assert, require) { - 'use strict'; - - var FIND_ELEMENT_TIMEOUT = 5000; - - var url = 'http://localhost:3030/age'; - var VERIFICATION_AGE = 13; - var VERIFICATION_YEAR = new Date().getFullYear() - VERIFICATION_AGE; - - registerSuite({ - name: 'age', - - setup: function () { - }, - - 'select the 1990s': function () { - - return this.get('remote') - .setImplicitWaitTimeout(FIND_ELEMENT_TIMEOUT) - .get(require.toUrl(url)) - .waitForElementById('fxa-age-header') - - .elementById('fxa-age-year') - .click() - .end() - - .elementById('fxa-1990') - // buttonDown & buttonUp are required for Firefox to select the - // item. This causes safari to blow its lid. - .buttonDown() - .buttonUp() - .click() - .end() - - .elementById('fxa-age-submit') - .click() - .end() - - // Success is being redirected to the create account screen. - .waitForElementById('fxa-create-account-header') - .end(); - }, - - 'select the age that requires further verification': function () { - - return this.get('remote') - .setImplicitWaitTimeout(FIND_ELEMENT_TIMEOUT) - .get(require.toUrl(url)) - .waitForElementById('fxa-age-header') - - .elementById('fxa-age-year') - .click() - .end() - - .elementById('fxa-' + VERIFICATION_YEAR) - .buttonDown() - .buttonUp() - .click() - .end() - - .elementById('fxa-age-submit') - .click() - .end() - - // Success is being redirected to the birthday screen. - .waitForElementById('fxa-birthday-header') - .end(); - }, - - 'select an age that is too young': function () { - return this.get('remote') - .get(require.toUrl(url)) - .waitForElementById('fxa-age-header') - - .elementById('fxa-age-year') - .click() - .end() - - .elementById('fxa-' + (VERIFICATION_YEAR + 1)) - .buttonDown() - .buttonUp() - .click() - .end() - - .elementById('fxa-age-submit') - .click() - .end() - - // Success is being redirected to the cannot create screen. - .waitForElementById('fxa-cannot-create-account-header') - .end(); - } - }); -}); diff --git a/tests/functional/birthday.js b/tests/functional/birthday.js deleted file mode 100644 index 751a17666..000000000 --- a/tests/functional/birthday.js +++ /dev/null @@ -1,130 +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([ - 'intern!object', - 'intern/chai!assert', - 'require' -], function (registerSuite, assert, require) { - 'use strict'; - - var url = 'http://localhost:3030/birthday'; - var MONTHS = [ - 'jan', 'feb', 'mar', 'apr', 'may', 'jun', - 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' - ]; - - registerSuite({ - name: 'birthday', - - 'pick a day that is before today - user can register': function () { - var month; - var day; - - var remote = this.get('remote') - /*jshint evil:true*/ - .eval('{ day: new Date(new Date().getTime() - 1000 * 60 * 60 * 24).getDate(), month: new Date(new Date().getTime() - 1000 * 60 * 60 * 24).getMonth() }') - .then(function (result) { - day = result.day; - month = MONTHS[result.month]; - - remote.get(require.toUrl(url + '#yesterday')) - .waitForElementById('fxa-birthday-header') - .elementById('fxa-month-' + month) - .click() - .end() - - .elementById('fxa-day-' + day) - .click() - .wait(1000) - .end() - - .elementById('fxa-birthday-submit') - .submit() - .end() - - // Success is being redirected to the create account screen. - .waitForElementById('fxa-create-account-header') - .end(); - }) - .end(); - - return remote; - }, - - 'pick today - user can register': function () { - var month; - var day; - - var remote = this.get('remote') - // Get client current date, we cannot use the date of the test runner. - /*jshint evil:true*/ - .eval('{ day: new Date().getDate(), month: new Date().getMonth() }') - .then(function (result) { - day = result.day; - month = MONTHS[result.month]; - - remote.get(require.toUrl(url + '#today')) - .waitForElementById('fxa-birthday-header') - - .elementById('fxa-month-' + month) - .click() - .end() - - .elementById('fxa-day-' + day) - .click() - .wait(1000) - .end() - - .elementById('fxa-birthday-submit') - .submit() - .end() - - // Success is being redirected to the create account screen. - .waitForElementById('fxa-create-account-header') - .end(); - }) - .end(); - - - return remote; - }, - - 'pick a day that is after today - user is too young': function () { - var month; - var day; - - var remote = this.get('remote') - /*jshint evil:true*/ - .eval('{ day: new Date(new Date().getTime() + 1000 * 60 * 60 * 24).getDate(), month: new Date(new Date().getTime() + 1000 * 60 * 60 * 24).getMonth() }') - .then(function (result) { - day = result.day; - month = MONTHS[result.month]; - - remote.get(require.toUrl(url + '#tomorrow')) - .waitForElementById('fxa-birthday-header') - .elementById('fxa-month-' + month) - .click() - .end() - - .elementById('fxa-day-' + day) - .click() - .wait(1000) - .end() - - .elementById('fxa-birthday-submit') - .submit() - .end() - - // Success is being redirected to the cannot create account screen. - .waitForElementById('fxa-cannot-create-account-header') - .end(); - }) - .end(); - - - return remote; - } - }); -}); diff --git a/tests/functional/sign_up.js b/tests/functional/sign_up.js index 0ebc9ede5..1e64d26de 100644 --- a/tests/functional/sign_up.js +++ b/tests/functional/sign_up.js @@ -11,6 +11,8 @@ define([ var url = 'http://localhost:3030/signup'; + var TOO_YOUNG_YEAR = new Date().getFullYear() - 13; + registerSuite({ name: 'sign_up', @@ -32,12 +34,64 @@ define([ .type(password) .end() + .elementByCssSelector('#fxa-age-year') + .click() + .end() + + .elementById('fxa-' + (TOO_YOUNG_YEAR - 1)) + .buttonDown() + .buttonUp() + .click() + .end() + .elementByCssSelector('button[type="submit"]') .click() .end() // Being pushed to the age verification screen is success. - .waitForElementById('fxa-age-header') + .waitForElementById('fxa-confirm-header') + .end(); + }, + + 'select an age that is too young': function () { + var email = 'signup' + Math.random() + '@example.com'; + var password = '12345678'; + + return this.get('remote') + .get(require.toUrl(url)) + .waitForElementById('fxa-signup-header') + + .elementByCssSelector('form input.email') + .click() + .type(email) + .end() + + .elementByCssSelector('form input.password') + .click() + .type(password) + .end() + + .elementByCssSelector('#fxa-age-year') + .click() + .end() + + .elementById('fxa-' + TOO_YOUNG_YEAR) + .buttonDown() + .buttonUp() + .click() + .end() + + .elementByCssSelector('button[type="submit"]') + .click() + .end() + + // Success is being redirected to the cannot create screen. + .waitForElementById('fxa-cannot-create-account-header') + .end() + + // ensure that this does not interfere with other tests. + /*jshint evil:true*/ + .eval('document.cookie = "tooyoung=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";') .end(); } });