From 14504eb9fe6a7571cc83bd977988c6dccc41f522 Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Wed, 22 Oct 2025 15:44:39 +0300 Subject: [PATCH 1/7] Move CIABEligibilityChecker to Yosemite --- .../Tools}/CIAB/CIABAffectedFeature.swift | 3 +- .../Tools/CIAB/CIABEligibilityChecker.swift | 46 +++++++++++++++++++ .../CIAB/CIABEligibilityCheckerProtocol.swift | 4 +- .../Classes/CIAB/CIABEligibilityChecker.swift | 45 ++---------------- .../POS/POSTabVisibilityChecker.swift | 2 + .../WooCommerce.xcodeproj/project.pbxproj | 8 ---- 6 files changed, 53 insertions(+), 55 deletions(-) rename {WooCommerce/Classes => Modules/Sources/Yosemite/Tools}/CIAB/CIABAffectedFeature.swift (87%) create mode 100644 Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift rename {WooCommerce/Classes => Modules/Sources/Yosemite/Tools}/CIAB/CIABEligibilityCheckerProtocol.swift (66%) diff --git a/WooCommerce/Classes/CIAB/CIABAffectedFeature.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift similarity index 87% rename from WooCommerce/Classes/CIAB/CIABAffectedFeature.swift rename to Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift index 0d3a55059df..66b010956dc 100644 --- a/WooCommerce/Classes/CIAB/CIABAffectedFeature.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift @@ -1,8 +1,7 @@ /// Describes the feature set affected by CIAB sites /// By the moment of introduction the features aren't supported by CIAB sites -/// periphery: ignore:all - Used through `.allCases` -enum CIABAffectedFeature: CaseIterable { +public enum CIABAffectedFeature: CaseIterable { case blaze case payments case splitShipments diff --git a/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift new file mode 100644 index 00000000000..85c97d09a51 --- /dev/null +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift @@ -0,0 +1,46 @@ +import Foundation + +public final class CIABEligibilityChecker { + public let stores: StoresManager + + public init(stores: StoresManager) { + self.stores = stores + } +} + +extension CIABEligibilityChecker: CIABEligibilityCheckerProtocol { + public var isCurrentSiteCIAB: Bool { + guard let currentSite = stores.sessionManager.defaultSite else { + return false + } + return isSiteCIAB(currentSite) + } + + public func isSiteCIAB(_ site: Site) -> Bool { + return site.isCIAB + } + + public func isFeatureSupportedForCurrentSite(_ feature: CIABAffectedFeature) -> Bool { + return !isCurrentSiteCIAB || !CIABAffectedFeature.unsupportedFeatures.contains(feature) + } + + public func isFeatureSupported( + _ feature: CIABAffectedFeature, + for site: Site + ) -> Bool { + return !isSiteCIAB(site) || !CIABAffectedFeature.unsupportedFeatures.contains(feature) + } +} + +// MARK: - Site checks + +private extension Site { + var isCIAB: Bool { + return isGarden && gardenName == GardenName.commerce.rawValue + } +} + +private enum GardenName: String { + /// Garden name for CIAB sites + case commerce +} diff --git a/WooCommerce/Classes/CIAB/CIABEligibilityCheckerProtocol.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift similarity index 66% rename from WooCommerce/Classes/CIAB/CIABEligibilityCheckerProtocol.swift rename to Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift index 6c7cd0aac92..2bd23952b90 100644 --- a/WooCommerce/Classes/CIAB/CIABEligibilityCheckerProtocol.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift @@ -1,8 +1,6 @@ import Foundation -import Yosemite -/// periphery: ignore - Will be used in upcoming changes for app feature gating -protocol CIABEligibilityCheckerProtocol { +public protocol CIABEligibilityCheckerProtocol { var isCurrentSiteCIAB: Bool { get } func isSiteCIAB(_ site: Site) -> Bool diff --git a/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift b/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift index b3627647e1c..3d88a264705 100644 --- a/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift +++ b/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift @@ -3,47 +3,8 @@ import Foundation import Yosemite -final class CIABEligibilityChecker { - private let stores: StoresManager - - init(stores: StoresManager = ServiceLocator.stores) { - self.stores = stores - } -} - -extension CIABEligibilityChecker: CIABEligibilityCheckerProtocol { - var isCurrentSiteCIAB: Bool { - guard let currentSite = stores.sessionManager.defaultSite else { - return false - } - return isSiteCIAB(currentSite) - } - - func isSiteCIAB(_ site: Site) -> Bool { - return site.isCIAB - } - - func isFeatureSupportedForCurrentSite(_ feature: CIABAffectedFeature) -> Bool { - return !isCurrentSiteCIAB || !CIABAffectedFeature.unsupportedFeatures.contains(feature) +extension CIABEligibilityChecker { + convenience init() { + self.init(stores: ServiceLocator.stores) } - - func isFeatureSupported( - _ feature: CIABAffectedFeature, - for site: Site - ) -> Bool { - return !isSiteCIAB(site) || !CIABAffectedFeature.unsupportedFeatures.contains(feature) - } -} - -// MARK: - Site checks - -private extension Site { - var isCIAB: Bool { - return isGarden && gardenName == GardenName.commerce.rawValue - } -} - -private enum GardenName: String { - /// Garden name for CIAB sites - case commerce } diff --git a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabVisibilityChecker.swift b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabVisibilityChecker.swift index a50687abd24..ec913be9076 100644 --- a/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabVisibilityChecker.swift +++ b/WooCommerce/Classes/ViewRelated/Dashboard/Settings/POS/POSTabVisibilityChecker.swift @@ -11,6 +11,8 @@ import protocol Yosemite.StoresManager import class Yosemite.POSEligibilityService import enum Yosemite.FeatureFlagAction import class Yosemite.SiteAddress +import protocol Yosemite.CIABEligibilityCheckerProtocol +import class Yosemite.CIABEligibilityChecker final class POSTabVisibilityChecker: POSTabVisibilityCheckerProtocol { private let site: Site diff --git a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj index 75f6968ef19..a88545a409e 100644 --- a/WooCommerce/WooCommerce.xcodeproj/project.pbxproj +++ b/WooCommerce/WooCommerce.xcodeproj/project.pbxproj @@ -1012,9 +1012,7 @@ 2DB8916B2E27F6D90001B175 /* OrderListCellViewModel+Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB8916A2E27F6CE0001B175 /* OrderListCellViewModel+Localizations.swift */; }; 2DB8916E2E27F7840001B175 /* OrderListCellViewModel+Localizations.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB8916A2E27F6CE0001B175 /* OrderListCellViewModel+Localizations.swift */; }; 2DCB54FA2E6AE8E100621F90 /* CIABEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */; }; - 2DCB54FC2E6AFE6A00621F90 /* CIABAffectedFeature.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */; }; 2DE9DDFB2E6EF4A500155408 /* MockCIABEligibilityChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE9DDFA2E6EF4A300155408 /* MockCIABEligibilityChecker.swift */; }; - 2DE9DDFD2E6EF53C00155408 /* CIABEligibilityCheckerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */; }; 2DF0D1BC2E2907C100F8995C /* MarkOrderAsReadUseCase+Woo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB88DA32E27DD790001B175 /* MarkOrderAsReadUseCase+Woo.swift */; }; 310D1B482734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310D1B472734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift */; }; 311237EE2714DA240033C44E /* CardPresentModalDisplayMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311237ED2714DA240033C44E /* CardPresentModalDisplayMessage.swift */; }; @@ -3893,9 +3891,7 @@ 2DB891682E27F61C0001B175 /* OrderListCellViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderListCellViewModel.swift; sourceTree = ""; }; 2DB8916A2E27F6CE0001B175 /* OrderListCellViewModel+Localizations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderListCellViewModel+Localizations.swift"; sourceTree = ""; }; 2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABEligibilityChecker.swift; sourceTree = ""; }; - 2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABAffectedFeature.swift; sourceTree = ""; }; 2DE9DDFA2E6EF4A300155408 /* MockCIABEligibilityChecker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCIABEligibilityChecker.swift; sourceTree = ""; }; - 2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CIABEligibilityCheckerProtocol.swift; sourceTree = ""; }; 310D1B472734919E001D55B4 /* InPersonPaymentsLiveSiteInTestModeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InPersonPaymentsLiveSiteInTestModeView.swift; sourceTree = ""; }; 311237ED2714DA240033C44E /* CardPresentModalDisplayMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalDisplayMessage.swift; sourceTree = ""; }; 311D21E7264AEDB900102316 /* CardPresentModalScanningForReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CardPresentModalScanningForReader.swift; sourceTree = ""; }; @@ -7936,8 +7932,6 @@ 2DCB54F82E6AE8C900621F90 /* CIAB */ = { isa = PBXGroup; children = ( - 2DE9DDFC2E6EF52E00155408 /* CIABEligibilityCheckerProtocol.swift */, - 2DCB54FB2E6AFE6900621F90 /* CIABAffectedFeature.swift */, 2DCB54F92E6AE8D800621F90 /* CIABEligibilityChecker.swift */, ); path = CIAB; @@ -14149,7 +14143,6 @@ CE7F778B2C074D2500C89F4E /* EditableOrderShippingLineViewModel.swift in Sources */, B95A45E92A77AE2C0073A91F /* CustomerSelectorViewModel.swift in Sources */, 024DF3072372C18D006658FE /* AztecUIConfigurator.swift in Sources */, - 2DCB54FC2E6AFE6A00621F90 /* CIABAffectedFeature.swift in Sources */, EE1B07F32C81CB4B006D9769 /* BlazeLocalNotificationScheduler.swift in Sources */, DE02ABBE2B578D0E008E0AC4 /* CreditCardType.swift in Sources */, 020BE74823B05CF2007FE54C /* ProductInventoryEditableData.swift in Sources */, @@ -14915,7 +14908,6 @@ B626C71B287659D60083820C /* CustomFieldsListView.swift in Sources */, 02ECD1E624FFB4E900735BE5 /* ProductFactory.swift in Sources */, 260520F42B87BA23005D5D59 /* WooAnalyticsEvent+ConnectivityTool.swift in Sources */, - 2DE9DDFD2E6EF53C00155408 /* CIABEligibilityCheckerProtocol.swift in Sources */, 579CDEFF274D7E7900E8903D /* StoreStatsUsageTracksEventEmitter.swift in Sources */, CEDBDA472B6BEF2E002047D4 /* AnalyticsWebReport.swift in Sources */, 314DC4BD268D158F00444C9E /* CardReaderSettingsKnownReadersProvider.swift in Sources */, From 6d4a5d23ec7c07f17c45c0f5aaf03029aff9567d Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Wed, 22 Oct 2025 16:11:05 +0300 Subject: [PATCH 2/7] Inject CIABEligibilityChecker into OrderCardPresentPaymentEligibilityStore --- ...erCardPresentPaymentEligibilityStore.swift | 20 ++++++++++++++++++- .../Classes/Yosemite/AuthenticatedState.swift | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift index 3ceec4f23e7..ca4afc0cc38 100644 --- a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift +++ b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift @@ -1,9 +1,27 @@ - import Foundation +import protocol Storage.StorageManagerType +import protocol NetworkingCore.Network /// Determines whether an order is eligible for card present payment or not /// public final class OrderCardPresentPaymentEligibilityStore: Store { + private let stores: () -> StoresManager + private lazy var siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol = CIABEligibilityChecker(stores: stores()) + + public init( + dispatcher: Dispatcher, + storageManager: StorageManagerType, + network: Network, + stores: @escaping () -> StoresManager + ) { + self.stores = stores + super.init( + dispatcher: dispatcher, + storageManager: storageManager, + network: network + ) + } + /// Registers for supported Actions. /// override public func registerSupportedActions(in dispatcher: Dispatcher) { diff --git a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift index 8efc471b60a..4dadba694a0 100644 --- a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift +++ b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift @@ -75,7 +75,7 @@ class AuthenticatedState: StoresManagerState { MediaStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationCountStore(dispatcher: dispatcher, storageManager: storageManager, fileStorage: PListFileStorage()), - OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network), + OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network, stores: { ServiceLocator.stores }), OrderNoteStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStatusStore(dispatcher: dispatcher, storageManager: storageManager, network: network), From 4d97b8b9bfd5b7e4abbed647b2dc0023e77c4ff7 Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Wed, 22 Oct 2025 16:23:14 +0300 Subject: [PATCH 3/7] Use CIAB eligibility checker in OrderCardPresentPaymentEligibilityStore --- ...erCardPresentPaymentEligibilityStore.swift | 20 ++++++++++++++++++- .../Tools/CIAB/CIABAffectedFeature.swift | 1 + 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift index ca4afc0cc38..44c5cce74cb 100644 --- a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift +++ b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift @@ -53,11 +53,27 @@ private extension OrderCardPresentPaymentEligibilityStore { cardPresentPaymentsConfiguration: CardPresentPaymentsConfiguration, onCompletion: (Result) -> Void) { let storage = storageManager.viewStorage + + guard let site = storage.loadSite(siteID: siteID)?.toReadOnly() else { + return onCompletion( + .failure( + OrderIsEligibleForCardPresentPaymentError.siteNotFoundInStorage + ) + ) + } + + guard siteCIABEligibilityChecker.isFeatureSupported(.cardReader, for: site) else { + return onCompletion( + .failure( + OrderIsEligibleForCardPresentPaymentError.cardReaderPaymentOptionIsNotSupportedForCIABSites + ) + ) + } + guard let order = storage.loadOrder(siteID: siteID, orderID: orderID)?.toReadOnly() else { return onCompletion(.failure(OrderIsEligibleForCardPresentPaymentError.orderNotFoundInStorage)) } - let orderProductsIDs = order.items.map(\.productID) let products = storage.loadProducts(siteID: siteID, productsIDs: orderProductsIDs).map { $0.toReadOnly() } @@ -68,5 +84,7 @@ private extension OrderCardPresentPaymentEligibilityStore { extension OrderCardPresentPaymentEligibilityStore { enum OrderIsEligibleForCardPresentPaymentError: Error { case orderNotFoundInStorage + case siteNotFoundInStorage + case cardReaderPaymentOptionIsNotSupportedForCIABSites } } diff --git a/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift index 66b010956dc..98dbedc4ef3 100644 --- a/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift @@ -10,6 +10,7 @@ public enum CIABAffectedFeature: CaseIterable { case giftCardEditing case productsStockDashboardCard case pointOfSale + case cardReader } extension CIABAffectedFeature { From 5be9f8fdb5dcad0c2198eceb6f3d57ab0c36702b Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Thu, 23 Oct 2025 16:10:49 +0300 Subject: [PATCH 4/7] Rework CIAB eligibility checker and add tests --- ...erCardPresentPaymentEligibilityStore.swift | 10 ++- .../Tools/CIAB/CIABEligibilityChecker.swift | 10 ++- ...dPresentPaymentEligibilityStoreTests.swift | 74 ++++++++++++++++++- .../Classes/CIAB/CIABEligibilityChecker.swift | 6 +- .../Classes/Yosemite/AuthenticatedState.swift | 2 +- .../CIAB/CIABEligibilityCheckerTests.swift | 11 ++- 6 files changed, 98 insertions(+), 15 deletions(-) diff --git a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift index 44c5cce74cb..72b3c4ec90d 100644 --- a/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift +++ b/Modules/Sources/Yosemite/Stores/OrderCardPresentPaymentEligibilityStore.swift @@ -5,16 +5,18 @@ import protocol NetworkingCore.Network /// Determines whether an order is eligible for card present payment or not /// public final class OrderCardPresentPaymentEligibilityStore: Store { - private let stores: () -> StoresManager - private lazy var siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol = CIABEligibilityChecker(stores: stores()) + private let currentSite: () -> Site? + private lazy var siteCIABEligibilityChecker: CIABEligibilityCheckerProtocol = CIABEligibilityChecker( + currentSite: currentSite + ) public init( dispatcher: Dispatcher, storageManager: StorageManagerType, network: Network, - stores: @escaping () -> StoresManager + currentSite: @escaping () -> Site? ) { - self.stores = stores + self.currentSite = currentSite super.init( dispatcher: dispatcher, storageManager: storageManager, diff --git a/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift index 85c97d09a51..3c2212c3a3a 100644 --- a/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityChecker.swift @@ -1,16 +1,18 @@ import Foundation public final class CIABEligibilityChecker { - public let stores: StoresManager + public typealias ObtainSiteClosure = () -> Site? - public init(stores: StoresManager) { - self.stores = stores + public let currentSite: ObtainSiteClosure + + public init(currentSite: @escaping ObtainSiteClosure) { + self.currentSite = currentSite } } extension CIABEligibilityChecker: CIABEligibilityCheckerProtocol { public var isCurrentSiteCIAB: Bool { - guard let currentSite = stores.sessionManager.defaultSite else { + guard let currentSite = currentSite() else { return false } return isSiteCIAB(currentSite) diff --git a/Modules/Tests/YosemiteTests/Stores/OrderCardPresentPaymentEligibilityStoreTests.swift b/Modules/Tests/YosemiteTests/Stores/OrderCardPresentPaymentEligibilityStoreTests.swift index c8a73a5bc7b..444a60e7512 100644 --- a/Modules/Tests/YosemiteTests/Stores/OrderCardPresentPaymentEligibilityStoreTests.swift +++ b/Modules/Tests/YosemiteTests/Stores/OrderCardPresentPaymentEligibilityStoreTests.swift @@ -27,12 +27,26 @@ final class OrderCardPresentPaymentEligibilityStoreTests: XCTestCase { /// private var store: OrderCardPresentPaymentEligibilityStore! + private var currentSite: Site? + override func setUp() { super.setUp() dispatcher = Dispatcher() network = MockNetwork(useResponseQueue: true) storageManager = MockStorageManager() - store = OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network) + store = OrderCardPresentPaymentEligibilityStore( + dispatcher: dispatcher, + storageManager: storageManager, + network: network, + currentSite: { [weak self] in + return self?.currentSite + } + ) + } + + override func tearDown() { + currentSite = nil + super.tearDown() } // Other behavioural tests are in Order_CardPresentPaymentTests @@ -55,6 +69,14 @@ final class OrderCardPresentPaymentEligibilityStoreTests: XCTestCase { name: "Chocolate cake", productTypeKey: "simple") + let regularSite = Site.fake().copy( + siteID: sampleSiteID, + isGarden: false, + gardenName: nil + ) + self.currentSite = regularSite + + storageManager.insertSampleSite(readOnlySite: regularSite) storageManager.insertSampleProduct(readOnlyProduct: nonSubscriptionProduct) storageManager.insertSampleOrder(readOnlyOrder: cppEligibleOrder) @@ -75,4 +97,54 @@ final class OrderCardPresentPaymentEligibilityStoreTests: XCTestCase { let eligibility = try XCTUnwrap(result.get()) XCTAssertTrue(eligibility) } + + func test_orderIsEligibleForCardPresentPayment_returns_failure_for_CIAB_sites() throws { + // Given + let orderItem = OrderItem.fake().copy(itemID: 1234, + name: "Chocolate cake", + productID: 678, + quantity: 1.0) + let cppEligibleOrder = Order.fake().copy(siteID: sampleSiteID, + orderID: 111, + status: .pending, + currency: "USD", + datePaid: nil, + total: "5.00", + paymentMethodID: "woocommerce_payments", + items: [orderItem]) + let nonSubscriptionProduct = Product.fake().copy(siteID: sampleSiteID, + productID: 678, + name: "Chocolate cake", + productTypeKey: "simple") + + let ciabSite = Site.fake().copy( + siteID: sampleSiteID, + isGarden: true, + gardenName: "commerce" + ) + self.currentSite = ciabSite + + storageManager.insertSampleSite(readOnlySite: ciabSite) + storageManager.insertSampleProduct(readOnlyProduct: nonSubscriptionProduct) + storageManager.insertSampleOrder(readOnlyOrder: cppEligibleOrder) + + let configuration = CardPresentPaymentsConfiguration(country: .US) + + // When + let result = waitFor { promise in + let action = OrderCardPresentPaymentEligibilityAction + .orderIsEligibleForCardPresentPayment(orderID: 111, + siteID: self.sampleSiteID, + cardPresentPaymentsConfiguration: configuration) { result in + promise(result) + } + self.store.onAction(action) + } + + // Then + XCTAssertThrowsError(try result.get()) { error in + XCTAssertEqual(error as? OrderCardPresentPaymentEligibilityStore.OrderIsEligibleForCardPresentPaymentError, + .cardReaderPaymentOptionIsNotSupportedForCIABSites) + } + } } diff --git a/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift b/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift index 3d88a264705..c347588057d 100644 --- a/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift +++ b/WooCommerce/Classes/CIAB/CIABEligibilityChecker.swift @@ -5,6 +5,10 @@ import Yosemite extension CIABEligibilityChecker { convenience init() { - self.init(stores: ServiceLocator.stores) + self.init( + currentSite: { + return ServiceLocator.stores.sessionManager.defaultSite + } + ) } } diff --git a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift index 4dadba694a0..9c166817c8e 100644 --- a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift +++ b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift @@ -75,7 +75,7 @@ class AuthenticatedState: StoresManagerState { MediaStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationCountStore(dispatcher: dispatcher, storageManager: storageManager, fileStorage: PListFileStorage()), - OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network, stores: { ServiceLocator.stores }), + OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network, currentSite: { ServiceLocator.stores.sessionManager.defaultSite }), OrderNoteStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStatusStore(dispatcher: dispatcher, storageManager: storageManager, network: network), diff --git a/WooCommerce/WooCommerceTests/ViewRelated/CIAB/CIABEligibilityCheckerTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/CIAB/CIABEligibilityCheckerTests.swift index 6c42affe685..8fa5a5791ec 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/CIAB/CIABEligibilityCheckerTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/CIAB/CIABEligibilityCheckerTests.swift @@ -3,20 +3,23 @@ import XCTest @testable import Yosemite class CIABEligibilityCheckerTests: XCTestCase { - private var storesManager: MockStoresManager! private var sessionManager: SessionManager! private var checker: CIABEligibilityChecker! override func setUp() { super.setUp() sessionManager = .makeForTesting() - storesManager = MockStoresManager(sessionManager: sessionManager) - checker = CIABEligibilityChecker(stores: storesManager) + checker = CIABEligibilityChecker( + currentSite: { + return MockStoresManager( + sessionManager: self.sessionManager + ).sessionManager.defaultSite + } + ) } override func tearDown() { checker = nil - storesManager = nil sessionManager = nil super.tearDown() } From 3f7bfae62772767869c920114f27716b3026c84f Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Thu, 23 Oct 2025 16:20:04 +0300 Subject: [PATCH 5/7] Fix line length --- WooCommerce/Classes/Yosemite/AuthenticatedState.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift index 9c166817c8e..ec79983faf1 100644 --- a/WooCommerce/Classes/Yosemite/AuthenticatedState.swift +++ b/WooCommerce/Classes/Yosemite/AuthenticatedState.swift @@ -75,7 +75,14 @@ class AuthenticatedState: StoresManagerState { MediaStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationStore(dispatcher: dispatcher, storageManager: storageManager, network: network), NotificationCountStore(dispatcher: dispatcher, storageManager: storageManager, fileStorage: PListFileStorage()), - OrderCardPresentPaymentEligibilityStore(dispatcher: dispatcher, storageManager: storageManager, network: network, currentSite: { ServiceLocator.stores.sessionManager.defaultSite }), + OrderCardPresentPaymentEligibilityStore( + dispatcher: dispatcher, + storageManager: storageManager, + network: network, + currentSite: { + ServiceLocator.stores.sessionManager.defaultSite + } + ), OrderNoteStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStore(dispatcher: dispatcher, storageManager: storageManager, network: network), OrderStatusStore(dispatcher: dispatcher, storageManager: storageManager, network: network), From 1bc3488065e42311f4f59ca16d144944bfde169b Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Thu, 23 Oct 2025 16:21:24 +0300 Subject: [PATCH 6/7] Delete untracked CIAB affected feature for now --- Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift index 98dbedc4ef3..82e574b8079 100644 --- a/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABAffectedFeature.swift @@ -7,7 +7,6 @@ public enum CIABAffectedFeature: CaseIterable { case splitShipments case groupedProducts case variableProducts - case giftCardEditing case productsStockDashboardCard case pointOfSale case cardReader From 98965ff8b8efdd3936389a34635caffda4350601 Mon Sep 17 00:00:00 2001 From: RafaelKayumov Date: Thu, 23 Oct 2025 16:23:05 +0300 Subject: [PATCH 7/7] Silence periphery --- .../Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift index 2bd23952b90..0d9393e05a9 100644 --- a/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift +++ b/Modules/Sources/Yosemite/Tools/CIAB/CIABEligibilityCheckerProtocol.swift @@ -1,5 +1,6 @@ import Foundation +/// periphery: ignore public protocol CIABEligibilityCheckerProtocol { var isCurrentSiteCIAB: Bool { get }