Skip to content

Commit f597572

Browse files
committed
Add PointOfSaleOrderControllerTests to confirm CouponsError handling
1 parent 9b70b7b commit f597572

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

WooCommerce/WooCommerceTests/POS/Controllers/PointOfSaleOrderControllerTests.swift

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import struct Yosemite.OrderCouponLine
99
import enum Yosemite.OrderAction
1010
import class WooFoundation.CurrencySettings
1111
import protocol WooFoundation.Analytics
12+
import enum Networking.DotcomError
13+
import enum Networking.NetworkError
1214

1315
struct PointOfSaleOrderControllerTests {
1416
let mockOrderService = MockPOSOrderService()
@@ -435,6 +437,93 @@ struct PointOfSaleOrderControllerTests {
435437
#expect(mockOrderService.syncOrderWasCalled == true)
436438
}
437439

440+
@available(iOS 17.0, *)
441+
@Test func syncOrder_when_orderService_fails_with_couponsError_then_sets_invalidCoupon_error() async throws {
442+
// Given
443+
let sut = PointOfSaleOrderController(orderService: mockOrderService,
444+
receiptService: mockReceiptService)
445+
let errorMessage = "Invalid coupon code"
446+
mockOrderService.errorToReturn = DotcomError.unknown(code: "woocommerce_rest_invalid_coupon", message: errorMessage)
447+
448+
var orderStates: [PointOfSaleInternalOrderState] = [sut.orderState]
449+
var orderStateAppendTask: Task<Void, Never>? = nil
450+
await confirmation(expectedCount: 2) { confirmation in
451+
@Sendable func observeOrderState() {
452+
withObservationTracking {
453+
_ = sut.orderState
454+
} onChange: {
455+
orderStateAppendTask = Task { @MainActor in
456+
orderStates.append(sut.orderState)
457+
}
458+
confirmation()
459+
observeOrderState()
460+
}
461+
}
462+
observeOrderState()
463+
464+
// When
465+
await sut.syncOrder(for: .init(items: [makeItem()],
466+
coupons: [.init(id: UUID(), code: "INVALID")]),
467+
retryHandler: {})
468+
}
469+
470+
await orderStateAppendTask?.value
471+
472+
// Then
473+
#expect(orderStates == [
474+
.idle,
475+
.syncing,
476+
.error(.invalidCoupon(errorMessage), {})
477+
])
478+
}
479+
480+
@available(iOS 17.0, *)
481+
@Test func syncOrder_when_orderService_fails_with_networkError_containing_couponsError_then_sets_invalidCoupon_error() async throws {
482+
// Given
483+
let sut = PointOfSaleOrderController(orderService: mockOrderService,
484+
receiptService: mockReceiptService)
485+
let errorMessage = "Coupon INVALID does not exist"
486+
let errorJSON = """
487+
{
488+
"code": "woocommerce_rest_invalid_coupon",
489+
"message": "\(errorMessage)"
490+
}
491+
"""
492+
let errorData = errorJSON.data(using: .utf8)!
493+
mockOrderService.errorToReturn = NetworkError.unacceptableStatusCode(statusCode: 400, response: errorData)
494+
495+
var orderStates: [PointOfSaleInternalOrderState] = [sut.orderState]
496+
var orderStateAppendTask: Task<Void, Never>? = nil
497+
await confirmation(expectedCount: 2) { confirmation in
498+
@Sendable func observeOrderState() {
499+
withObservationTracking {
500+
_ = sut.orderState
501+
} onChange: {
502+
orderStateAppendTask = Task { @MainActor in
503+
orderStates.append(sut.orderState)
504+
}
505+
confirmation()
506+
observeOrderState()
507+
}
508+
}
509+
observeOrderState()
510+
511+
// When
512+
await sut.syncOrder(for: .init(items: [makeItem()],
513+
coupons: [.init(id: UUID(), code: "INVALID")]),
514+
retryHandler: {})
515+
}
516+
517+
await orderStateAppendTask?.value
518+
519+
// Then
520+
#expect(orderStates == [
521+
.idle,
522+
.syncing,
523+
.error(.invalidCoupon(errorMessage), {})
524+
])
525+
}
526+
438527
struct AnalyticsTests {
439528
private let analytics: WooAnalytics
440529
private let analyticsProvider = MockAnalyticsProvider()

WooCommerce/WooCommerceTests/POS/Mocks/MockPOSOrderService.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import WooFoundation
55
class MockPOSOrderService: POSOrderServiceProtocol {
66
var simulateSyncing = false
77
var orderToReturn: Order?
8+
var errorToReturn: Error?
89

910
var syncOrderWasCalled = false
1011
var updateOrderWasCalled = false
@@ -20,6 +21,10 @@ class MockPOSOrderService: POSOrderServiceProtocol {
2021
try await Task.sleep(nanoseconds: UInt64(1 * Double(NSEC_PER_SEC)))
2122
}
2223

24+
if let error = errorToReturn {
25+
throw error
26+
}
27+
2328
guard let order = orderToReturn else {
2429
throw MockPOSOrderServiceError.noOrderToReturn
2530
}

0 commit comments

Comments
 (0)