diff --git a/lms/static/js/spec/student_account/account_spec.js b/lms/static/js/spec/student_account/account_spec.js deleted file mode 100644 index e7504499ba..0000000000 --- a/lms/static/js/spec/student_account/account_spec.js +++ /dev/null @@ -1,201 +0,0 @@ -define(['js/student_account/account'], - function() { - describe('edx.student.account.AccountModel', function() { - 'use strict'; - - var account = null; - - var assertValid = function(fields, isValid, expectedErrors) { - account.set(fields); - var errors = account.validate(account.attributes); - - if (isValid) { - expect(errors).toBe(undefined); - } else { - expect(errors).toEqual(expectedErrors); - } - }; - - var EXPECTED_ERRORS = { - email: { - email: 'Please enter a valid email address' - }, - password: { - password: 'Please enter a valid password' - } - }; - - beforeEach(function() { - account = new edx.student.account.AccountModel(); - account.set({ - email: 'bob@example.com', - password: 'password' - }); - }); - - it('accepts valid email addresses', function() { - assertValid({email: 'bob@example.com'}, true); - assertValid({email: 'bob+smith@example.com'}, true); - assertValid({email: 'bob+smith@example.com'}, true); - assertValid({email: 'bob+smith@example.com'}, true); - assertValid({email: 'bob@test.example.com'}, true); - assertValid({email: 'bob@test-example.com'}, true); - }); - - it('rejects blank email addresses', function() { - assertValid({email: ''}, false, EXPECTED_ERRORS.email); - assertValid({email: ' '}, false, EXPECTED_ERRORS.email); - }); - - it('rejects invalid email addresses', function() { - assertValid({email: 'bob'}, false, EXPECTED_ERRORS.email); - assertValid({email: 'bob@example'}, false, EXPECTED_ERRORS.email); - assertValid({email: '@'}, false, EXPECTED_ERRORS.email); - assertValid({email: '@example.com'}, false, EXPECTED_ERRORS.email); - - // The server will reject emails with non-ASCII unicode - // Technically these are valid email addresses, but the email validator - // in Django 1.4 will reject them anyway, so we should too. - assertValid({email: 'fŕáńḱ@example.com'}, false, EXPECTED_ERRORS.email); - assertValid({email: 'frank@éxáḿṕĺé.com'}, false, EXPECTED_ERRORS.email); - }); - - it('rejects a long email address', function() { - // Construct an email exactly one character longer than the maximum length - var longEmail = new Array(account.EMAIL_MAX_LENGTH - 10).join('e') + '@example.com'; - assertValid({email: longEmail}, false, EXPECTED_ERRORS.email); - }); - - it('accepts a valid password', function() { - assertValid({password: 'password-test123'}, true, EXPECTED_ERRORS.password); - }); - - it('rejects a short password', function() { - assertValid({password: ''}, false, EXPECTED_ERRORS.password); - assertValid({password: 'a'}, false, EXPECTED_ERRORS.password); - assertValid({password: 'aa'}, true, EXPECTED_ERRORS.password); - }); - - it('rejects a long password', function() { - // Construct a password exactly one character longer than the maximum length - var longPassword = new Array(account.PASSWORD_MAX_LENGTH + 2).join('a'); - assertValid({password: longPassword}, false, EXPECTED_ERRORS.password); - }); - }); - - - describe('edx.student.account.AccountView', function() { - var view = null, - ajaxSuccess = true; - - var requestEmailChange = function(email, password) { - var fakeEvent = {preventDefault: function() {}}; - view.model.set({ - email: email, - password: password - }); - view.submit(fakeEvent); - }; - - var requestPasswordChange = function() { - var fakeEvent = {preventDefault: function() {}}; - view.click(fakeEvent); - }; - - var assertAjax = function(url, method, data) { - expect($.ajax).toHaveBeenCalled(); - var ajaxArgs = $.ajax.calls.mostRecent().args[0]; - expect(ajaxArgs.url).toEqual(url); - expect(ajaxArgs.type).toEqual(method); - expect(ajaxArgs.data).toEqual(data); - expect(ajaxArgs.headers.hasOwnProperty('X-CSRFToken')).toBe(true); - }; - - var assertStatus = function(selection, success, errorClass, expectedStatus) { - if (!success) { - expect(selection).toHaveClass(errorClass); - } else { - expect(selection).not.toHaveClass(errorClass); - } - expect(selection.text()).toEqual(expectedStatus); - }; - - beforeEach(function() { - var fixture = readFixtures('templates/student_account/account.underscore'); - setFixtures('
' + fixture + '
'); - - view = new edx.student.account.AccountView().render(); - - // Stub Ajax calls to return success/failure - spyOn($, 'ajax').and.callFake(function() { - return $.Deferred(function(defer) { - if (ajaxSuccess) { - defer.resolve(); - } else { - defer.reject(); - } - }).promise(); - }); - }); - - it('requests an email address change', function() { - requestEmailChange('bob@example.com', 'password'); - assertAjax('email', 'POST', { - email: 'bob@example.com', - password: 'password' - }); - assertStatus(view.$requestStatus, true, 'error', 'Please check your email to confirm the change'); - }); - - it('displays email validation errors', function() { - // Invalid email should display an error - requestEmailChange('invalid', 'password'); - assertStatus(view.$emailStatus, false, 'validation-error', 'Please enter a valid email address'); - - // Once the error is fixed, the status should return to normal - requestEmailChange('bob@example.com', 'password'); - assertStatus(view.$emailStatus, true, 'validation-error', ''); - }); - - it('displays an invalid password error', function() { - // Password cannot be empty - requestEmailChange('bob@example.com', ''); - assertStatus(view.$passwordStatus, false, 'validation-error', 'Please enter a valid password'); - - // Once the error is fixed, the status should return to normal - requestEmailChange('bob@example.com', 'password'); - assertStatus(view.$passwordStatus, true, 'validation-error', ''); - }); - - it('displays server errors', function() { - // Simulate an error from the server - ajaxSuccess = false; - requestEmailChange('bob@example.com', 'password'); - assertStatus(view.$requestStatus, false, 'error', 'The data could not be saved.'); - - // On retry, it should succeed - ajaxSuccess = true; - requestEmailChange('bob@example.com', 'password'); - assertStatus(view.$requestStatus, true, 'error', 'Please check your email to confirm the change'); - }); - - it('requests a password reset', function() { - requestPasswordChange(); - assertAjax('password', 'POST', {}); - assertStatus(view.$passwordResetStatus, true, 'error', 'Password reset email sent. Follow the link in the email to change your password.'); - }); - - it('displays an error message if a password reset email could not be sent', function() { - // Simulate an error from the server - ajaxSuccess = false; - requestPasswordChange(); - assertStatus(view.$passwordResetStatus, false, 'error', "We weren't able to send you a password reset email."); - - // Retry, this time simulating success - ajaxSuccess = true; - requestPasswordChange(); - assertStatus(view.$passwordResetStatus, true, 'error', 'Password reset email sent. Follow the link in the email to change your password.'); - }); - }); - } -); diff --git a/lms/static/js/student_account/account.js b/lms/static/js/student_account/account.js deleted file mode 100644 index 51fe1d7981..0000000000 --- a/lms/static/js/student_account/account.js +++ /dev/null @@ -1,191 +0,0 @@ -var edx = edx || {}; - -(function($, _, Backbone, gettext) { - 'use strict'; - - edx.student = edx.student || {}; - edx.student.account = edx.student.account || {}; - - edx.student.account.AccountModel = Backbone.Model.extend({ - // These should be the same length limits enforced by the server - EMAIL_MIN_LENGTH: 3, - EMAIL_MAX_LENGTH: 254, - PASSWORD_MIN_LENGTH: 2, - PASSWORD_MAX_LENGTH: 75, - - // This is the same regex used to validate email addresses in Django 1.4 - EMAIL_REGEX: new RegExp( - "(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" + - '|^"([\\001-\\010\\013\\014\\016-\\037!#-\\[\\]-\\177]|\\\\[\\001-\\011\\013\\014\\016-\\177])*"' + - ')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\\.)+[A-Z]{2,6}\\.?$)' + - '|\\[(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\]$', - 'i' - ), - - defaults: { - email: '', - password: '' - }, - - urlRoot: 'email', - - sync: function(method, model) { - var headers = { - 'X-CSRFToken': $.cookie('csrftoken') - }; - - $.ajax({ - url: model.urlRoot, - type: 'POST', - data: model.attributes, - headers: headers - }) - .done(function() { - model.trigger('sync'); - }) - .fail(function() { - var error = gettext('The data could not be saved.'); - model.trigger('error', error); - }); - }, - - validate: function(attrs) { - var errors = {}; - - if (attrs.email.length < this.EMAIL_MIN_LENGTH || - attrs.email.length > this.EMAIL_MAX_LENGTH || - !this.EMAIL_REGEX.test(attrs.email) - ) { errors.email = gettext('Please enter a valid email address'); } - - if (attrs.password.length < this.PASSWORD_MIN_LENGTH || attrs.password.length > this.PASSWORD_MAX_LENGTH) { - errors.password = gettext('Please enter a valid password'); - } - - if (!$.isEmptyObject(errors)) { - return errors; - } - } - }); - - edx.student.account.AccountView = Backbone.View.extend({ - - events: { - submit: 'submit', - change: 'change', - 'click #password-reset': 'click' - }, - - initialize: function() { - _.bindAll(this, 'render', 'submit', 'change', 'click', 'clearStatus', 'invalid', 'error', 'sync'); - this.model = new edx.student.account.AccountModel(); - this.model.on('invalid', this.invalid); - this.model.on('error', this.error); - this.model.on('sync', this.sync); - }, - - render: function() { - this.$el.html(_.template($('#account-tpl').html())({})); - this.$email = $('#new-email', this.$el); - this.$password = $('#password', this.$el); - this.$emailStatus = $('#new-email-status', this.$el); - this.$passwordStatus = $('#password-status', this.$el); - this.$requestStatus = $('#request-email-status', this.$el); - this.$passwordReset = $('#password-reset', this.$el); - this.$passwordResetStatus = $('#password-reset-status', this.$el); - - return this; - }, - - submit: function(event) { - event.preventDefault(); - this.clearStatus(); - this.model.save(); - }, - - change: function() { - this.model.set({ - email: this.$email.val(), - password: this.$password.val() - }); - }, - - click: function(event) { - event.preventDefault(); - this.clearStatus(); - - var self = this; - $.ajax({ - url: 'password', - type: 'POST', - data: {}, - headers: { - 'X-CSRFToken': $.cookie('csrftoken') - } - }) - .done(function() { - self.$passwordResetStatus - .addClass('success') - .text(gettext('Password reset email sent. Follow the link in the email to change your password.')); - }) - .fail(function() { - self.$passwordResetStatus - .addClass('error') - .text(gettext("We weren't able to send you a password reset email.")); - }); - }, - - invalid: function(model) { - var errors = model.validationError; - - if (errors.hasOwnProperty('email')) { - this.$emailStatus - .addClass('validation-error') - .text(errors.email); - } - - if (errors.hasOwnProperty('password')) { - this.$passwordStatus - .addClass('validation-error') - .text(errors.password); - } - }, - - error: function(error) { - this.$requestStatus - .addClass('error') - .text(error); - }, - - sync: function() { - this.$requestStatus - .addClass('success') - .text(gettext('Please check your email to confirm the change')); - }, - - clearStatus: function() { - this.$emailStatus - .removeClass('validation-error') - .text(''); - - this.$passwordStatus - .removeClass('validation-error') - .text(''); - - this.$requestStatus - .removeClass('error') - .text(''); - - this.$passwordResetStatus - .removeClass('error') - .text(''); - } - }); - - try { - new edx.student.account.AccountView({ - el: $('#account-container') - }).render(); - } catch (e) { - // TODO: handle exception - } -}(jQuery, _, Backbone, gettext)); diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js index cd278f5cc6..88cd485897 100644 --- a/lms/static/lms/js/spec/main.js +++ b/lms/static/lms/js/spec/main.js @@ -778,7 +778,6 @@ 'js/spec/student_account/account_settings_factory_spec.js', 'js/spec/student_account/account_settings_fields_spec.js', 'js/spec/student_account/account_settings_view_spec.js', - 'js/spec/student_account/account_spec.js', 'js/spec/student_account/emailoptin_spec.js', 'js/spec/student_account/enrollment_spec.js', 'js/spec/student_account/finish_auth_spec.js',