Merge pull request #268 from mozilla/issue-265-coppa-updates
Update COPPA to be done on the sign_up screen.
This commit is contained in:
Коммит
269d9452d1
|
@ -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 () {
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<header>
|
||||
<h1 id="fxa-age-header">{{#t}}Firefox Accounts{{/t}}</h1>
|
||||
|
||||
<h2>{{#t}}When were you born?{{/t}}</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<div class="error"></div>
|
||||
|
||||
<form>
|
||||
<div class="input-row">
|
||||
<select id="fxa-age-year" autofocus>
|
||||
<option id="fxa-none" value="none">{{#t}}Pick a year{{/t}}</option>
|
||||
<option id="fxa-1960" value="1960">{{#t}}1960s or earlier{{/t}}</option>
|
||||
<option id="fxa-1970" value="1970">{{#t}}1970s{{/t}}</option>
|
||||
<option id="fxa-1980" value="1980">{{#t}}1980s{{/t}}</option>
|
||||
<option id="fxa-1990" value="1990">{{#t}}1990s{{/t}}</option>
|
||||
<option id="fxa-2000" value="2000">{{#t}}2000{{/t}}</option>
|
||||
<option id="fxa-2001" value="2001">{{#t}}2001{{/t}}</option>
|
||||
<option id="fxa-2002" value="2002">{{#t}}2002{{/t}}</option>
|
||||
<option id="fxa-2003" value="2003">{{#t}}2003{{/t}}</option>
|
||||
<option id="fxa-2004" value="2004">{{#t}}2004{{/t}}</option>
|
||||
<option id="fxa-2005" value="2005">{{#t}}2005{{/t}}</option>
|
||||
<option id="fxa-2006" value="2006">{{#t}}2006{{/t}}</option>
|
||||
<option id="fxa-2007" value="2007">{{#t}}2007{{/t}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="button-row">
|
||||
<button id="fxa-age-submit" type="submit" disabled>{{#t}}Next{{/t}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
|
@ -1,68 +0,0 @@
|
|||
<header>
|
||||
<h1 id="fxa-birthday-header">{{#t}}Firefox Accounts{{/t}}</h1>
|
||||
|
||||
<h2>{{#t}}When is your birthday?{{/t}}</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<div class="error"></div>
|
||||
|
||||
<form>
|
||||
<div class="input-row input-row-month-day">
|
||||
<select id="fxa-month" autofocus>
|
||||
<option id="fxa-month-none" value="none">{{#t}}Month{{/t}}</option>
|
||||
<option id="fxa-month-jan" value="1">{{#t}}January{{/t}}</option>
|
||||
<option id="fxa-month-feb" value="2">{{#t}}February{{/t}}</option>
|
||||
<option id="fxa-month-mar" value="3">{{#t}}March{{/t}}</option>
|
||||
<option id="fxa-month-apr" value="4">{{#t}}April{{/t}}</option>
|
||||
<option id="fxa-month-may" value="5">{{#t}}May{{/t}}</option>
|
||||
<option id="fxa-month-jun" value="6">{{#t}}June{{/t}}</option>
|
||||
<option id="fxa-month-jul" value="7">{{#t}}July{{/t}}</option>
|
||||
<option id="fxa-month-aug" value="8">{{#t}}August{{/t}}</option>
|
||||
<option id="fxa-month-sep" value="9">{{#t}}September{{/t}}</option>
|
||||
<option id="fxa-month-oct" value="10">{{#t}}October{{/t}}</option>
|
||||
<option id="fxa-month-nov" value="11">{{#t}}November{{/t}}</option>
|
||||
<option id="fxa-month-dec" value="12">{{#t}}December{{/t}}</option>
|
||||
</select>
|
||||
|
||||
<select id="fxa-day">
|
||||
<option id="fxa-day-none" value="none">{{#t}}Day{{/t}}</option>
|
||||
<option id="fxa-day-1" value="1">{{#t}}1{{/t}}</option>
|
||||
<option id="fxa-day-2" value="2">{{#t}}2{{/t}}</option>
|
||||
<option id="fxa-day-3" value="3">{{#t}}3{{/t}}</option>
|
||||
<option id="fxa-day-4" value="4">{{#t}}4{{/t}}</option>
|
||||
<option id="fxa-day-5" value="5">{{#t}}5{{/t}}</option>
|
||||
<option id="fxa-day-6" value="6">{{#t}}6{{/t}}</option>
|
||||
<option id="fxa-day-7" value="7">{{#t}}7{{/t}}</option>
|
||||
<option id="fxa-day-8" value="8">{{#t}}8{{/t}}</option>
|
||||
<option id="fxa-day-9" value="9">{{#t}}9{{/t}}</option>
|
||||
<option id="fxa-day-10" value="10">{{#t}}10{{/t}}</option>
|
||||
<option id="fxa-day-11" value="11">{{#t}}11{{/t}}</option>
|
||||
<option id="fxa-day-12" value="12">{{#t}}12{{/t}}</option>
|
||||
<option id="fxa-day-13" value="13">{{#t}}13{{/t}}</option>
|
||||
<option id="fxa-day-14" value="14">{{#t}}14{{/t}}</option>
|
||||
<option id="fxa-day-15" value="15">{{#t}}15{{/t}}</option>
|
||||
<option id="fxa-day-16" value="16">{{#t}}16{{/t}}</option>
|
||||
<option id="fxa-day-17" value="17">{{#t}}17{{/t}}</option>
|
||||
<option id="fxa-day-18" value="18">{{#t}}18{{/t}}</option>
|
||||
<option id="fxa-day-19" value="19">{{#t}}19{{/t}}</option>
|
||||
<option id="fxa-day-20" value="20">{{#t}}20{{/t}}</option>
|
||||
<option id="fxa-day-21" value="21">{{#t}}21{{/t}}</option>
|
||||
<option id="fxa-day-22" value="22">{{#t}}22{{/t}}</option>
|
||||
<option id="fxa-day-23" value="23">{{#t}}23{{/t}}</option>
|
||||
<option id="fxa-day-24" value="24">{{#t}}24{{/t}}</option>
|
||||
<option id="fxa-day-25" value="25">{{#t}}25{{/t}}</option>
|
||||
<option id="fxa-day-26" value="26">{{#t}}26{{/t}}</option>
|
||||
<option id="fxa-day-27" value="27">{{#t}}27{{/t}}</option>
|
||||
<option id="fxa-day-28" value="28">{{#t}}28{{/t}}</option>
|
||||
<option id="fxa-day-29" value="29">{{#t}}29{{/t}}</option>
|
||||
<option id="fxa-day-30" value="30">{{#t}}30{{/t}}</option>
|
||||
<option id="fxa-day-31" value="31">{{#t}}31{{/t}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="button-row">
|
||||
<button id="fxa-birthday-submit" type="submit">{{#t}}Next{{/t}}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
|
@ -1,7 +1,14 @@
|
|||
<header>
|
||||
<h1 id="fxa-cannot-create-account-header">{{#t}}Firefox Accounts{{/t}}</h1>
|
||||
<h2>{{#t}}Cannot create account{{/t}}</h2>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<p>We are unable to create an account for you.</p>
|
||||
<section class="cannot-create-account-content">
|
||||
<p>
|
||||
<strong>{{#t}}You must meet certain age requirements to create a Firefox Account.{{/t}}</strong>
|
||||
</p>
|
||||
|
||||
<p class="links">
|
||||
<a href="http://www.ftc.gov/news-events/media-resources/protecting-consumer-privacy/kids-privacy-coppa" target="_blank">{{#t}}Learn more.{{/t}}</a>
|
||||
</p>
|
||||
</section>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<header>
|
||||
<h1 id="fxa-create-account-header">{{#t}}Firefox Accounts{{/t}}</h1>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<div class="error"></div>
|
||||
|
||||
<div class="spinner">{{#t}}Please wait...{{/t}}</div>
|
||||
</section>
|
|
@ -16,6 +16,25 @@
|
|||
<input type="password" class="password" placeholder="{{#t}}Password{{/t}}" pattern=".{8,}">
|
||||
</div>
|
||||
|
||||
<div class="input-row">
|
||||
<label for="fxa-age-year">{{#t}}When were you born?{{/t}}</label>
|
||||
<select id="fxa-age-year" value="none">
|
||||
<option id="fxa-none" value="none">{{#t}}Pick a year{{/t}}</option>
|
||||
<option id="fxa-1960" value="1960">{{#t}}1960s or earlier{{/t}}</option>
|
||||
<option id="fxa-1970" value="1970">{{#t}}1970s{{/t}}</option>
|
||||
<option id="fxa-1980" value="1980">{{#t}}1980s{{/t}}</option>
|
||||
<option id="fxa-1990" value="1990">{{#t}}1990s{{/t}}</option>
|
||||
<option id="fxa-2000" value="2000">{{#t}}2000{{/t}}</option>
|
||||
<option id="fxa-2001" value="2001">{{#t}}2001{{/t}}</option>
|
||||
<option id="fxa-2002" value="2002">{{#t}}2002{{/t}}</option>
|
||||
<option id="fxa-2003" value="2003">{{#t}}2003{{/t}}</option>
|
||||
<option id="fxa-2004" value="2004">{{#t}}2004{{/t}}</option>
|
||||
<option id="fxa-2005" value="2005">{{#t}}2005{{/t}}</option>
|
||||
<option id="fxa-2006" value="2006">{{#t}}2006{{/t}}</option>
|
||||
<option id="fxa-2007" value="2007">{{#t}}2007{{/t}}</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="privacy-links">
|
||||
{{#t}}By proceeding, I agree to the <a id="fxa-tos" href="/tos">Terms of Service</a> and <a id="fxa-pp" href="/pp">Privacy Notice</a> for Sync.{{/t}}
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
@ -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() {
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
@ -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;
|
||||
});
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -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',
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче