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 535e534eec..b218d8612a 100644 --- a/modules/users/client/directives/password-validator.client.directive.js +++ b/modules/users/client/directives/password-validator.client.directive.js @@ -11,7 +11,7 @@ angular.module('users') var result = PasswordValidator.getResult(password); var requirementsIdx = 0; - // requirements Meter - visual indicator for users + // Requirements Meter - visual indicator for users var requirementsMeter = [ { color: 'danger', progress: '20' }, { color: 'warning', progress: '40' }, @@ -33,6 +33,7 @@ angular.module('users') status = false; } else { scope.popoverMsg = ''; + scope.passwordErrors = []; status = true; } } 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 = '
' + template + 'submit form
'; + + // 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 = '
' + template + 'submit form
'; + + // 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'); + }); }); });