mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-03-06 12:11:02 +01:00
Merge pull request #910 from jloveland/hide-password-validator
Hide the password strength progress when the field is empty
This commit is contained in:
22
gruntfile.js
22
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']);
|
||||
|
||||
19
gulpfile.js
19
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
|
||||
|
||||
@@ -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.requirementsColor = requirementsMeter[requirementsIdx].color;
|
||||
scope.requirementsProgress = requirementsMeter[requirementsIdx].progress;
|
||||
|
||||
if (result.errors.length) {
|
||||
scope.popoverMsg = PasswordValidator.getPopoverMsg();
|
||||
scope.passwordErrors = result.errors;
|
||||
status = false;
|
||||
} else {
|
||||
scope.popoverMsg = '';
|
||||
scope.passwordErrors = [];
|
||||
status = true;
|
||||
}
|
||||
}
|
||||
|
||||
scope.strengthColor = strengthMeter[strengthIdx].color;
|
||||
scope.strengthProgress = strengthMeter[strengthIdx].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;
|
||||
}
|
||||
});
|
||||
return status;
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
@@ -7,25 +7,20 @@ 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;
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -38,13 +38,13 @@
|
||||
<div ng-messages="userForm.password.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">Password is required.</p>
|
||||
<div ng-repeat="passwordError in passwordErrors">
|
||||
<p class="help-block error-text" ng-show="userForm.password.$error.strength">{{passwordError}}</p>
|
||||
<p class="help-block error-text" ng-show="userForm.password.$error.requirements">{{passwordError}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="!userForm.password.$pristine">
|
||||
<label>Password Strength</label>
|
||||
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
|
||||
<div class="form-group" ng-show="!userForm.password.$error.required">
|
||||
<label>Password Requirements</label>
|
||||
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
|
||||
</div>
|
||||
<div class="text-center form-group">
|
||||
<button type="submit" class="btn btn-primary">Sign up</button>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div ng-messages="resetPasswordForm.newPassword.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">Enter a new password.</p>
|
||||
<div ng-repeat="passwordError in passwordErrors">
|
||||
<p class="help-block error-text" ng-show="resetPasswordForm.newPassword.$error.strength">{{passwordError}}</p>
|
||||
<p class="help-block error-text" ng-show="resetPasswordForm.newPassword.$error.requirements">{{passwordError}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,9 +21,9 @@
|
||||
<p class="help-block error-text" ng-show=resetPasswordForm.verifyPassword.$error.passwordVerify>Passwords do not match.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="!resetPasswordForm.newPassword.$pristine">
|
||||
<label>Password Strength</label>
|
||||
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
|
||||
<div class="form-group" ng-show="!resetPasswordForm.newPassword.$error.required">
|
||||
<label>Password Requirements</label>
|
||||
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
|
||||
</div>
|
||||
<div class="text-center form-group">
|
||||
<button type="submit" class="btn btn-primary">Update Password</button>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<div ng-messages="passwordForm.newPassword.$error" role="alert">
|
||||
<p class="help-block error-text" ng-message="required">Enter a new password.</p>
|
||||
<div ng-repeat="passwordError in passwordErrors">
|
||||
<p class="help-block error-text" ng-show="passwordForm.newPassword.$error.strength">{{passwordError}}</p>
|
||||
<p class="help-block error-text" ng-show="passwordForm.newPassword.$error.requirements">{{passwordError}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,9 +27,9 @@
|
||||
<p class="help-block error-text" ng-show=passwordForm.verifyPassword.$error.passwordVerify>Passwords do not match.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="!passwordForm.newPassword.$pristine">
|
||||
<label>Password Strength</label>
|
||||
<progressbar value="strengthProgress" type="{{strengthColor}}"><span style="color:white; white-space:nowrap;">{{strengthProgress}}%</span></progressbar>
|
||||
<div class="form-group" ng-show="!passwordForm.newPassword.$error.required">
|
||||
<label>Password Requirements</label>
|
||||
<progressbar value="requirementsProgress" type="{{requirementsColor}}"><span style="color:white; white-space:nowrap;">{{requirementsProgress}}%</span></progressbar>
|
||||
</div>
|
||||
<div class="text-center form-group">
|
||||
<button type="submit" class="btn btn-primary">Save Password</button>
|
||||
|
||||
@@ -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 = '<input type="password" id="password" name="password" ng-model="passwordMock.password" password-validator required>';
|
||||
template = '<form name="form"><div>' + template + '<input type="submit">submit form</input></div></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');
|
||||
});
|
||||
|
||||
});
|
||||
}());
|
||||
@@ -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 = '<input type="password" id="newPassword" name="newPassword" class="form-control" ng-model="passwordMock.newPassword" placeholder="New Password" autocomplete="new-password" popover="{{popoverMsg}}" popover-trigger="focus" popover-placement="top" password-validator required>' +
|
||||
'<input type="password" id="verifyPassword" name="verifyPassword" class="form-control" ng-model="passwordMock.verifyPassword" placeholder="Verify Password" password-verify="passwordMock.newPassword" required>';
|
||||
template = '<form name="form"><div>' + template + '<input type="submit">submit form</input></div></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();
|
||||
});
|
||||
|
||||
});
|
||||
}());
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
(function() {
|
||||
// Authentication controller Spec
|
||||
// Password controller Spec
|
||||
describe('PasswordController', function() {
|
||||
// Initialize global variables
|
||||
var PasswordController,
|
||||
|
||||
@@ -1,14 +1,442 @@
|
||||
'use strict';
|
||||
|
||||
describe('Users E2E Tests:', function () {
|
||||
describe('Signin Validation', function () {
|
||||
it('Should report missing credentials', function () {
|
||||
browser.get('http://localhost:3001/authentication/signin');
|
||||
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');
|
||||
// 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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user