@@ -53,26 +53,57 @@ struct PointOfSaleOrderControllerTests {
5353 #expect( mockOrderService. syncOrderWasCalled == false )
5454 }
5555
56- @Test func syncOrder_when_already_syncing_doesnt_call_orderService( ) async throws {
56+ @Test @ MainActor func syncOrder_when_already_syncing_doesnt_call_orderService( ) async throws {
5757 // Given
5858 let sut = PointOfSaleOrderController ( orderService: mockOrderService,
5959 receiptSender: mockReceiptSender,
6060 currencySettingsProvider: MockCurrencySettingsProvider ( ) ,
6161 analytics: MockPOSAnalytics ( ) )
62- mockOrderService. simulateSyncing = true
63- Task {
62+
63+ // Block the sync so it doesn't complete until we manually resume it
64+ mockOrderService. blockNextSync ( )
65+
66+ // Start the first sync in a detached task so it runs concurrently
67+ let firstSyncTask = Task . detached {
6468 await sut. syncOrder ( for: Cart ( purchasableItems: [ makeItem ( quantity: 1 ) ] ) , retryHandler: { } )
6569 }
66- try await Task . sleep ( nanoseconds: UInt64 ( 100 * Double( NSEC_PER_MSEC) ) )
70+
71+ // Wait for the order state to actually become syncing
72+ await withCheckedContinuation { ( continuation: CheckedContinuation < Void , Never > ) in
73+ @Sendable func observeOrderState( ) {
74+ withObservationTracking {
75+ _ = sut. orderState
76+ } onChange: {
77+ Task { @MainActor in
78+ if sut. orderState. isSyncing {
79+ continuation. resume ( )
80+ } else {
81+ observeOrderState ( )
82+ }
83+ }
84+ }
85+ }
86+ observeOrderState ( )
87+ }
88+
89+ // Verify the state is actually syncing
90+ #expect( sut. orderState. isSyncing == true )
91+ #expect( mockOrderService. syncOrderWasCalled == true )
92+
93+ // Reset the flag after confirming the sync has started
6794 mockOrderService. syncOrderWasCalled = false
6895
69- // When
96+ // When - try to sync while the first sync is still in progress
7097 await sut. syncOrder ( for: Cart ( purchasableItems: [ makeItem ( quantity: 2 ) ,
7198 makeItem ( quantity: 5 ) ] ) ,
7299 retryHandler: { } )
73100
74- // Then
101+ // Then - the second sync should have been skipped
75102 #expect( mockOrderService. syncOrderWasCalled == false )
103+
104+ // Cleanup - allow the first sync to complete
105+ mockOrderService. resumeBlockedSync ( )
106+ _ = await firstSyncTask. result
76107 }
77108
78109 @Test func syncOrder_with_no_previous_order_calls_orderService( ) async throws {
0 commit comments