blob: 5883434916b0125cf4811d2b1be8acf3e56ceb65 [file] [log] [blame]
Matteo Scandolod58d5042016-12-16 16:59:21 -08001import * as angular from 'angular';
2import 'angular-mocks';
3import 'angular-ui-router';
4
Matteo Scandolo07e2f622017-01-09 10:54:13 -08005import {IXosConfigHelpersService, ConfigHelpers, IXosModelDefsField} from './config.helpers';
Matteo Scandolo1aee1982017-02-17 08:33:23 -08006import {IXosModeldef} from '../../../datasources/rest/modeldefs.rest';
Matteo Scandolocb466ed2017-01-04 17:16:24 -08007import {IXosTableCfg} from '../../table/table';
Matteo Scandolo1aee1982017-02-17 08:33:23 -08008import {IXosFormInput, IXosFormCfg} from '../../form/form';
Matteo Scandolo07e2f622017-01-09 10:54:13 -08009import {BehaviorSubject} from 'rxjs';
Matteo Scandolod58d5042016-12-16 16:59:21 -080010
11let service: IXosConfigHelpersService;
Matteo Scandolocb466ed2017-01-04 17:16:24 -080012
Matteo Scandolo1aee1982017-02-17 08:33:23 -080013const model: IXosModeldef = {
Matteo Scandolocb466ed2017-01-04 17:16:24 -080014 name: 'Test',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080015 app: 'test',
Matteo Scandolocb466ed2017-01-04 17:16:24 -080016 fields: [
17 {
18 type: 'number',
19 name: 'id',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080020 validators: []
Matteo Scandolocb466ed2017-01-04 17:16:24 -080021 },
22 {
23 type: 'string',
24 name: 'name',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080025 validators: [
26 {
27 bool_value: true,
28 name: 'required'
29 }
30 ]
Matteo Scandolocb466ed2017-01-04 17:16:24 -080031 },
32 {
33 type: 'string',
34 name: 'something',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080035 validators: [
36 {
37 int_value: 30,
38 name: 'maxlength'
39 }
40 ]
Matteo Scandolo80c3a652017-01-06 10:48:31 -080041 },
42 {
43 type: 'number',
44 name: 'else',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080045 validators: [
46 {
47 int_value: 20,
48 name: 'min'
49 },
50 {
51 int_value: 40,
52 name: 'max'
53 }
54 ]
Matteo Scandolocb466ed2017-01-04 17:16:24 -080055 },
56 {
57 type: 'date',
58 name: 'updated',
Matteo Scandolo1aee1982017-02-17 08:33:23 -080059 validators: []
Matteo Scandolocb466ed2017-01-04 17:16:24 -080060 },
61 ]
62};
63
Matteo Scandolod58d5042016-12-16 16:59:21 -080064describe('The ConfigHelpers service', () => {
65
Matteo Scandolo0a8b02e2017-01-06 14:43:36 -080066 beforeEach(() => {
67 angular
68 .module('test', ['toastr'])
69 .service('ConfigHelpers', ConfigHelpers)
70 .value('AuthService', {
71 getUser: () => {
72 return {id: 1};
73 }
Matteo Scandolo04964232017-01-07 12:53:46 -080074 })
Matteo Scandolo1aee1982017-02-17 08:33:23 -080075 .value('XosModelStore', {
Matteo Scandolo04964232017-01-07 12:53:46 -080076
Matteo Scandoloa242c872017-01-12 15:13:00 -080077 })
78 .value('$state', {
79 get: () => {
80 return [
81 {
82 name: 'xos.core.tests',
83 data: {model: 'Test'}
84 },
85 {
86 name: 'xos.core.slices',
87 data: {model: 'Slices'}
88 }
89 ];
90 }
Matteo Scandolo0a8b02e2017-01-06 14:43:36 -080091 });
92 angular.mock.module('test');
93 });
Matteo Scandolod58d5042016-12-16 16:59:21 -080094
95 beforeEach(angular.mock.inject((
96 ConfigHelpers: IXosConfigHelpersService,
97 ) => {
98 service = ConfigHelpers;
99 }));
100
101 describe('The pluralize function', () => {
102 it('should pluralize string', () => {
103 expect(service.pluralize('test')).toEqual('tests');
104 expect(service.pluralize('test', 1)).toEqual('test');
Matteo Scandolo08464e52017-01-17 13:35:27 -0800105 expect(service.pluralize('xos')).toEqual('xoses');
Matteo Scandolod58d5042016-12-16 16:59:21 -0800106 expect(service.pluralize('slice')).toEqual('slices');
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800107 expect(service.pluralize('Slice', 1)).toEqual('Slice');
Matteo Scandolod58d5042016-12-16 16:59:21 -0800108 });
109
110 it('should preprend count to string', () => {
111 expect(service.pluralize('test', 6, true)).toEqual('6 tests');
112 expect(service.pluralize('test', 1, true)).toEqual('1 test');
113 });
114 });
115
116 describe('the label formatter', () => {
117 it('should format a camel case string', () => {
118 expect(service.toLabel('camelCase')).toEqual('Camel case');
119 });
120
121 it('should format a snake case string', () => {
122 expect(service.toLabel('snake_case')).toEqual('Snake case');
123 });
124
125 it('should format a kebab case string', () => {
126 expect(service.toLabel('kebab-case')).toEqual('Kebab case');
127 });
128
129 it('should set plural', () => {
130 expect(service.toLabel('kebab-case', true)).toEqual('Kebab cases');
131 });
132
133 it('should format an array of strings', () => {
134 let strings: string[] = ['camelCase', 'snake_case', 'kebab-case'];
135 let labels = ['Camel case', 'Snake case', 'Kebab case'];
Matteo Scandoloe0d71ea2016-12-19 11:56:12 -0800136 expect(service.toLabels(strings)).toEqual(labels);
Matteo Scandolod58d5042016-12-16 16:59:21 -0800137 });
138
139 it('should set plural on an array of strings', () => {
140 let strings: string[] = ['camelCase', 'snake_case', 'kebab-case'];
141 let labels = ['Camel cases', 'Snake cases', 'Kebab cases'];
Matteo Scandoloe0d71ea2016-12-19 11:56:12 -0800142 expect(service.toLabels(strings, true)).toEqual(labels);
Matteo Scandolod58d5042016-12-16 16:59:21 -0800143 });
144 });
145
Matteo Scandoloa242c872017-01-12 15:13:00 -0800146 describe('the navigation methods', () => {
Matteo Scandoloa242c872017-01-12 15:13:00 -0800147 describe('stateFromCoreModels', () => {
148
149 let state: ng.ui.IStateService;
150
151 beforeEach(angular.mock.inject(($state) => {
152 state = $state;
153 }));
154
155 it('should return the state for a given model', () => {
156 expect(service.stateFromCoreModel('Test')).toBe('xos.core.tests');
157 });
Matteo Scandolocf5a9932017-08-09 13:46:04 -0700158 });
159 describe('stateWithParams', () => {
Matteo Scandoloa242c872017-01-12 15:13:00 -0800160 it('should return the state with params for a given model', () => {
161 expect(service.stateWithParams('Test', {id: 1})).toBe('xos.core.tests({id: 1})');
162 });
Matteo Scandolocf5a9932017-08-09 13:46:04 -0700163 it('should return the state with params for a given relation', () => {
164 expect(service.relatedStateWithParams('Test', '1')).toBe('xos.core.tests({id: 1})');
165 });
166
167 it('should return the state with params for usage in js', () => {
168 expect(service.stateWithParamsForJs('Test', {id: 1})).toEqual({ name: 'xos.core.tests', params: Object({ id: 1 }) });
169 });
Matteo Scandoloa242c872017-01-12 15:13:00 -0800170 });
171 });
172
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800173 describe('the modelFieldsToColumnsCfg method', () => {
174 it('should return an array of columns', () => {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800175 const cols = service.modelFieldsToColumnsCfg({fields: model.fields, name: 'testUrl', app: 'test'});
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800176 expect(cols[0].label).toBe('Id');
177 expect(cols[0].prop).toBe('id');
178 expect(cols[0].link).toBeDefined();
179
180 expect(cols[1].label).toBe('Name');
181 expect(cols[1].prop).toBe('name');
182 expect(cols[1].link).toBeDefined();
183
184 expect(cols[2].label).toBe('Something');
185 expect(cols[2].prop).toBe('something');
186 expect(cols[2].link).not.toBeDefined();
187
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800188 expect(cols[3].label).toBe('Else');
189 expect(cols[3].prop).toBe('else');
190 expect(cols[3].link).not.toBeDefined();
191
192 expect(cols[4]).not.toBeDefined();
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800193 });
194 });
195
196 describe('the modelToTableCfg method', () => {
197 it('should return a table config', () => {
198 const cfg: IXosTableCfg = service.modelToTableCfg(model, 'testUrl/:id?');
199 expect(cfg.columns).toBeDefined();
200 expect(cfg.filter).toBe('fulltext');
201 expect(cfg.order).toEqual({field: 'id', reverse: false});
Matteo Scandolo2c61b882017-08-07 13:11:47 -0700202 expect(cfg.actions.length).toBe(2);
203 expect(cfg.actions[0].label).toEqual('details');
204 expect(cfg.actions[1].label).toEqual('delete');
Matteo Scandolocb466ed2017-01-04 17:16:24 -0800205 });
206 });
Matteo Scandolo1c5905f2017-01-04 17:41:15 -0800207
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800208 describe('the modelFieldToInputConfig', () => {
209 it('should return an array of inputs', () => {
210 const inputs: IXosFormInput[] = service.modelFieldToInputCfg(model.fields);
211 expect(inputs[0].name).toBe('id');
212 expect(inputs[0].type).toBe('number');
213 expect(inputs[0].label).toBe('Id');
214
215 expect(inputs[1].name).toBe('name');
216 expect(inputs[1].type).toBe('string');
217 expect(inputs[1].label).toBe('Name');
218 expect(inputs[1].validators.required).toBe(true);
219
220 expect(inputs[2].name).toBe('something');
221 expect(inputs[2].type).toBe('string');
222 expect(inputs[2].label).toBe('Something');
223 expect(inputs[2].validators.maxlength).toBe(30);
224
225 expect(inputs[3].name).toBe('else');
226 expect(inputs[3].type).toBe('number');
227 expect(inputs[3].label).toBe('Else');
228 expect(inputs[3].validators.min).toBe(20);
229 expect(inputs[3].validators.max).toBe(40);
230 });
231 });
232
233 describe('the modelToFormCfg method', () => {
234 it('should return a form config', () => {
Matteo Scandolo1aee1982017-02-17 08:33:23 -0800235 const config: IXosFormCfg = service.modelToFormCfg(model);
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800236 expect(config.formName).toBe('TestForm');
237 expect(config.actions.length).toBe(1);
238 expect(config.actions[0].label).toBe('Save');
239 expect(config.actions[0].class).toBe('success');
240 expect(config.actions[0].icon).toBe('ok');
241 expect(config.actions[0].cb).toBeDefined();
242 expect(config.inputs.length).toBe(4);
243 });
244 });
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800245
246 describe('the private methods', () => {
Matteo Scandolo88be90f2017-09-11 12:21:39 -0700247 let modelStoreMock, toastr, auth, stateMock, logMock;
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800248
Matteo Scandolo88be90f2017-09-11 12:21:39 -0700249 beforeEach(angular.mock.inject(($log, _toastr_, AuthService) => {
250 logMock = $log;
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800251 modelStoreMock = {
252 query: () => {
253 const subject = new BehaviorSubject([
254 {id: 1, humanReadableName: 'test'},
255 {id: 2, humanReadableName: 'second'}
256 ]);
257 return subject.asObservable();
258 }
259 };
260 toastr = _toastr_;
261 auth = AuthService;
Matteo Scandoloa242c872017-01-12 15:13:00 -0800262 stateMock = {
263 get: ''
264 };
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800265 }));
266
267 const field: IXosModelDefsField = {
268 name: 'test',
269 type: 'number',
270 relation: {
271 model: 'Test',
272 type: 'many_to_one'
273 }
274 };
275
276 describe('the populateRelated method', () => {
277 const item = {
278 test: 2
279 };
280 it('should add the formatted data to the column definition', () => {
Matteo Scandolo88be90f2017-09-11 12:21:39 -0700281 service = new ConfigHelpers(logMock, stateMock, toastr, modelStoreMock);
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800282 service['populateRelated'](item, item.test, field);
283 expect(item['test-formatted']).toBe('second');
284 });
285 });
286
287 describe('the populateSelectField', () => {
288
289 const input: IXosFormInput = {
290 name: 'test',
291 label: 'Test',
292 type: 'select',
293 validators: {}
294 };
295
296 it('should add the available choice to the select', () => {
Matteo Scandolo88be90f2017-09-11 12:21:39 -0700297 service = new ConfigHelpers(logMock, stateMock, toastr, modelStoreMock);
Matteo Scandolo07e2f622017-01-09 10:54:13 -0800298 service['populateSelectField'](field, input);
299 expect(input.options).toEqual([
300 {id: 1, label: 'test'},
301 {id: 2, label: 'second'}
302 ]);
303 });
304 });
305 });
Matteo Scandolod58d5042016-12-16 16:59:21 -0800306});
Matteo Scandolo80c3a652017-01-06 10:48:31 -0800307