diff --git a/gruntfile.js b/gruntfile.js
index 9564b81dfd..bb609408dc 100644
--- a/gruntfile.js
+++ b/gruntfile.js
@@ -258,6 +258,26 @@ module.exports = function (grunt) {
});
});
+ // Drops the MongoDB database, used in e2e testing
+ grunt.task.registerTask('dropdb', 'drop the database', function () {
+ // async mode
+ var done = this.async();
+
+ // Use mongoose configuration
+ var mongoose = require('./config/lib/mongoose.js');
+
+ mongoose.connect(function (db) {
+ db.connection.db.dropDatabase(function (err) {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log('Successfully dropped db: ', db.connection.db.databaseName);
+ }
+ db.connection.db.close(done);
+ });
+ });
+ });
+
grunt.task.registerTask('server', 'Starting the server', function () {
// Get the callback
var done = this.async();
@@ -279,7 +299,7 @@ module.exports = function (grunt) {
grunt.registerTask('test', ['env:test', 'lint', 'mkdir:upload', 'copy:localConfig', 'server', 'mochaTest', 'karma:unit', 'protractor']);
grunt.registerTask('test:server', ['env:test', 'lint', 'server', 'mochaTest']);
grunt.registerTask('test:client', ['env:test', 'lint', 'server', 'karma:unit']);
- grunt.registerTask('test:e2e', ['env:test', 'lint', 'server', 'protractor']);
+ grunt.registerTask('test:e2e', ['env:test', 'lint', 'dropdb', 'server', 'protractor']);
// Run project coverage
grunt.registerTask('coverage', ['env:test', 'lint', 'mocha_istanbul:coverage']);
diff --git a/gulpfile.js b/gulpfile.js
index 84e0cb6a64..ddde34e8f9 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -199,6 +199,23 @@ gulp.task('karma', function (done) {
}));
});
+// Drops the MongoDB database, used in e2e testing
+gulp.task('dropdb', function (done) {
+ // Use mongoose configuration
+ var mongoose = require('./config/lib/mongoose.js');
+
+ mongoose.connect(function (db) {
+ db.connection.db.dropDatabase(function (err) {
+ if(err) {
+ console.log(err);
+ } else {
+ console.log('Successfully dropped db: ', db.connection.db.databaseName);
+ }
+ db.connection.db.close(done);
+ });
+ });
+});
+
// Downloads the selenium webdriver
gulp.task('webdriver_update', webdriver_update);
@@ -248,7 +265,7 @@ gulp.task('test:client', function (done) {
});
gulp.task('test:e2e', function (done) {
- runSequence('env:test', 'lint', 'nodemon', 'protractor', done);
+ runSequence('env:test', 'lint', 'dropdb', 'nodemon', 'protractor', done);
});
// Run the project in development mode
diff --git a/modules/users/client/directives/password-validator.client.directive.js b/modules/users/client/directives/password-validator.client.directive.js
index a0ef1eaa95..b218d8612a 100644
--- a/modules/users/client/directives/password-validator.client.directive.js
+++ b/modules/users/client/directives/password-validator.client.directive.js
@@ -4,39 +4,41 @@ angular.module('users')
.directive('passwordValidator', ['PasswordValidator', function(PasswordValidator) {
return {
require: 'ngModel',
- link: function(scope, element, attrs, modelCtrl) {
- modelCtrl.$parsers.unshift(function (password) {
- var result = PasswordValidator.getResult(password);
- var strengthIdx = 0;
+ link: function(scope, element, attrs, ngModel) {
+ ngModel.$validators.requirements = function (password) {
+ var status = true;
+ if (password) {
+ var result = PasswordValidator.getResult(password);
+ var requirementsIdx = 0;
- // Strength Meter - visual indicator for users
- var strengthMeter = [
- { color: 'danger', progress: '20' },
- { color: 'warning', progress: '40' },
- { color: 'info', progress: '60' },
- { color: 'primary', progress: '80' },
- { color: 'success', progress: '100' }
- ];
- var strengthMax = strengthMeter.length;
+ // Requirements Meter - visual indicator for users
+ var requirementsMeter = [
+ { color: 'danger', progress: '20' },
+ { color: 'warning', progress: '40' },
+ { color: 'info', progress: '60' },
+ { color: 'primary', progress: '80' },
+ { color: 'success', progress: '100' }
+ ];
- if (result.errors.length < strengthMeter.length) {
- strengthIdx = strengthMeter.length - result.errors.length - 1;
- }
+ if (result.errors.length < requirementsMeter.length) {
+ requirementsIdx = requirementsMeter.length - result.errors.length - 1;
+ }
- scope.strengthColor = strengthMeter[strengthIdx].color;
- scope.strengthProgress = strengthMeter[strengthIdx].progress;
+ scope.requirementsColor = requirementsMeter[requirementsIdx].color;
+ scope.requirementsProgress = requirementsMeter[requirementsIdx].progress;
- if (result.errors.length) {
- scope.popoverMsg = PasswordValidator.getPopoverMsg();
- scope.passwordErrors = result.errors;
- modelCtrl.$setValidity('strength', false);
- return undefined;
- } else {
- scope.popoverMsg = '';
- modelCtrl.$setValidity('strength', true);
- return password;
+ if (result.errors.length) {
+ scope.popoverMsg = PasswordValidator.getPopoverMsg();
+ scope.passwordErrors = result.errors;
+ status = false;
+ } else {
+ scope.popoverMsg = '';
+ scope.passwordErrors = [];
+ status = true;
+ }
}
- });
+ return status;
+ };
}
};
}]);
diff --git a/modules/users/client/directives/password-verify.client.directive.js b/modules/users/client/directives/password-verify.client.directive.js
index e31565dbde..acb876899e 100644
--- a/modules/users/client/directives/password-verify.client.directive.js
+++ b/modules/users/client/directives/password-verify.client.directive.js
@@ -7,27 +7,22 @@ angular.module('users')
scope: {
passwordVerify: '='
},
- link: function(scope, element, attrs, modelCtrl) {
+ link: function(scope, element, attrs, ngModel) {
+ var status = true;
scope.$watch(function() {
var combined;
- if (scope.passwordVerify || modelCtrl.$viewValue) {
- combined = scope.passwordVerify + '_' + modelCtrl.$viewValue;
+ if (scope.passwordVerify || ngModel) {
+ combined = scope.passwordVerify + '_' + ngModel;
}
return combined;
}, function(value) {
if (value) {
- modelCtrl.$parsers.unshift(function(viewValue) {
+ ngModel.$validators.passwordVerify = function (password) {
var origin = scope.passwordVerify;
- if (origin !== viewValue) {
- modelCtrl.$setValidity('passwordVerify', false);
- return undefined;
- } else {
- modelCtrl.$setValidity('passwordVerify', true);
- return viewValue;
- }
- });
+ return (origin !== password) ? false : true;
+ };
}
});
- }
+ }
};
});
diff --git a/modules/users/client/views/authentication/signup.client.view.html b/modules/users/client/views/authentication/signup.client.view.html
index 65fbb4bb5c..7093ff1392 100644
--- a/modules/users/client/views/authentication/signup.client.view.html
+++ b/modules/users/client/views/authentication/signup.client.view.html
@@ -38,13 +38,13 @@
Or sign up using your email
Password is required.
-
{{passwordError}}
+
{{passwordError}}
-
-
-
-
-
{{strengthProgress}}%
+
diff --git a/modules/users/tests/client/password-validator.client.directive.tests.js b/modules/users/tests/client/password-validator.client.directive.tests.js
new file mode 100644
index 0000000000..c6f318349c
--- /dev/null
+++ b/modules/users/tests/client/password-validator.client.directive.tests.js
@@ -0,0 +1,208 @@
+'use strict';
+
+(function() {
+ // Password Validator Directive Spec
+ describe('PasswordValidatorDirective', function() {
+ // Initialize global variables
+ var scope,
+ element,
+ $compile,
+ form;
+
+ // Load the main application module
+ beforeEach(module(ApplicationConfiguration.applicationModuleName));
+
+ beforeEach(inject(function(_$rootScope_, _$compile_) {
+ // Set a new global scope
+ scope = _$rootScope_.$new();
+ $compile = _$compile_;
+
+ scope.passwordMock = {
+ password: 'P@ssw0rd!!'
+ };
+ }));
+
+ function compileDirective(template) {
+ // function to compile a fresh directive with the given template, or a default one
+ // input form with directive
+ if (!template) template = '
';
+ template = '
';
+
+ // inject allows you to use AngularJS dependency injection
+ // to retrieve and use other services
+ inject(function($compile) {
+ var form = $compile(template)(scope);
+ element = form.find('div');
+
+ // $digest is necessary to finalize the directive generation
+ scope.$digest();
+ });
+ }
+
+ describe('Initialize', function() {
+ beforeEach(function () {
+ compileDirective();
+ });
+
+ it('should produce the password input', function () {
+ expect(element.find('input').length).toEqual(2);
+ });
+
+ it('should check form validity upon initializing', function () {
+ expect(scope.form.$valid).toBeTruthy();
+ });
+
+ });
+
+ it('should set form to invalid with empty password', function () {
+ scope.passwordMock.password = '';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeTruthy();
+ expect(scope.requirementsColor).toEqual(undefined);
+ expect(scope.requirementsProgress).toEqual(undefined);
+ });
+
+ it('should be valid when password meets requirements - "P@ssw0rd!!""', function() {
+ scope.passwordMock.password = 'P@ssw0rd!!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeTruthy();
+ expect(scope.form.password.$error).toEqual({});
+ expect(scope.requirementsColor).toEqual('success');
+ expect(scope.requirementsProgress).toEqual('100');
+ });
+
+ it('should be valid when password meets requirements with a passphrase', function() {
+ scope.passwordMock.password = 'Open-Source Full-Stack Solution for MEAN';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeTruthy();
+ expect(scope.form.password.$error).toEqual({});
+ expect(scope.requirementsColor).toEqual('success');
+ expect(scope.requirementsProgress).toEqual('100');
+ });
+
+ it('should not allow a less than 10 characters long - "P@$$w0rd!"', function() {
+ scope.passwordMock.password = 'P@$$w0rd!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password must be at least 10 characters long.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should not allow a greater than 128 characters long', function() {
+ scope.passwordMock.password = ')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password must be fewer than 128 characters.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should not allow more than 3 or more repeating characters - "P@$$w0rd!!!"', function() {
+ scope.passwordMock.password = 'P@$$w0rd!!!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password may not contain sequences of three or more repeated characters.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should not allow a password with no uppercase letters - "p@$$w0rd!!"', function() {
+ scope.passwordMock.password = 'p@$$w0rd!!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password must contain at least one uppercase letter.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should not allow a password with less than one number - "P@$$word!!"', function() {
+ scope.passwordMock.password = 'P@$$word!!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password must contain at least one number.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should not allow a password with less than one special character - "Passw0rdss"', function() {
+ scope.passwordMock.password = 'Passw0rdss';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.form.password.$valid).toBeFalsy();
+ expect(scope.form.password.$error.required).toBeFalsy();
+ expect(scope.passwordErrors).toEqual(['The password must contain at least one special character.']);
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should show 20% progress and "danger" color', function() {
+ scope.passwordMock.password = 'P';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.requirementsColor).toEqual('danger');
+ expect(scope.requirementsProgress).toEqual('20');
+ });
+
+ it('should show 40% progress and "warning" color', function() {
+ scope.passwordMock.password = 'Pa';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.requirementsColor).toEqual('warning');
+ expect(scope.requirementsProgress).toEqual('40');
+ });
+
+ it('should show 60% progress and "info" color', function() {
+ scope.passwordMock.password = 'Pa$';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.requirementsColor).toEqual('info');
+ expect(scope.requirementsProgress).toEqual('60');
+ });
+
+ it('should show 80% progress and "primary" color', function() {
+ scope.passwordMock.password = 'Pa$$w0rd';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.requirementsColor).toEqual('primary');
+ expect(scope.requirementsProgress).toEqual('80');
+ });
+
+ it('should show 100% progress and "success" color', function() {
+ scope.passwordMock.password = 'Pa$$w0rd!!';
+ compileDirective();
+ scope.$digest();
+
+ expect(scope.requirementsColor).toEqual('success');
+ expect(scope.requirementsProgress).toEqual('100');
+ });
+
+ });
+}());
diff --git a/modules/users/tests/client/password-verify.client.directive.tests.js b/modules/users/tests/client/password-verify.client.directive.tests.js
new file mode 100644
index 0000000000..a4481ecad1
--- /dev/null
+++ b/modules/users/tests/client/password-verify.client.directive.tests.js
@@ -0,0 +1,86 @@
+'use strict';
+
+(function() {
+ // Password Verify Directive Spec
+ describe('PasswordVerifyDirective', function() {
+ // Initialize global variables
+ var scope,
+ element,
+ $compile,
+ form;
+
+ // Load the main application module
+ beforeEach(module(ApplicationConfiguration.applicationModuleName));
+
+ beforeEach(inject(function(_$rootScope_, _$compile_) {
+ // Set a new global scope
+ scope = _$rootScope_.$new();
+ $compile = _$compile_;
+
+ scope.passwordMock = {
+ newPassword: 'P@ssw0rd!!',
+ verifyPassword: 'P@ssw0rd!!'
+ };
+ }));
+
+ function compileDirective(template) {
+ // function to compile a fresh directive with the given template, or a default one
+ // input form with directive
+ if (!template) template = '
' +
+ '
';
+ template = '
';
+
+ // inject allows you to use AngularJS dependency injection
+ // to retrieve and use other services
+ inject(function($compile) {
+ var form = $compile(template)(scope);
+ element = form.find('div');
+
+ // $digest is necessary to finalize the directive generation
+ scope.$digest();
+ });
+ }
+
+ describe('Initialize', function() {
+ beforeEach(function () {
+ compileDirective();
+ });
+
+ it('should produce the password input', function () {
+ expect(element.find('input').length).toEqual(3);
+ });
+
+ it('should check form validity upon initializing', function () {
+ expect(scope.form.$valid).toBeTruthy();
+ });
+
+ });
+
+ it('should not show error when passwords match', function () {
+ compileDirective();
+ scope.passwordMock.newPassword = 'P@ssw0rd!!';
+ scope.passwordMock.verifyPassword = 'P@ssw0rd!!';
+ scope.$digest();
+
+ expect(scope.form.newPassword.$valid).toBeTruthy();
+ expect(scope.form.newPassword.$error).toEqual({});
+ expect(scope.form.verifyPassword.$valid).toBeTruthy();
+ expect(scope.form.verifyPassword.$error).toEqual({});
+ expect(scope.form.$valid).toBeTruthy();
+ });
+
+ it('should show error when passwords do not match', function () {
+ compileDirective();
+ scope.passwordMock.newPassword = 'P@ssw0rd!!';
+ scope.passwordMock.verifyPassword = 'P@ssw0rd!';
+ scope.$digest();
+
+ expect(scope.form.newPassword.$valid).toBeTruthy();
+ expect(scope.form.newPassword.$error).toEqual({});
+ expect(scope.form.verifyPassword.$valid).toBeFalsy();
+ expect(scope.form.verifyPassword.$error.passwordVerify).toBeTruthy();
+ expect(scope.form.$valid).toBeFalsy();
+ });
+
+ });
+}());
diff --git a/modules/users/tests/client/password.client.controller.tests.js b/modules/users/tests/client/password.client.controller.tests.js
index 2b1f4a6718..5f0d59e651 100644
--- a/modules/users/tests/client/password.client.controller.tests.js
+++ b/modules/users/tests/client/password.client.controller.tests.js
@@ -1,7 +1,7 @@
'use strict';
(function() {
- // Authentication controller Spec
+ // Password controller Spec
describe('PasswordController', function() {
// Initialize global variables
var PasswordController,
diff --git a/modules/users/tests/e2e/users.e2e.tests.js b/modules/users/tests/e2e/users.e2e.tests.js
index 1cb9c6c4bc..abff70dda5 100644
--- a/modules/users/tests/e2e/users.e2e.tests.js
+++ b/modules/users/tests/e2e/users.e2e.tests.js
@@ -1,14 +1,442 @@
'use strict';
describe('Users E2E Tests:', function () {
+ var user1 = {
+ firstName: 'test',
+ lastName: 'user',
+ email: 'test.user@meanjs.com',
+ username: 'testUser',
+ password: 'P@$$w0rd!!'
+ };
+
+ var user2 = {
+ firstName: 'test',
+ lastName: 'user2',
+ email: 'test.user2@meanjs.com',
+ username: 'testUser2',
+ password: 'P@$$w0rd!!'
+ };
+
+ var signout = function () {
+ // Make sure user is signed out first
+ browser.get('http://localhost:3001/authentication/signout');
+ // Delete all cookies
+ browser.driver.manage().deleteAllCookies();
+ };
+
+ describe('Signup Validation', function () {
+ it('Should report missing first name', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // First Name Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('First name is required.');
+ });
+
+ it('Should report missing last name', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Last Name Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Last name is required.');
+ });
+
+ it('Should report missing email address', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Email address error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is required.');
+ });
+
+ it('Should report invalid email address - "123"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys('123');
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Email address error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is invalid.');
+ });
+
+ /**
+ * Note: 123@123 is a valid email adress according to HTML5.
+ * However, 123@123@123 is an invalid email address.
+ */
+ it('Should report invalid email address - "123@123@123"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys('123@123@123');
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Email address error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Email address is invalid.');
+ });
+
+ it('Should report missing username', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Username Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Username is required.');
+ });
+
+ it('Should report a password with less than 10 characters long - "P@$$w0rd!"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys('P@$$w0rd!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be at least 10 characters long.');
+ });
+
+ it('Should report a password with greater than 128 characters long.', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys(')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be fewer than 128 characters.');
+ });
+
+ it('Should report a password with more than 3 or more repeating characters - "P@$$w0rd!!!"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys('P@$$w0rd!!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password may not contain sequences of three or more repeated characters.');
+ });
+
+ it('Should report a password with no uppercase letters - "p@$$w0rd!!"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys('p@$$w0rd!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one uppercase letter.');
+ });
+
+ it('Should report a password with less than one number - "P@$$word!!"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys('P@$$word!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one number.');
+ });
+
+ it('Should report a password with less than one special character - "Passw0rdss"', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys('Passw0rdss');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one special character.');
+ });
+
+ it('Should Successfully register new user', function () {
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter FirstName
+ element(by.model('credentials.firstName')).sendKeys(user1.firstName);
+ // Enter LastName
+ element(by.model('credentials.lastName')).sendKeys(user1.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter UserName
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type="submit"]')).click();
+ expect(browser.getCurrentUrl()).toEqual('http://localhost:3001/');
+ });
+
+ it('Should report Email already exists', function () {
+ // Make sure user is signed out first
+ signout();
+ // Signup
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user2.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user2.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user1.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user2.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys(user2.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('strong')).get(0).getText()).toBe('Email already exists');
+ });
+
+ it('Should report Username already exists', function () {
+ // Signup
+ browser.get('http://localhost:3001/authentication/signup');
+ // Enter First Name
+ element(by.model('credentials.firstName')).sendKeys(user2.firstName);
+ // Enter Last Name
+ element(by.model('credentials.lastName')).sendKeys(user2.lastName);
+ // Enter Email
+ element(by.model('credentials.email')).sendKeys(user2.email);
+ // Enter Username
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Invalid Password
+ element(by.model('credentials.password')).sendKeys(user2.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('strong')).get(0).getText()).toBe('Username already exists');
+ });
+
+ });
+
describe('Signin Validation', function () {
+
it('Should report missing credentials', function () {
+ //Make sure user is signed out first
+ signout();
+ //Sign in
browser.get('http://localhost:3001/authentication/signin');
- element(by.css('button[type=submit]')).click();
+ // Click Submit button
+ element(by.css('button[type="submit"]')).click();
// Username Error
expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Username is required.');
// Password Error
expect(element.all(by.css('.error-text')).get(1).getText()).toBe('Password is required.');
});
+
+ it('Verify that the user is logged in', function() {
+ //Make sure user is signed out first
+ signout();
+ //Sign in
+ browser.get('http://localhost:3001/authentication/signin');
+ // Enter UserName
+ element(by.model('credentials.username')).sendKeys(user1.username);
+ // Enter Password
+ element(by.model('credentials.password')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type="submit"]')).click();
+ expect(browser.getCurrentUrl()).toEqual('http://localhost:3001/');
+ });
+
+ });
+
+ describe ('Change Password Settings Validation', function () {
+
+ it('Should report missing passwords', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Errors
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Your current password is required.');
+ expect(element.all(by.css('.error-text')).get(1).getText()).toBe('Enter a new password.');
+ expect(element.all(by.css('.error-text')).get(2).getText()).toBe('Verify your new password.');
+ });
+
+ it('Should report a password with less than 10 characters long - "P@$$w0rd!"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rd!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be at least 10 characters long.');
+ });
+
+ it('Should report a password with greater than 128 characters long.', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys(')!/uLT="lh&:`6X!]|15o!$!TJf,.13l?vG].-j],lFPe/QhwN#{Z<[*1nX@n1^?WW-%_.*D)m$toB+N7z}kcN#B_d(f41h%w@0F!]igtSQ1gl~6sEV&r~}~1ub>If1c+');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must be fewer than 128 characters.');
+ });
+
+ it('Should report a password with more than 3 or more repeating characters - "P@$$w0rd!!!"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rd!!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password may not contain sequences of three or more repeated characters.');
+ });
+
+ it('Should report a password with no uppercase letters - "p@$$w0rd!!"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('p@$$w0rd!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one uppercase letter.');
+ });
+
+ it('Should report a password with less than one number - "P@$$word!!"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('P@$$word!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one number.');
+ });
+
+ it('Should report a password with less than one special character - "Passw0rdss"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter Invalid Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('Passw0rdss');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Error
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('The password must contain at least one special character.');
+ });
+
+ it('Should report passwords do not match', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter New Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rds!!');
+ // Verify New Password
+ element(by.model('passwordDetails.verifyPassword')).sendKeys(user1.password);
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Errors
+ expect(element.all(by.css('.error-text')).get(0).getText()).toBe('Passwords do not match.');
+ });
+
+ it('Should change the password to - "P@$$w0rds!!"', function () {
+ browser.get('http://localhost:3001/settings/password');
+ // Enter Current Password
+ element(by.model('passwordDetails.currentPassword')).sendKeys(user1.password);
+ // Enter New Password
+ element(by.model('passwordDetails.newPassword')).sendKeys('P@$$w0rds!!');
+ // Verify New Password
+ element(by.model('passwordDetails.verifyPassword')).sendKeys('P@$$w0rds!!');
+ // Click Submit button
+ element(by.css('button[type=submit]')).click();
+ // Password Changed
+ expect(element.all(by.css('.text-success')).get(0).getText()).toBe('Password Changed Successfully');
+ });
});
});