\ No newline at end of file
diff --git a/client/src/app/projects/productbacklog/productbacklog-list.tpl.html b/client/src/app/projects/productbacklog/productbacklog-list.tpl.html
index 53e53c8f..b6335e63 100644
--- a/client/src/app/projects/productbacklog/productbacklog-list.tpl.html
+++ b/client/src/app/projects/productbacklog/productbacklog-list.tpl.html
@@ -20,5 +20,5 @@
-
+
\ No newline at end of file
diff --git a/client/src/app/projects/sprints/sprints-edit.tpl.html b/client/src/app/projects/sprints/sprints-edit.tpl.html
index c1cba063..2a1e9bb6 100644
--- a/client/src/app/projects/sprints/sprints-edit.tpl.html
+++ b/client/src/app/projects/sprints/sprints-edit.tpl.html
@@ -16,63 +16,59 @@
\ No newline at end of file
diff --git a/client/src/app/projects/sprints/sprints-list.tpl.html b/client/src/app/projects/sprints/sprints-list.tpl.html
index 6d25cc0e..321bc9d2 100644
--- a/client/src/app/projects/sprints/sprints-list.tpl.html
+++ b/client/src/app/projects/sprints/sprints-list.tpl.html
@@ -15,7 +15,7 @@
{{sprint.end}}
ACTIVE
-
+
@@ -24,5 +24,5 @@
-
+
\ No newline at end of file
diff --git a/client/src/app/projects/sprints/tasks/tasks-list.tpl.html b/client/src/app/projects/sprints/tasks/tasks-list.tpl.html
index 6102cfa3..d16e9bc0 100644
--- a/client/src/app/projects/sprints/tasks/tasks-list.tpl.html
+++ b/client/src/app/projects/sprints/tasks/tasks-list.tpl.html
@@ -20,5 +20,5 @@
-
+
\ No newline at end of file
diff --git a/client/src/common/directives/button.js b/client/src/common/directives/button.js
new file mode 100644
index 00000000..a97e47a6
--- /dev/null
+++ b/client/src/common/directives/button.js
@@ -0,0 +1,22 @@
+angular.module('directives.button', [])
+
+.directive('button', function() {
+ return {
+ restrict: 'E',
+ compile: function(element) {
+ element.addClass('btn');
+ }
+ };
+})
+
+.directive('primaryButton', function() {
+ return {
+ restrict: 'E',
+ template: '',
+ transclude: true,
+ replace: true,
+ compile: function(element) {
+ element.addClass('btn-primary');
+ }
+ };
+});
\ No newline at end of file
diff --git a/client/src/common/directives/crud/crudButtons.js b/client/src/common/directives/crud/crudButtons.js
index 0aebf891..4544b260 100644
--- a/client/src/common/directives/crud/crudButtons.js
+++ b/client/src/common/directives/crud/crudButtons.js
@@ -6,9 +6,9 @@ angular.module('directives.crud.buttons', [])
replace:true,
template:
'
'
};
});
\ No newline at end of file
diff --git a/client/test/unit/app/admin/users/admin-usersSpec.js b/client/test/unit/app/admin/users/admin-usersSpec.js
index e050aea5..53043541 100644
--- a/client/test/unit/app/admin/users/admin-usersSpec.js
+++ b/client/test/unit/app/admin/users/admin-usersSpec.js
@@ -54,102 +54,120 @@ describe('admin users', function () {
});
describe('validateEquals directive', function() {
- var $scope, form;
-
- function setTestValue(value) {
- $scope.model.testValue = value;
- $scope.$digest();
- }
- function setCompareTo(value) {
- $scope.model.compareTo = value;
- $scope.$digest();
- }
+ var $scope, modelCtrl, modelValue;
beforeEach(inject(function($compile, $rootScope) {
$scope = $rootScope;
var element = angular.element(
- ''
+ ''
);
- $scope.model = {
- testValue: '',
- compareTo: ''
- };
$compile(element)($scope);
+ modelValue = $scope.model = {};
+ modelCtrl = $scope.testForm.testInput;
$scope.$digest();
- form = $scope.form;
}));
- describe('model validity', function() {
- it('should be valid initially', function() {
- expect(form.testInput.$valid).toBe(true);
- });
+ it('should be valid initially', function() {
+ expect(modelCtrl.$valid).toBeTruthy();
+ });
+
+ describe('model value changes', function() {
it('should be invalid if the model changes', function() {
- setTestValue('different');
- expect(form.testInput.$valid).toBe(false);
+ modelValue.testValue = 'different';
+ $scope.$digest();
+ expect(modelCtrl.$valid).toBeFalsy();
+ expect(modelCtrl.$viewValue).toBe(undefined);
});
it('should be invalid if the reference model changes', function() {
- setCompareTo('different');
- expect(form.testInput.$valid).toBe(false);
+ modelValue.compareTo = 'different';
+ $scope.$digest();
+ expect(modelCtrl.$valid).toBeFalsy();
+ expect(modelCtrl.$viewValue).toBe(undefined);
+ });
+ it('should be valid if the modelValue changes to be the same as the reference', function() {
+ modelValue.compareTo = 'different';
+ $scope.$digest();
+ expect(modelCtrl.$valid).toBeFalsy();
+
+ modelValue.testValue = 'different';
+ $scope.$digest();
+ expect(modelCtrl.$valid).toBeTruthy();
+ expect(modelCtrl.$viewValue).toBe('different');
+ });
+ });
+
+ describe('input value changes', function() {
+ it('should be invalid if the input value changes', function() {
+ modelCtrl.$setViewValue('different');
+ expect(modelCtrl.$valid).toBeFalsy();
+ expect(modelValue.testValue).toBe(undefined);
});
- it('should be valid if the model changes to be the same as the reference', function() {
- setCompareTo('different');
- expect(form.testInput.$valid).toBe(false);
- setTestValue('different');
- expect(form.testInput.$valid).toBe(true);
+ it('should be invalid if the input value changes to be the same as the reference', function() {
+ modelValue.compareTo = 'different';
+ $scope.$digest();
+ expect(modelCtrl.$valid).toBeFalsy();
+
+ modelCtrl.$setViewValue('different');
+ expect(modelCtrl.$viewValue).toBe('different');
+ expect(modelCtrl.$valid).toBeTruthy();
});
});
});
describe('uniqueEmail directive', function() {
- var Users, $scope, form;
+ var $scope, testInput, querySpy, respondWith;
- function setTestValue(value) {
- $scope.model.testValue = value;
- $scope.$digest();
- }
-
- // Mockup Users resource
+ // We are best to mock up the whole Users object this way because Users
+ // relies on so many other services, including the MONGOLAB_CONFIG constant
angular.module('test', []).factory('Users', function() {
- Users = jasmine.createSpyObj('Users', ['query']);
- return Users;
+ querySpy = jasmine.createSpy('query');
+ querySpy.andCallFake(function(query, response) {
+ // We capture the response so that the tests can call it with their own data
+ respondWith = response;
+ });
+ return { query: querySpy };
});
-
beforeEach(module('test'));
+
beforeEach(inject(function($compile, $rootScope){
$scope = $rootScope;
var element = angular.element(
- ''
+ ''
);
- $scope.model = { testValue: null};
$compile(element)($scope);
+ $scope.model = {};
$scope.$digest();
- form = $scope.form;
+ // Keep a reference to the test input for the tests
+ testInput = $scope.form.testInput;
}));
it('should be valid initially', function() {
- expect(form.testInput.$valid).toBe(true);
+ expect(testInput.$valid).toBe(true);
});
it('should not call Users.query when the model changes', function() {
- setTestValue('different');
- expect(Users.query).not.toHaveBeenCalled();
+ $scope.model.testValue = 'different';
+ $scope.$digest();
+ expect(querySpy).not.toHaveBeenCalled();
});
it('should call Users.query when the view changes', function() {
- form.testInput.$setViewValue('different');
- expect(Users.query).toHaveBeenCalled();
+ testInput.$setViewValue('different');
+ expect(querySpy).toHaveBeenCalled();
});
- it('should set model to invalid if the Users callback contains users', function() {
- Users.query.andCallFake(function(query, callback) {
- callback(['someUser']);
- });
- form.testInput.$setViewValue('different');
- expect(form.testInput.$valid).toBe(false);
+ it('should set model to invalid if the Users.query response contains users', function() {
+ testInput.$setViewValue('different');
+ respondWith(['someUser']);
+ expect(testInput.$valid).toBe(false);
});
- it('should set model to valid if the Users callback contains no users', function() {
- Users.query.andCallFake(function(query, callback) {
- callback([]);
- });
- form.testInput.$setViewValue('different');
- expect(form.testInput.$valid).toBe(true);
+ it('should set model to valid if the Users.query response contains no users', function() {
+ testInput.$setViewValue('different');
+ respondWith([]);
+ expect(testInput.$valid).toBe(true);
});
});
});
\ No newline at end of file
diff --git a/client/test/unit/common/directives/buttonSpec.js b/client/test/unit/common/directives/buttonSpec.js
new file mode 100644
index 00000000..2223468b
--- /dev/null
+++ b/client/test/unit/common/directives/buttonSpec.js
@@ -0,0 +1,46 @@
+describe('button directive', function () {
+ beforeEach(module('directives.button'));
+
+ it('adds a "btn" class to the button element', function() {
+ inject(function($compile, $rootScope) {
+ var element = $compile('')($rootScope);
+ expect(element.hasClass('btn')).toBe(true);
+ });
+ });
+
+ it('leaves the contents of the button intact', function() {
+ inject(function($compile, $rootScope) {
+ var element = $compile('')($rootScope);
+ expect(element.text()).toBe('Click Me!');
+ });
+ });
+});
+
+describe('primaryButton directive', function () {
+ var element;
+ beforeEach(module('directives.button'));
+ beforeEach(function() {
+ inject(function($compile, $rootScope) {
+ element = $compile('')($rootScope);
+ });
+ });
+
+ it('replaces the directive element with a button element', function() {
+ expect(element[0].localName).toBe('button');
+ });
+
+ it('adds a "btn-primary" class to the button element', function() {
+ expect(element.hasClass('btn')).toBe(true);
+ });
+
+ it('adds a "btn" class to button elements (because it is a button!)', function() {
+ expect(element.hasClass('btn')).toBe(true);
+ });
+
+ it('transcludes the contents of the button correctly', function() {
+ inject(function($compile, $rootScope) {
+ var element = $compile('Click Me!')($rootScope);
+ expect(element.text()).toBe('Click Me!');
+ });
+ });
+});