@osimatic/helpers-js 1.5.3 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/details_sub_array.js +45 -41
- package/form_helper.js +283 -232
- package/google_charts.js +154 -144
- package/google_maps.js +1 -1
- package/import_from_csv.js +166 -157
- package/multi_files_input.js +42 -34
- package/multiple_action_in_table.js +115 -105
- package/package.json +1 -1
- package/paging.js +103 -84
- package/select_all.js +65 -70
- package/sortable_list.js +12 -13
- package/tests/details_sub_array.test.js +211 -239
- package/tests/form_helper.test.js +553 -673
- package/tests/google_charts.test.js +338 -339
- package/tests/google_maps.test.js +3 -15
- package/tests/import_from_csv.test.js +391 -652
- package/tests/multi_files_input.test.js +292 -722
- package/tests/multiple_action_in_table.test.js +439 -417
- package/tests/paging.test.js +344 -475
- package/tests/select_all.test.js +232 -318
- package/tests/sortable_list.test.js +176 -500
- package/tests/user.test.js +163 -54
- package/user.js +35 -38
|
@@ -4,259 +4,217 @@
|
|
|
4
4
|
const { DetailsSubArray } = require('../details_sub_array');
|
|
5
5
|
const { HTTPClient } = require('../http_client');
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
function setupTable(nbLinks = 1) {
|
|
8
|
+
document.body.innerHTML = `
|
|
9
|
+
<table>
|
|
10
|
+
<thead>
|
|
11
|
+
<tr>
|
|
12
|
+
<th>Col1</th><th>Col2</th><th>Col3</th><th>Col4</th><th>Col5</th>
|
|
13
|
+
</tr>
|
|
14
|
+
</thead>
|
|
15
|
+
<tbody>
|
|
16
|
+
${Array.from({ length: nbLinks }, (_, i) => `
|
|
17
|
+
<tr id="tr${i}">
|
|
18
|
+
<td><a class="details_link hide" data-url_details="http://example.com/details/${i}">Details</a></td>
|
|
19
|
+
</tr>`).join('')}
|
|
20
|
+
</tbody>
|
|
21
|
+
</table>
|
|
22
|
+
`;
|
|
23
|
+
return document.querySelector('table');
|
|
24
|
+
}
|
|
12
25
|
|
|
26
|
+
describe('DetailsSubArray', () => {
|
|
13
27
|
beforeEach(() => {
|
|
14
28
|
jest.spyOn(HTTPClient, 'request').mockImplementation(() => {});
|
|
15
|
-
|
|
16
|
-
// Clear all mocks
|
|
17
|
-
jest.clearAllMocks();
|
|
18
|
-
|
|
19
|
-
// Create mock DOM structure
|
|
20
|
-
mockThead = {
|
|
21
|
-
find: jest.fn((selector) => {
|
|
22
|
-
if (selector === 'thead tr') {
|
|
23
|
-
return {
|
|
24
|
-
children: jest.fn(() => ({ length: 5 }))
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
children: jest.fn(() => ({ length: 5 }))
|
|
29
|
-
};
|
|
30
|
-
})
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
mockTr = {
|
|
34
|
-
closest: jest.fn((selector) => {
|
|
35
|
-
if (selector === 'table') {
|
|
36
|
-
return {
|
|
37
|
-
find: jest.fn((sel) => {
|
|
38
|
-
if (sel === 'thead tr') {
|
|
39
|
-
return {
|
|
40
|
-
children: jest.fn(() => ({ length: 5 }))
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return mockThead;
|
|
44
|
-
})
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
return mockTr;
|
|
48
|
-
}),
|
|
49
|
-
after: jest.fn(),
|
|
50
|
-
addClass: jest.fn().mockReturnThis(),
|
|
51
|
-
next: jest.fn(() => ({
|
|
52
|
-
hasClass: jest.fn(() => false),
|
|
53
|
-
remove: jest.fn()
|
|
54
|
-
}))
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
mockLink = {
|
|
58
|
-
data: jest.fn((key) => {
|
|
59
|
-
if (key === 'url_details') return 'http://example.com/details';
|
|
60
|
-
return null;
|
|
61
|
-
}),
|
|
62
|
-
closest: jest.fn(() => mockTr),
|
|
63
|
-
prop: jest.fn().mockReturnThis(),
|
|
64
|
-
attr: jest.fn().mockReturnThis(),
|
|
65
|
-
html: jest.fn().mockReturnThis(),
|
|
66
|
-
click: jest.fn().mockReturnThis(),
|
|
67
|
-
stop: jest.fn().mockReturnThis(),
|
|
68
|
-
off: jest.fn().mockReturnThis(),
|
|
69
|
-
removeClass: jest.fn().mockReturnThis()
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
mockTable = {
|
|
73
|
-
find: jest.fn(() => ({
|
|
74
|
-
each: jest.fn((callback) => {
|
|
75
|
-
// Simulate one link found
|
|
76
|
-
callback(0, mockLink);
|
|
77
|
-
})
|
|
78
|
-
}))
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// Mock jQuery
|
|
82
|
-
global.$ = jest.fn((selector) => {
|
|
83
|
-
if (typeof selector === 'string') {
|
|
84
|
-
if (selector.includes('<tr')) {
|
|
85
|
-
return {
|
|
86
|
-
find: jest.fn().mockReturnThis(),
|
|
87
|
-
append: jest.fn().mockReturnThis(),
|
|
88
|
-
after: jest.fn().mockReturnThis()
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
if (selector.includes('<span')) {
|
|
92
|
-
return selector; // Return the HTML string for glyphicon
|
|
93
|
-
}
|
|
94
|
-
if (selector.includes('<i')) {
|
|
95
|
-
return selector; // Return the HTML string for fa icons
|
|
96
|
-
}
|
|
97
|
-
return {
|
|
98
|
-
length: 0,
|
|
99
|
-
remove: jest.fn()
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
// Wrap element
|
|
103
|
-
return selector;
|
|
104
|
-
});
|
|
105
29
|
});
|
|
106
30
|
|
|
107
31
|
afterEach(() => {
|
|
108
32
|
jest.restoreAllMocks();
|
|
109
|
-
|
|
33
|
+
document.body.innerHTML = '';
|
|
110
34
|
});
|
|
111
35
|
|
|
112
36
|
describe('initDetailsLink', () => {
|
|
113
|
-
test('should initialize details links', () => {
|
|
114
|
-
|
|
37
|
+
test('should initialize details links and remove hide class', () => {
|
|
38
|
+
const table = setupTable();
|
|
39
|
+
DetailsSubArray.initDetailsLink(table);
|
|
115
40
|
|
|
116
|
-
|
|
117
|
-
expect(
|
|
41
|
+
const link = table.querySelector('a.details_link');
|
|
42
|
+
expect(link.classList.contains('hide')).toBe(false);
|
|
118
43
|
});
|
|
119
44
|
|
|
120
|
-
test('should
|
|
121
|
-
|
|
45
|
+
test('should show plus button initially', () => {
|
|
46
|
+
const table = setupTable();
|
|
47
|
+
DetailsSubArray.initDetailsLink(table);
|
|
122
48
|
|
|
123
|
-
|
|
49
|
+
const link = table.querySelector('a.details_link');
|
|
50
|
+
expect(link.innerHTML).toContain('glyphicon-plus');
|
|
124
51
|
});
|
|
125
52
|
|
|
126
|
-
test('should
|
|
127
|
-
|
|
53
|
+
test('should set showDetailsLabel as title initially', () => {
|
|
54
|
+
const table = setupTable();
|
|
55
|
+
DetailsSubArray.initDetailsLink(table, { showDetailsLabel: 'Show details' });
|
|
128
56
|
|
|
129
|
-
|
|
57
|
+
const link = table.querySelector('a.details_link');
|
|
58
|
+
expect(link.title).toBe('Show details');
|
|
130
59
|
});
|
|
131
60
|
|
|
132
|
-
test('should
|
|
133
|
-
const
|
|
61
|
+
test('should make HTTP request when link is clicked', () => {
|
|
62
|
+
const table = setupTable();
|
|
63
|
+
DetailsSubArray.initDetailsLink(table);
|
|
134
64
|
|
|
135
|
-
|
|
65
|
+
const link = table.querySelector('a.details_link');
|
|
66
|
+
link.click();
|
|
136
67
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
68
|
+
expect(HTTPClient.request).toHaveBeenCalledWith(
|
|
69
|
+
'GET',
|
|
70
|
+
'http://example.com/details/0',
|
|
71
|
+
null,
|
|
72
|
+
expect.any(Function),
|
|
73
|
+
expect.any(Function)
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test('should disable link while loading', () => {
|
|
78
|
+
HTTPClient.request.mockImplementation(() => {
|
|
79
|
+
// Don't call callbacks — simulate loading state
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const table = setupTable();
|
|
83
|
+
DetailsSubArray.initDetailsLink(table);
|
|
142
84
|
|
|
143
|
-
|
|
144
|
-
|
|
85
|
+
const link = table.querySelector('a.details_link');
|
|
86
|
+
link.click();
|
|
87
|
+
|
|
88
|
+
expect(link.disabled).toBe(true);
|
|
145
89
|
});
|
|
146
90
|
|
|
147
|
-
test('should
|
|
148
|
-
|
|
91
|
+
test('should show loading row while request is pending', () => {
|
|
92
|
+
HTTPClient.request.mockImplementation(() => {});
|
|
93
|
+
|
|
94
|
+
const table = setupTable();
|
|
95
|
+
DetailsSubArray.initDetailsLink(table);
|
|
149
96
|
|
|
150
|
-
|
|
97
|
+
const link = table.querySelector('a.details_link');
|
|
98
|
+
const tr = link.closest('tr');
|
|
99
|
+
link.click();
|
|
151
100
|
|
|
152
|
-
|
|
153
|
-
expect(
|
|
101
|
+
const loadingRow = tr.nextElementSibling;
|
|
102
|
+
expect(loadingRow).not.toBeNull();
|
|
103
|
+
expect(loadingRow.classList.contains('waiting_icon')).toBe(true);
|
|
154
104
|
});
|
|
155
105
|
|
|
156
|
-
test('should
|
|
157
|
-
const
|
|
106
|
+
test('should call success callback with JSON response', () => {
|
|
107
|
+
const jsonResponse = { items: ['item1', 'item2'] };
|
|
108
|
+
const successCallback = jest.fn(() => '<div>Details</div>');
|
|
158
109
|
|
|
159
|
-
|
|
110
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
111
|
+
successCb(jsonResponse);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const table = setupTable();
|
|
115
|
+
DetailsSubArray.initDetailsLink(table, { onSuccess: successCallback });
|
|
116
|
+
|
|
117
|
+
const link = table.querySelector('a.details_link');
|
|
118
|
+
link.click();
|
|
160
119
|
|
|
161
|
-
|
|
162
|
-
expect(mockTable.find).toHaveBeenCalled();
|
|
120
|
+
expect(successCallback).toHaveBeenCalledWith(jsonResponse, link);
|
|
163
121
|
});
|
|
164
122
|
|
|
165
|
-
test('should
|
|
166
|
-
HTTPClient.request.mockImplementation((method, url, data, successCb
|
|
123
|
+
test('should show details row after successful request', () => {
|
|
124
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
167
125
|
successCb({ data: 'test' });
|
|
168
126
|
});
|
|
169
127
|
|
|
170
|
-
const
|
|
171
|
-
DetailsSubArray.initDetailsLink(
|
|
128
|
+
const table = setupTable();
|
|
129
|
+
DetailsSubArray.initDetailsLink(table, { onSuccess: jest.fn(() => '<div class="content">Details</div>') });
|
|
172
130
|
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
clickHandler.call(mockLink);
|
|
177
|
-
}
|
|
131
|
+
const link = table.querySelector('a.details_link');
|
|
132
|
+
const tr = link.closest('tr');
|
|
133
|
+
link.click();
|
|
178
134
|
|
|
179
|
-
|
|
180
|
-
expect(
|
|
181
|
-
|
|
182
|
-
'http://example.com/details',
|
|
183
|
-
null,
|
|
184
|
-
expect.any(Function),
|
|
185
|
-
expect.any(Function)
|
|
186
|
-
);
|
|
135
|
+
const detailsRow = tr.nextElementSibling;
|
|
136
|
+
expect(detailsRow).not.toBeNull();
|
|
137
|
+
expect(detailsRow.classList.contains('participants')).toBe(true);
|
|
187
138
|
});
|
|
188
139
|
|
|
189
|
-
test('should
|
|
140
|
+
test('should show minus button after successful request', () => {
|
|
190
141
|
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
191
|
-
successCb(
|
|
142
|
+
successCb({ data: 'test' });
|
|
192
143
|
});
|
|
193
144
|
|
|
194
|
-
|
|
145
|
+
const table = setupTable();
|
|
146
|
+
DetailsSubArray.initDetailsLink(table, { onSuccess: jest.fn(() => '') });
|
|
195
147
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (clickHandler) {
|
|
199
|
-
clickHandler.call(mockLink);
|
|
200
|
-
}
|
|
148
|
+
const link = table.querySelector('a.details_link');
|
|
149
|
+
link.click();
|
|
201
150
|
|
|
202
|
-
|
|
203
|
-
expect(mockTr.after).toHaveBeenCalled();
|
|
151
|
+
expect(link.innerHTML).toContain('glyphicon-minus');
|
|
204
152
|
});
|
|
205
153
|
|
|
206
|
-
test('should
|
|
207
|
-
HTTPClient.request.mockImplementation((method, url, data, successCb
|
|
208
|
-
|
|
154
|
+
test('should set hideDetailsLabel as title after loading', () => {
|
|
155
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
156
|
+
successCb({ data: 'test' });
|
|
209
157
|
});
|
|
210
158
|
|
|
211
|
-
|
|
159
|
+
const table = setupTable();
|
|
160
|
+
DetailsSubArray.initDetailsLink(table, {
|
|
161
|
+
onSuccess: jest.fn(() => ''),
|
|
162
|
+
hideDetailsLabel: 'Hide details',
|
|
163
|
+
});
|
|
212
164
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
if (clickHandler) {
|
|
216
|
-
clickHandler.call(mockLink);
|
|
217
|
-
}
|
|
165
|
+
const link = table.querySelector('a.details_link');
|
|
166
|
+
link.click();
|
|
218
167
|
|
|
219
|
-
|
|
220
|
-
expect(mockTr.after).toHaveBeenCalled();
|
|
168
|
+
expect(link.title).toBe('Hide details');
|
|
221
169
|
});
|
|
222
170
|
|
|
223
|
-
test('should
|
|
224
|
-
const jsonResponse = { items: ['item1', 'item2'] };
|
|
225
|
-
const successCallback = jest.fn(() => '<div>Details</div>');
|
|
226
|
-
|
|
171
|
+
test('should hide details row when clicking minus button', () => {
|
|
227
172
|
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
228
|
-
successCb(
|
|
173
|
+
successCb({ data: 'test' });
|
|
229
174
|
});
|
|
230
175
|
|
|
231
|
-
|
|
176
|
+
const table = setupTable();
|
|
177
|
+
DetailsSubArray.initDetailsLink(table, { onSuccess: jest.fn(() => '<div>Details</div>') });
|
|
232
178
|
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
179
|
+
const link = table.querySelector('a.details_link');
|
|
180
|
+
const tr = link.closest('tr');
|
|
181
|
+
link.click(); // open
|
|
182
|
+
expect(tr.nextElementSibling?.classList.contains('participants')).toBe(true);
|
|
238
183
|
|
|
239
|
-
//
|
|
240
|
-
expect(
|
|
184
|
+
link.click(); // close
|
|
185
|
+
expect(tr.nextElementSibling?.classList.contains('participants')).toBeFalsy();
|
|
241
186
|
});
|
|
242
187
|
|
|
243
|
-
test('should
|
|
244
|
-
|
|
188
|
+
test('should display error row when response is null with no error callback', () => {
|
|
189
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
190
|
+
successCb(null);
|
|
191
|
+
});
|
|
245
192
|
|
|
193
|
+
const table = setupTable();
|
|
194
|
+
DetailsSubArray.initDetailsLink(table);
|
|
195
|
+
|
|
196
|
+
const link = table.querySelector('a.details_link');
|
|
197
|
+
const tr = link.closest('tr');
|
|
198
|
+
link.click();
|
|
199
|
+
|
|
200
|
+
expect(tr.nextElementSibling).not.toBeNull();
|
|
201
|
+
expect(tr.nextElementSibling.classList.contains('text-error')).toBe(true);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test('should display error row when HTTP request fails with no error callback', () => {
|
|
246
205
|
HTTPClient.request.mockImplementation((method, url, data, successCb, errorCb) => {
|
|
247
206
|
errorCb();
|
|
248
207
|
});
|
|
249
208
|
|
|
250
|
-
|
|
209
|
+
const table = setupTable();
|
|
210
|
+
DetailsSubArray.initDetailsLink(table);
|
|
251
211
|
|
|
252
|
-
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
clickHandler.call(mockLink);
|
|
256
|
-
}
|
|
212
|
+
const link = table.querySelector('a.details_link');
|
|
213
|
+
const tr = link.closest('tr');
|
|
214
|
+
link.click();
|
|
257
215
|
|
|
258
|
-
|
|
259
|
-
expect(
|
|
216
|
+
expect(tr.nextElementSibling).not.toBeNull();
|
|
217
|
+
expect(tr.nextElementSibling.classList.contains('error')).toBe(true);
|
|
260
218
|
});
|
|
261
219
|
|
|
262
220
|
test('should call error callback when response is null', () => {
|
|
@@ -266,85 +224,99 @@ describe('DetailsSubArray', () => {
|
|
|
266
224
|
successCb(null);
|
|
267
225
|
});
|
|
268
226
|
|
|
269
|
-
|
|
227
|
+
const table = setupTable();
|
|
228
|
+
DetailsSubArray.initDetailsLink(table, { onError: errorCallback });
|
|
229
|
+
|
|
230
|
+
const link = table.querySelector('a.details_link');
|
|
231
|
+
link.click();
|
|
232
|
+
|
|
233
|
+
expect(errorCallback).toHaveBeenCalledWith(link);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test('should call error callback on HTTP error', () => {
|
|
237
|
+
const errorCallback = jest.fn();
|
|
238
|
+
|
|
239
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb, errorCb) => {
|
|
240
|
+
errorCb();
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
const table = setupTable();
|
|
244
|
+
DetailsSubArray.initDetailsLink(table, { onError: errorCallback });
|
|
270
245
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (clickHandler) {
|
|
274
|
-
clickHandler.call(mockLink);
|
|
275
|
-
}
|
|
246
|
+
const link = table.querySelector('a.details_link');
|
|
247
|
+
link.click();
|
|
276
248
|
|
|
277
|
-
|
|
278
|
-
expect(errorCallback).toHaveBeenCalledWith(mockLink);
|
|
249
|
+
expect(errorCallback).toHaveBeenCalledWith(link);
|
|
279
250
|
});
|
|
280
251
|
|
|
281
252
|
test('should use before send callback instead of HTTP request', () => {
|
|
282
253
|
const beforeSendCallback = jest.fn(() => '<div>Immediate content</div>');
|
|
283
254
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
// Simulate click
|
|
287
|
-
const clickHandler = mockLink.click.mock.calls[0][0];
|
|
288
|
-
if (clickHandler) {
|
|
289
|
-
clickHandler.call(mockLink);
|
|
290
|
-
}
|
|
255
|
+
const table = setupTable();
|
|
256
|
+
DetailsSubArray.initDetailsLink(table, { onBeforeSend: beforeSendCallback });
|
|
291
257
|
|
|
292
|
-
|
|
293
|
-
|
|
258
|
+
const link = table.querySelector('a.details_link');
|
|
259
|
+
link.click();
|
|
294
260
|
|
|
295
|
-
|
|
261
|
+
expect(beforeSendCallback).toHaveBeenCalledWith(link);
|
|
296
262
|
expect(HTTPClient.request).not.toHaveBeenCalled();
|
|
297
263
|
});
|
|
298
264
|
|
|
299
|
-
test('should
|
|
300
|
-
const
|
|
265
|
+
test('should show details row when using before send callback', () => {
|
|
266
|
+
const table = setupTable();
|
|
267
|
+
DetailsSubArray.initDetailsLink(table, { onBeforeSend: jest.fn(() => '<div>Immediate</div>') });
|
|
301
268
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
callback(1, mockLink2);
|
|
306
|
-
})
|
|
307
|
-
}));
|
|
269
|
+
const link = table.querySelector('a.details_link');
|
|
270
|
+
const tr = link.closest('tr');
|
|
271
|
+
link.click();
|
|
308
272
|
|
|
309
|
-
|
|
273
|
+
const detailsRow = tr.nextElementSibling;
|
|
274
|
+
expect(detailsRow).not.toBeNull();
|
|
275
|
+
expect(detailsRow.classList.contains('participants')).toBe(true);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test('should handle multiple links independently', () => {
|
|
279
|
+
const table = setupTable(2);
|
|
280
|
+
DetailsSubArray.initDetailsLink(table);
|
|
310
281
|
|
|
311
|
-
|
|
312
|
-
expect(
|
|
282
|
+
const links = table.querySelectorAll('a.details_link');
|
|
283
|
+
expect(links.length).toBe(2);
|
|
284
|
+
links.forEach(link => {
|
|
285
|
+
expect(link.innerHTML).toContain('glyphicon-plus');
|
|
286
|
+
expect(link.classList.contains('hide')).toBe(false);
|
|
287
|
+
});
|
|
313
288
|
});
|
|
314
289
|
|
|
315
|
-
test('should
|
|
316
|
-
HTTPClient.request.mockImplementation(() => {
|
|
317
|
-
|
|
290
|
+
test('should use colspan matching number of columns', () => {
|
|
291
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
292
|
+
successCb(null);
|
|
318
293
|
});
|
|
319
294
|
|
|
320
|
-
|
|
295
|
+
const table = setupTable();
|
|
296
|
+
DetailsSubArray.initDetailsLink(table);
|
|
321
297
|
|
|
322
|
-
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
clickHandler.call(mockLink);
|
|
326
|
-
}
|
|
298
|
+
const link = table.querySelector('a.details_link');
|
|
299
|
+
const tr = link.closest('tr');
|
|
300
|
+
link.click();
|
|
327
301
|
|
|
328
|
-
|
|
329
|
-
expect(
|
|
302
|
+
const errorRow = tr.nextElementSibling;
|
|
303
|
+
expect(errorRow.querySelector('td').getAttribute('colspan')).toBe('5');
|
|
330
304
|
});
|
|
331
305
|
|
|
332
|
-
test('should
|
|
333
|
-
HTTPClient.request.mockImplementation(() => {
|
|
334
|
-
|
|
306
|
+
test('should use custom error label', () => {
|
|
307
|
+
HTTPClient.request.mockImplementation((method, url, data, successCb) => {
|
|
308
|
+
successCb(null);
|
|
335
309
|
});
|
|
336
310
|
|
|
337
|
-
|
|
311
|
+
const table = setupTable();
|
|
312
|
+
DetailsSubArray.initDetailsLink(table, { labelErrorOccurred: 'Custom error' });
|
|
338
313
|
|
|
339
|
-
|
|
340
|
-
const
|
|
341
|
-
|
|
342
|
-
clickHandler.call(mockLink);
|
|
343
|
-
}
|
|
314
|
+
const link = table.querySelector('a.details_link');
|
|
315
|
+
const tr = link.closest('tr');
|
|
316
|
+
link.click();
|
|
344
317
|
|
|
345
|
-
|
|
346
|
-
expect(
|
|
347
|
-
expect(mockTr.after).toHaveBeenCalled();
|
|
318
|
+
const errorRow = tr.nextElementSibling;
|
|
319
|
+
expect(errorRow.textContent).toContain('Custom error');
|
|
348
320
|
});
|
|
349
321
|
});
|
|
350
322
|
});
|