Skip to content

Commit 0881b91

Browse files
committed
extract mocks to their own directory
1 parent 3275559 commit 0881b91

File tree

5 files changed

+274
-258
lines changed

5 files changed

+274
-258
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Foundation
2+
import Yosemite
3+
import Combine
4+
import WooFoundationCore
5+
import PointOfSale
6+
7+
final class CardPresentPaymentServiceScreenshotMock: CardPresentPaymentFacade {
8+
let paymentEventPublisher: AnyPublisher<CardPresentPaymentEvent, Never>
9+
let readerConnectionStatusPublisher: AnyPublisher<CardPresentPaymentReaderConnectionStatus, Never>
10+
let cardReaderUpdateStatePublisher: AnyPublisher<CardReaderSoftwareUpdateState, Never>
11+
12+
private let paymentEventSubject = PassthroughSubject<CardPresentPaymentEvent, Never>()
13+
14+
init() {
15+
paymentEventPublisher = paymentEventSubject
16+
.receive(on: DispatchQueue.main)
17+
.eraseToAnyPublisher()
18+
19+
// Always return a connected card reader for screenshots
20+
let mockReader = CardPresentPaymentCardReader(
21+
name: "Simulated POS E",
22+
batteryLevel: 0.5,
23+
softwareVersion: "1.00.03.34-SZZZ_Generic_v45-300001"
24+
)
25+
readerConnectionStatusPublisher = Just(.connected(mockReader))
26+
.receive(on: DispatchQueue.main)
27+
.eraseToAnyPublisher()
28+
29+
// No updates needed for screenshots
30+
cardReaderUpdateStatePublisher = Just(.none)
31+
.receive(on: DispatchQueue.main)
32+
.eraseToAnyPublisher()
33+
}
34+
35+
func connectReader(using connectionMethod: CardReaderConnectionMethod) async throws -> CardPresentPaymentReaderConnectionResult {
36+
// Return connected reader immediately
37+
let mockReader = CardPresentPaymentCardReader(
38+
name: "Simulated POS E",
39+
batteryLevel: 0.5,
40+
softwareVersion: "1.00.03.34-SZZZ_Generic_v45-300001"
41+
)
42+
return .connected(mockReader)
43+
}
44+
45+
func disconnectReader() async {
46+
// No-op for screenshots
47+
}
48+
49+
func updateCardReaderSoftware() async throws {
50+
// No-op for screenshots
51+
}
52+
53+
func collectPayment(for order: Order, using connectionMethod: CardReaderConnectionMethod, channel: PaymentChannel) async throws -> CardPresentPaymentResult {
54+
55+
// 1. Validating order
56+
paymentEventSubject.send(.show(eventDetails: .validatingOrder(cancelPayment: {})))
57+
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
58+
59+
// 2. Preparing reader
60+
paymentEventSubject.send(.show(eventDetails: .preparingForPayment(cancelPayment: {})))
61+
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
62+
63+
// 3. Ready to accept card
64+
let inputMethods: Yosemite.CardReaderInput = [.tap, .swipe, .insert]
65+
paymentEventSubject.send(.show(eventDetails: .tapSwipeOrInsertCard(inputMethods: inputMethods, cancelPayment: {})))
66+
67+
try await Task.sleep(nanoseconds: 3_000_000_000) // 3 seconds, give it some time for the screenshot
68+
69+
return .success(CardPresentPaymentTransaction())
70+
}
71+
72+
func cancelPayment() {
73+
// No-op for screenshots
74+
}
75+
76+
func cancelPayment() async throws {
77+
// No-op for screenshots
78+
}
79+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import Foundation
2+
import Yosemite
3+
import WooFoundationCore
4+
import class WooFoundation.CurrencySettings
5+
import class WooFoundationCore.CurrencyFormatter
6+
import struct NetworkingCore.OrderItem
7+
import PointOfSale
8+
9+
/// Mock order service for screenshot tests that returns immediate loaded state
10+
final class POSOrderServiceScreenshotMock: POSOrderServiceProtocol {
11+
private let currency: String
12+
13+
init(currency: String) {
14+
self.currency = currency
15+
}
16+
17+
func syncOrder(cart: POSCart, currency: CurrencyCode) async throws -> Order {
18+
// Create a mock order with totals calculated from the cart
19+
// For screenshot tests with 2 products: $35.00 + $45.00 = $80.00
20+
let orderItems = [
21+
OrderItem(
22+
itemID: 1,
23+
name: "Product 1",
24+
productID: 1,
25+
variationID: 0,
26+
quantity: 1,
27+
price: NSDecimalNumber(string: "35.00"),
28+
sku: nil,
29+
subtotal: "35.00",
30+
subtotalTax: "0.00",
31+
taxClass: "",
32+
taxes: [],
33+
total: "35.00",
34+
totalTax: "0.00",
35+
attributes: [],
36+
addOns: [],
37+
image: nil,
38+
parent: nil,
39+
bundleConfiguration: []
40+
),
41+
OrderItem(
42+
itemID: 2,
43+
name: "Product 2",
44+
productID: 2,
45+
variationID: 0,
46+
quantity: 1,
47+
price: NSDecimalNumber(string: "45.00"),
48+
sku: nil,
49+
subtotal: "45.00",
50+
subtotalTax: "0.00",
51+
taxClass: "",
52+
taxes: [],
53+
total: "45.00",
54+
totalTax: "0.00",
55+
attributes: [],
56+
addOns: [],
57+
image: nil,
58+
parent: nil,
59+
bundleConfiguration: []
60+
)
61+
]
62+
63+
let total = "80.00"
64+
let tax = "0.00"
65+
66+
return Order(siteID: 0,
67+
orderID: 1,
68+
parentID: 0,
69+
customerID: 0,
70+
orderKey: "",
71+
isEditable: true,
72+
needsPayment: true,
73+
needsProcessing: true,
74+
number: "1",
75+
status: .pending,
76+
currency: currency.rawValue,
77+
currencySymbol: "$",
78+
customerNote: nil,
79+
dateCreated: Date(),
80+
dateModified: Date(),
81+
datePaid: nil,
82+
discountTotal: "0.00",
83+
discountTax: "0.00",
84+
shippingTotal: "0.00",
85+
shippingTax: "0.00",
86+
total: total,
87+
totalTax: tax,
88+
paymentMethodID: "",
89+
paymentMethodTitle: "",
90+
paymentURL: nil,
91+
chargeID: nil,
92+
items: orderItems, // Necessary for the card payment flow to be presented in POS
93+
billingAddress: nil,
94+
shippingAddress: nil,
95+
shippingLines: [],
96+
coupons: [],
97+
refunds: [],
98+
fees: [],
99+
taxes: [],
100+
customFields: [],
101+
renewalSubscriptionID: nil,
102+
appliedGiftCards: [],
103+
attributionInfo: nil,
104+
shippingLabels: [],
105+
createdVia: "pos")
106+
}
107+
108+
func updatePOSOrder(orderID: Int64, recipientEmail: String) async throws {}
109+
110+
func markOrderAsCompletedWithCashPayment(order: Order, changeDueAmount: String?) async throws {}
111+
}
112+
113+
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Foundation
2+
import Yosemite
3+
4+
final class PointOfSaleItemServiceScreenshotMock: Yosemite.PointOfSaleItemServiceProtocol {
5+
6+
func providePointOfSaleItems(pageNumber: Int,
7+
fetchStrategy: Yosemite.PointOfSalePurchasableItemFetchStrategy) async throws -> PagedItems<Yosemite.POSItem> {
8+
let port = UserDefaults.standard.integer(forKey: "mocks-port")
9+
let mockResourceUrlHost = "http://localhost:\(port)/"
10+
11+
let mockItems = Self.makeScreenshotMockItems(mockResourceUrlHost: mockResourceUrlHost)
12+
13+
return PagedItems(items: mockItems, hasMorePages: false, totalItems: mockItems.count)
14+
}
15+
16+
func providePointOfSaleVariationItems(for parentProduct: Yosemite.POSVariableParentProduct,
17+
pageNumber: Int,
18+
fetchStrategy: Yosemite.PointOfSalePurchasableItemFetchStrategy) async throws -> PagedItems<Yosemite.POSItem> {
19+
// Not needed for screenshot tests, return empty
20+
return PagedItems(items: [], hasMorePages: false, totalItems: 0)
21+
}
22+
23+
private static func makeScreenshotMockItems(mockResourceUrlHost: String) -> [Yosemite.POSItem] {
24+
let product1 = Yosemite.POSSimpleProduct(
25+
id: UUID(),
26+
name: "Rose Gold Shades",
27+
formattedPrice: "$35.00",
28+
productImageSource: mockResourceUrlHost + "rose-gold-shades",
29+
productID: 1,
30+
price: "35.00",
31+
manageStock: false,
32+
stockQuantity: nil,
33+
stockStatusKey: "instock"
34+
)
35+
36+
let product2 = Yosemite.POSSimpleProduct(
37+
id: UUID(),
38+
name: "Black Coral Shades",
39+
formattedPrice: "$45.00",
40+
productImageSource: mockResourceUrlHost + "black-coral-shades",
41+
productID: 2,
42+
price: "45.00",
43+
manageStock: false,
44+
stockQuantity: nil,
45+
stockStatusKey: "instock"
46+
)
47+
48+
let product3 = Yosemite.POSSimpleProduct(
49+
id: UUID(),
50+
name: "Akoya Pearl Shades",
51+
formattedPrice: "$50.00",
52+
productImageSource: mockResourceUrlHost + "akoya-pearl-shades",
53+
productID: 3,
54+
price: "50.00",
55+
manageStock: true,
56+
stockQuantity: 10,
57+
stockStatusKey: "instock"
58+
)
59+
60+
let product4 = Yosemite.POSSimpleProduct(
61+
id: UUID(),
62+
name: "Malaya Shades",
63+
formattedPrice: "$40.00",
64+
productImageSource: mockResourceUrlHost + "malaya-shades",
65+
productID: 4,
66+
price: "40.00",
67+
manageStock: false,
68+
stockQuantity: nil,
69+
stockStatusKey: "instock"
70+
)
71+
72+
return [
73+
.simpleProduct(product1),
74+
.simpleProduct(product2),
75+
.simpleProduct(product3),
76+
.simpleProduct(product4)
77+
]
78+
}
79+
}

0 commit comments

Comments
 (0)