blob: c5244e0e54459bf24f4c154b42c2b0b1eba7a41c [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',
99 validators: {}
100 },
101 {
102 name: 'birthDate',
103 label: 'DOB:',
104 type: 'date',
105 validators: {}
106 },
107 {
108 name: 'enabled',
109 label: 'Status:',
110 type: 'boolean',
111 validators: {}
112 },
113 {
114 name: 'role',
115 label: 'Role:',
116 type: 'select',
117 options: [
118 {id: 1, label: 'user'},
119 {id: 2, label: 'admin'}
120 ],
121 validators: {}
122 }
123 ];
124
125 let config: IXosFormCfg = {
126 formName: 'testForm',
127 actions: [
128 {
129 label: 'Save',
130 icon: 'ok',
131 cb: cb,
132 class: 'success'
133 }
134 ],
135 inputs: inputs
136 };
137
138 scope.config = config;
139
140 scope.model = {
141 id: 1,
142 first_name: 'Jhon',
143 email: 'test@onlab.us',
144 birthDate: new Date('2016-04-18T23:44:16.883181Z'),
145 enabled: true,
146 role: 1, // select
147 };
148
149 compileElement();
150 }));
151
152 it('should render 4 input field', () => {
153 // boolean and select are in the form model, but are not input
154 expect(Object.keys(isolatedScope.config.inputs).length).toEqual(6);
155 const htmlInputs = $('input', element);
156 expect(htmlInputs.length).toEqual(4);
157 });
158
159 it('should render 1 boolean field', () => {
160 expect($(element).find('.boolean-field > a').length).toEqual(2);
161 });
162
163 it('when clicking on action should invoke callback', () => {
164 const link = $(element).find('[role="button"]');
165 link.click();
166 // TODO : Check correct parameters
167 expect(cb).toHaveBeenCalled();
168
169 });
170
171 // TODO move in xosField test
172 it('should set a custom label', () => {
173 let nameField = element[0].getElementsByClassName('form-group')[0];
174 let label = angular.element(nameField.getElementsByTagName('label')[0]).text();
175 expect(label).toEqual('Id:');
176 });
177
178 // TODO move test in xos-field
179 xdescribe('the boolean field test', () => {
180
181 let setFalse, setTrue;
182
183 beforeEach(() => {
184 setFalse = $('.boolean-field > button:first-child', element);
185 setTrue = $('.boolean-field > button:last-child', element);
186 });
187
188 it('should change value to false', () => {
189 expect(isolatedScope.ngModel.enabled).toEqual(true);
190 setFalse.click();
191 expect(isolatedScope.ngModel.enabled).toEqual(false);
192 });
193
194 it('should change value to true', () => {
195 isolatedScope.ngModel.enabled = false;
196 scope.$apply();
197 expect(isolatedScope.ngModel.enabled).toEqual(false);
198 setTrue.click();
199 expect(isolatedScope.ngModel.enabled).toEqual(true);
200 });
201 });
202 });
203 describe('when correctly configured for feedback', () => {
204 // NOTE move this tests in xos-alert??
205 let fb = jasmine.createSpy('feedback').and.callFake(function(statusFlag: boolean) {
206 if (statusFlag) {
207 scope.config.feedback.show = true;
208 scope.config.feedback.message = 'Form Submitted';
209 scope.config.feedback.type = 'success';
210 }
211 else {
212 scope.config.feedback.show = true;
213 scope.config.feedback.message = 'Error';
214 scope.config.feedback.type = 'danger';
215 }
216 });
217
218 beforeEach(() => {
219 scope = rootScope.$new();
220 scope.config = {
221 formName: 'testForm',
222 feedback: {
223 show: false,
224 message: 'Form submitted successfully !!!',
225 type: 'success'
226 },
227 actions: [
228 {
229 label: 'Save',
230 icon: 'ok', // refers to bootstraps glyphicon
231 cb: () => null,
232 class: 'success'
233 }
234 ]
235 };
236 scope.model = {};
237 compileElement();
238 });
239
240 it('should not show feedback when loaded', () => {
241 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success ng-hide');
242 });
243
244 it('should show a success feedback', () => {
245 fb(true);
246 scope.$digest();
247 expect(isolatedScope.config.feedback.type).toEqual('success');
248 expect(fb).toHaveBeenCalledWith(true);
249 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-success');
250 });
251
252 it('should show an error feedback', function() {
253 fb(false);
254 scope.$digest();
255 expect(isolatedScope.config.feedback.type).toEqual('danger');
256 expect(fb).toHaveBeenCalledWith(false);
257 expect($(element).find('xos-alert > div')).toHaveClass('alert alert-danger');
258 });
259 });
260});