import Foundation import Testing @testable import PediFoods private func makeItem(id: String, quantity: Int, unitPrice: Double, addons: [CartItemAddonState] = []) -> CartItemState { CartItemState(id: id, productId: "p-\(id)", storeId: "s1", name: "Item \(id)", addons: addons, quantity: quantity, unitPrice: unitPrice) } @Test("totalItems sums quantities across every item") func totalItemsSumsQuantities() { var cart = CartState() cart.items = [makeItem(id: "1", quantity: 2, unitPrice: 10), makeItem(id: "2", quantity: 3, unitPrice: 5)] #expect(cart.totalItems == 5) } @Test("recalculateTotal sums quantity times unitPrice across every item") func recalculateTotalSumsLineItems() { var cart = CartState() cart.items = [makeItem(id: "1", quantity: 2, unitPrice: 10), makeItem(id: "2", quantity: 1, unitPrice: 5)] cart.recalculateTotal() #expect(cart.total == 25) } @Test("toOrderItemsPayload drops zero-quantity addons and nils out empty choices") func toOrderItemsPayloadDropsZeroQuantityAddonsAndEmptyChoices() { var cart = CartState() let item = CartItemState( id: "1", productId: "p1", storeId: "s1", name: "Pizza", choices: [], addons: [ CartItemAddonState(id: "a1", name: "Cheese", quantity: 1, unitPrice: 2), CartItemAddonState(id: "a2", name: "Removed", quantity: 0, unitPrice: 3) ], quantity: 1, unitPrice: 20 ) cart.items = [item] let payload = cart.toOrderItemsPayload() #expect(payload.count == 1) #expect(payload[0].addons.count == 1) #expect(payload[0].addons[0].addonId == "a1") #expect(payload[0].choices == nil) } /// `CartState`'s mutating methods persist through `SessionStateStore`, /// which shares one static `UserDefaults` swap point. `.serialized` only /// orders tests *within* a suite, not across two separate suite types - /// so these live as an extension of `SessionStateStorePersistenceTests` /// (defined in SessionStateStoreTests.swift) rather than their own /// `@Suite`, putting them in the same serialization domain instead of a /// second one that could still race the first. extension SessionStateStorePersistenceTests { @Test("add appends a new item and recalculates the total") func addAppendsNewItem() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 2, unitPrice: 10)) #expect(cart.items.count == 1) #expect(cart.total == 20) } } @Test("add increments the quantity of an already-present item instead of duplicating it") func addIncrementsExistingItem() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.add(item: makeItem(id: "1", quantity: 2, unitPrice: 10)) #expect(cart.items.count == 1) #expect(cart.items[0].quantity == 3) #expect(cart.total == 30) } } @Test("set removes the item when its quantity is zero or less") func setRemovesItemAtZeroQuantity() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.set(item: makeItem(id: "1", quantity: 0, unitPrice: 10)) #expect(cart.items.isEmpty) } } @Test("set clears storeId/storeName once the cart becomes empty") func setClearsStoreWhenCartBecomesEmpty() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.set(item: makeItem(id: "1", quantity: 0, unitPrice: 10)) #expect(cart.storeId == nil) #expect(cart.storeName == nil) } } @Test("increment increases an existing item's quantity by one") func incrementIncreasesQuantity() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.increment(itemId: "1") #expect(cart.items[0].quantity == 2) #expect(cart.total == 20) } } @Test("decrement removes the item once its quantity reaches zero") func decrementRemovesItemAtZero() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.decrement(itemId: "1") #expect(cart.items.isEmpty) #expect(cart.total == 0) } } @Test("clear empties the cart and resets the total") func clearEmptiesCart() { withIsolatedDefaults { var cart = CartState(storeId: "s1", storeName: "Loja A") cart.add(item: makeItem(id: "1", quantity: 1, unitPrice: 10)) cart.clear() #expect(cart.items.isEmpty) #expect(cart.storeId == nil) #expect(cart.total == 0) } } }