@@ -135,6 +135,101 @@ struct POSOrderServiceTests {
135135 item. productID == 102 && item. quantity == 5
136136 } ) , " Item for product 102 should be added " )
137137 }
138+
139+ @Test func syncOrder_after_adding_coupon_to_cart_adds_it_to_the_order( ) async throws {
140+ // Given
141+ let orderItems = [ OrderItem . fake ( ) . copy ( itemID: 1 , name: " Item 1 " , productID: 100 , quantity: 1 ) ]
142+ let order = Order . fake ( ) . copy ( siteID: 123 , orderID: 456 , items: orderItems, coupons: [ ] )
143+
144+ // When
145+ let cart = POSCart (
146+ items: [ makePOSCartItem ( productID: 100 , quantity: 1 ) ] ,
147+ coupons: [ . init( code: " SAVE10 " ) ]
148+ )
149+ _ = try await sut. syncOrder ( cart: cart, order: order, currency: . USD)
150+
151+ // Then
152+ let updatedOrderCoupons = try #require( mockOrdersRemote. spyUpdatePOSOrder? . coupons)
153+ #expect( updatedOrderCoupons. count == 1 )
154+ #expect( updatedOrderCoupons. first? . code == " SAVE10 " )
155+ }
156+
157+ @Test func syncOrder_after_removing_coupon_from_cart_removes_it_from_the_order( ) async throws {
158+ // Given
159+ let orderItems = [ OrderItem . fake ( ) . copy ( itemID: 1 , name: " Item 1 " , productID: 100 , quantity: 1 ) ]
160+ let existingCoupons = [ OrderCouponLine . fake ( ) . copy ( code: " SAVE10 " ) ]
161+ let order = Order . fake ( ) . copy ( siteID: 123 , orderID: 456 , items: orderItems, coupons: existingCoupons)
162+
163+ // When
164+ let cart = POSCart (
165+ items: [ makePOSCartItem ( productID: 100 , quantity: 1 ) ] ,
166+ coupons: [ ] // Empty coupons in cart
167+ )
168+ _ = try await sut. syncOrder ( cart: cart, order: order, currency: . USD)
169+
170+ // Then
171+ let updatedOrderCoupons = try #require( mockOrdersRemote. spyUpdatePOSOrder? . coupons)
172+ #expect( updatedOrderCoupons. isEmpty)
173+ }
174+
175+ @Test func syncOrder_with_multiple_coupons_handles_mixed_changes( ) async throws {
176+ // Given
177+ let orderItems = [ OrderItem . fake ( ) . copy ( itemID: 1 , name: " Item 1 " , productID: 100 , quantity: 1 ) ]
178+ let existingCoupons = [
179+ OrderCouponLine . fake ( ) . copy ( code: " REMOVE1 " ) ,
180+ OrderCouponLine . fake ( ) . copy ( code: " KEEP1 " ) ,
181+ OrderCouponLine . fake ( ) . copy ( code: " REMOVE2 " )
182+ ]
183+ let order = Order . fake ( ) . copy ( siteID: 123 , orderID: 456 , items: orderItems, coupons: existingCoupons)
184+
185+ // When
186+ let cart = POSCart (
187+ items: [ makePOSCartItem ( productID: 100 , quantity: 1 ) ] ,
188+ coupons: [
189+ . init( code: " KEEP1 " ) ,
190+ . init( code: " NEW1 " ) ,
191+ . init( code: " NEW2 " )
192+ ]
193+ )
194+ _ = try await sut. syncOrder ( cart: cart, order: order, currency: . USD)
195+
196+ // Then
197+ let updatedOrderCoupons = try #require( mockOrdersRemote. spyUpdatePOSOrder? . coupons)
198+
199+ // Verify kept coupon
200+ #expect( updatedOrderCoupons. contains ( where: { $0. code == " KEEP1 " } ) )
201+
202+ // Verify removed coupons
203+ #expect( !updatedOrderCoupons. contains ( where: { $0. code == " REMOVE1 " } ) )
204+ #expect( !updatedOrderCoupons. contains ( where: { $0. code == " REMOVE2 " } ) )
205+
206+ // Verify new coupons
207+ #expect( updatedOrderCoupons. contains ( where: { $0. code == " NEW1 " } ) )
208+ #expect( updatedOrderCoupons. contains ( where: { $0. code == " NEW2 " } ) )
209+
210+ // Verify total count
211+ #expect( updatedOrderCoupons. count == 3 )
212+ }
213+
214+ @Test func syncOrder_with_unchanged_coupons_preserves_existing_coupon_data( ) async throws {
215+ // Given
216+ let orderItems = [ OrderItem . fake ( ) . copy ( itemID: 1 , name: " Item 1 " , productID: 100 , quantity: 1 ) ]
217+ let existingCoupon = OrderCouponLine . fake ( ) . copy ( code: " KEEP1 " , discount: " 10.00 " )
218+ let order = Order . fake ( ) . copy ( siteID: 123 , orderID: 456 , items: orderItems, coupons: [ existingCoupon] )
219+
220+ // When
221+ let cart = POSCart (
222+ items: [ makePOSCartItem ( productID: 100 , quantity: 1 ) ] ,
223+ coupons: [ . init( code: " KEEP1 " ) ] // Same coupon in cart
224+ )
225+ _ = try await sut. syncOrder ( cart: cart, order: order, currency: . USD)
226+
227+ // Then
228+ let updatedOrderCoupons = try #require( mockOrdersRemote. spyUpdatePOSOrder? . coupons)
229+ #expect( updatedOrderCoupons. count == 1 )
230+ #expect( updatedOrderCoupons. first? . code == " KEEP1 " )
231+ #expect( updatedOrderCoupons. first? . discount == " 10.00 " , " Existing coupon data should be preserved " )
232+ }
138233}
139234
140235private func makePOSCartItem(
0 commit comments