Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Modules/Sources/Networking/Remote/POSCatalogSyncRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
]

let request = JetpackRequest(
wooApiVersion: .wcAnalytics,
wooApiVersion: .mark3,
method: .get,
siteID: siteID,
path: path,
Expand Down Expand Up @@ -249,7 +249,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
]

let request = JetpackRequest(
wooApiVersion: .wcAnalytics,
wooApiVersion: .mark3,
method: .get,
siteID: siteID,
path: path,
Expand Down Expand Up @@ -303,7 +303,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
]

let request = JetpackRequest(
wooApiVersion: .wcAnalytics,
wooApiVersion: .mark3,
method: .get,
siteID: siteID,
path: path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public enum POSLocalCatalogEligibilityState: Equatable {
public enum POSLocalCatalogIneligibleReason: Equatable {
case posTabNotEligible
case featureFlagDisabled
case unsupportedWooCommerceVersion(minimumVersion: String)
case catalogSizeTooLarge(totalCount: Int, limit: Int)
case catalogSizeCheckFailed(underlyingError: String)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Foundation
import Alamofire
import WooFoundationCore

public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServiceProtocol {
private let catalogSizeChecker: POSCatalogSizeCheckerProtocol
private let systemStatusService: POSSystemStatusServiceProtocol
private let catalogSizeLimit: Int
private let isLocalCatalogFeatureFlagEnabled: Bool

Expand All @@ -15,14 +17,17 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
/// Initialize eligibility service
/// - Parameters:
/// - catalogSizeChecker: Service to check catalog size for sites
/// - systemStatusService: Service to check WooCommerce plugin version
/// - isLocalCatalogFeatureFlagEnabled: Whether the local catalog feature flag is enabled
/// - catalogSizeLimit: Maximum allowed catalog size (products + variations)
public init(
catalogSizeChecker: POSCatalogSizeCheckerProtocol,
systemStatusService: POSSystemStatusServiceProtocol,
isLocalCatalogFeatureFlagEnabled: Bool,
catalogSizeLimit: Int? = nil
) {
self.catalogSizeChecker = catalogSizeChecker
self.systemStatusService = systemStatusService
self.isLocalCatalogFeatureFlagEnabled = isLocalCatalogFeatureFlagEnabled
self.catalogSizeLimit = catalogSizeLimit ?? Constants.defaultCatalogSizeLimit
}
Expand Down Expand Up @@ -76,6 +81,41 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
return state
}

// Check WooCommerce version - local catalog requires 10.3.0 or higher
do {
let pluginInfo = try await systemStatusService.loadWooCommercePluginAndPOSFeatureSwitch(siteID: siteID)

guard let wcPlugin = pluginInfo.wcPlugin, wcPlugin.active else {
let state = POSLocalCatalogEligibilityState.ineligible(reason: .posTabNotEligible)
eligibilityStates[siteID] = state
DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce plugin not found or inactive for site \(siteID)")
return state
}

guard VersionHelpers.isVersionSupported(version: wcPlugin.version,
minimumRequired: Constants.wcPluginMinimumVersionForLocalCatalog) else {
let state = POSLocalCatalogEligibilityState.ineligible(
reason: .unsupportedWooCommerceVersion(minimumVersion: Constants.wcPluginMinimumVersionForLocalCatalog)
)
eligibilityStates[siteID] = state
DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce version \(wcPlugin.version) below minimum" +
"\(Constants.wcPluginMinimumVersionForLocalCatalog) for site \(siteID)")
return state
}

DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce version \(wcPlugin.version) meets minimum requirement for site \(siteID)")
} catch AFError.explicitlyCancelled, is CancellationError {
throw POSCatalogSyncError.requestCancelled
} catch {
let errorString = String(describing: error)
let state = POSLocalCatalogEligibilityState.ineligible(
reason: .catalogSizeCheckFailed(underlyingError: errorString)
)
eligibilityStates[siteID] = state
DDLogError("📋 POSLocalCatalogEligibilityService: Failed to check WooCommerce version for site \(siteID): \(error)")
return state
}

// Fetch remote catalog size and check against limit
do {
let size = try await catalogSizeChecker.checkCatalogSize(for: siteID)
Expand Down Expand Up @@ -112,5 +152,6 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
private extension POSLocalCatalogEligibilityService {
enum Constants {
static let defaultCatalogSizeLimit = 1000
static let wcPluginMinimumVersionForLocalCatalog = "10.3.0-beta"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,6 @@ struct POSCatalogSyncRemoteTests {
_ = try? await remote.getProductVariationCount(siteID: sampleSiteID)

// Then - verify API versions match the data endpoints
// Products should use .mark3, variations should use .wcAnalytics (based on the load endpoints)
// This is verified by checking that the correct paths are called
let requests = network.requestsForResponseData.compactMap { $0 as? JetpackRequest }
#expect(requests.contains { $0.path.contains("products") })
Expand Down
40 changes: 40 additions & 0 deletions Modules/Tests/YosemiteTests/Mocks/MockPOSSystemStatusService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Foundation
import Networking
@testable import Yosemite

final class MockPOSSystemStatusService: POSSystemStatusServiceProtocol {
var pluginInfoToReturn: Result<POSPluginAndFeatureInfo, Error>
var loadPluginCallCount = 0
var lastCheckedSiteID: Int64?

init(pluginInfoToReturn: Result<POSPluginAndFeatureInfo, Error> = .success(
POSPluginAndFeatureInfo(
wcPlugin: SystemPlugin(
siteID: 123,
plugin: "woocommerce/woocommerce.php",
name: "WooCommerce",
version: "10.3.0",
versionLatest: "10.3.0",
url: "https://woocommerce.com",
authorName: "WooCommerce",
authorUrl: "https://woocommerce.com",
networkActivated: false,
active: true
),
featureValue: true
)
)) {
self.pluginInfoToReturn = pluginInfoToReturn
}

func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo {
loadPluginCallCount += 1
lastCheckedSiteID = siteID
switch pluginInfoToReturn {
case .success(let info):
return info
case .failure(let error):
throw error
}
}
}
Loading