blob: 9247caecc3b02322e6257c5154d75bd368bc71c8 [file] [log] [blame]
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -07001/**
2 * © OpenCORD
3 *
4 * Created by teone on 3/24/16.
5 */
6
7(function () {
8 'use strict';
9
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070010 var scope, element, isolatedScope, rootScope, compile;
11 const compileElement = () => {
12
13 if(!scope){
14 scope = rootScope.$new();
15 }
16
17 element = angular.element('<xos-table config="config" data="data"></xos-table>');
18 compile(element)(scope);
19 scope.$digest();
20 isolatedScope = element.isolateScope().vm;
21 }
22
23
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070024 describe('The xos.helper module', function(){
25 describe('The xos-table component', () => {
26
27 beforeEach(module('xos.helpers'));
28
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070029 beforeEach(inject(function ($compile, $rootScope) {
30 compile = $compile;
31 rootScope = $rootScope;
32 }));
33
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070034 it('should throw an error if no config is specified', inject(($compile, $rootScope) => {
35 function errorFunctionWrapper(){
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070036 compileElement();
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070037 }
38 expect(errorFunctionWrapper).toThrow(new Error('[xosTable] Please provide a configuration via the "config" attribute'));
39 }));
40
41 it('should throw an error if no config columns are specified', inject(($compile, $rootScope) => {
42 function errorFunctionWrapper(){
43 // setup the parent scope
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070044 scope = $rootScope.$new();
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070045 scope.config = 'green';
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070046 compileElement();
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070047 }
48 expect(errorFunctionWrapper).toThrow(new Error('[xosTable] Please provide a columns list in the configuration'));
49 }));
50
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070051 describe('when basicly configured', function() {
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070052
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070053 beforeEach(inject(function ($compile, $rootScope) {
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070054
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070055 scope = $rootScope.$new();
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070056
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070057 scope.config = {
58 columns: [
59 {
60 label: 'Label 1',
61 prop: 'label-1'
62 },
63 {
64 label: 'Label 2',
65 prop: 'label-2'
66 }
67 ]
68 };
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070069
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070070 scope.data = [
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070071 {
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070072 'label-1': 'Sample 1.1',
73 'label-2': 'Sample 1.2'
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070074 },
75 {
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070076 'label-1': 'Sample 2.1',
77 'label-2': 'Sample 2.2'
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070078 }
79 ]
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070080
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070081 element = angular.element('<xos-table config="config" data="data"></xos-table>');
82 $compile(element)(scope);
83 scope.$digest();
84 isolatedScope = element.isolateScope().vm;
85 }));
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070086
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070087 it('should contain 2 columns', function() {
88 var th = element[0].getElementsByTagName('th');
89 expect(th.length).toEqual(2);
90 expect(isolatedScope.columns.length).toEqual(2);
91 });
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -070092
Matteo Scandolo6a6586e2016-04-14 16:52:13 -070093 it('should contain 3 rows', function() {
94 var tr = element[0].getElementsByTagName('tr');
95 expect(tr.length).toEqual(3);
96 });
97
Matteo Scandolo8cd182a2016-05-06 09:42:45 -070098 it('should render labels', () => {
99 let label1 = $(element).find('thead tr th')[0]
100 let label2 = $(element).find('thead tr th')[1]
101 expect($(label1).text().trim()).toEqual('Label 1');
102 expect($(label2).text().trim()).toEqual('Label 2');
103 });
104
Matteo Scandolofb5937d2016-04-15 14:27:54 -0700105 describe('when no data are provided', () => {
106 beforeEach(() => {
107 isolatedScope.data = [];
108 scope.$digest();
109 });
110 it('should render an alert', () => {
111 let alert = element[0].getElementsByClassName('alert');
112 let table = element[0].getElementsByTagName('table');
113 expect(alert.length).toEqual(1);
114 expect(table.length).toEqual(1);
115 });
116 });
117
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700118 describe('when a field type is provided', () => {
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700119 describe('and is boolean', () => {
120 beforeEach(() => {
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700121 scope.config = {
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700122 columns: [
123 {
124 label: 'Label 1',
125 prop: 'label-1',
126 type: 'boolean'
127 }
128 ]
129 };
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700130 scope.data = [
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700131 {
132 'label-1': true
133 },
134 {
135 'label-1': false
136 }
137 ];
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700138 compileElement();
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700139 });
140
141 it('should render an incon', () => {
142 let td1 = $(element).find('tbody tr:first-child td')[0];
143 let td2 = $(element).find('tbody tr:last-child td')[0];
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700144 expect($(td1).find('i')).toHaveClass('glyphicon-ok');
145 expect($(td2).find('i')).toHaveClass('glyphicon-remove');
146 });
147 });
148
149 describe('and is date', () => {
150 beforeEach(() => {
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700151 scope.config = {
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700152 columns: [
153 {
154 label: 'Label 1',
155 prop: 'label-1',
156 type: 'date'
157 }
158 ]
159 };
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700160 scope.data = [
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700161 {
162 'label-1': '2015-02-17T22:06:38.059000Z'
163 }
164 ];
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700165 compileElement();
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700166 });
167
168 it('should render an formatted date', () => {
169 let td1 = $(element).find('tbody tr:first-child td')[0];
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700170 expect($(td1).text().trim()).toEqual('14:06 Feb 17, 2015');
171 });
172 });
173
174 describe('and is array', () => {
175 beforeEach(() => {
176 scope.data = [
177 {categories: ['Film', 'Music']}
178 ];
179 scope.config = {
180 columns: [
181 {
182 label: 'Categories',
183 prop: 'categories',
184 type: 'array'
185 }
186 ]
187 }
188 compileElement();
189 });
190 it('should render a comma separated list', () => {
191 let td1 = $(element).find('tbody tr:first-child')[0];
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700192 expect($(td1).text().trim()).toEqual('Film, Music');
193 });
194 });
195
Matteo Scandoloe5d74562016-05-06 10:08:34 -0700196 describe('and is object', () => {
197 beforeEach(() => {
198 scope.data = [
199 {
200 attributes: {
201 age: 20,
202 height: 50
203 }
204 }
205 ];
206 scope.config = {
207 columns: [
208 {
209 label: 'Categories',
210 prop: 'attributes',
211 type: 'object'
212 }
213 ]
214 }
215 compileElement();
216 });
217 it('should render a list of key-values', () => {
218 let td = $(element).find('tbody tr:first-child')[0];
Matteo Scandolo7ebd1bf2016-05-06 11:39:56 -0700219 let ageLabel = $(td).find('dl dt')[0];
220 let ageValue = $(td).find('dl dd')[0];
221 let heightLabel = $(td).find('dl dt')[1];
222 let heightValue = $(td).find('dl dd')[1];
Matteo Scandoloe5d74562016-05-06 10:08:34 -0700223 expect($(ageLabel).text().trim()).toEqual('age');
224 expect($(ageValue).text().trim()).toEqual('20');
225 expect($(heightLabel).text().trim()).toEqual('height');
226 expect($(heightValue).text().trim()).toEqual('50');
227 });
228 });
229
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700230 describe('and is custom', () => {
231 beforeEach(() => {
232 scope.data = [
233 {categories: ['Film', 'Music']}
234 ];
235 scope.config = {
236 columns: [
237 {
238 label: 'Categories',
239 prop: 'categories',
240 type: 'custom',
Matteo Scandolo7ebd1bf2016-05-06 11:39:56 -0700241 formatter: () => 'Formatted Content'
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700242 }
243 ]
244 }
245 compileElement();
246 });
247
248 it('should check for a formatter property', () => {
249 function errorFunctionWrapper(){
250 // setup the parent scope
251 scope = rootScope.$new();
252 scope.config = {
253 columns: [
254 {
255 label: 'Categories',
256 prop: 'categories',
257 type: 'custom'
258 }
259 ]
260 };
261 compileElement();
262 }
263 expect(errorFunctionWrapper).toThrow(new Error('[xosTable] You have provided a custom field type, a formatter function should provided too.'));
264 });
265
Matteo Scandoloabb75622016-05-06 13:09:19 -0700266 it('should check that the formatter property is a function', () => {
267 function errorFunctionWrapper(){
268 // setup the parent scope
269 scope = rootScope.$new();
270 scope.config = {
271 columns: [
272 {
273 label: 'Categories',
274 prop: 'categories',
275 type: 'custom',
276 formatter: 'formatter'
277 }
278 ]
279 };
280 compileElement();
281 }
282 expect(errorFunctionWrapper).toThrow(new Error('[xosTable] You have provided a custom field type, a formatter function should provided too.'));
283 });
284
Matteo Scandolo8cd182a2016-05-06 09:42:45 -0700285 it('should format data using the formatter property', () => {
286 let td1 = $(element).find('tbody tr:first-child')[0];
287 expect($(td1).text().trim()).toEqual('Formatted Content');
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700288 });
289 });
Matteo Scandoloea6ef002016-05-13 10:12:09 -0700290
291 describe('and is icon', () => {
292
293 beforeEach(() => {
294 scope.config = {
295 columns: [
296 {
297 label: 'Label 1',
298 prop: 'label-1',
299 type: 'icon',
300 formatter: item => {
301 switch (item['label-1']){
302 case 1:
303 return 'ok';
304 case 2:
305 return 'remove';
306 case 3:
307 return 'plus'
308 }
309 }
310 }
311 ]
312 };
313 scope.data = [
314 {
315 'label-1': 1
316 },
317 {
318 'label-1': 2
319 },
320 {
321 'label-1': 3
322 }
323 ];
324 compileElement();
325 });
326
327 it('should render a custom icon', () => {
328 let td1 = $(element).find('tbody tr:first-child td')[0];
329 let td2 = $(element).find('tbody tr:nth-child(2) td')[0];
330 let td3 = $(element).find('tbody tr:last-child td')[0];
331 expect($(td1).find('i')).toHaveClass('glyphicon-ok');
332 expect($(td2).find('i')).toHaveClass('glyphicon-remove');
333 expect($(td3).find('i')).toHaveClass('glyphicon-plus');
334 });
335 });
Matteo Scandolo250a29c2016-04-27 17:26:21 -0700336 });
337
Matteo Scandoloabb75622016-05-06 13:09:19 -0700338 describe('when a link property is provided', () => {
339 beforeEach(() => {
340 scope.data = [
341 {
342 id: 1}
343 ];
344 scope.config = {
345 columns: [
346 {
347 label: 'Id',
348 prop: 'id',
349 link: (item) => {
350 return `/link/${item.id}`;
351 }
352 }
353 ]
354 }
355 compileElement();
356 });
357
358 it('should check that the link property is a function', () => {
359 function errorFunctionWrapper(){
360 // setup the parent scope
361 scope = rootScope.$new();
362 scope.config = {
363 columns: [
364 {
365 label: 'Categories',
366 prop: 'categories',
367 link: 'custom'
368 }
369 ]
370 };
371 compileElement();
372 }
373 expect(errorFunctionWrapper).toThrow(new Error('[xosTable] The link property should be a function.'));
374 });
375
376 it('should render a comma separated list', () => {
377 let link = $(element).find('tbody tr:first-child td a')[0];
378 expect($(link).attr('href')).toEqual('/link/1');
379 });
380 });
381
Matteo Scandolo6a6586e2016-04-14 16:52:13 -0700382 describe('when actions are passed', () => {
383
384 let cb = jasmine.createSpy('callback')
385
386 beforeEach(() => {
387 isolatedScope.config.actions = [
388 {
389 label: 'delete',
390 icon: 'remove',
391 cb: cb,
392 color: 'red'
393 }
394 ];
395 scope.$digest();
396 });
397
398 it('should have 3 columns', () => {
399 var th = element[0].getElementsByTagName('th');
400 expect(th.length).toEqual(3);
401 expect(isolatedScope.columns.length).toEqual(2);
402 });
403
404 it('when clicking on action should invoke callback', () => {
405 var link = element[0].getElementsByTagName('a')[0];
406 link.click();
407 expect(cb).toHaveBeenCalledWith(scope.data[0]);
408 });
409 });
410
411 describe('when filter is fulltext', () => {
412 beforeEach(() => {
413 isolatedScope.config.filter = 'fulltext';
414 scope.$digest();
415 });
416
417 it('should render a text field', () => {
418 var textField = element[0].getElementsByTagName('input');
419 expect(textField.length).toEqual(1);
420 });
421
422 describe('and a value is enterd', () => {
423 beforeEach(() => {
424 isolatedScope.query = '2.2';
425 scope.$digest();
426 });
427
428 it('should contain 2 rows', function() {
429 var tr = element[0].getElementsByTagName('tr');
430 expect(tr.length).toEqual(2);
431 });
432 });
433 });
434
435 describe('when filter is field', () => {
436 beforeEach(() => {
437 isolatedScope.config.filter = 'field';
438 scope.$digest();
439 });
440
441 it('should render a text field for each column', () => {
442 var textField = element[0].getElementsByTagName('input');
443 expect(textField.length).toEqual(2);
444 });
445
446 describe('and a value is enterd', () => {
447 beforeEach(() => {
448 isolatedScope.query = {'label-1': '2.1'};
449 scope.$digest();
450 });
451
452 it('should contain 3 rows', function() {
453 var tr = element[0].getElementsByTagName('tr');
454 expect(tr.length).toEqual(3);
455 });
456 });
457 });
Matteo Scandolof32a2e92016-04-14 17:19:08 -0700458
459 describe('when order is true', () => {
460 beforeEach(() => {
461 isolatedScope.config.order = true;
462 scope.$digest();
463 });
464
465 it('should render a arrows beside', () => {
466 var arrows = element[0].getElementsByTagName('i');
467 expect(arrows.length).toEqual(4);
468 });
469
Matteo Scandoloea6ef002016-05-13 10:12:09 -0700470 describe('and a default ordering is passed', () => {
471
472 beforeEach(() => {
473 scope.config.order = {
474 field: 'label-1',
475 reverse: true
476 };
477 compileElement();
478 });
479
480 it('should orderBy the default order', () => {
481 var tr = $(element).find('tr');
482 expect($(tr[1]).text()).toContain('Sample 2.2');
483 expect($(tr[2]).text()).toContain('Sample 1.1');
484 });
485 });
486
Matteo Scandolof32a2e92016-04-14 17:19:08 -0700487 describe('and an order is set', () => {
488 beforeEach(() => {
489 isolatedScope.orderBy = 'label-1';
490 isolatedScope.reverse = true;
491 scope.$digest();
492 });
493
494 it('should orderBy', function() {
Matteo Scandoloea6ef002016-05-13 10:12:09 -0700495 // console.log($(element).find('table'));
Matteo Scandoloabb75622016-05-06 13:09:19 -0700496 var tr = $(element).find('tr');
497 expect($(tr[1]).text()).toContain('Sample 2.2');
498 expect($(tr[2]).text()).toContain('Sample 1.1');
Matteo Scandolof32a2e92016-04-14 17:19:08 -0700499 });
500 });
501 });
Matteo Scandoloa7e64fd2016-04-14 14:59:09 -0700502 });
503 });
504 });
505})();
506