mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-24 02:13:15 +00:00
Add unit tests
This commit is contained in:
committed by
Romain Neutron
parent
e6418df60e
commit
700324be09
@@ -71,6 +71,7 @@
|
|||||||
<script src="/skins/login/js/bootstrap-switch.js"></script>
|
<script src="/skins/login/js/bootstrap-switch.js"></script>
|
||||||
<script src="/assets/underscore/underscore.js"></script>
|
<script src="/assets/underscore/underscore.js"></script>
|
||||||
<script src="/skins/login/js/main.js"></script>
|
<script src="/skins/login/js/main.js"></script>
|
||||||
|
<script src="/skins/login/js/angular/app/app.js"></script>
|
||||||
{% endblock header_javascript %}
|
{% endblock header_javascript %}
|
||||||
{% endblock header %}
|
{% endblock header %}
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
144
www/skins/login/js/angular/app/app.js
vendored
Normal file
144
www/skins/login/js/angular/app/app.js
vendored
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
// controllers
|
||||||
|
function LoginFormController($scope) {
|
||||||
|
$scope.$watch('loginForm', function() {
|
||||||
|
$scope.loginForm.email.errors = {'filled' : true, 'valid' : true};
|
||||||
|
$scope.loginForm.password.errors = {'filled' : true, 'valid' : true};
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.submit = function() {
|
||||||
|
$scope.$broadcast('event:force-model-update');
|
||||||
|
|
||||||
|
if (true === $scope.loginForm.$valid) {
|
||||||
|
$scope.loginForm.email.errors = {'filled' : true, 'valid' : true};
|
||||||
|
$scope.loginForm.password.errors = {'filled' : true,'valid' : true};
|
||||||
|
// submit
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.loginForm.email.errors.valid = $scope.loginForm.email.$valid;
|
||||||
|
$scope.loginForm.email.errors.filled = !$scope.loginForm.email.$error.required;
|
||||||
|
|
||||||
|
$scope.loginForm.password.errors.filled = !$scope.loginForm.password.$error.required;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getInputClass = function(name) {
|
||||||
|
return _.every($scope.loginForm[name].errors, function(value) {
|
||||||
|
return value === true;
|
||||||
|
}) ? '' : 'input-table-error';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function forgottenPasswordFormCtrl($scope) {
|
||||||
|
$scope.$watch('forgottenPasswordForm', function() {
|
||||||
|
$scope.forgottenPasswordForm.email.errors = {'filled' : true, 'valid' : true};
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.submit = function() {
|
||||||
|
$scope.$broadcast('event:force-model-update');
|
||||||
|
|
||||||
|
if (true === $scope.forgottenPasswordForm.$valid) {
|
||||||
|
$scope.forgottenPasswordForm.email.errors = {'filled' : true, 'valid' : true};
|
||||||
|
// submit
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.forgottenPasswordForm.email.errors.valid = $scope.forgottenPasswordForm.email.$valid;
|
||||||
|
$scope.forgottenPasswordForm.email.errors.filled = !$scope.forgottenPasswordForm.email.$error.required;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getInputClass = function(name) {
|
||||||
|
return _.every($scope.forgottenPasswordForm[name].errors, function(value) {
|
||||||
|
return value === true;
|
||||||
|
}) ? '' : 'input-table-error';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function passwordChangeFormCtrl($scope) {
|
||||||
|
$scope.$watch('passwordChangeForm', function() {
|
||||||
|
$scope.passwordChangeForm.password.errors = {'filled' : true, 'valid' : true};
|
||||||
|
$scope.passwordChangeForm.passwordConfirm.errors = {'filled' : true, 'valid' : true};
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.submit = function() {
|
||||||
|
$scope.$broadcast('event:force-model-update');
|
||||||
|
|
||||||
|
if (true === $scope.passwordChangeForm.$valid) {
|
||||||
|
$scope.passwordChangeForm.password.errors = {'filled' : true, 'valid' : true};
|
||||||
|
$scope.passwordChangeForm.passwordConfirm.errors = {'filled' : true, 'valid' : true};
|
||||||
|
// submit
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.passwordChangeForm.password.errors.filled = !$scope.passwordChangeForm.password.$error.required;
|
||||||
|
$scope.passwordChangeForm.passwordConfirm.errors.filled = !$scope.passwordChangeForm.passwordConfirm.$error.required;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getInputClass = function(name) {
|
||||||
|
return _.every($scope.passwordChangeForm[name].errors, function(value) {
|
||||||
|
return value === true;
|
||||||
|
}) ? '' : 'input-table-error';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// bootstrap angular
|
||||||
|
angular.element(document).ready(function() {
|
||||||
|
angular.bootstrap(document, ['phraseanetAuthentication']);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// angular app
|
||||||
|
angular.module('phraseanetAuthentication', ['ui'])
|
||||||
|
// force model update for autofill inputs. Yuck.
|
||||||
|
.directive('forceModelUpdate', function($compile) {
|
||||||
|
return {
|
||||||
|
restrict: 'A',
|
||||||
|
require: 'ngModel',
|
||||||
|
link: function(scope, element, attrs, ctrl) {
|
||||||
|
scope.$on('event:force-model-update', function() {
|
||||||
|
ctrl.$setViewValue(element.val());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).directive('alert', function () {
|
||||||
|
return {
|
||||||
|
restrict:'EA',
|
||||||
|
template: [
|
||||||
|
'<div class="alert" ng-class=\'type && "alert-" + type || "warning"\'>',
|
||||||
|
'<table><tr>',
|
||||||
|
'<td class="alert-block-logo"><i class="icon-2x icon-white" ng-class=\'icon || "icon-exclamation-sign"\'></i></td>',
|
||||||
|
'<td class="alert-block-content" ng-transclude></td>',
|
||||||
|
'<td class="alert-block-close"><a href="#"><b>×</b></a></td>',
|
||||||
|
'</tr></table>',
|
||||||
|
'</div>'
|
||||||
|
].join(''),
|
||||||
|
transclude:true,
|
||||||
|
replace:true,
|
||||||
|
scope:{
|
||||||
|
type: '@'
|
||||||
|
},
|
||||||
|
compile: function (element, attrs, transclude) {
|
||||||
|
return function (scope, element, attr) {
|
||||||
|
if (true === 'type' in attrs) {
|
||||||
|
switch (attrs.type) {
|
||||||
|
case 'error' :
|
||||||
|
scope.icon = 'icon-warning-sign';
|
||||||
|
break;
|
||||||
|
case 'success' :
|
||||||
|
scope.icon = 'icon-ok-sign';
|
||||||
|
break;
|
||||||
|
case 'info' :
|
||||||
|
scope.icon = 'icon-info-sign';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
16
www/skins/login/js/angular/config/testacular.conf.js
Normal file
16
www/skins/login/js/angular/config/testacular.conf.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
basePath = '../../../../../';
|
||||||
|
|
||||||
|
files = [
|
||||||
|
JASMINE,
|
||||||
|
JASMINE_ADAPTER,
|
||||||
|
'assets/angular/angular.js',
|
||||||
|
'assets/angular-ui/build/angular-ui.js',
|
||||||
|
'assets/underscore/underscore.js',
|
||||||
|
'assets/angular-mocks/angular-mocks.js',
|
||||||
|
'skins/login/js/angular/app/*.js',
|
||||||
|
'skins/login/js/angular/tests/unit/*.js'
|
||||||
|
];
|
||||||
|
|
||||||
|
autoWatch = true;
|
||||||
|
|
||||||
|
browsers = ['firefox'];
|
||||||
11
www/skins/login/js/angular/scripts/test.bat
Normal file
11
www/skins/login/js/angular/scripts/test.bat
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
REM Windows script for running unit tests
|
||||||
|
REM You have to run server and capture some browser first
|
||||||
|
REM
|
||||||
|
REM Requirements:
|
||||||
|
REM - NodeJS (http://nodejs.org/)
|
||||||
|
REM - Testacular (npm install -g testacular)
|
||||||
|
|
||||||
|
set BASE_DIR=%~dp0
|
||||||
|
testacular start "%BASE_DIR%\..\config\testacular.conf.js" %*
|
||||||
9
www/skins/login/js/angular/scripts/test.sh
Normal file
9
www/skins/login/js/angular/scripts/test.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BASE_DIR=`dirname $0`
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Starting Testacular Server (http://vojtajina.github.com/testacular)"
|
||||||
|
echo "-------------------------------------------------------------------"
|
||||||
|
|
||||||
|
testacular start $BASE_DIR/../config/testacular.conf.js $*
|
||||||
19
www/skins/login/js/angular/scripts/watchr.rb
Normal file
19
www/skins/login/js/angular/scripts/watchr.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env watchr
|
||||||
|
|
||||||
|
# config file for watchr http://github.com/mynyml/watchr
|
||||||
|
# install: gem install watchr
|
||||||
|
# run: watch watchr.rb
|
||||||
|
# note: make sure that you have jstd server running (server.sh) and a browser captured
|
||||||
|
|
||||||
|
log_file = File.expand_path(File.dirname(__FILE__) + '/../logs/jstd.log')
|
||||||
|
|
||||||
|
`cd ..`
|
||||||
|
`touch #{log_file}`
|
||||||
|
|
||||||
|
puts "String watchr... log file: #{log_file}"
|
||||||
|
|
||||||
|
watch( '(app/js|test/unit)' ) do
|
||||||
|
`echo "\n\ntest run started @ \`date\`" > #{log_file}`
|
||||||
|
`scripts/test.sh &> #{log_file}`
|
||||||
|
end
|
||||||
|
|
||||||
107
www/skins/login/js/angular/tests/unit/controllersSpec.js
vendored
Normal file
107
www/skins/login/js/angular/tests/unit/controllersSpec.js
vendored
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
describe('LoginFormController', function(){
|
||||||
|
var scope;
|
||||||
|
beforeEach(inject(function($rootScope) {
|
||||||
|
scope = $rootScope.$new();
|
||||||
|
|
||||||
|
scope.loginForm = {
|
||||||
|
email : {
|
||||||
|
errors:{},
|
||||||
|
$valid : true,
|
||||||
|
$error : {
|
||||||
|
required : false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
password : {
|
||||||
|
errors:{},
|
||||||
|
$valid : true,
|
||||||
|
$error : {
|
||||||
|
required : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should create model errors with 2 validation for each input', inject(function($controller) {
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$digest();
|
||||||
|
|
||||||
|
expect(Object.keys(scope.loginForm.email.errors).length).toEqual(2);
|
||||||
|
expect(Object.keys(scope.loginForm.password.errors).length).toEqual(2);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should return input-table-error class when input is not valid', inject(function($controller) {
|
||||||
|
scope.loginForm.email.errors.valid = false;
|
||||||
|
scope.loginForm.password.errors.valid = true;
|
||||||
|
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(scope.getInputClass('password')).toBe('');
|
||||||
|
expect(scope.getInputClass('email')).toEqual('input-table-error');
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('The valid email input validation should be equal to input form validation if form is submited and not valid', inject(function($controller) {
|
||||||
|
scope.loginForm.$valid = false;
|
||||||
|
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$digest();
|
||||||
|
|
||||||
|
expect(scope.loginForm.email.errors.valid).toBe(scope.loginForm.email.$valid);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('The filled password and email input validation should be true if input is not required and form is submited and not valid', inject(function($controller) {
|
||||||
|
scope.loginForm.$valid = false;
|
||||||
|
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$digest();
|
||||||
|
|
||||||
|
expect(scope.loginForm.email.errors.filled).not.toBe(scope.loginForm.email.$error.required);
|
||||||
|
expect(scope.loginForm.password.errors.filled).not.toBe(scope.loginForm.password.$error.required);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('Should reset input validation errors when form is submited and valid', inject(function($controller) {
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$digest();
|
||||||
|
|
||||||
|
var startEmailState = _.clone(scope.loginForm.email.errors);
|
||||||
|
var startPasswordState = _.clone(scope.loginForm.password.errors);
|
||||||
|
|
||||||
|
scope.loginForm.$valid = true;
|
||||||
|
|
||||||
|
scope.loginForm.email.errors.valid = false;
|
||||||
|
scope.loginForm.password.errors.valid = false;
|
||||||
|
|
||||||
|
scope.submit();
|
||||||
|
|
||||||
|
expect(scope.loginForm.email.errors).toEqual(startEmailState);
|
||||||
|
expect(scope.loginForm.password.errors).toEqual(startPasswordState);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should not submit form if it is not valid', inject(function($controller) {
|
||||||
|
scope.loginForm.$valid = false;
|
||||||
|
|
||||||
|
$controller(LoginFormController, {
|
||||||
|
$scope: scope
|
||||||
|
});
|
||||||
|
|
||||||
|
scope.$digest();
|
||||||
|
|
||||||
|
expect(scope.submit()).toBe(false);
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
@@ -6,146 +6,3 @@ $(document).ready(function() {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// angular app
|
|
||||||
angular.module('phraseanetAuthentication', ['ui'])
|
|
||||||
// force model update for autofill inputs. Yuck.
|
|
||||||
.directive('forceModelUpdate', function($compile) {
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
require: 'ngModel',
|
|
||||||
link: function(scope, element, attrs, ctrl) {
|
|
||||||
scope.$on('event:force-model-update', function() {
|
|
||||||
ctrl.$setViewValue(element.val());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).directive('alert', function () {
|
|
||||||
return {
|
|
||||||
restrict:'EA',
|
|
||||||
template: [
|
|
||||||
'<div class="alert" ng-class=\'type && "alert-" + type || "warning"\'>',
|
|
||||||
'<table><tr>',
|
|
||||||
'<td class="alert-block-logo"><i class="icon-2x icon-white" ng-class=\'icon || "icon-exclamation-sign"\'></i></td>',
|
|
||||||
'<td class="alert-block-content" ng-transclude></td>',
|
|
||||||
'<td class="alert-block-close"><a href="#"><b>×</b></a></td>',
|
|
||||||
'</tr></table>',
|
|
||||||
'</div>'
|
|
||||||
].join(''),
|
|
||||||
transclude:true,
|
|
||||||
replace:true,
|
|
||||||
scope:{
|
|
||||||
type: '@'
|
|
||||||
},
|
|
||||||
compile: function (element, attrs, transclude) {
|
|
||||||
return function (scope, element, attr) {
|
|
||||||
if (true === 'type' in attrs) {
|
|
||||||
switch (attrs.type) {
|
|
||||||
case 'error' :
|
|
||||||
scope.icon = 'icon-warning-sign';
|
|
||||||
break;
|
|
||||||
case 'success' :
|
|
||||||
scope.icon = 'icon-ok-sign';
|
|
||||||
break;
|
|
||||||
case 'info' :
|
|
||||||
scope.icon = 'icon-info-sign';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
// controllers
|
|
||||||
function LoginFormController($scope) {
|
|
||||||
$scope.$watch('loginForm', function() {
|
|
||||||
$scope.loginForm.email.errors = {'filled' : true, 'valid' : true};
|
|
||||||
$scope.loginForm.password.errors = {'filled' : true, 'valid' : true};
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.submit = function() {
|
|
||||||
$scope.$broadcast('event:force-model-update');
|
|
||||||
|
|
||||||
if (true === $scope.loginForm.$valid) {
|
|
||||||
$scope.loginForm.email.errors = {'filled' : true, 'valid' : true};
|
|
||||||
$scope.loginForm.password.errors = {'filled' : true,'valid' : true};
|
|
||||||
// submit
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.loginForm.email.errors.valid = $scope.loginForm.email.$valid;
|
|
||||||
$scope.loginForm.email.errors.filled = !$scope.loginForm.email.$error.required;
|
|
||||||
|
|
||||||
$scope.loginForm.password.errors.filled = !$scope.loginForm.password.$error.required;
|
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getInputClass = function(name) {
|
|
||||||
return _.every($scope.loginForm[name].errors, function(value) {
|
|
||||||
return value === true;
|
|
||||||
}) ? '' : 'input-table-error';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function forgottenPasswordFormCtrl($scope) {
|
|
||||||
$scope.$watch('forgottenPasswordForm', function() {
|
|
||||||
$scope.forgottenPasswordForm.email.errors = {'filled' : true, 'valid' : true};
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.submit = function() {
|
|
||||||
$scope.$broadcast('event:force-model-update');
|
|
||||||
|
|
||||||
if (true === $scope.forgottenPasswordForm.$valid) {
|
|
||||||
$scope.forgottenPasswordForm.email.errors = {'filled' : true, 'valid' : true};
|
|
||||||
// submit
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.forgottenPasswordForm.email.errors.valid = $scope.forgottenPasswordForm.email.$valid;
|
|
||||||
$scope.forgottenPasswordForm.email.errors.filled = !$scope.forgottenPasswordForm.email.$error.required;
|
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getInputClass = function(name) {
|
|
||||||
return _.every($scope.forgottenPasswordForm[name].errors, function(value) {
|
|
||||||
return value === true;
|
|
||||||
}) ? '' : 'input-table-error';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function passwordChangeFormCtrl($scope) {
|
|
||||||
$scope.$watch('passwordChangeForm', function() {
|
|
||||||
$scope.passwordChangeForm.password.errors = {'filled' : true, 'valid' : true};
|
|
||||||
$scope.passwordChangeForm.passwordConfirm.errors = {'filled' : true, 'valid' : true};
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.submit = function() {
|
|
||||||
$scope.$broadcast('event:force-model-update');
|
|
||||||
|
|
||||||
if (true === $scope.passwordChangeForm.$valid) {
|
|
||||||
$scope.passwordChangeForm.password.errors = {'filled' : true, 'valid' : true};
|
|
||||||
$scope.passwordChangeForm.passwordConfirm.errors = {'filled' : true, 'valid' : true};
|
|
||||||
// submit
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.passwordChangeForm.password.errors.filled = !$scope.passwordChangeForm.password.$error.required;
|
|
||||||
$scope.passwordChangeForm.passwordConfirm.errors.filled = !$scope.passwordChangeForm.passwordConfirm.$error.required;
|
|
||||||
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getInputClass = function(name) {
|
|
||||||
return _.every($scope.passwordChangeForm[name].errors, function(value) {
|
|
||||||
return value === true;
|
|
||||||
}) ? '' : 'input-table-error';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// bootstrap angular
|
|
||||||
angular.element(document).ready(function() {
|
|
||||||
angular.bootstrap(document, ['phraseanetAuthentication']);
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user