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:
Nick Chapman 2014-01-17 15:16:14 -08:00
Родитель 0624ae871f 909c9dd889
Коммит 269d9452d1
19 изменённых файлов: 363 добавлений и 593 удалений

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

@ -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&nbsp;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();
}
});