@osimatic/helpers-js 1.5.2 → 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/count_down.js +46 -48
- package/date_time.js +0 -1
- package/details_sub_array.js +65 -50
- package/flash_message.js +10 -6
- package/form_date.js +144 -153
- package/form_helper.js +283 -232
- package/google_charts.js +154 -144
- package/google_maps.js +1 -1
- package/import_from_csv.js +198 -160
- package/multi_files_input.js +44 -35
- package/multiple_action_in_table.js +123 -109
- package/package.json +1 -1
- package/paging.js +103 -84
- package/select_all.js +65 -70
- package/sortable_list.js +12 -13
- package/tests/count_down.test.js +131 -352
- package/tests/details_sub_array.test.js +213 -258
- package/tests/flash_message.test.js +21 -153
- package/tests/form_date.test.js +287 -961
- 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 +421 -640
- package/tests/multi_files_input.test.js +305 -737
- package/tests/multiple_action_in_table.test.js +442 -429
- package/tests/open_street_map.test.js +15 -23
- 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
package/tests/count_down.test.js
CHANGED
|
@@ -12,13 +12,8 @@ describe('CountDown', () => {
|
|
|
12
12
|
let clickCallback;
|
|
13
13
|
|
|
14
14
|
beforeEach(() => {
|
|
15
|
-
// Setup fake timers
|
|
16
15
|
jest.useFakeTimers();
|
|
17
16
|
|
|
18
|
-
// Setup global labels
|
|
19
|
-
global.labelNextUpdate = 'Next Update';
|
|
20
|
-
global.labelDoUpdate = 'Refresh Now';
|
|
21
|
-
|
|
22
17
|
// Mock link element
|
|
23
18
|
mockLink = {
|
|
24
19
|
click: jest.fn(function(callback) {
|
|
@@ -72,23 +67,17 @@ describe('CountDown', () => {
|
|
|
72
67
|
afterEach(() => {
|
|
73
68
|
jest.clearAllTimers();
|
|
74
69
|
jest.restoreAllMocks();
|
|
75
|
-
delete global.labelNextUpdate;
|
|
76
|
-
delete global.labelDoUpdate;
|
|
77
70
|
});
|
|
78
71
|
|
|
79
|
-
describe('
|
|
80
|
-
test('should return
|
|
81
|
-
const
|
|
82
|
-
const countDown = new CountDown(emptyDiv, jest.fn());
|
|
72
|
+
describe('init', () => {
|
|
73
|
+
test('should return undefined when div has no length', () => {
|
|
74
|
+
const result = CountDown.init({ length: 0 }, { onRefreshData: jest.fn() });
|
|
83
75
|
|
|
84
|
-
expect(
|
|
76
|
+
expect(result).toBeUndefined();
|
|
85
77
|
});
|
|
86
78
|
|
|
87
|
-
test('should create countdown UI elements', () => {
|
|
88
|
-
|
|
89
|
-
completeCallback();
|
|
90
|
-
});
|
|
91
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
79
|
+
test('should create countdown UI elements with provided labels', () => {
|
|
80
|
+
CountDown.init(mockDiv, { labelNextUpdate: 'Next Update', labelDoUpdate: 'Refresh Now' });
|
|
92
81
|
|
|
93
82
|
expect(mockDiv.append).toHaveBeenCalledTimes(4);
|
|
94
83
|
expect(mockDiv.append).toHaveBeenCalledWith('<div class="count_down_title">Next Update</div>');
|
|
@@ -97,484 +86,274 @@ describe('CountDown', () => {
|
|
|
97
86
|
expect(mockDiv.append).toHaveBeenCalledWith('<div class="count_down_link"><a href="#" data-loading-text="<i class=\'fa fa-circle-notch fa-spin\'></i>">Refresh Now</a></div>');
|
|
98
87
|
});
|
|
99
88
|
|
|
100
|
-
test('should
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
expect(countDown.div).toBe(mockDiv);
|
|
107
|
-
expect(countDown.callbackOnRefreshData).toBe(callback);
|
|
108
|
-
expect(countDown.alreadyMakingRequest).toBe(false);
|
|
109
|
-
expect(countDown.secondsBefRefresh).toBe(10);
|
|
110
|
-
expect(countDown.refreshIntervalMillis).toBe(60);
|
|
111
|
-
expect(countDown.currentMillis).toBe(0);
|
|
112
|
-
expect(countDown.currentSecond).toBe(0);
|
|
89
|
+
test('should use default labels when not provided', () => {
|
|
90
|
+
CountDown.init(mockDiv, {});
|
|
91
|
+
|
|
92
|
+
expect(mockDiv.append).toHaveBeenCalledWith('<div class="count_down_title">Prochaine mise à jour</div>');
|
|
93
|
+
expect(mockDiv.append).toHaveBeenCalledWith(expect.stringContaining('Mettre à jour'));
|
|
113
94
|
});
|
|
114
95
|
|
|
115
96
|
test('should set up click handler on refresh link', () => {
|
|
116
|
-
|
|
117
|
-
completeCallback();
|
|
118
|
-
});
|
|
119
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
97
|
+
CountDown.init(mockDiv, {});
|
|
120
98
|
|
|
121
99
|
expect(mockLink.click).toHaveBeenCalled();
|
|
122
100
|
});
|
|
123
101
|
|
|
124
|
-
test('should
|
|
125
|
-
const callback = jest.fn((completeCallback) =>
|
|
126
|
-
|
|
127
|
-
});
|
|
128
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
102
|
+
test('should return false on click', () => {
|
|
103
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
104
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
129
105
|
|
|
130
|
-
// Execute the click callback
|
|
131
106
|
const result = clickCallback.call(mockLink);
|
|
132
107
|
|
|
133
108
|
expect(result).toBe(false);
|
|
134
|
-
expect(callback).toHaveBeenCalled();
|
|
135
109
|
});
|
|
136
110
|
|
|
137
111
|
test('should start interval timer', () => {
|
|
138
|
-
|
|
139
|
-
completeCallback();
|
|
140
|
-
});
|
|
141
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
112
|
+
CountDown.init(mockDiv, {});
|
|
142
113
|
|
|
143
114
|
expect(setInterval).toHaveBeenCalledWith(expect.any(Function), 60);
|
|
144
115
|
});
|
|
145
116
|
|
|
146
|
-
test('should call
|
|
147
|
-
const callback = jest.fn((completeCallback) =>
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
117
|
+
test('should call onRefreshData immediately after init', () => {
|
|
118
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
119
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
151
120
|
|
|
152
121
|
expect(callback).toHaveBeenCalled();
|
|
153
122
|
});
|
|
154
123
|
|
|
155
|
-
test('should
|
|
156
|
-
const mockEmptyLink = {
|
|
157
|
-
length: 0,
|
|
158
|
-
attr: jest.fn().mockReturnThis(),
|
|
159
|
-
button: jest.fn().mockReturnThis()
|
|
160
|
-
};
|
|
161
|
-
|
|
124
|
+
test('should not throw when refresh link is missing', () => {
|
|
162
125
|
mockDiv.find = jest.fn((selector) => {
|
|
163
|
-
if (selector === '.count_down_link a') {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (selector === '.count_down_current') {
|
|
167
|
-
return mockCountDownCurrent;
|
|
168
|
-
}
|
|
169
|
-
if (selector === '.count_down_text') {
|
|
170
|
-
return mockCountDownText;
|
|
171
|
-
}
|
|
126
|
+
if (selector === '.count_down_link a') return { length: 0, attr: jest.fn().mockReturnThis(), button: jest.fn().mockReturnThis() };
|
|
127
|
+
if (selector === '.count_down_current') return mockCountDownCurrent;
|
|
128
|
+
if (selector === '.count_down_text') return mockCountDownText;
|
|
172
129
|
return { length: 0 };
|
|
173
130
|
});
|
|
174
131
|
|
|
175
|
-
const callback = jest.fn((completeCallback) => {
|
|
176
|
-
completeCallback();
|
|
177
|
-
});
|
|
178
132
|
expect(() => {
|
|
179
|
-
|
|
133
|
+
CountDown.init(mockDiv, {});
|
|
180
134
|
}).not.toThrow();
|
|
181
135
|
});
|
|
182
136
|
});
|
|
183
137
|
|
|
184
|
-
describe('setCallbackOnRefreshData', () => {
|
|
185
|
-
test('should update callback', () => {
|
|
186
|
-
const callback1 = jest.fn();
|
|
187
|
-
const callback2 = jest.fn();
|
|
188
|
-
const countDown = new CountDown(mockDiv, callback1);
|
|
189
|
-
|
|
190
|
-
countDown.setCallbackOnRefreshData(callback2);
|
|
191
|
-
|
|
192
|
-
expect(countDown.callbackOnRefreshData).toBe(callback2);
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
|
|
196
138
|
describe('refreshData', () => {
|
|
197
|
-
test('should
|
|
198
|
-
const callback = jest.fn((completeCallback) =>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
202
|
-
|
|
203
|
-
countDown.currentMillis = 5000;
|
|
204
|
-
countDown.refreshData();
|
|
205
|
-
|
|
206
|
-
expect(countDown.currentMillis).toBe(0);
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
test('should not launch new request if already making request', () => {
|
|
210
|
-
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
211
|
-
const callback = jest.fn((completeCallback) => {
|
|
212
|
-
completeCallback();
|
|
213
|
-
});
|
|
214
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
215
|
-
|
|
216
|
-
countDown.alreadyMakingRequest = true;
|
|
217
|
-
const callCountBefore = callback.mock.calls.length;
|
|
218
|
-
|
|
219
|
-
countDown.refreshData();
|
|
139
|
+
test('should call onRefreshData on click', () => {
|
|
140
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
141
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
142
|
+
jest.clearAllMocks();
|
|
220
143
|
|
|
221
|
-
|
|
222
|
-
expect(consoleLogSpy).toHaveBeenCalledWith('Already making request, no new request lauched.');
|
|
144
|
+
clickCallback.call(mockLink);
|
|
223
145
|
|
|
224
|
-
|
|
146
|
+
expect(callback).toHaveBeenCalledWith(expect.any(Function));
|
|
225
147
|
});
|
|
226
148
|
|
|
227
149
|
test('should disable button during request', () => {
|
|
150
|
+
let callCount = 0;
|
|
228
151
|
const callback = jest.fn((completeCallback) => {
|
|
229
|
-
|
|
152
|
+
callCount++;
|
|
153
|
+
if (callCount === 1) completeCallback(); // init call complète
|
|
154
|
+
// le click ne complète pas → alreadyMakingRequest reste true
|
|
230
155
|
});
|
|
231
|
-
|
|
232
|
-
|
|
156
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
233
157
|
jest.clearAllMocks();
|
|
234
|
-
|
|
158
|
+
|
|
159
|
+
clickCallback.call(mockLink);
|
|
235
160
|
|
|
236
161
|
expect(mockLink.attr).toHaveBeenCalledWith('disabled', true);
|
|
237
162
|
expect(mockLink.button).toHaveBeenCalledWith('loading');
|
|
238
163
|
});
|
|
239
164
|
|
|
240
|
-
test('should enable button after request completes', () => {
|
|
241
|
-
const callback = jest.fn((completeCallback) =>
|
|
242
|
-
|
|
243
|
-
});
|
|
244
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
245
|
-
|
|
165
|
+
test('should re-enable button after request completes', () => {
|
|
166
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
167
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
246
168
|
jest.clearAllMocks();
|
|
247
|
-
|
|
169
|
+
|
|
170
|
+
clickCallback.call(mockLink);
|
|
248
171
|
|
|
249
172
|
expect(mockLink.attr).toHaveBeenCalledWith('disabled', false);
|
|
250
173
|
expect(mockLink.button).toHaveBeenCalledWith('reset');
|
|
251
|
-
expect(countDown.alreadyMakingRequest).toBe(false);
|
|
252
174
|
});
|
|
253
175
|
|
|
254
|
-
test('should
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
});
|
|
258
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
176
|
+
test('should not launch new request if already making request', () => {
|
|
177
|
+
const consoleLogSpy = jest.spyOn(console, 'log').mockImplementation();
|
|
178
|
+
const callback = jest.fn(); // ne complète pas, laisse alreadyMakingRequest = true
|
|
179
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
259
180
|
|
|
260
|
-
|
|
261
|
-
|
|
181
|
+
// à ce stade le premier refreshData() a été appelé sans compléter
|
|
182
|
+
const callCountAfterInit = callback.mock.calls.length;
|
|
262
183
|
|
|
263
|
-
|
|
264
|
-
|
|
184
|
+
clickCallback.call(mockLink); // bloqué
|
|
185
|
+
|
|
186
|
+
expect(callback.mock.calls.length).toBe(callCountAfterInit);
|
|
187
|
+
expect(consoleLogSpy).toHaveBeenCalledWith('Already making request, no new request lauched.');
|
|
265
188
|
|
|
266
|
-
|
|
267
|
-
|
|
189
|
+
consoleLogSpy.mockRestore();
|
|
190
|
+
});
|
|
268
191
|
|
|
192
|
+
test('should not crash if onRefreshData is not a function', () => {
|
|
269
193
|
expect(() => {
|
|
270
|
-
|
|
194
|
+
CountDown.init(mockDiv, {});
|
|
271
195
|
}).not.toThrow();
|
|
272
196
|
});
|
|
273
197
|
|
|
274
|
-
test('should
|
|
275
|
-
let
|
|
276
|
-
const callback = jest.fn((
|
|
277
|
-
|
|
278
|
-
// We test the actual behavior, not the intended behavior
|
|
279
|
-
completeCallback();
|
|
280
|
-
});
|
|
281
|
-
countDownInstance = new CountDown(mockDiv, callback);
|
|
198
|
+
test('should allow new request after previous completes', () => {
|
|
199
|
+
let completeCallback;
|
|
200
|
+
const callback = jest.fn((cb) => { completeCallback = cb; });
|
|
201
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
282
202
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
203
|
+
// complète la première requête
|
|
204
|
+
completeCallback();
|
|
205
|
+
const callCountAfterComplete = callback.mock.calls.length;
|
|
206
|
+
|
|
207
|
+
clickCallback.call(mockLink);
|
|
286
208
|
|
|
287
|
-
|
|
288
|
-
expect(countDownInstance.alreadyMakingRequest).toBe(false);
|
|
209
|
+
expect(callback.mock.calls.length).toBe(callCountAfterComplete + 1);
|
|
289
210
|
});
|
|
290
211
|
});
|
|
291
212
|
|
|
292
213
|
describe('interval timer behavior', () => {
|
|
293
|
-
test('should
|
|
294
|
-
const callback = jest.fn((completeCallback) =>
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
298
|
-
|
|
299
|
-
countDown.currentMillis = 0;
|
|
214
|
+
test('should show remaining seconds in text', () => {
|
|
215
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
216
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
217
|
+
jest.clearAllMocks();
|
|
300
218
|
|
|
301
|
-
// Execute interval callback
|
|
302
219
|
intervalCallback();
|
|
303
220
|
|
|
304
|
-
expect(
|
|
305
|
-
expect(countDown.currentSecond).toBe(0);
|
|
221
|
+
expect(mockCountDownText.html).toHaveBeenCalledWith('10s');
|
|
306
222
|
});
|
|
307
223
|
|
|
308
|
-
test('should
|
|
309
|
-
const callback = jest.fn((completeCallback) =>
|
|
310
|
-
|
|
311
|
-
});
|
|
312
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
313
|
-
|
|
314
|
-
countDown.currentMillis = 0;
|
|
224
|
+
test('should show 0s when time reaches limit', () => {
|
|
225
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
226
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
315
227
|
|
|
316
|
-
|
|
317
|
-
for (let i = 0; i < 17; i++) {
|
|
228
|
+
for (let i = 0; i < 166; i++) {
|
|
318
229
|
intervalCallback();
|
|
319
230
|
}
|
|
231
|
+
jest.clearAllMocks();
|
|
232
|
+
intervalCallback(); // tick 167 : currentMillis = 10020 → 0s
|
|
320
233
|
|
|
321
|
-
expect(
|
|
234
|
+
expect(mockCountDownText.html).toHaveBeenCalledWith('0s');
|
|
322
235
|
});
|
|
323
236
|
|
|
324
|
-
test('should
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const callback = jest.fn((completeCallback) => {
|
|
328
|
-
completeCallback();
|
|
329
|
-
});
|
|
330
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
331
|
-
|
|
332
|
-
countDown.currentMillis = 5000;
|
|
237
|
+
test('should set progress bar to full when time reaches limit', () => {
|
|
238
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
239
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
333
240
|
|
|
334
|
-
|
|
241
|
+
for (let i = 0; i < 166; i++) {
|
|
242
|
+
intervalCallback();
|
|
243
|
+
}
|
|
244
|
+
jest.clearAllMocks();
|
|
245
|
+
intervalCallback(); // tick 167 : width = 120
|
|
335
246
|
|
|
336
|
-
expect(
|
|
247
|
+
expect(mockCountDownCurrent.width).toHaveBeenCalledWith(120);
|
|
337
248
|
});
|
|
338
249
|
|
|
339
|
-
test('should update progress bar width
|
|
340
|
-
const callback = jest.fn((completeCallback) =>
|
|
341
|
-
|
|
342
|
-
});
|
|
343
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
344
|
-
|
|
345
|
-
countDown.currentMillis = 5000;
|
|
250
|
+
test('should update progress bar width', () => {
|
|
251
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
252
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
346
253
|
jest.clearAllMocks();
|
|
347
254
|
|
|
348
255
|
intervalCallback();
|
|
349
256
|
|
|
350
257
|
expect(mockCountDownCurrent.width).toHaveBeenCalled();
|
|
351
258
|
const widthArg = mockCountDownCurrent.width.mock.calls[0][0];
|
|
352
|
-
expect(widthArg).
|
|
259
|
+
expect(widthArg).toBeGreaterThanOrEqual(0);
|
|
353
260
|
expect(widthArg).toBeLessThanOrEqual(120);
|
|
354
261
|
});
|
|
355
262
|
|
|
356
|
-
test('should update text with remaining seconds', () => {
|
|
357
|
-
const callback = jest.fn((completeCallback) => {
|
|
358
|
-
completeCallback();
|
|
359
|
-
});
|
|
360
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
361
|
-
|
|
362
|
-
countDown.currentMillis = 0;
|
|
363
|
-
jest.clearAllMocks();
|
|
364
|
-
|
|
365
|
-
intervalCallback();
|
|
366
|
-
|
|
367
|
-
expect(mockCountDownText.html).toHaveBeenCalledWith('10s');
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
test('should show 0s when time reaches limit', () => {
|
|
371
|
-
const callback = jest.fn((completeCallback) => {
|
|
372
|
-
completeCallback();
|
|
373
|
-
});
|
|
374
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
375
|
-
|
|
376
|
-
countDown.currentMillis = 10000;
|
|
377
|
-
countDown.currentSecond = 10;
|
|
378
|
-
jest.clearAllMocks();
|
|
379
|
-
|
|
380
|
-
intervalCallback();
|
|
381
|
-
|
|
382
|
-
expect(mockCountDownText.html).toHaveBeenCalledWith('0s');
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
test('should set progress bar to full when time reaches limit', () => {
|
|
386
|
-
const callback = jest.fn((completeCallback) => {
|
|
387
|
-
completeCallback();
|
|
388
|
-
});
|
|
389
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
390
|
-
|
|
391
|
-
countDown.currentMillis = 10000;
|
|
392
|
-
countDown.currentSecond = 10;
|
|
393
|
-
jest.clearAllMocks();
|
|
394
|
-
|
|
395
|
-
intervalCallback();
|
|
396
|
-
|
|
397
|
-
expect(mockCountDownCurrent.width).toHaveBeenCalledWith(120);
|
|
398
|
-
});
|
|
399
|
-
|
|
400
263
|
test('should trigger refreshData after timeout when time limit reached', () => {
|
|
401
|
-
const callback = jest.fn((completeCallback) =>
|
|
402
|
-
|
|
403
|
-
});
|
|
404
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
264
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
265
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
405
266
|
|
|
406
|
-
|
|
407
|
-
|
|
267
|
+
for (let i = 0; i < 167; i++) {
|
|
268
|
+
intervalCallback();
|
|
269
|
+
}
|
|
408
270
|
|
|
409
271
|
const callCountBefore = callback.mock.calls.length;
|
|
410
|
-
jest.clearAllMocks();
|
|
411
|
-
|
|
412
|
-
// Execute interval callback which should schedule a setTimeout
|
|
413
272
|
intervalCallback();
|
|
414
|
-
|
|
415
|
-
// Advance timers to trigger the setTimeout(callback, 100)
|
|
416
273
|
jest.advanceTimersByTime(100);
|
|
417
274
|
|
|
418
|
-
|
|
419
|
-
expect(callback.mock.calls.length).toBeGreaterThan(0);
|
|
275
|
+
expect(callback.mock.calls.length).toBeGreaterThan(callCountBefore);
|
|
420
276
|
});
|
|
421
277
|
|
|
422
|
-
test('should reset
|
|
423
|
-
|
|
424
|
-
completeCallback();
|
|
425
|
-
});
|
|
426
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
278
|
+
test('should reset progress to 0 when button is disabled', () => {
|
|
279
|
+
mockLink.prop = jest.fn(() => true); // bouton désactivé
|
|
427
280
|
|
|
428
|
-
|
|
429
|
-
|
|
281
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
282
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
283
|
+
jest.clearAllMocks();
|
|
430
284
|
|
|
431
285
|
intervalCallback();
|
|
432
286
|
|
|
433
|
-
|
|
287
|
+
// currentMillis reste à 0 → currentSecond = 0 → width = 0
|
|
288
|
+
const widthArg = mockCountDownCurrent.width.mock.calls[0][0];
|
|
289
|
+
expect(widthArg).toBe(0);
|
|
434
290
|
});
|
|
435
291
|
|
|
436
292
|
test('should handle missing progress bar element', () => {
|
|
437
293
|
mockDiv.find = jest.fn((selector) => {
|
|
438
|
-
if (selector === '.count_down_link a')
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
if (selector === '.count_down_current') {
|
|
442
|
-
return { length: 0 };
|
|
443
|
-
}
|
|
444
|
-
if (selector === '.count_down_text') {
|
|
445
|
-
return mockCountDownText;
|
|
446
|
-
}
|
|
294
|
+
if (selector === '.count_down_link a') return mockLink;
|
|
295
|
+
if (selector === '.count_down_current') return { length: 0 };
|
|
296
|
+
if (selector === '.count_down_text') return mockCountDownText;
|
|
447
297
|
return { length: 0 };
|
|
448
298
|
});
|
|
449
299
|
|
|
450
|
-
const callback = jest.fn((completeCallback) =>
|
|
451
|
-
|
|
452
|
-
});
|
|
453
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
300
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
301
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
454
302
|
|
|
455
|
-
expect(() => {
|
|
456
|
-
intervalCallback();
|
|
457
|
-
}).not.toThrow();
|
|
303
|
+
expect(() => { intervalCallback(); }).not.toThrow();
|
|
458
304
|
});
|
|
459
305
|
|
|
460
306
|
test('should handle missing text element', () => {
|
|
461
307
|
mockDiv.find = jest.fn((selector) => {
|
|
462
|
-
if (selector === '.count_down_link a')
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
if (selector === '.count_down_current') {
|
|
466
|
-
return mockCountDownCurrent;
|
|
467
|
-
}
|
|
468
|
-
if (selector === '.count_down_text') {
|
|
469
|
-
return { length: 0 };
|
|
470
|
-
}
|
|
308
|
+
if (selector === '.count_down_link a') return mockLink;
|
|
309
|
+
if (selector === '.count_down_current') return mockCountDownCurrent;
|
|
310
|
+
if (selector === '.count_down_text') return { length: 0 };
|
|
471
311
|
return { length: 0 };
|
|
472
312
|
});
|
|
473
313
|
|
|
474
|
-
const callback = jest.fn((completeCallback) =>
|
|
475
|
-
|
|
476
|
-
});
|
|
477
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
314
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
315
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
478
316
|
|
|
479
|
-
expect(() => {
|
|
480
|
-
intervalCallback();
|
|
481
|
-
}).not.toThrow();
|
|
482
|
-
});
|
|
483
|
-
|
|
484
|
-
test('should calculate progress correctly at different time points', () => {
|
|
485
|
-
const callback = jest.fn((completeCallback) => {
|
|
486
|
-
completeCallback();
|
|
487
|
-
});
|
|
488
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
489
|
-
|
|
490
|
-
// Test at 5 seconds (50%)
|
|
491
|
-
countDown.currentMillis = 5000;
|
|
492
|
-
countDown.currentSecond = 5;
|
|
493
|
-
jest.clearAllMocks();
|
|
494
|
-
|
|
495
|
-
intervalCallback();
|
|
496
|
-
|
|
497
|
-
expect(mockCountDownText.html).toHaveBeenCalledWith('5s');
|
|
498
|
-
const width1 = mockCountDownCurrent.width.mock.calls[0][0];
|
|
499
|
-
expect(width1).toBeGreaterThan(50);
|
|
500
|
-
expect(width1).toBeLessThan(70);
|
|
501
|
-
|
|
502
|
-
// Test at 9 seconds (90%)
|
|
503
|
-
countDown.currentMillis = 9000;
|
|
504
|
-
countDown.currentSecond = 9;
|
|
505
|
-
jest.clearAllMocks();
|
|
506
|
-
|
|
507
|
-
intervalCallback();
|
|
508
|
-
|
|
509
|
-
expect(mockCountDownText.html).toHaveBeenCalledWith('1s');
|
|
510
|
-
const width2 = mockCountDownCurrent.width.mock.calls[0][0];
|
|
511
|
-
expect(width2).toBeGreaterThan(100);
|
|
317
|
+
expect(() => { intervalCallback(); }).not.toThrow();
|
|
512
318
|
});
|
|
513
319
|
});
|
|
514
320
|
|
|
515
321
|
describe('integration scenarios', () => {
|
|
516
322
|
test('should complete full countdown cycle', () => {
|
|
517
|
-
const callback = jest.fn((completeCallback) =>
|
|
518
|
-
|
|
519
|
-
});
|
|
520
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
323
|
+
const callback = jest.fn((completeCallback) => completeCallback());
|
|
324
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
521
325
|
|
|
522
326
|
const initialCallCount = callback.mock.calls.length;
|
|
523
327
|
|
|
524
|
-
|
|
525
|
-
countDown.currentMillis = 0;
|
|
526
|
-
|
|
527
|
-
// Simulate intervals until reaching 10 seconds
|
|
528
|
-
for (let i = 0; i < 167; i++) { // 167 * 60ms ≈ 10020ms
|
|
328
|
+
for (let i = 0; i < 167; i++) {
|
|
529
329
|
intervalCallback();
|
|
530
330
|
}
|
|
531
|
-
|
|
532
|
-
// Advance timers to trigger the setTimeout(callback, 100)
|
|
533
331
|
jest.advanceTimersByTime(100);
|
|
534
332
|
|
|
535
|
-
// Should have triggered refresh at least once more
|
|
536
333
|
expect(callback.mock.calls.length).toBeGreaterThan(initialCallCount);
|
|
537
334
|
});
|
|
538
335
|
|
|
539
336
|
test('should handle rapid manual refreshes', () => {
|
|
540
|
-
const callback = jest.fn(
|
|
541
|
-
|
|
542
|
-
});
|
|
543
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
544
|
-
|
|
545
|
-
jest.clearAllMocks();
|
|
337
|
+
const callback = jest.fn(); // ne complète pas
|
|
338
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
546
339
|
|
|
547
|
-
|
|
548
|
-
countDown.refreshData();
|
|
549
|
-
expect(callback).toHaveBeenCalledTimes(1);
|
|
340
|
+
const callCountAfterInit = callback.mock.calls.length;
|
|
550
341
|
|
|
551
|
-
//
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
// Try to refresh again while first is in progress
|
|
555
|
-
countDown.refreshData();
|
|
556
|
-
expect(callback).toHaveBeenCalledTimes(1); // Should not call again
|
|
342
|
+
// déjà en cours → bloqué
|
|
343
|
+
clickCallback.call(mockLink);
|
|
344
|
+
expect(callback.mock.calls.length).toBe(callCountAfterInit);
|
|
557
345
|
});
|
|
558
346
|
|
|
559
347
|
test('should allow new refresh after previous completes', () => {
|
|
560
348
|
let completeCallback;
|
|
561
|
-
const callback = jest.fn((cb) => {
|
|
562
|
-
|
|
563
|
-
});
|
|
564
|
-
const countDown = new CountDown(mockDiv, callback);
|
|
565
|
-
|
|
566
|
-
jest.clearAllMocks();
|
|
567
|
-
|
|
568
|
-
// First refresh
|
|
569
|
-
countDown.refreshData();
|
|
570
|
-
expect(callback).toHaveBeenCalledTimes(1);
|
|
349
|
+
const callback = jest.fn((cb) => { completeCallback = cb; });
|
|
350
|
+
CountDown.init(mockDiv, { onRefreshData: callback });
|
|
571
351
|
|
|
572
|
-
// Complete the first refresh
|
|
573
352
|
completeCallback();
|
|
353
|
+
const callCountAfterComplete = callback.mock.calls.length;
|
|
574
354
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
expect(callback).toHaveBeenCalledTimes(2);
|
|
355
|
+
clickCallback.call(mockLink);
|
|
356
|
+
expect(callback.mock.calls.length).toBe(callCountAfterComplete + 1);
|
|
578
357
|
});
|
|
579
358
|
});
|
|
580
359
|
});
|