@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.
@@ -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('constructor', () => {
80
- test('should return early when div has no length', () => {
81
- const emptyDiv = { length: 0 };
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(countDown.div).toBeUndefined();
76
+ expect(result).toBeUndefined();
85
77
  });
86
78
 
87
- test('should create countdown UI elements', () => {
88
- const callback = jest.fn((completeCallback) => {
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 initialize properties', () => {
101
- const callback = jest.fn((completeCallback) => {
102
- completeCallback();
103
- });
104
- const countDown = new CountDown(mockDiv, callback);
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
- const callback = jest.fn((completeCallback) => {
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 handle click on refresh link', () => {
125
- const callback = jest.fn((completeCallback) => {
126
- completeCallback();
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
- const callback = jest.fn((completeCallback) => {
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 refreshData immediately after construction', () => {
147
- const callback = jest.fn((completeCallback) => {
148
- completeCallback();
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 handle missing refresh link', () => {
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
- return mockEmptyLink;
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
- new CountDown(mockDiv, callback);
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 reset currentMillis', () => {
198
- const callback = jest.fn((completeCallback) => {
199
- completeCallback();
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
- expect(callback.mock.calls.length).toBe(callCountBefore);
222
- expect(consoleLogSpy).toHaveBeenCalledWith('Already making request, no new request lauched.');
144
+ clickCallback.call(mockLink);
223
145
 
224
- consoleLogSpy.mockRestore();
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
- // Don't call completeCallback to keep request active
152
+ callCount++;
153
+ if (callCount === 1) completeCallback(); // init call complète
154
+ // le click ne complète pas → alreadyMakingRequest reste true
230
155
  });
231
- const countDown = new CountDown(mockDiv, callback);
232
-
156
+ CountDown.init(mockDiv, { onRefreshData: callback });
233
157
  jest.clearAllMocks();
234
- countDown.refreshData();
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
- completeCallback();
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
- countDown.refreshData();
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 call callback if it is a function', () => {
255
- const callback = jest.fn((completeCallback) => {
256
- completeCallback();
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
- jest.clearAllMocks();
261
- countDown.refreshData();
181
+ // à ce stade le premier refreshData() a été appelé sans compléter
182
+ const callCountAfterInit = callback.mock.calls.length;
262
183
 
263
- expect(callback).toHaveBeenCalledWith(expect.any(Function));
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
- test('should not crash if callback is not a function', () => {
267
- const countDown = new CountDown(mockDiv, null);
189
+ consoleLogSpy.mockRestore();
190
+ });
268
191
 
192
+ test('should not crash if onRefreshData is not a function', () => {
269
193
  expect(() => {
270
- countDown.refreshData();
194
+ CountDown.init(mockDiv, {});
271
195
  }).not.toThrow();
272
196
  });
273
197
 
274
- test('should set alreadyMakingRequest to true during request', () => {
275
- let countDownInstance;
276
- const callback = jest.fn((completeCallback) => {
277
- // Note: Bug in original code - sets CountDown.alreadyMakingRequest (static) instead of this.alreadyMakingRequest
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
- countDownInstance.alreadyMakingRequest = false;
284
- jest.clearAllMocks();
285
- countDownInstance.refreshData();
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
- // After refreshData completes, alreadyMakingRequest should be false again
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 increment currentMillis on each interval tick', () => {
294
- const callback = jest.fn((completeCallback) => {
295
- completeCallback();
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(countDown.currentMillis).toBe(60);
305
- expect(countDown.currentSecond).toBe(0);
221
+ expect(mockCountDownText.html).toHaveBeenCalledWith('10s');
306
222
  });
307
223
 
308
- test('should update currentSecond correctly', () => {
309
- const callback = jest.fn((completeCallback) => {
310
- completeCallback();
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
- // Run multiple intervals to reach 1 second
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(countDown.currentSecond).toBe(1);
234
+ expect(mockCountDownText.html).toHaveBeenCalledWith('0s');
322
235
  });
323
236
 
324
- test('should reset currentMillis when button is disabled', () => {
325
- mockLink.prop = jest.fn(() => true); // Button disabled
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
- intervalCallback();
241
+ for (let i = 0; i < 166; i++) {
242
+ intervalCallback();
243
+ }
244
+ jest.clearAllMocks();
245
+ intervalCallback(); // tick 167 : width = 120
335
246
 
336
- expect(countDown.currentMillis).toBe(0);
247
+ expect(mockCountDownCurrent.width).toHaveBeenCalledWith(120);
337
248
  });
338
249
 
339
- test('should update progress bar width correctly', () => {
340
- const callback = jest.fn((completeCallback) => {
341
- completeCallback();
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).toBeGreaterThan(0);
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
- completeCallback();
403
- });
404
- const countDown = new CountDown(mockDiv, callback);
264
+ const callback = jest.fn((completeCallback) => completeCallback());
265
+ CountDown.init(mockDiv, { onRefreshData: callback });
405
266
 
406
- countDown.currentMillis = 10000;
407
- countDown.currentSecond = 10;
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
- // Should have called refreshData through the timeout
419
- expect(callback.mock.calls.length).toBeGreaterThan(0);
275
+ expect(callback.mock.calls.length).toBeGreaterThan(callCountBefore);
420
276
  });
421
277
 
422
- test('should reset currentMillis after reaching time limit', () => {
423
- const callback = jest.fn((completeCallback) => {
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
- countDown.currentMillis = 10000;
429
- countDown.currentSecond = 10;
281
+ const callback = jest.fn((completeCallback) => completeCallback());
282
+ CountDown.init(mockDiv, { onRefreshData: callback });
283
+ jest.clearAllMocks();
430
284
 
431
285
  intervalCallback();
432
286
 
433
- expect(countDown.currentMillis).toBe(0);
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
- return mockLink;
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
- completeCallback();
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
- return mockLink;
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
- completeCallback();
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
- completeCallback();
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
- // Start from 0
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((completeCallback) => {
541
- // Simulate async request - don't complete immediately
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
- // First manual refresh
548
- countDown.refreshData();
549
- expect(callback).toHaveBeenCalledTimes(1);
340
+ const callCountAfterInit = callback.mock.calls.length;
550
341
 
551
- // Manually set alreadyMakingRequest to true to simulate in-progress request
552
- countDown.alreadyMakingRequest = true;
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
- completeCallback = cb;
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
- // Now should allow new refresh
576
- countDown.refreshData();
577
- expect(callback).toHaveBeenCalledTimes(2);
355
+ clickCallback.call(mockLink);
356
+ expect(callback.mock.calls.length).toBe(callCountAfterComplete + 1);
578
357
  });
579
358
  });
580
359
  });