blob: 6b2a196ad84df2861023ea2de0c72e6379902b82 [file] [log] [blame]
Matteo Scandolob2225a02017-04-11 15:23:04 -07001import * as angular from 'angular';
2import * as $ from 'jquery';
3import 'angular-mocks';
4import {xosForm, IXosFormCfg, IXosFormInput} from './form';
5import {XosFormHelpers} from './form-helpers';
6import {xosField} from '../field/field';
7import {xosAlert} from '../alert/alert';
8
9describe('The Xos Form component', () => {
10
11 let element, scope, isolatedScope, rootScope, compile;
12
13 const compileElement = () => {
14
15 if (!scope) {
16 scope = rootScope.$new();
17 }
18
19 element = angular.element(`<xos-form config="config" ng-model="model"></xos-form>`);
20 compile(element)(scope);
21 scope.$digest();
22 isolatedScope = element.isolateScope().vm;
23 };
24
25 const MockConfigHelpers = {
26 toLabel: string => string
27 };
28
29 beforeEach(() => {
30
31 angular
32 .module('form', [])
33 .component('xosForm', xosForm)
34 .service('XosFormHelpers', XosFormHelpers)
35 .component('xosField', xosField) // NOTE does it make sense to mock it?
36 .component('xosAlert', xosAlert)
37 .value('ConfigHelpers', MockConfigHelpers);
38
39 angular.mock.module('form');
40
41 inject(($compile: ng.ICompileService, $rootScope: ng.IScope) => {
42 rootScope = $rootScope;
43 compile = $compile;
44 });
45 });
46
47 it('should throw an error if no config is specified', () => {
48 function errorFunctionWrapper() {
49 compileElement();
50 }
51 expect(errorFunctionWrapper).toThrow(new Error('[xosForm] Please provide a configuration via the "config" attribute'));
52 });
53
54 it('should throw an error if no actions are specified in config', () => {
55 function errorFunctionWrapper() {
56 scope = rootScope.$new();
57 scope.config = 'green';
58 compileElement();
59 }
60 expect(errorFunctionWrapper).toThrow(new Error('[xosForm] Please provide an action list in the configuration'));
61 });
62
63 it('should throw an error if no formName is specified in config', () => {
64 function errorFunctionWrapper() {
65 scope = rootScope.$new();
66 scope.config = {
67 actions: []
68 };
69 compileElement();
70 }
71 expect(errorFunctionWrapper).toThrow(new Error('[xosForm] Please provide a formName property in the config'));
72 });
73
74 describe('when correctly configured', () => {
75
76 let cb = jasmine.createSpy('callback');
77
78 beforeEach(inject(($rootScope) => {
79
80 scope = $rootScope.$new();
81
82 let inputs: IXosFormInput[] = [
83 {
84 name: 'id',
85 label: 'Id:',
86 type: 'number',
87 validators: {}
88 },
89 {
90 name: 'first_name',
91 label: 'Name:',
92 type: 'text',
93 validators: {}
94 },
95 {
96 name: 'email',
97 label: 'Mail:',
98 type: 'email',
Matteo Scandolo80056232017-07-10 16:24:41 -070099 validators: {
100 required: true
101 }
Matteo Scandolob2225a02017-04-11 15:23:04 -0700102 },
103 {
104 name: 'birthDate',
105 label: 'DOB:',
106 type: 'date',
107 validators: {}
108 },
109 {
110 name: 'enabled',
111 label: 'Status:',
112 type: 'boolean',
113 validators: {}
114 },
115 {
116 name: 'role',
117 label: 'Role:',
118 type: 'select',
119 options: [
120 {id: 1, label: 'user'},
121 {id: 2, label: 'admin'}
122 ],
123 validators: {}
124 }
125 ];
126
127 let config: IXosFormCfg = {
128 formName: 'testForm',
129 actions: [
130 {
131 label: 'Save',
132 icon: 'ok',
133 cb: cb,
134 class: 'success'
135 }
136 ],
137 inputs: inputs
138 };
139
140 scope.config = config;
141
142 scope.model = {
143 id: 1,
144 first_name: 'Jhon',
145 email: 'test@onlab.us',
146 birthDate: new Date('2016-04-18T23:44:16.883181Z'),
147 enabled: true,
148 role: 1, // select
149 };
150
151 compileElement();
152 }));
153
154 it('should render 4 input field', () => {
155 // boolean and select are in the form model, but are not input
156 expect(Object.keys(isolatedScope.config.inputs).length).toEqual(6);
157 const htmlInputs = $('input', element);
158 expect(htmlInputs.length).toEqual(4);
159 });
160
161 it('should render 1 boolean field', () => {
162 expect($(element).find('.boolean-field > a').length).toEqual(2);
163 });
164
165 it('when clicking on action should invoke callback', () => {
166 const link = $(element).find('[role="button"]');
167 link.click();
168 // TODO : Check correct parameters
169 expect(cb).toHaveBeenCalled();
170
171 });
172
173 // TODO move in xosField test
174 it('should set a custom label', () => {
Matteo Scandolo80056232017-07-10 16:24:41 -0700175 let nameField = element[0].getElementsByClassName('form-group')[1];
Matteo Scandolob2225a02017-04-11 15:23:04 -0700176 let label = angular.element(nameField.getElementsByTagName('label')[0]).text();
Matteo Scandolo80056232017-07-10 16:24:41 -0700177 expect(label).toContain('Name:');
178 expect(label).not.toContain('*');
179 });
180
181 it('should print an * for required fields', () => {
182 let nameField = element[0].getElementsByClassName('form-group')[2];
183 let label = angular.element(nameField.getElementsByTagName('label')[0]).text();
184 expect(label).toContain('*');
Matteo Scandolob2225a02017-04-11 15:23:04 -0700185 });
186
187 // TODO move test in xos-field
188 xdescribe('the boolean field test', () => {
189
190 let setFalse, setTrue;
191
192 beforeEach(() => {
193 setFalse = $('.boolean-field > button:first-child', element);
194 setTrue = $('.boolean-field > button:last-child', element);
195 });
196
197 it('should change value to false', () => {
198 expect(isolatedScope.ngModel.enabled).toEqual(true);
199 setFalse.click();
200 expect(isolatedScope.ngModel.enabled).toEqual(false);
201 });
202
203 it('should change value to true', () => {
204 isolatedScope.ngModel.enabled = false;
205 scope.$apply();
206 expect(isolatedScope.ngModel.enabled).toEqual(false);
207 setTrue.click();
208 expect(isolatedScope.ngModel.enabled).toEqual(true);
209 });
210 });
211 });
212 describe('when correctly configured for feedback', () => {
213 // NOTE move this tests in xos-alert??
214 let fb = jasmine.createSpy('feedback').and.callFake(function(statusFlag: boolean) {
215 if (statusFlag) {
216 scope.config.feedback.show = true;
217 scope.config.feedback.message = 'Form Submitted';
218 scope.config.feedback.type = 'success';
219 }
220 else {
221 scope.config.feedback.show = true;
222 scope.config.feedback.message = 'Error';
223 scope.config.feedback.type = 'danger';
224 }
225 });
226
227 beforeEach(() => {
228 scope = rootScope.$new();
229 scope.config = {
230 formName: 'testForm',
231 feedback: {
232 show: false,
233 message: 'Form submitted successfully !!!',
234 type: 'success'
235 },
236 actions: [
237 {
238 label: 'Save',
239 icon: 'ok', // refers to bootstraps glyphicon
240 cb: () => null,
241 class: 'success'
242 }
243 ]
244 };
245 scope.model = {};
246 compileElement();
247 });
248
249 it('should not show feedback when loaded', () => {
250 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success ng-hide');
251 });
252
253 it('should show a success feedback', () => {
254 fb(true);
255 scope.$digest();
256 expect(isolatedScope.config.feedback.type).toEqual('success');
257 expect(fb).toHaveBeenCalledWith(true);
258 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success');
259 });
260
261 it('should show an error feedback', function() {
262 fb(false);
263 scope.$digest();
264 expect(isolatedScope.config.feedback.type).toEqual('danger');
265 expect(fb).toHaveBeenCalledWith(false);
266 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-danger');
267 });
268 });
269});