@@ -21,6 +21,7 @@ import { TrackingConsent } from '@/types/tracking-consent';
2121import {
2222 appendWishlistMergeFlag ,
2323 captureGuestWishlistSnapshot ,
24+ getOrCreateWishlist ,
2425 getWishlist ,
2526 loadWishlistPageData ,
2627 mergeWishlist ,
@@ -687,3 +688,56 @@ describe('appendWishlistMergeFlag', () => {
687688 expect ( result2 . setCookie ) . toContain ( 'wishlist_merge' ) ;
688689 } ) ;
689690} ) ;
691+
692+ describe ( 'getOrCreateWishlist — create branch' , ( ) => {
693+ const mockContext = { } as any ;
694+
695+ beforeEach ( ( ) => {
696+ vi . clearAllMocks ( ) ;
697+ } ) ;
698+
699+ test ( 'fast path: returns the POST body without re-fetching when id is present' , async ( ) => {
700+ // No existing list: getCustomerProductLists returns empty.
701+ mockGetCustomerProductLists . mockResolvedValueOnce ( { data : { data : [ ] } } ) ;
702+
703+ const created = { id : 'list-new' , type : 'wish_list' , customerProductListItems : [ ] } ;
704+ mockCreateCustomerProductList . mockResolvedValue ( { data : created } ) ;
705+
706+ const result = await getOrCreateWishlist ( mockContext , 'cust-1' ) ;
707+
708+ expect ( result ) . toEqual ( created ) ;
709+ expect ( mockCreateCustomerProductList ) . toHaveBeenCalledTimes ( 1 ) ;
710+ // Only the initial lookup before create — no second GET after the POST.
711+ expect ( mockGetCustomerProductLists ) . toHaveBeenCalledTimes ( 1 ) ;
712+ expect ( mockLoggerWarn ) . not . toHaveBeenCalled ( ) ;
713+ } ) ;
714+
715+ test ( 'fallback path: waits for index, re-fetches when POST returns no id' , async ( ) => {
716+ vi . useFakeTimers ( ) ;
717+ try {
718+ // No existing list: initial lookup empty.
719+ // After the create, the post-sleep GET returns the indexed list.
720+ const created = { id : 'list-indexed' , type : 'wish_list' , customerProductListItems : [ ] } ;
721+ mockGetCustomerProductLists
722+ . mockResolvedValueOnce ( { data : { data : [ ] } } )
723+ . mockResolvedValueOnce ( { data : { data : [ created ] } } ) ;
724+
725+ // POST resolves with a body that lacks id (the schema-anomaly we're guarding against).
726+ mockCreateCustomerProductList . mockResolvedValue ( { data : { type : 'wish_list' } } ) ;
727+
728+ const promise = getOrCreateWishlist ( mockContext , 'cust-1' ) ;
729+ await vi . advanceTimersByTimeAsync ( 1500 ) ;
730+ const result = await promise ;
731+
732+ expect ( result ) . toEqual ( created ) ;
733+ expect ( mockCreateCustomerProductList ) . toHaveBeenCalledTimes ( 1 ) ;
734+ expect ( mockGetCustomerProductLists ) . toHaveBeenCalledTimes ( 2 ) ;
735+ expect ( mockLoggerWarn ) . toHaveBeenCalledWith (
736+ 'Wishlist: createCustomerProductList returned without an id, waiting for index propagation' ,
737+ expect . objectContaining ( { customerId : 'cust-1' } )
738+ ) ;
739+ } finally {
740+ vi . useRealTimers ( ) ;
741+ }
742+ } ) ;
743+ } ) ;
0 commit comments