@@ -455,9 +455,14 @@ struct BookingStoreTests {
455455
456456 @Test func searchBookings_returns_bookings_on_success( ) async throws {
457457 // Given
458- let booking1 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 123 )
459- let booking2 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 456 )
458+ let booking1 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 123 , orderID : 1 )
459+ let booking2 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 456 , orderID : 2 )
460460 remote. whenLoadingAllBookings ( thenReturn: . success( [ booking1, booking2] ) )
461+
462+ let order1 = Order . fake ( ) . copy ( orderID: 1 )
463+ let order2 = Order . fake ( ) . copy ( orderID: 2 )
464+ ordersRemote. whenLoadingOrders ( thenReturn: . success( [ order1, order2] ) )
465+
461466 let store = BookingStore ( dispatcher: Dispatcher ( ) ,
462467 storageManager: storageManager,
463468 network: network,
@@ -510,8 +515,12 @@ struct BookingStoreTests {
510515
511516 @Test func searchBookings_does_not_save_results_to_storage( ) async throws {
512517 // Given
513- let booking = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 123 )
518+ let booking = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 123 , orderID : 1 )
514519 remote. whenLoadingAllBookings ( thenReturn: . success( [ booking] ) )
520+
521+ let order = Order . fake ( ) . copy ( orderID: 1 )
522+ ordersRemote. whenLoadingOrders ( thenReturn: . success( [ order] ) )
523+
515524 let store = BookingStore ( dispatcher: Dispatcher ( ) ,
516525 storageManager: storageManager,
517526 network: network,
@@ -535,6 +544,80 @@ struct BookingStoreTests {
535544 #expect( storedBookingCount == 0 )
536545 }
537546
547+ @Test func searchBookings_fetches_orders_for_bookings( ) async throws {
548+ // Given
549+ let booking1 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 123 , orderID: 10 )
550+ let booking2 = Booking . fake ( ) . copy ( siteID: sampleSiteID, bookingID: 456 , orderID: 20 )
551+ remote. whenLoadingAllBookings ( thenReturn: . success( [ booking1, booking2] ) )
552+
553+ let order1 = Order . fake ( ) . copy ( orderID: 10 )
554+ let order2 = Order . fake ( ) . copy ( orderID: 20 )
555+ ordersRemote. whenLoadingOrders ( thenReturn: . success( [ order1, order2] ) )
556+
557+ let store = BookingStore ( dispatcher: Dispatcher ( ) ,
558+ storageManager: storageManager,
559+ network: network,
560+ remote: remote,
561+ ordersRemote: ordersRemote)
562+
563+ // When
564+ let result = await withCheckedContinuation { continuation in
565+ store. onAction ( BookingAction . searchBookings ( siteID: sampleSiteID,
566+ searchQuery: " test " ,
567+ pageNumber: defaultPageNumber,
568+ pageSize: defaultPageSize,
569+ onCompletion: { result in
570+ continuation. resume ( returning: result)
571+ } ) )
572+ }
573+
574+ // Then
575+ #expect( result. isSuccess)
576+ #expect( ordersRemote. invokedLoadOrders)
577+ #expect( ordersRemote. invokedLoadOrdersParameters? . orderIDs == [ 10 , 20 ] )
578+ }
579+
580+ @Test func searchBookings_returns_bookings_with_orderInfo_when_orders_are_available( ) async throws {
581+ // Given
582+ let productID : Int64 = 100
583+ let booking = Booking . fake ( ) . copy (
584+ siteID: sampleSiteID,
585+ bookingID: 123 ,
586+ orderID: 1 ,
587+ productID: productID
588+ )
589+ remote. whenLoadingAllBookings ( thenReturn: . success( [ booking] ) )
590+
591+ let orderItem = OrderItem . fake ( ) . copy ( itemID: 1 , name: " Test Product " , productID: productID)
592+ let order = Order . fake ( ) . copy ( orderID: 1 , status: . processing, items: [ orderItem] )
593+ ordersRemote. whenLoadingOrders ( thenReturn: . success( [ order] ) )
594+
595+ let store = BookingStore ( dispatcher: Dispatcher ( ) ,
596+ storageManager: storageManager,
597+ network: network,
598+ remote: remote,
599+ ordersRemote: ordersRemote)
600+
601+ // When
602+ let result = await withCheckedContinuation { continuation in
603+ store. onAction ( BookingAction . searchBookings ( siteID: sampleSiteID,
604+ searchQuery: " test " ,
605+ pageNumber: defaultPageNumber,
606+ pageSize: defaultPageSize,
607+ onCompletion: { result in
608+ continuation. resume ( returning: result)
609+ } ) )
610+ }
611+
612+ // Then
613+ let bookings = try result. get ( )
614+ #expect( bookings. count == 1 )
615+ let returnedBooking = try #require( bookings. first)
616+ let orderInfo = try #require( returnedBooking. orderInfo)
617+ #expect( orderInfo. productInfo? . name == " Test Product " )
618+ #expect( orderInfo. statusKey == " processing " )
619+ }
620+
538621 // MARK: - orderInfo Storage Tests
539622
540623 @Test func synchronizeBookings_stores_complete_orderInfo_with_all_nested_properties( ) async throws {
@@ -663,144 +746,6 @@ struct BookingStoreTests {
663746 #expect( customerInfo. billingFirstName == " Test " )
664747 #expect( customerInfo. billingLastName == " User " )
665748 }
666-
667- @Test func synchronizeBookings_falls_back_to_cached_product_when_order_cannot_be_fetched( ) async throws {
668- // Given
669- let productID : Int64 = 200
670- let booking = Booking . fake ( ) . copy (
671- siteID: sampleSiteID,
672- bookingID: 999 ,
673- orderID: 0 , // No valid order
674- productID: productID,
675- statusKey: " pending "
676- )
677- remote. whenLoadingAllBookings ( thenReturn: . success( [ booking] ) )
678-
679- // Store a cached product in storage
680- let product = Product . fake ( ) . copy ( siteID: sampleSiteID, productID: productID, name: " Cached Product " )
681- storeProduct ( product)
682-
683- // Orders remote returns empty (order not found)
684- ordersRemote. whenLoadingOrders ( thenReturn: . success( [ ] ) )
685-
686- let store = BookingStore ( dispatcher: Dispatcher ( ) ,
687- storageManager: storageManager,
688- network: network,
689- remote: remote,
690- ordersRemote: ordersRemote)
691-
692- // When
693- let result = await withCheckedContinuation { continuation in
694- store. onAction ( BookingAction . synchronizeBookings ( siteID: sampleSiteID,
695- pageNumber: defaultPageNumber,
696- pageSize: defaultPageSize,
697- onCompletion: { result in
698- continuation. resume ( returning: result)
699- } ) )
700- }
701-
702- // Then
703- #expect( result. isSuccess)
704- let storedBooking = try #require( viewStorage. loadBooking ( siteID: sampleSiteID, bookingID: 999 ) )
705- let orderInfo = try #require( storedBooking. orderInfo)
706-
707- // Verify orderInfo has product info from cached product
708- let productInfo = try #require( orderInfo. productInfo)
709- #expect( productInfo. name == " Cached Product " )
710-
711- // Verify status is from booking
712- #expect( orderInfo. statusKey == " pending " )
713-
714- // Verify customer and payment info are not present
715- #expect( orderInfo. customerInfo == nil )
716- #expect( orderInfo. paymentInfo == nil )
717- }
718-
719- @Test func synchronizeBooking_falls_back_to_cached_product_when_order_cannot_be_fetched( ) async throws {
720- // Given
721- let productID : Int64 = 300
722- let booking = Booking . fake ( ) . copy (
723- siteID: sampleSiteID,
724- bookingID: 888 ,
725- orderID: 0 ,
726- productID: productID,
727- statusKey: " confirmed "
728- )
729- remote. whenLoadingBooking ( thenReturn: . success( booking) )
730-
731- // Store a cached product
732- let product = Product . fake ( ) . copy ( siteID: sampleSiteID, productID: productID, name: " Spa Treatment " )
733- storeProduct ( product)
734-
735- // Orders remote returns empty
736- ordersRemote. whenLoadingOrders ( thenReturn: . success( [ ] ) )
737-
738- let store = BookingStore ( dispatcher: Dispatcher ( ) ,
739- storageManager: storageManager,
740- network: network,
741- remote: remote,
742- ordersRemote: ordersRemote)
743-
744- // When
745- let result = await withCheckedContinuation { continuation in
746- store. onAction (
747- BookingAction . synchronizeBooking (
748- siteID: sampleSiteID,
749- bookingID: 888
750- ) { result in
751- continuation. resume ( returning: result)
752- }
753- )
754- }
755-
756- // Then
757- #expect( result. isSuccess)
758- let storedBooking = try #require( viewStorage. loadBooking ( siteID: sampleSiteID, bookingID: 888 ) )
759- let orderInfo = try #require( storedBooking. orderInfo)
760-
761- // Verify fallback behavior
762- let productInfo = try #require( orderInfo. productInfo)
763- #expect( productInfo. name == " Spa Treatment " )
764- #expect( orderInfo. statusKey == " confirmed " )
765- #expect( orderInfo. customerInfo == nil )
766- #expect( orderInfo. paymentInfo == nil )
767- }
768-
769- @Test func synchronizeBookings_has_no_orderInfo_when_order_and_product_not_found( ) async throws {
770- // Given
771- let booking = Booking . fake ( ) . copy (
772- siteID: sampleSiteID,
773- bookingID: 777 ,
774- orderID: 0 ,
775- productID: 999 , // Product doesn't exist in cache
776- statusKey: " pending "
777- )
778- remote. whenLoadingAllBookings ( thenReturn: . success( [ booking] ) )
779- ordersRemote. whenLoadingOrders ( thenReturn: . success( [ ] ) )
780-
781- let store = BookingStore ( dispatcher: Dispatcher ( ) ,
782- storageManager: storageManager,
783- network: network,
784- remote: remote,
785- ordersRemote: ordersRemote)
786-
787- // When
788- let result = await withCheckedContinuation { continuation in
789- store. onAction ( BookingAction . synchronizeBookings ( siteID: sampleSiteID,
790- pageNumber: defaultPageNumber,
791- pageSize: defaultPageSize,
792- onCompletion: { result in
793- continuation. resume ( returning: result)
794- } ) )
795- }
796-
797- // Then
798- #expect( result. isSuccess)
799- let storedBooking = try #require( viewStorage. loadBooking ( siteID: sampleSiteID, bookingID: 777 ) )
800-
801- // Verify no orderInfo is created when neither order nor product is available
802- #expect( storedBooking. orderInfo == nil )
803- }
804749}
805750
806751private extension BookingStoreTests {
0 commit comments