1
1
import { TSource } from '@hyperdx/common-utils/dist/types' ;
2
- import { renderHook , act } from '@testing-library/react' ;
3
- import * as utils from '../utils' ;
2
+ import { act , renderHook } from '@testing-library/react' ;
4
3
5
4
import { MetricsDataType , NumberFormat } from '../types' ;
5
+ import * as utils from '../utils' ;
6
6
import {
7
7
formatAttributeClause ,
8
8
formatDate ,
@@ -274,7 +274,7 @@ describe('formatNumber', () => {
274
274
describe ( 'useLocalStorage' , ( ) => {
275
275
// Create a mock for localStorage
276
276
let localStorageMock : jest . Mocked < Storage > ;
277
-
277
+
278
278
beforeEach ( ( ) => {
279
279
// Clear all mocks between tests
280
280
jest . clearAllMocks ( ) ;
@@ -288,14 +288,14 @@ describe('useLocalStorage', () => {
288
288
key : jest . fn ( ) ,
289
289
length : 0 ,
290
290
} ;
291
-
291
+
292
292
// Replace window.localStorage with our mock
293
- Object . defineProperty ( window , 'localStorage' , {
293
+ Object . defineProperty ( window , 'localStorage' , {
294
294
value : localStorageMock ,
295
- writable : true
295
+ writable : true ,
296
296
} ) ;
297
297
} ) ;
298
-
298
+
299
299
afterAll ( ( ) => {
300
300
// Restore original implementations
301
301
jest . restoreAllMocks ( ) ;
@@ -304,13 +304,15 @@ describe('useLocalStorage', () => {
304
304
test ( 'should initialize with initial value when localStorage is empty' , ( ) => {
305
305
// Mock localStorage.getItem to return null (empty)
306
306
localStorageMock . getItem . mockReturnValueOnce ( null ) ;
307
-
307
+
308
308
const initialValue = { test : 'value' } ;
309
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , initialValue ) ) ;
309
+ const { result } = renderHook ( ( ) =>
310
+ utils . useLocalStorage ( 'testKey' , initialValue ) ,
311
+ ) ;
310
312
311
313
// Check if initialized with initial value
312
314
expect ( result . current [ 0 ] ) . toEqual ( initialValue ) ;
313
-
315
+
314
316
// Verify localStorage was checked
315
317
expect ( localStorageMock . getItem ) . toHaveBeenCalledWith ( 'testKey' ) ;
316
318
} ) ;
@@ -319,8 +321,10 @@ describe('useLocalStorage', () => {
319
321
// Mock localStorage to return existing value
320
322
const existingValue = { test : 'existing' } ;
321
323
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( existingValue ) ) ;
322
-
323
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , { test : 'default' } ) ) ;
324
+
325
+ const { result } = renderHook ( ( ) =>
326
+ utils . useLocalStorage ( 'testKey' , { test : 'default' } ) ,
327
+ ) ;
324
328
325
329
// Should use the value from localStorage, not the initial value
326
330
expect ( result . current [ 0 ] ) . toEqual ( existingValue ) ;
@@ -329,8 +333,10 @@ describe('useLocalStorage', () => {
329
333
330
334
test ( 'should update localStorage when setValue is called' , ( ) => {
331
335
localStorageMock . getItem . mockReturnValueOnce ( null ) ;
332
-
333
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , 'initial' ) ) ;
336
+
337
+ const { result } = renderHook ( ( ) =>
338
+ utils . useLocalStorage ( 'testKey' , 'initial' ) ,
339
+ ) ;
334
340
335
341
// Update value
336
342
const newValue = 'updated' ;
@@ -340,43 +346,55 @@ describe('useLocalStorage', () => {
340
346
341
347
// Check if state updated
342
348
expect ( result . current [ 0 ] ) . toBe ( newValue ) ;
343
-
349
+
344
350
// Check if localStorage was updated
345
- expect ( localStorageMock . setItem ) . toHaveBeenCalledWith ( 'testKey' , JSON . stringify ( newValue ) ) ;
351
+ expect ( localStorageMock . setItem ) . toHaveBeenCalledWith (
352
+ 'testKey' ,
353
+ JSON . stringify ( newValue ) ,
354
+ ) ;
346
355
} ) ;
347
356
348
357
test ( 'should handle functional updates' , ( ) => {
349
358
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 0 ) ) ;
350
-
351
- const { result } = renderHook ( ( ) => utils . useLocalStorage < number > ( 'testKey' , 0 ) ) ;
359
+
360
+ const { result } = renderHook ( ( ) =>
361
+ utils . useLocalStorage < number > ( 'testKey' , 0 ) ,
362
+ ) ;
352
363
353
364
// Update using function
354
365
act ( ( ) => {
355
- result . current [ 1 ] ( ( prev ) => prev + 1 ) ;
366
+ result . current [ 1 ] ( prev => prev + 1 ) ;
356
367
} ) ;
357
368
358
369
// Check if state updated correctly
359
370
expect ( result . current [ 0 ] ) . toBe ( 1 ) ;
360
-
371
+
361
372
// Check if localStorage was updated
362
- expect ( localStorageMock . setItem ) . toHaveBeenCalledWith ( 'testKey' , JSON . stringify ( 1 ) ) ;
373
+ expect ( localStorageMock . setItem ) . toHaveBeenCalledWith (
374
+ 'testKey' ,
375
+ JSON . stringify ( 1 ) ,
376
+ ) ;
363
377
} ) ;
364
378
365
379
test ( 'should handle storage event from another window' , ( ) => {
366
380
// Initial setup
367
381
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 'initial' ) ) ;
368
-
369
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , 'initial' ) ) ;
382
+
383
+ const { result } = renderHook ( ( ) =>
384
+ utils . useLocalStorage ( 'testKey' , 'initial' ) ,
385
+ ) ;
370
386
371
387
// Update mock to return new value when checked after event
372
388
localStorageMock . getItem . mockReturnValue ( JSON . stringify ( 'external update' ) ) ;
373
-
389
+
374
390
// Dispatch storage event
375
391
act ( ( ) => {
376
- window . dispatchEvent ( new StorageEvent ( 'storage' , {
377
- key : 'testKey' ,
378
- newValue : JSON . stringify ( 'external update' ) ,
379
- } ) ) ;
392
+ window . dispatchEvent (
393
+ new StorageEvent ( 'storage' , {
394
+ key : 'testKey' ,
395
+ newValue : JSON . stringify ( 'external update' ) ,
396
+ } ) ,
397
+ ) ;
380
398
} ) ;
381
399
382
400
// State should be updated
@@ -386,31 +404,40 @@ describe('useLocalStorage', () => {
386
404
test ( 'should handle customStorage event from same window but different hook instance' , ( ) => {
387
405
// First hook instance
388
406
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 'initial1' ) ) ;
389
- const { result : result1 } = renderHook ( ( ) => utils . useLocalStorage ( 'sharedKey' , 'initial1' ) ) ;
390
-
407
+ const { result : result1 } = renderHook ( ( ) =>
408
+ utils . useLocalStorage ( 'sharedKey' , 'initial1' ) ,
409
+ ) ;
410
+
391
411
// Second hook instance
392
412
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 'initial1' ) ) ;
393
- const { result : result2 } = renderHook ( ( ) => utils . useLocalStorage ( 'sharedKey' , 'initial2' ) ) ;
413
+ const { result : result2 } = renderHook ( ( ) =>
414
+ utils . useLocalStorage ( 'sharedKey' , 'initial2' ) ,
415
+ ) ;
394
416
395
417
// Clear mock calls count
396
418
localStorageMock . getItem . mockClear ( ) ;
397
-
419
+
398
420
// When the second hook checks localStorage after custom event
399
- localStorageMock . getItem . mockReturnValue ( JSON . stringify ( 'updated by hook 1' ) ) ;
400
-
421
+ localStorageMock . getItem . mockReturnValue (
422
+ JSON . stringify ( 'updated by hook 1' ) ,
423
+ ) ;
424
+
401
425
// Update value in the first instance
402
426
act ( ( ) => {
403
427
result1 . current [ 1 ] ( 'updated by hook 1' ) ;
404
428
} ) ;
405
429
406
430
// Manually trigger custom event (since it's happening within the same test)
407
431
act ( ( ) => {
408
- const event = new CustomEvent < utils . CustomStorageChangeDetail > ( 'customStorage' , {
409
- detail : {
410
- key : 'sharedKey' ,
411
- instanceId : 'some-id' , // Different from the instance updating
432
+ const event = new CustomEvent < utils . CustomStorageChangeDetail > (
433
+ 'customStorage' ,
434
+ {
435
+ detail : {
436
+ key : 'sharedKey' ,
437
+ instanceId : 'some-id' , // Different from the instance updating
438
+ } ,
412
439
} ,
413
- } ) ;
440
+ ) ;
414
441
window . dispatchEvent ( event ) ;
415
442
} ) ;
416
443
@@ -421,72 +448,26 @@ describe('useLocalStorage', () => {
421
448
test ( 'should not update if storage event is for a different key' , ( ) => {
422
449
// Initial setup
423
450
localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 'initial' ) ) ;
424
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , 'initial' ) ) ;
451
+ const { result } = renderHook ( ( ) =>
452
+ utils . useLocalStorage ( 'testKey' , 'initial' ) ,
453
+ ) ;
425
454
426
455
// Clear the mock calls counter
427
456
localStorageMock . getItem . mockClear ( ) ;
428
-
457
+
429
458
// Simulate storage event for a different key
430
459
act ( ( ) => {
431
- window . dispatchEvent ( new StorageEvent ( 'storage' , {
432
- key : 'differentKey' ,
433
- newValue : JSON . stringify ( 'different value' ) ,
434
- } ) ) ;
460
+ window . dispatchEvent (
461
+ new StorageEvent ( 'storage' , {
462
+ key : 'differentKey' ,
463
+ newValue : JSON . stringify ( 'different value' ) ,
464
+ } ) ,
465
+ ) ;
435
466
} ) ;
436
467
437
468
// State should remain unchanged
438
469
expect ( result . current [ 0 ] ) . toBe ( 'initial' ) ;
439
470
// localStorage should not be accessed since key doesn't match
440
471
expect ( localStorageMock . getItem ) . not . toHaveBeenCalled ( ) ;
441
472
} ) ;
442
-
443
- test ( 'should handle JSON parsing errors' , ( ) => {
444
- // Mock console.log to test error logging
445
- const originalConsoleLog = console . log ;
446
- console . log = jest . fn ( ) ;
447
-
448
- // Set invalid JSON in localStorage
449
- localStorageMock . getItem . mockReturnValueOnce ( 'invalid-json' ) ;
450
-
451
- // Should fall back to initial value on error
452
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , 'fallback' ) ) ;
453
-
454
- // Verify console.log was called (error was logged)
455
- expect ( console . log ) . toHaveBeenCalled ( ) ;
456
-
457
- // Initial value should be used
458
- expect ( result . current [ 0 ] ) . toBe ( 'fallback' ) ;
459
-
460
- // Restore console.log
461
- console . log = originalConsoleLog ;
462
- } ) ;
463
-
464
- test ( 'should handle errors when setting localStorage' , ( ) => {
465
- // Mock console.log to test error logging
466
- const originalConsoleLog = console . log ;
467
- console . log = jest . fn ( ) ;
468
-
469
- // Initial setup
470
- localStorageMock . getItem . mockReturnValueOnce ( JSON . stringify ( 'initial' ) ) ;
471
- const { result } = renderHook ( ( ) => utils . useLocalStorage ( 'testKey' , 'initial' ) ) ;
472
-
473
- // Mock setItem to throw error
474
- localStorageMock . setItem . mockImplementationOnce ( ( ) => {
475
- throw new Error ( 'QuotaExceededError' ) ;
476
- } ) ;
477
-
478
- // Try to update value
479
- act ( ( ) => {
480
- result . current [ 1 ] ( 'updated' ) ;
481
- } ) ;
482
-
483
- // State should still update even if localStorage fails
484
- expect ( result . current [ 0 ] ) . toBe ( 'updated' ) ;
485
-
486
- // Verify error was logged
487
- expect ( console . log ) . toHaveBeenCalled ( ) ;
488
-
489
- // Restore console.log
490
- console . log = originalConsoleLog ;
491
- } ) ;
492
473
} ) ;
0 commit comments