1- import React from 'react'
2- import { act , render } from '@testing-library/react'
1+ import React , { useContext } from 'react'
2+ import { act , render , waitFor } from '@testing-library/react'
33import { useCached } from '../src'
4- import { clear } from 'idb-keyval'
4+ import { clear , createStore } from 'idb-keyval'
5+ import { CacheContext } from '../src/context'
56
6- function setup ( ...propsArray : Parameters < typeof useCached > [ 0 ] [ ] ) {
7+ async function setup (
8+ propsArray : Parameters < typeof useCached > [ 0 ] [ ] = [ undefined ] ,
9+ renderArray : ( ( api : ReturnType < typeof useCached > ) => void ) [ ] = [ ] ,
10+ ) {
711 const hook : ReturnType < typeof useCached > [ ] = [ ]
8- function TestComponent ( { i = 0 , p = { } } : { i ?: number , p ?: Parameters < typeof useCached > [ 0 ] } = { } ) {
12+ function TestComponent ( {
13+ i = 0 ,
14+ p = { } ,
15+ r = ( ) => { return } ,
16+ } : {
17+ i ?: number ,
18+ p ?: Parameters < typeof useCached > [ 0 ] ,
19+ r ?: ( api : ReturnType < typeof useCached > ) => void ,
20+ } = { } ) {
921 hook [ i ] = useCached ( Object . keys ( p ) . length ? p : undefined )
22+ r ( hook [ i ] )
1023 return null
1124 }
1225
26+ // clear IndexedDb and default reactCache to get a fresh start
27+ for ( const p of propsArray ) {
28+ const store = createStore ( p ?. dbName ?? 'Cached' , p ?. storeName ?? 'keyval' )
29+ await clear ( store )
30+ }
31+ function ClearComponent ( ) {
32+ const cache = useContext ( CacheContext )
33+ Object . keys ( cache ) . forEach ( k => { delete cache [ k ] } )
34+ return null
35+ }
36+ render ( < ClearComponent /> )
37+
1338 render ( < >
14- { ( propsArray . length ? propsArray : [ undefined ] ) . map ( ( p , i ) => < TestComponent key = { i } i = { i } p = { p } /> ) }
39+ { propsArray . map ( ( p , i ) => < TestComponent key = { i } i = { i } p = { p } r = { renderArray [ i ] } /> ) }
1540 </ > )
1641
1742 return { getHook : ( i = 0 ) => hook [ i ] }
1843}
1944
20- it ( 'provide api' , ( ) => {
21- const { getHook } = setup ( )
45+ it ( 'provide api' , async ( ) => {
46+ const { getHook } = await setup ( )
2247
2348 expect ( getHook ( ) ) . toEqual ( expect . objectContaining ( {
2449 clear : expect . any ( Function ) ,
@@ -28,8 +53,8 @@ it('provide api', () => {
2853 } ) )
2954} )
3055
31- it ( 'provide api with custom store' , ( ) => {
32- const { getHook } = setup ( { dbName : 'foo' , storeName : 'bar' } )
56+ it ( 'provide api with custom store' , async ( ) => {
57+ const { getHook } = await setup ( [ { dbName : 'foo' , storeName : 'bar' } ] )
3358
3459 expect ( getHook ( ) ) . toEqual ( expect . objectContaining ( {
3560 clear : expect . any ( Function ) ,
@@ -40,7 +65,7 @@ it('provide api with custom store', () => {
4065} )
4166
4267it ( 'get and set without context' , async ( ) => {
43- const { getHook } = setup ( { context : false } , { context : false } )
68+ const { getHook } = await setup ( [ { context : false } , { context : false } ] )
4469
4570 await act ( async ( ) => {
4671 getHook ( 0 ) . set ( 'foo' , 'bar' )
@@ -52,7 +77,7 @@ it('get and set without context', async () => {
5277} )
5378
5479it ( 'get and set with context' , async ( ) => {
55- const { getHook } = setup ( { context : true } , { context : true } )
80+ const { getHook } = await setup ( [ { context : true } , { context : true } ] )
5681
5782 await act ( async ( ) => {
5883 getHook ( 0 ) . set ( 'foo' , 'bar' )
@@ -62,3 +87,25 @@ it('get and set with context', async () => {
6287 expect ( getHook ( 0 ) . get ( 'foo' ) ) . toBe ( 'bar' )
6388 expect ( getHook ( 1 ) . get ( 'foo' ) ) . toBe ( 'bar' )
6489} )
90+
91+ it ( 'rerender component on updated cache' , async ( ) => {
92+ let loadingResolve : ( ( ) => void ) | undefined = undefined
93+ const render = jest . fn ( ( api : ReturnType < typeof useCached > ) => {
94+ return api . get ( 'foo' , async ( ) => new Promise ( res => {
95+ api . set ( 'foo' , 'bar' )
96+ loadingResolve = res
97+ } ) )
98+ } )
99+ await setup ( [ undefined ] , [ render ] )
100+
101+ expect ( render ) . toReturnTimes ( 1 )
102+ expect ( render ) . toHaveNthReturnedWith ( 1 , undefined )
103+
104+ await waitFor ( ( ) => expect ( loadingResolve ) . toBeTruthy ( ) )
105+ act ( ( ) => {
106+ loadingResolve && loadingResolve ( )
107+ } )
108+
109+ expect ( render ) . toReturnTimes ( 2 )
110+ expect ( render ) . toHaveNthReturnedWith ( 2 , 'bar' )
111+ } )
0 commit comments