@@ -62,9 +62,15 @@ describe('Flashbar persistence', () => {
6262 } ) ;
6363
6464 it ( 'handles mixed persistent and non-persistent items' , async ( ) => {
65- mockRetrieveFlashbarDismiss
66- . mockResolvedValueOnce ( true ) // key-0: hidden
67- . mockResolvedValueOnce ( false ) ; // key-2: visible
65+ mockRetrieveFlashbarDismiss . mockImplementation ( config => {
66+ if ( config . uniqueKey === 'key-0' ) {
67+ return Promise . resolve ( true ) ;
68+ }
69+ if ( config . uniqueKey === 'key-2' ) {
70+ return Promise . resolve ( false ) ;
71+ }
72+ throw new Error ( `Unknown key ${ config . uniqueKey } ` ) ;
73+ } ) ;
6874
6975 const items = createItems ( [ true , false , true ] ) ;
7076
@@ -196,5 +202,81 @@ describe('Flashbar persistence', () => {
196202 expect ( mockRetrieveFlashbarDismiss ) . toHaveBeenLastCalledWith ( { uniqueKey : 'new-key' } ) ;
197203 } ) ;
198204 } ) ;
205+
206+ it ( 'checks persistence only for newly added items when start with empty array' , async ( ) => {
207+ mockRetrieveFlashbarDismiss . mockResolvedValue ( false ) ;
208+
209+ // Start with empty array
210+ const { rerender } = render ( < Flashbar items = { [ ] } /> ) ;
211+
212+ expect ( mockRetrieveFlashbarDismiss ) . not . toHaveBeenCalled ( ) ;
213+
214+ // Add one item, check that mockRetrieveFlashbarDismiss was called with that item id
215+ const items = createItems ( [ true ] ) ;
216+ rerender ( < Flashbar items = { items } /> ) ;
217+
218+ await waitFor ( ( ) => {
219+ expect ( mockRetrieveFlashbarDismiss ) . toHaveBeenCalledTimes ( 1 ) ;
220+ expect ( mockRetrieveFlashbarDismiss ) . toHaveBeenCalledWith ( { uniqueKey : 'key-0' } ) ;
221+ } ) ;
222+
223+ mockRetrieveFlashbarDismiss . mockClear ( ) ;
224+
225+ // Add one more item, check that mockRetrieveFlashbarDismiss was called with only the 2nd item id
226+ const secondItem = { ...createItems ( [ true ] ) [ 0 ] , id : 'item-1' , persistenceConfig : { uniqueKey : 'key-1' } } ;
227+ rerender ( < Flashbar items = { [ ...items , secondItem ] } /> ) ;
228+
229+ await waitFor ( ( ) => {
230+ expect ( mockRetrieveFlashbarDismiss ) . toHaveBeenCalledTimes ( 1 ) ;
231+ expect ( mockRetrieveFlashbarDismiss ) . toHaveBeenCalledWith ( { uniqueKey : 'key-1' } ) ;
232+ } ) ;
233+ } ) ;
234+
235+ it ( 'handles concurrent async calls without race conditions' , async ( ) => {
236+ let resolveFirst : ( value : boolean ) => void ;
237+ let resolveSecond : ( value : boolean ) => void ;
238+
239+ const firstPromise = new Promise < boolean > ( resolve => {
240+ resolveFirst = resolve ;
241+ } ) ;
242+ const secondPromise = new Promise < boolean > ( resolve => {
243+ resolveSecond = resolve ;
244+ } ) ;
245+
246+ mockRetrieveFlashbarDismiss . mockImplementation ( config => {
247+ if ( config . uniqueKey === 'key-0' ) {
248+ return firstPromise ;
249+ }
250+ if ( config . uniqueKey === 'key-2' ) {
251+ return secondPromise ;
252+ }
253+ throw new Error ( `Unknown key ${ config . uniqueKey } ` ) ;
254+ } ) ;
255+
256+ const initialItems = createItems ( [ true , false ] ) ; // Create item 0 with persistence, item 1 without persistence
257+ const { rerender, container } = render ( < Flashbar items = { initialItems } /> ) ;
258+
259+ // Add third item while first item still loading
260+ const updatedItems = [
261+ ...initialItems ,
262+ { ...createItems ( [ true ] ) [ 0 ] , content : 'Item 2' , id : 'item-second' , persistenceConfig : { uniqueKey : 'key-2' } } ,
263+ ] ;
264+ rerender ( < Flashbar items = { updatedItems } /> ) ;
265+
266+ // Resolve second call first (race condition scenario)
267+ resolveSecond ! ( false ) ; // Item 2 should be visible
268+ await waitFor ( ( ) => { } ) ;
269+
270+ // Then resolve first call
271+ resolveFirst ! ( true ) ; // Item 0 should be hidden
272+
273+ const wrapper = createWrapper ( container ) . findFlashbar ( ) ! ;
274+ await waitFor ( ( ) => {
275+ const items = wrapper . findItems ( ) ;
276+ expect ( items ) . toHaveLength ( 2 ) ;
277+ expect ( items [ 0 ] . findContent ( ) ! . getElement ( ) ) . toHaveTextContent ( 'Item 1' ) ;
278+ expect ( items [ 1 ] . findContent ( ) ! . getElement ( ) ) . toHaveTextContent ( 'Item 2' ) ;
279+ } ) ;
280+ } ) ;
199281 } ) ;
200282} ) ;
0 commit comments