Compare commits

...

9 commits

Author SHA1 Message Date
David Baldwynn aa554c8210 added coveralls support 2017-10-29 13:02:41 -07:00
David Baldwynn 759a4efdd1 got all tests to pass 2017-10-29 12:44:12 -07:00
David Baldwynn 88fbf9e51f got user tests to pass 2017-10-29 12:20:49 -07:00
David Baldwynn 6fbfa35473 fixed on-finish-render directive tests 2017-10-29 12:17:54 -07:00
David Baldwynn f427092144 fixed field directive tests 2017-10-29 12:16:34 -07:00
David Baldwynn ebcc0c63cd fixed field-icon tests 2017-10-29 12:13:22 -07:00
David Baldwynn 7d65f0161b removed duplicate translation keyword for form admin panel 2017-10-29 12:07:42 -07:00
David Baldwynn 538030c551 got edit-form-directive tests to pass 2017-10-29 12:01:30 -07:00
David Baldwynn 76d6d54cd5 got edit-submissions-form directive tests to pass 2017-10-29 11:54:40 -07:00
29 changed files with 477 additions and 164 deletions

View file

@ -11,5 +11,7 @@ services:
addons: addons:
code_climate: code_climate:
repo_token: 6c3a1b81a09b2338d6f30913c1bcad115026689752cbb499a0a25061cda6fbcf repo_token: 6c3a1b81a09b2338d6f30913c1bcad115026689752cbb499a0a25061cda6fbcf
script:
- npm travis
after_script: after_script:
- grunt coverage - grunt coverage

View file

@ -88,15 +88,13 @@ exports.listSubmissions = function(req, res) {
} }
res.json(_submissions); res.json(_submissions);
}); });
}; };
/** /**
* Create a new form * Create a new form
*/ */
exports.create = function(req, res) { exports.create = function(req, res) {
debugger;
if(!req.body.form){ if(!req.body.form){
return res.status(401).send({ return res.status(401).send({
message: 'Invalid Input' message: 'Invalid Input'
@ -107,7 +105,6 @@ exports.create = function(req, res) {
form.admin = req.user._id; form.admin = req.user._id;
form.save(function(err) { form.save(function(err) {
debugger;
if (err) { if (err) {
return res.status(500).send({ return res.status(500).send({
message: errorHandler.getErrorMessage(err) message: errorHandler.getErrorMessage(err)

View file

@ -190,7 +190,7 @@ exports.signin = function(req, res, next) {
*/ */
exports.signout = function(req, res) { exports.signout = function(req, res) {
if(req.cookies.hasOwnProperty('userLang')){ if(req.cookies.hasOwnProperty('userLang')){
res.destroyCookie('userLang'); res.clearCookie('userLang');
} }
req.logout(); req.logout();
return res.status(200).send('You have successfully logged out.'); return res.status(200).send('You have successfully logged out.');

View file

@ -71,7 +71,6 @@ var VisitorDataSchema = new Schema({
userAgent: { userAgent: {
type: String type: String
} }
}); });
var formSchemaOptions = { var formSchemaOptions = {

View file

@ -68,7 +68,6 @@ describe('Form Routes Unit tests', function() {
.send({form: myForm}) .send({form: myForm})
.expect(401) .expect(401)
.end(function(FormSaveErr, FormSaveRes) { .end(function(FormSaveErr, FormSaveRes) {
// Call the assertion callback // Call the assertion callback
done(FormSaveErr); done(FormSaveErr);
}); });
@ -275,6 +274,8 @@ describe('Form Routes Unit tests', function() {
authenticatedSession.get('/auth/signout') authenticatedSession.get('/auth/signout')
.expect(200) .expect(200)
.end(function(signoutErr, signoutRes) { .end(function(signoutErr, signoutRes) {
console.log(signoutRes.error.text);
// Handle signout error // Handle signout error
if (signoutErr) return done(signoutErr); if (signoutErr) return done(signoutErr);
authenticatedSession.destroy(); authenticatedSession.destroy();

View file

@ -199,6 +199,7 @@ describe('FormSubmission Model Unit Tests:', function() {
it('should preserve deleted form_fields that have submissions without any problems', function(done) { it('should preserve deleted form_fields that have submissions without any problems', function(done) {
var fieldPropertiesToOmit = ['deletePreserved', 'globalId', 'lastModified', 'created', '_id', 'submissionId', 'isSubmission', 'validFieldTypes', 'title'];
var old_fields = myForm.toObject().form_fields; var old_fields = myForm.toObject().form_fields;
var new_form_fields = _.clone(myForm.toObject().form_fields); var new_form_fields = _.clone(myForm.toObject().form_fields);
new_form_fields.splice(0, 1); new_form_fields.splice(0, 1);
@ -210,8 +211,8 @@ describe('FormSubmission Model Unit Tests:', function() {
should.not.exist(err); should.not.exist(err);
should.exist(_form.form_fields); should.exist(_form.form_fields);
var actual_fields = _.deepOmit(_form.toObject().form_fields, ['deletePreserved', 'globalId', 'lastModified', 'created', '_id', 'submissionId']); var actual_fields = _.deepOmit(_form.toObject().form_fields, fieldPropertiesToOmit);
old_fields = _.deepOmit(old_fields, ['deletePreserved', 'globalId', 'lastModified', 'created', '_id', 'submissionId']); old_fields = _.deepOmit(old_fields, fieldPropertiesToOmit);
should.deepEqual(actual_fields, old_fields, 'old form_fields not equal to newly saved form_fields'); should.deepEqual(actual_fields, old_fields, 'old form_fields not equal to newly saved form_fields');
done(); done();

View file

@ -5,7 +5,7 @@ block content
div.row.valign div.row.valign
h3.col-md-12.text-center=__('500_HEADER') h3.col-md-12.text-center=__('500_HEADER')
div.col-md-4.col-md-offset-4 div.col-md-4.col-md-offset-4
if process.env.NODE_ENV == 'development' if process.env.NODE_ENV == 'development' || process.env.NODE_ENV == 'test'
div.col-md-12.text-center(style="padding-bottom: 50px;") div.col-md-12.text-center(style="padding-bottom: 50px;")
| #{error} | #{error}
else else

View file

@ -263,9 +263,13 @@ module.exports = function(db) {
//Visitor Language Detection //Visitor Language Detection
app.use(function(req, res, next) { app.use(function(req, res, next) {
var acceptLanguage = req.headers['accept-language']; var acceptLanguage = req.headers['accept-language'];
var languages = acceptLanguage.match(/[a-z]{2}(?!-)/g) || []; var languages, supportedLanguage;
if(acceptLanguage){
languages = acceptLanguage.match(/[a-z]{2}(?!-)/g) || [];
supportedLanguage = containsAnySupportedLanguages(languages);
}
var supportedLanguage = containsAnySupportedLanguages(languages);
if(!req.user && supportedLanguage !== null){ if(!req.user && supportedLanguage !== null){
var currLanguage = res.cookie('userLang'); var currLanguage = res.cookie('userLang');
@ -320,16 +324,10 @@ module.exports = function(db) {
// Log it // Log it
client.captureError(err); client.captureError(err);
if(process.env.NODE_ENV === 'production'){ // Error page
res.status(500).render('500', { res.status(500).render('500', {
error: 'Internal Server Error' error: err.stack
}); });
} else {
// Error page
res.status(500).render('500', {
error: err.stack
});
}
}); });
// Assume 404 since no middleware responded // Assume 404 since no middleware responded

View file

@ -14,8 +14,6 @@ module.exports = function () {
passwordField: 'password' passwordField: 'password'
}, },
function (username, password, done) { function (username, password, done) {
console.log('\n\n\n\n\nusername: '+username);
console.log('password: '+password)
User.findOne({ User.findOne({
$or: [ $or: [
{'username': username.toLowerCase()}, {'username': username.toLowerCase()},

View file

@ -204,18 +204,6 @@ module.exports = function(grunt) {
singleRun: true singleRun: true
} }
}, },
protractor: {
options: {
configFile: 'protractor.conf.js',
keepAlive: true,
noColor: false
},
e2e: {
options: {
args: {} // Target-specific arguments
}
}
},
mocha_istanbul: { mocha_istanbul: {
coverage: { coverage: {
src: watchFiles.allTests, // a folder works nicely src: watchFiles.allTests, // a folder works nicely
@ -349,9 +337,11 @@ module.exports = function(grunt) {
grunt.registerTask('setup', ['execute']); grunt.registerTask('setup', ['execute']);
// Test task(s). // Test task(s).
grunt.registerTask('test', ['lint:tests', 'test:server', 'test:client']); grunt.registerTask('test', ['test:server', 'test:client']);
grunt.registerTask('test:server', ['lint:tests', 'env:test', 'mochaTest']); grunt.registerTask('test:server', ['lint:tests', 'env:test', 'mochaTest']);
grunt.registerTask('test:client', ['lint:tests', 'html2js:main', 'html2js:forms', 'env:test', 'karma:unit']); grunt.registerTask('test:client', ['lint:tests', 'html2js:main', 'html2js:forms', 'env:test', 'karma:unit']);
grunt.registerTask('test:travis', ['env:test', 'html2js:main', 'html2js:forms', 'env:test', 'karma:unit', 'mochaTest', 'coveralls']);
grunt.registerTask('testdebug', ['env:test', 'karma:debug']); grunt.registerTask('testdebug', ['env:test', 'karma:debug']);
}; };

View file

@ -21,6 +21,7 @@
"generate": "all-contributors generate", "generate": "all-contributors generate",
"start": "grunt", "start": "grunt",
"test": "grunt test", "test": "grunt test",
"travis": "grunt test:travis",
"postinstall": "bower install --config.interactive=false; grunt build;", "postinstall": "bower install --config.interactive=false; grunt build;",
"init": "node scripts/setup.js" "init": "node scripts/setup.js"
}, },
@ -100,7 +101,7 @@
"grunt-usemin": "^3.1.1", "grunt-usemin": "^3.1.1",
"grunt-wiredep": "^3.0.1", "grunt-wiredep": "^3.0.1",
"istanbul": "^0.4.0", "istanbul": "^0.4.0",
"jasmine-core": "^2.4.1", "jasmine-core": "^2.6",
"karma": "~0.13.14", "karma": "~0.13.14",
"karma-chrome-launcher": "~0.2.1", "karma-chrome-launcher": "~0.2.1",
"karma-coverage": "~0.5.3", "karma-coverage": "~0.5.3",

File diff suppressed because one or more lines are too long

View file

@ -6,9 +6,38 @@
var scope, var scope,
HeaderController; HeaderController;
var sampleUser = {
firstName: 'Full',
lastName: 'Name',
email: 'test@test.com',
username: 'test@test.com',
language: 'en',
password: 'password',
provider: 'local',
roles: ['user'],
_id: 'ed873933b1f1dea0ce12fab9'
};
// Load the main application module // Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName)); beforeEach(module(ApplicationConfiguration.applicationModuleName));
//Mock Authentication Service
beforeEach(module(function($provide) {
$provide.service('Auth', function() {
return {
ensureHasCurrentUser: function() {
return sampleUser;
},
isAuthenticated: function() {
return true;
},
getUserState: function() {
return true;
}
};
});
}));
beforeEach(inject(function($controller, $rootScope) { beforeEach(inject(function($controller, $rootScope) {
scope = $rootScope.$new(); scope = $rootScope.$new();

View file

@ -153,7 +153,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
MULTIPLE_CHOICE: 'Multiple Choice', MULTIPLE_CHOICE: 'Multiple Choice',
DROPDOWN: 'Dropdown', DROPDOWN: 'Dropdown',
DATE: 'Date', DATE: 'Date',
PARAGRAPH_T: 'Paragraph', PARAGRAPH_FIELD: 'Paragraph',
YES_NO: 'Yes/No', YES_NO: 'Yes/No',
LEGAL: 'Legal', LEGAL: 'Legal',
RATING: 'Rating', RATING: 'Rating',

View file

@ -152,7 +152,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
MULTIPLE_CHOICE: 'Choix multiple', MULTIPLE_CHOICE: 'Choix multiple',
DROPDOWN: 'Menu Déroulant', DROPDOWN: 'Menu Déroulant',
DATE: 'Date', DATE: 'Date',
PARAGRAPH_T: "Paragraphe", PARAGRAPH_FIELD: "Paragraphe",
OUI_NON: 'Oui / Non', OUI_NON: 'Oui / Non',
LEGAL: 'Légal', LEGAL: 'Légal',
RATING: "Évaluation", RATING: "Évaluation",

View file

@ -84,7 +84,6 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
ADD_OPTION: 'Option hinzufügen', ADD_OPTION: 'Option hinzufügen',
NUM_OF_STEPS: 'Anzahl der Schritte', NUM_OF_STEPS: 'Anzahl der Schritte',
CLICK_FIELDS_FOOTER: 'Klicken Sie auf Felder, um sie hier hinzuzufügen', CLICK_FIELDS_FOOTER: 'Klicken Sie auf Felder, um sie hier hinzuzufügen',
FORM: 'Formular',
IF_THIS_FIELD: 'Wenn dieses Feld', IF_THIS_FIELD: 'Wenn dieses Feld',
IS_EQUAL_TO: 'ist gleich', IS_EQUAL_TO: 'ist gleich',
IS_NOT_EQUAL_TO: 'ist nicht gleich', IS_NOT_EQUAL_TO: 'ist nicht gleich',
@ -152,7 +151,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
MULTIPLE_CHOICE: 'Mehrfachauswahl', MULTIPLE_CHOICE: 'Mehrfachauswahl',
DROPDOWN: 'Dropdown-Liste', DROPDOWN: 'Dropdown-Liste',
DATE: 'Datum', DATE: 'Datum',
PARAGRAPH_T: "Absatz", PARAGRAPH_FIELD: "Absatz",
YES_NO: 'Ja / Nein', YES_NO: 'Ja / Nein',
LEGAL: "Rechtliche", LEGAL: "Rechtliche",
RATING: 'Bewertung', RATING: 'Bewertung',

View file

@ -152,7 +152,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
MULTIPLE_CHOICE: 'Scelta multipla', MULTIPLE_CHOICE: 'Scelta multipla',
DROPDOWN: 'Dropdown', DROPDOWN: 'Dropdown',
DATE: 'Data', DATE: 'Data',
PARAGRAPH_T: 'Paragrafo', PARAGRAPH_FIELD: 'Paragrafo',
YES_NO: 'Sì / no', YES_NO: 'Sì / no',
LEGAL: 'Legale', LEGAL: 'Legale',
RATING: 'Valutazione', RATING: 'Valutazione',

View file

@ -153,7 +153,7 @@ angular.module('forms').config(['$translateProvider', function ($translateProvid
MULTIPLE_CHOICE: 'Opciones múltiples', MULTIPLE_CHOICE: 'Opciones múltiples',
DROPDOWN: 'Desplegable', DROPDOWN: 'Desplegable',
DATE: 'Fecha', DATE: 'Fecha',
PARAGRAPH_T: 'Párrafo', PARAGRAPH_FIELD: 'Párrafo',
YES_NO: 'Si/No', YES_NO: 'Si/No',
LEGAL: 'Legal', LEGAL: 'Legal',
RATING: 'Puntaje', RATING: 'Puntaje',

View file

@ -10,13 +10,33 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
myform: '=' myform: '='
}, },
controller: function($scope){ controller: function($scope){
$scope.table = { $scope.table = {
masterChecker: false, masterChecker: false,
rows: [] rows: []
}; };
var getSubmissions = function(){ $scope.deletionInProgress = false;
$scope.waitingForDeletion = false;
//Waits until deletionInProgress is false before running getSubmissions
$scope.$watch("deletionInProgress",function(newVal, oldVal){
if(newVal === oldVal) return;
if(newVal === false && $scope.waitingForDeletion) {
$scope.getSubmissions();
$scope.waitingForDeletion = false;
}
});
$scope.handleSubmissionsRefresh = function(){
if(!$scope.deletionInProgress) {
$scope.getSubmissions();
} else {
$scope.waitingForDeletion = true;
}
};
$scope.getSubmissions = function(cb){
$http({ $http({
method: 'GET', method: 'GET',
url: '/forms/'+$scope.myform._id+'/submissions' url: '/forms/'+$scope.myform._id+'/submissions'
@ -36,10 +56,19 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
} }
$scope.table.rows = submissions; $scope.table.rows = submissions;
});
if(cb && typeof cb === 'function'){
cb();
}
}, function errorCallback(err){
console.error(err);
if(cb && typeof cb === 'function'){
cb(err);
}
});
}; };
var getVisitors = function(){ $scope.getVisitors = function(){
$http({ $http({
method: 'GET', method: 'GET',
url: '/forms/'+$scope.myform._id+'/visitors' url: '/forms/'+$scope.myform._id+'/visitors'
@ -52,8 +81,23 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
}); });
}; };
getSubmissions(); $scope.handleSubmissionsRefresh();
getVisitors(); $scope.getVisitors();
//Fetch submissions and visitor data every 1.67 min
var updateSubmissions = $interval($scope.handleSubmissionsRefresh, 100000);
var updateVisitors = $interval($scope.getVisitors, 1000000);
//Prevent $intervals from running after directive is destroyed
$scope.$on('$destroy', function() {
if (updateSubmissions) {
$interval.cancel($scope.updateSubmissions);
}
if (updateVisitors) {
$interval.cancel($scope.updateVisitors);
}
});
/* /*
** Analytics Functions ** Analytics Functions
@ -72,14 +116,48 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
return (totalTime/numSubmissions).toFixed(0); return (totalTime/numSubmissions).toFixed(0);
})(); })();
var updateFields = $interval(getSubmissions, 100000); $scope.DeviceStatistics = (function(){
var updateFields = $interval(getVisitors, 1000000); var newStatItem = function(){
return {
visits: 0,
responses: 0,
completion: 0,
average_time: 0,
total_time: 0
};
};
$scope.$on('$destroy', function() { var stats = {
if (updateFields) { desktop: newStatItem(),
$interval.cancel($scope.updateFields); tablet: newStatItem(),
phone: newStatItem(),
other: newStatItem()
};
if($scope.myform.analytics && $scope.myform.analytics.visitors) {
var visitors = $scope.myform.analytics.visitors;
for (var i = 0; i < visitors.length; i++) {
var visitor = visitors[i];
var deviceType = visitor.deviceType;
stats[deviceType].visits++;
if (visitor.isSubmitted) {
stats[deviceType].total_time = stats[deviceType].total_time + visitor.timeElapsed;
stats[deviceType].responses++;
}
if(stats[deviceType].visits) {
stats[deviceType].completion = 100*(stats[deviceType].responses / stats[deviceType].visits).toFixed(2);
}
if(stats[deviceType].responses){
stats[deviceType].average_time = (stats[deviceType].total_time / stats[deviceType].responses).toFixed(0);
}
}
} }
}); return stats;
})();
/* /*
** Table Functions ** Table Functions
@ -109,25 +187,24 @@ angular.module('forms').directive('editSubmissionsFormDirective', ['$rootScope',
//Delete selected submissions of Form //Delete selected submissions of Form
$scope.deleteSelectedSubmissions = function(){ $scope.deleteSelectedSubmissions = function(){
$scope.deletionInProgress = true;
var delete_ids = _.chain($scope.table.rows).filter(function(row){ var delete_ids = _.chain($scope.table.rows).filter(function(row){
return !!row.selected; return !!row.selected;
}).pluck('_id').value(); }).pluck('_id').value();
$http({ url: '/forms/'+$scope.myform._id+'/submissions', return $http({ url: '/forms/'+$scope.myform._id+'/submissions',
method: 'DELETE', method: 'DELETE',
data: {deleted_submissions: delete_ids}, data: {deleted_submissions: delete_ids},
headers: {'Content-Type': 'application/json;charset=utf-8'} headers: {'Content-Type': 'application/json;charset=utf-8'}
}).success(function(data, status){ }).success(function(data, status){
$scope.deletionInProgress = true;
//Remove deleted ids from table //Remove deleted ids from table
var tmpArray = []; $scope.table.rows = $scope.table.rows.filter(function(field){
for(var i=0; i<$scope.table.rows.length; i++){ return !field.selected;
if(!$scope.table.rows[i].selected){ });
tmpArray.push($scope.table.rows[i]);
}
}
$scope.table.rows = tmpArray;
}) })
.error(function(err){ .error(function(err){
$scope.deletionInProgress = true;
console.error(err); console.error(err);
}); });
}; };

View file

@ -4,7 +4,6 @@
angular.module('forms').service('FormFields', [ '$rootScope', '$translate', '$window', angular.module('forms').service('FormFields', [ '$rootScope', '$translate', '$window',
function($rootScope, $translate, $window) { function($rootScope, $translate, $window) {
$translate.use($window.user.language); $translate.use($window.user.language);
console.log($translate.instant('SHORT_TEXT'));
this.types = [ this.types = [
{ {
@ -29,7 +28,7 @@ angular.module('forms').service('FormFields', [ '$rootScope', '$translate', '$wi
}, },
{ {
name : 'textarea', name : 'textarea',
value : $translate.instant('PARAGRAPH'), value : $translate.instant('PARAGRAPH_FIELD'),
}, },
{ {
name : 'yes_no', name : 'yes_no',

View file

@ -57,22 +57,7 @@
_id: '525a8422f6d0f87f0e407a33' _id: '525a8422f6d0f87f0e407a33'
}; };
var newFakeModal = function(){ //Mock myForm Service
var result = {
opened: true,
close: function( item ) {
//The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
this.opened = false;
},
dismiss: function( type ) {
//The user clicked cancel on the modal dialog, call the stored cancel callback
this.opened = false;
}
};
return result;
};
//Mock Users Service
beforeEach(module(function($provide) { beforeEach(module(function($provide) {
$provide.service('myForm', function($q) { $provide.service('myForm', function($q) {
return sampleForm; return sampleForm;
@ -159,6 +144,27 @@
}); });
})); }));
var newFakeModal = function(){
var modal = {
opened: true,
close: function( item ) {
//The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
this.opened = false;
},
dismiss: function( type ) {
//The user clicked cancel on the modal dialog, call the stored cancel callback
this.opened = false;
},
result: {
then: function (cb) {
if(cb && typeof cb === 'function'){
cb();
}
}
}
};
return modal;
};
//Mock $uibModal //Mock $uibModal
beforeEach(inject(function($uibModal) { beforeEach(inject(function($uibModal) {
@ -199,7 +205,7 @@
expect(scope.myform).toEqualData(sampleForm); expect(scope.myform).toEqualData(sampleForm);
}); });
it('$scope.removeCurrentForm() with valid form data should send a DELETE request with the id of form', function() { it('$scope.removeCurrentForm() with valid form data should send a DELETE request with the id of form', inject(function($uibModal) {
var controller = createAdminFormController(); var controller = createAdminFormController();
//Set $state transition //Set $state transition
@ -214,7 +220,7 @@
$httpBackend.flush(); $httpBackend.flush();
$state.ensureAllTransitionsHappened(); $state.ensureAllTransitionsHappened();
}); }));
it('$scope.update() should send a PUT request with the id of form', function() { it('$scope.update() should send a PUT request with the id of form', function() {
var controller = createAdminFormController(); var controller = createAdminFormController();

View file

@ -86,7 +86,6 @@
}); });
})); }));
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
// This allows us to inject a service but then attach it to a variable // This allows us to inject a service but then attach it to a variable
// with the same name as the service. // with the same name as the service.
@ -106,25 +105,13 @@
// Initialize the Forms controller. // Initialize the Forms controller.
createListFormsController = function(){ createListFormsController = function(){
return $controller('ListFormsController', { $scope: scope }); return $controller('ListFormsController', {
$scope: scope,
myForms: sampleFormList
});
}; };
})); }));
it('$scope.findAll() should query all User\'s Forms', inject(function() {
var controller = createListFormsController();
// Set GET response
$httpBackend.expectGET(/^(\/forms)$/).respond(200, sampleFormList);
// Run controller functionality
scope.findAll();
$httpBackend.flush();
// Test scope value
expect( scope.myforms ).toEqualData(sampleFormList);
}));
it('$scope.duplicateForm() should duplicate a Form', inject(function() { it('$scope.duplicateForm() should duplicate a Form', inject(function() {
var dupSampleForm = sampleFormList[2], var dupSampleForm = sampleFormList[2],
@ -135,12 +122,6 @@
var controller = createListFormsController(); var controller = createListFormsController();
// Set GET response
$httpBackend.expectGET(/^(\/forms)$/).respond(200, sampleFormList);
// Run controller functionality
scope.findAll();
$httpBackend.flush();
// Set GET response // Set GET response
$httpBackend.expect('POST', '/forms').respond(200, dupSampleForm); $httpBackend.expect('POST', '/forms').respond(200, dupSampleForm);
// Run controller functionality // Run controller functionality
@ -164,13 +145,6 @@
var controller = createListFormsController(); var controller = createListFormsController();
// Set GET response
$httpBackend.expectGET(/^(\/forms)$/).respond(200, sampleFormList);
// Run controller functionality
scope.findAll();
$httpBackend.flush();
// Set GET response // Set GET response
$httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, delSampleForm); $httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, delSampleForm);

View file

@ -2,7 +2,7 @@
(function() { (function() {
// Forms Controller Spec // Forms Controller Spec
describe('EditSubmissions Directive-Controller Tests', function() { describe('EditFormSubmissions Directive-Controller Tests', function() {
// Initialize global variables // Initialize global variables
var el, scope, controller, $httpBackend; var el, scope, controller, $httpBackend;
@ -10,13 +10,25 @@
firstName: 'Full', firstName: 'Full',
lastName: 'Name', lastName: 'Name',
email: 'test@test.com', email: 'test@test.com',
username: 'test@test.com', username: 'test1234',
password: 'password', password: 'password',
provider: 'local', provider: 'local',
roles: ['user'], roles: ['user'],
_id: 'ed873933b1f1dea0ce12fab9' _id: 'ed873933b1f1dea0ce12fab9'
}; };
var sampleVisitors = [{
socketId: '33b1f1dea0ce12fab9ed8739',
referrer: 'https://tellform.com/examples',
lastActiveField: 'ed873933b0ce121f1deafab9',
timeElapsed: 100000,
isSubmitted: true,
language: 'en',
ipAddr: '192.168.1.1',
deviceType: 'desktop',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4'
}]
var sampleForm = { var sampleForm = {
title: 'Form Title', title: 'Form Title',
admin: 'ed873933b1f1dea0ce12fab9', admin: 'ed873933b1f1dea0ce12fab9',
@ -27,7 +39,18 @@
{fieldType:'checkbox', title:'hockey', fieldOptions: [], fieldValue: '', required: true, disabled: false, deletePreserved: false, _id: 'ed8317393deab0ce121ffab9'} {fieldType:'checkbox', title:'hockey', fieldOptions: [], fieldValue: '', required: true, disabled: false, deletePreserved: false, _id: 'ed8317393deab0ce121ffab9'}
], ],
analytics: { analytics: {
visitors: [] visitors: sampleVisitors,
conversionRate: 80.5,
fields: [
{
dropoffViews: 0,
responses: 1,
totalViews: 1,
continueRate: 100,
dropoffRate: 0,
field: {fieldType:'textfield', title:'First Name', fieldOptions: [], fieldValue: '', required: true, disabled: false, deletePreserved: false, _id: 'ed873933b0ce121f1deafab9'}
}
]
}, },
submissions: [], submissions: [],
startPage: { startPage: {
@ -61,7 +84,8 @@
], ],
admin: sampleUser, admin: sampleUser,
form: sampleForm, form: sampleForm,
timeElapsed: 10.33 timeElapsed: 10.33,
selected: false
}, },
{ {
form_fields: [ form_fields: [
@ -71,7 +95,8 @@
], ],
admin: sampleUser, admin: sampleUser,
form: sampleForm, form: sampleForm,
timeElapsed: 2.33 timeElapsed: 2.33,
selected: false
}, },
{ {
form_fields: [ form_fields: [
@ -81,7 +106,8 @@
], ],
admin: sampleUser, admin: sampleUser,
form: sampleForm, form: sampleForm,
timeElapsed: 11.11 timeElapsed: 11.11,
selected: false
}]; }];
// The $resource service augments the response object with methods for updating and deleting the resource. // The $resource service augments the response object with methods for updating and deleting the resource.
@ -118,10 +144,12 @@
$httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); $httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm);
$httpBackend.whenGET('/forms').respond(200, sampleForm); $httpBackend.whenGET('/forms').respond(200, sampleForm);
$httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm); $httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})$/).respond(200, sampleForm);
//Instantiate directive. $httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})\/submissions$/).respond(200, sampleSubmissions);
$httpBackend.whenGET(/^(\/forms\/)([0-9a-fA-F]{24})\/visitors$/).respond(200, sampleVisitors);
//Instantiate directive.
var tmp_scope = $rootScope.$new(); var tmp_scope = $rootScope.$new();
tmp_scope.myform = sampleForm; tmp_scope.myform = sampleForm;
tmp_scope.myform.submissions = sampleSubmissions;
tmp_scope.user = sampleUser; tmp_scope.user = sampleUser;
//gotacha: Controller and link functions will execute. //gotacha: Controller and link functions will execute.
@ -141,6 +169,7 @@
it('$scope.toggleAllCheckers should toggle all checkboxes in table', function(){ it('$scope.toggleAllCheckers should toggle all checkboxes in table', function(){
//Run Controller Logic to Test //Run Controller Logic to Test
scope.table.rows = sampleSubmissions;
scope.table.masterChecker = true; scope.table.masterChecker = true;
scope.toggleAllCheckers(); scope.toggleAllCheckers();
@ -151,6 +180,7 @@
}); });
it('$scope.isAtLeastOneChecked should return true when at least one checkbox is selected', function(){ it('$scope.isAtLeastOneChecked should return true when at least one checkbox is selected', function(){
scope.table.rows = sampleSubmissions;
scope.table.masterChecker = true; scope.table.masterChecker = true;
scope.toggleAllCheckers(); scope.toggleAllCheckers();
@ -161,16 +191,22 @@
}); });
it('$scope.deleteSelectedSubmissions should delete all submissions that are selected', function(){ it('$scope.deleteSelectedSubmissions should delete all submissions that are selected', function(){
$httpBackend.expect('GET', /^(\/forms\/)([0-9a-fA-F]{24})(\/submissions)$/).respond(200, sampleSubmissions);
scope.table.masterChecker = true; scope.table.masterChecker = true;
scope.toggleAllCheckers(); scope.getSubmissions(function(err){
scope.toggleAllCheckers();
$httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})(\/submissions)$/).respond(200); $httpBackend.expect('DELETE', /^(\/forms\/)([0-9a-fA-F]{24})(\/submissions)$/).respond(200);
//Run Controller Logic to Test //Run Controller Logic to Test
scope.deleteSelectedSubmissions(); scope.deleteSelectedSubmissions().then(function(){
expect(scope.table.rows.length).toEqual(0);
});
expect(err).not.toBeDefined();
});
$httpBackend.flush(); $httpBackend.flush();
expect(scope.table.rows.length).toEqual(0);
}); });
}); });

View file

@ -62,6 +62,52 @@
beforeEach(module('module-templates')); beforeEach(module('module-templates'));
beforeEach(module('stateMock')); beforeEach(module('stateMock'));
//Mock FormFields Service
beforeEach(module(function($provide) {
$provide.service('FormFields', function() {
return {
types: [
{
name : 'textfield',
value : 'Short Text'
},
{
name : 'email',
value : 'Email'
}
]
};
});
}));
var newFakeModal = function(){
var modal = {
opened: true,
close: function( item ) {
//The user clicked OK on the modal dialog, call the stored confirm callback with the selected item
this.opened = false;
},
dismiss: function( type ) {
//The user clicked cancel on the modal dialog, call the stored cancel callback
this.opened = false;
},
result: {
then: function (cb) {
if(cb && typeof cb === 'function'){
cb();
}
}
}
};
return modal;
};
//Mock $uibModal
beforeEach(inject(function($uibModal) {
var modal = newFakeModal();
spyOn($uibModal, 'open').and.returnValue(modal);
}));
beforeEach(inject(function($compile, $controller, $rootScope, _$httpBackend_) { beforeEach(inject(function($compile, $controller, $rootScope, _$httpBackend_) {
//Instantiate directive. //Instantiate directive.
var tmp_scope = $rootScope.$new(); var tmp_scope = $rootScope.$new();
@ -97,26 +143,12 @@
scope.myform = _.cloneDeep(sampleForm); scope.myform = _.cloneDeep(sampleForm);
}); });
it('$scope.addNewField() should ADD a new field to $scope.myform.form_fields', function() { it('$scope.addNewField() should open the new field modal', function() {
//Run controller methods //Run controller methods
scope.addNewField(true, 'textfield'); scope.addNewField('textfield');
var expectedFormField = { expect(scope.editFieldModal.opened).toBeTruthy();
title: 'Short Text2',
fieldType: 'textfield',
fieldValue: '',
required: true,
disabled: false,
deletePreserved: false,
logicJump: Object({ })
};
var actualFormField = _.cloneDeep(_.last(scope.myform.form_fields));
delete actualFormField._id;
expect(scope.myform.form_fields.length).toEqual(sampleForm.form_fields.length+1);
expect(actualFormField).toEqualData(expectedFormField);
}); });
it('$scope.deleteField() should DELETE a field to $scope.myform.form_fields', function() { it('$scope.deleteField() should DELETE a field to $scope.myform.form_fields', function() {

View file

@ -5,7 +5,6 @@
describe('FieldIcon Directive Tests', function() { describe('FieldIcon Directive Tests', function() {
// Initialize global variables // Initialize global variables
var scope, var scope,
FormFields,
faClasses = { faClasses = {
'textfield': 'fa fa-pencil-square-o', 'textfield': 'fa fa-pencil-square-o',
'dropdown': 'fa fa-th-list', 'dropdown': 'fa fa-th-list',
@ -28,10 +27,68 @@
// Load the main application module // Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName)); beforeEach(module(ApplicationConfiguration.applicationModuleName));
//Mock FormFields Service
var FormFields = {
types: [
{
name : 'textfield',
value : 'Short Text'
},
{
name : 'email',
value : 'Email'
},
{
name : 'radio',
value : 'Muliple Choice'
},
{
name : 'dropdown',
value : 'Dropdown'
},
{
name : 'date',
value : 'Date'
},
{
name : 'textarea',
value : 'Paragraph',
},
{
name : 'yes_no',
value : 'Yes/No',
},
{
name : 'legal',
value : 'Legal',
},
{
name : 'rating',
value : 'Rating',
},
{
name : 'link',
value : 'Link',
},
{
name : 'number',
value : 'Numbers',
},
{
name : 'statement',
value : 'Statement'
}
]
};
beforeEach(module(function($provide) {
$provide.service('FormFields', function() {
return FormFields;
});
}));
beforeEach(inject(function ($rootScope, _FormFields_) { beforeEach(inject(function ($rootScope, _FormFields_) {
scope = $rootScope.$new(); scope = $rootScope.$new();
FormFields = _FormFields_; }));
}));
it('should be able render all field-icon types', inject(function($compile) { it('should be able render all field-icon types', inject(function($compile) {
var currType, currClass; var currType, currClass;

View file

@ -5,11 +5,63 @@
describe('Field Directive Tests', function() { describe('Field Directive Tests', function() {
// Initialize global variables // Initialize global variables
var scope, var scope,
FormFields,
$templateCache, $templateCache,
$httpBackend, $httpBackend,
$compile; $compile;
var FormFields = {
types: [
{
name : 'textfield',
value : 'Short Text'
},
{
name : 'email',
value : 'Email'
},
{
name : 'radio',
value : 'Muliple Choice'
},
{
name : 'dropdown',
value : 'Dropdown'
},
{
name : 'date',
value : 'Date'
},
{
name : 'textarea',
value : 'Paragraph',
},
{
name : 'yes_no',
value : 'Yes/No',
},
{
name : 'legal',
value : 'Legal',
},
{
name : 'rating',
value : 'Rating',
},
{
name : 'link',
value : 'Link',
},
{
name : 'number',
value : 'Numbers',
},
{
name : 'statement',
value : 'Statement'
}
]
};
var sampleUser = { var sampleUser = {
firstName: 'Full', firstName: 'Full',
lastName: 'Name', lastName: 'Name',
@ -65,9 +117,15 @@
beforeEach(module('ngSanitize', 'ui.select')); beforeEach(module('ngSanitize', 'ui.select'));
//Mock FormFields Service
beforeEach(module(function($provide) {
$provide.service('FormFields', function() {
return FormFields;
});
}));
beforeEach(inject(function($rootScope, _FormFields_, _$compile_, _$httpBackend_) { beforeEach(inject(function($rootScope, _FormFields_, _$compile_, _$httpBackend_) {
scope = $rootScope.$new(); scope = $rootScope.$new();
FormFields = _FormFields_;
// Point global variables to injected services // Point global variables to injected services
$httpBackend = _$httpBackend_; $httpBackend = _$httpBackend_;
@ -76,6 +134,7 @@
$compile = _$compile_; $compile = _$compile_;
})); }));
it('should be able to render all field types in html', inject(function($rootScope) { it('should be able to render all field types in html', inject(function($rootScope) {
scope.fields = sampleFields; scope.fields = sampleFields;

View file

@ -4,15 +4,73 @@
// Forms Controller Spec // Forms Controller Spec
describe('onFinishRender Directive Tests', function() { describe('onFinishRender Directive Tests', function() {
// Initialize global variables // Initialize global variables
var scope, var scope;
FormFields;
var FormFields = {
types: [
{
name : 'textfield',
value : 'Short Text'
},
{
name : 'email',
value : 'Email'
},
{
name : 'radio',
value : 'Muliple Choice'
},
{
name : 'dropdown',
value : 'Dropdown'
},
{
name : 'date',
value : 'Date'
},
{
name : 'textarea',
value : 'Paragraph',
},
{
name : 'yes_no',
value : 'Yes/No',
},
{
name : 'legal',
value : 'Legal',
},
{
name : 'rating',
value : 'Rating',
},
{
name : 'link',
value : 'Link',
},
{
name : 'number',
value : 'Numbers',
},
{
name : 'statement',
value : 'Statement'
}
]
};
// Load the main application module // Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName)); beforeEach(module(ApplicationConfiguration.applicationModuleName));
beforeEach(inject(function ($rootScope, _FormFields_) { //Mock FormFields Service
beforeEach(module(function($provide) {
$provide.service('FormFields', function() {
return FormFields;
});
}));
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new(); scope = $rootScope.$new();
FormFields = _FormFields_;
spyOn($rootScope, '$broadcast'); spyOn($rootScope, '$broadcast');
})); }));

View file

@ -9,7 +9,7 @@ angular.module('users').controller('AuthenticationController', ['$scope', '$loca
$scope.forms = {}; $scope.forms = {};
$scope.signin = function() { $scope.signin = function() {
if(!$scope.forms.signinForm.$invalid){ if($scope.forms && $scope.forms.hasOwnProperty('siginForm') && !$scope.forms.signinForm.$invalid){
User.login($scope.credentials).then( User.login($scope.credentials).then(
function(response) { function(response) {
Auth.login(response); Auth.login(response);

View file

@ -80,7 +80,7 @@
// Load the main application module // Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName)); beforeEach(module(ApplicationConfiguration.applicationModuleName));
beforeEach(module('module-templates'));
beforeEach(module('stateMock')); beforeEach(module('stateMock'));
// Mock Users Service // Mock Users Service