blob: dc9c9571b5a55b426584e0cbe00cd16716c792f6 [file] [log] [blame]
Matteo Scandolo7bc39c42016-04-20 11:38:42 -07001/**
2 * © OpenCORD
3 *
4 * Created by teone on 4/18/16.
5 */
6
7(function () {
8 'use strict';
9
Matteo Scandolob9fb6252016-05-26 15:09:55 -070010 let element, scope, isolatedScope, rootScope, compile;
11
12 const compileElement = () => {
13
14 if(!scope){
15 scope = rootScope.$new();
16 }
17
18 element = angular.element(`<xos-form config="config" ng-model="model"></xos-form>`);
19 compile(element)(scope);
20 scope.$digest();
21 isolatedScope = element.isolateScope().vm;
22 }
23
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070024 describe('The xos.helper module', function(){
25
Matteo Scandolo6ba12872016-04-27 16:29:33 -070026 describe('The xos-form component', () => {
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070027
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070028
29 beforeEach(module('xos.helpers'));
30
Matteo Scandolob9fb6252016-05-26 15:09:55 -070031 beforeEach(inject(($compile, $rootScope) => {
32 rootScope = $rootScope;
33 compile = $compile;
34 }));
35
Matteo Scandolob6ca3012016-06-03 16:58:43 -070036 it('should throw an error if no config is specified', () => {
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070037 function errorFunctionWrapper(){
Matteo Scandolob9fb6252016-05-26 15:09:55 -070038 compileElement();
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070039 }
40 expect(errorFunctionWrapper).toThrow(new Error('[xosForm] Please provide a configuration via the "config" attribute'));
Matteo Scandolob6ca3012016-06-03 16:58:43 -070041 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070042
Matteo Scandolob6ca3012016-06-03 16:58:43 -070043 it('should throw an error if no actions is specified', () => {
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070044 function errorFunctionWrapper(){
Matteo Scandolob6ca3012016-06-03 16:58:43 -070045 scope = rootScope.$new();
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070046 scope.config = 'green';
Matteo Scandolob9fb6252016-05-26 15:09:55 -070047 compileElement();
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070048 }
49 expect(errorFunctionWrapper).toThrow(new Error('[xosForm] Please provide an action list in the configuration'));
Matteo Scandolob6ca3012016-06-03 16:58:43 -070050 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070051
52 describe('when correctly configured', () => {
53
54 let cb = jasmine.createSpy('callback');
55
Matteo Scandolob9fb6252016-05-26 15:09:55 -070056 beforeEach(inject(($rootScope) => {
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070057
58 scope = $rootScope.$new();
59
60 scope.config = {
61 exclude: ['excludedField'],
Matteo Scandolob3d686f2016-04-22 14:14:03 -070062 formName: 'testForm',
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070063 actions: [
64 {
65 label: 'Save',
66 icon: 'ok', // refers to bootstraps glyphicon
67 cb: cb,
68 class: 'success'
69 }
70 ],
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -070071 fields: {
72 first_name: {
73 label: 'Custom Label'
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070074 }
Matteo Scandolo9f0e5ae2016-04-20 12:24:52 -070075 }
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070076 };
77
78 scope.model = {
79 id: 1,
80 first_name: 'Jhon',
81 last_name: 'Snow',
82 age: 25,
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -070083 email: 'test@onlab.us',
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070084 birthDate: '2016-04-18T23:44:16.883181Z',
85 enabled: true,
86 role: 'user', //select
87 a_permissions: [
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070088 ],
Matteo Scandolo974c0e42016-05-25 16:02:16 -070089 object_field: {
90 string: 'bar',
91 number: 1,
92 email: 'teo@onlab.us'
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070093 }
94 };
95
Matteo Scandolob9fb6252016-05-26 15:09:55 -070096 compileElement();
Matteo Scandolo7bc39c42016-04-20 11:38:42 -070097 }));
98
99 it('should add excluded properties to the list', () => {
100 let expected = ['id', 'validators', 'created', 'updated', 'deleted', 'backend_status', 'excludedField'];
101 expect(isolatedScope.excludedField).toEqual(expected);
102 });
103
Matteo Scandolo03d8b8e2016-05-25 17:37:37 -0700104 it('should render 10 input field', () => {
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700105 // boolean are in the form model, but are not input
106 expect(Object.keys(isolatedScope.formField).length).toEqual(9);
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700107 var field = element[0].getElementsByTagName('input');
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700108 expect(field.length).toEqual(10);
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700109 });
110
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700111 it('should render 1 boolean field', () => {
arpiagariu10bd9cb2016-06-10 13:28:34 -0700112 expect($(element).find('.boolean-field > a').length).toEqual(2)
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700113 });
114
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700115 it('when clicking on action should invoke callback', () => {
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700116 var link = $(element).find('[role="button"]');
arpiagariu10bd9cb2016-06-10 13:28:34 -0700117 //console.log(link);
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700118 link.click();
arpiagariu10bd9cb2016-06-10 13:28:34 -0700119 // TODO : Check correct parameters
120 expect(cb).toHaveBeenCalled();
121
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700122 });
123
124 it('should set a custom label', () => {
125 let nameField = element[0].getElementsByClassName('form-group')[0];
126 let label = angular.element(nameField.getElementsByTagName('label')[0]).text()
127 expect(label).toEqual('Custom Label:');
128 });
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700129
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700130 it('should use the correct input type', () => {
131 expect($(element).find('[name="age"]')).toHaveAttr('type', 'number');
132 expect($(element).find('[name="birthDate"]')).toHaveAttr('type', 'date');
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700133 expect($(element).find('[name="email"]')).toHaveAttr('type', 'email');
134 });
135
arpiagariu10bd9cb2016-06-10 13:28:34 -0700136 xdescribe('the boolean field test', () => {
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700137
138 let setFalse, setTrue;
139
140 beforeEach(() => {
141 setFalse= $(element).find('.boolean-field > button:first-child');
142 setTrue = $(element).find('.boolean-field > button:last-child');
143 });
144
145 it('should change value to false', () => {
146 expect(isolatedScope.ngModel.enabled).toEqual(true);
arpiagariu10bd9cb2016-06-10 13:28:34 -0700147 setFalse.click();
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700148 expect(isolatedScope.ngModel.enabled).toEqual(false);
149 });
150
Matteo Scandolo974c0e42016-05-25 16:02:16 -0700151 it('should change value to true', () => {
Matteo Scandolo4ba4cf12016-04-20 16:36:17 -0700152 isolatedScope.ngModel.enabled = false;
153 scope.$apply();
154 expect(isolatedScope.ngModel.enabled).toEqual(false);
155 setTrue.click()
156 expect(isolatedScope.ngModel.enabled).toEqual(true);
157 });
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700158 });
Matteo Scandolob3d686f2016-04-22 14:14:03 -0700159
Matteo Scandolo6ba12872016-04-27 16:29:33 -0700160 // NOTE not sure why this tests are failing
161 xdescribe('the custom validation options', () => {
Matteo Scandolob3d686f2016-04-22 14:14:03 -0700162 beforeEach(() => {
163 scope.config.fields.first_name.validators = {
164 minlength: 10,
165 maxlength: 15,
166 required: true
167 };
168
Matteo Scandolo01c87572016-04-25 08:15:24 -0700169 scope.config.fields.age = {
170 validators: {
171 min: 10,
172 max: 20
173 }
174 };
175
Matteo Scandolob3d686f2016-04-22 14:14:03 -0700176 scope.$digest();
177 });
178
179 it('should validate required', () => {
180 scope.model.first_name = null;
181 scope.$digest();
182
183 expect(isolatedScope.testForm.first_name.$valid).toBeFalsy();
184 expect(isolatedScope.testForm.first_name.$error.required).toBeTruthy();
185 });
186
187 it('should validate minlength', () => {
188 scope.model.first_name = 'short';
189 scope.$digest();
190
191 expect(isolatedScope.testForm.first_name.$valid).toBeFalsy();
192 expect(isolatedScope.testForm.first_name.$error.minlength).toBeTruthy();
193 });
194
195 it('should validate maxlength', () => {
196 scope.model.first_name = 'this is way too long!';
197 scope.$digest();
198
199 expect(isolatedScope.testForm.first_name.$valid).toBeFalsy();
200 expect(isolatedScope.testForm.first_name.$error.maxlength).toBeTruthy();
201 });
Matteo Scandolo01c87572016-04-25 08:15:24 -0700202
Matteo Scandolo6ba12872016-04-27 16:29:33 -0700203 it('should validate min', () => {
Matteo Scandolo01c87572016-04-25 08:15:24 -0700204 // not validating min and max for now
205 scope.model.age = 8;
206 scope.$digest();
207
208 expect(isolatedScope.testForm.age.$valid).toBeFalsy();
209 expect(isolatedScope.testForm.age.$error.min).toBeTruthy();
210 });
Matteo Scandolob3d686f2016-04-22 14:14:03 -0700211 });
Matteo Scandolob9fb6252016-05-26 15:09:55 -0700212
213 describe('when a deep model is passed', () => {
214
215 beforeEach(inject(($rootScope) => {
216
217 scope = $rootScope.$new();
218
219 scope.config = {
220 exclude: ['excludedField'],
221 formName: 'testForm',
222 actions: [
223 {
224 label: 'Save',
225 icon: 'ok', // refers to bootstraps glyphicon
226 cb: cb,
227 class: 'success'
228 }
229 ],
230 fields: {
231 object_field: {
232 field_one: {
233 label: 'Custom Label'
234 }
235 }
236 }
237 };
238
239 scope.model = {
240 object_field: {
241 field_one: 'bar',
242 number: 1,
243 email: 'teo@onlab.us'
244 }
245 };
246
247 compileElement();
248 }));
249
250 it('should print nested field', () => {
251 expect($(element).find('input').length).toBe(3);
252 });
253
254 xit('should configure nested fields', () => {
255 let custom_label = $(element).find('input[name=field_one]').parent().find('label');
256 expect(custom_label.text()).toBe('Custom Label');
257 });
258 });
Matteo Scandolo6e2e6ff2016-04-20 14:59:39 -0700259 });
arpiagariu10bd9cb2016-06-10 13:28:34 -0700260 describe('when correctly configured for feedback', () => {
261
Matteo Scandolob585d382016-06-15 14:53:33 -0700262 let fb = jasmine.createSpy('feedback').and.callFake(function(statusFlag) {
263 if(statusFlag){
264 scope.config.feedback.show = true;
265 scope.config.feedback.message = 'Form Submitted';
266 scope.config.feedback.type = 'success';
267 }
268 else {
269 scope.config.feedback.show = true;
270 scope.config.feedback.message = 'Error';
271 scope.config.feedback.type = 'danger';
arpiagariu10bd9cb2016-06-10 13:28:34 -0700272
Matteo Scandolob585d382016-06-15 14:53:33 -0700273 }
274 });
arpiagariu10bd9cb2016-06-10 13:28:34 -0700275
Matteo Scandolob585d382016-06-15 14:53:33 -0700276 beforeEach(()=> {
277 scope = rootScope.$new();
278 scope.config =
279 {
arpiagariu10bd9cb2016-06-10 13:28:34 -0700280
arpiagariu10bd9cb2016-06-10 13:28:34 -0700281 feedback: {
282 show: false,
283 message: 'Form submitted successfully !!!',
284 type: 'success'
285 },
286 actions: [
287 {
288 label: 'Save',
289 icon: 'ok', // refers to bootstraps glyphicon
Matteo Scandolob585d382016-06-15 14:53:33 -0700290 cb: () => {},
arpiagariu10bd9cb2016-06-10 13:28:34 -0700291 class: 'success'
292 }
Matteo Scandolob585d382016-06-15 14:53:33 -0700293 ]
arpiagariu10bd9cb2016-06-10 13:28:34 -0700294 };
Matteo Scandolob585d382016-06-15 14:53:33 -0700295 scope.model={};
arpiagariu10bd9cb2016-06-10 13:28:34 -0700296 compileElement();
arpiagariu10bd9cb2016-06-10 13:28:34 -0700297 });
298
Matteo Scandolob585d382016-06-15 14:53:33 -0700299 it('should not show feedback when loaded', () => {
300 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success ng-hide');
arpiagariu10bd9cb2016-06-10 13:28:34 -0700301 });
302
Matteo Scandolob585d382016-06-15 14:53:33 -0700303 it('should show a success feedback', () => {
304 fb(true);
305 scope.$digest();
306 expect(isolatedScope.config.feedback.type).toEqual('success');
307 expect(fb).toHaveBeenCalledWith(true);
308 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success');
arpiagariu10bd9cb2016-06-10 13:28:34 -0700309 });
310
Matteo Scandolob585d382016-06-15 14:53:33 -0700311 it('should show an error feedback', function() {
312 fb(false);
313 scope.$digest();
314 expect(isolatedScope.config.feedback.type).toEqual('danger');
315 expect(fb).toHaveBeenCalledWith(false);
316 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-danger');
arpiagariu10bd9cb2016-06-10 13:28:34 -0700317 });
318 });
319
Matteo Scandolo7bc39c42016-04-20 11:38:42 -0700320 });
321 });
322})();