Skip to content

Commit 13529c5

Browse files
authored
[Local Catalog] Use variations endpoint for incremental sync (#16322)
2 parents 39ab7b5 + c48b5cb commit 13529c5

File tree

7 files changed

+229
-4
lines changed

7 files changed

+229
-4
lines changed

Modules/Sources/Networking/Remote/POSCatalogSyncRemote.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
134134
]
135135

136136
let request = JetpackRequest(
137-
wooApiVersion: .wcAnalytics,
137+
wooApiVersion: .mark3,
138138
method: .get,
139139
siteID: siteID,
140140
path: path,
@@ -249,7 +249,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
249249
]
250250

251251
let request = JetpackRequest(
252-
wooApiVersion: .wcAnalytics,
252+
wooApiVersion: .mark3,
253253
method: .get,
254254
siteID: siteID,
255255
path: path,
@@ -303,7 +303,7 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
303303
]
304304

305305
let request = JetpackRequest(
306-
wooApiVersion: .wcAnalytics,
306+
wooApiVersion: .mark3,
307307
method: .get,
308308
siteID: siteID,
309309
path: path,

Modules/Sources/Yosemite/Protocols/POSLocalCatalogEligibilityServiceProtocol.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public enum POSLocalCatalogEligibilityState: Equatable {
1414
public enum POSLocalCatalogIneligibleReason: Equatable {
1515
case posTabNotEligible
1616
case featureFlagDisabled
17+
case unsupportedWooCommerceVersion(minimumVersion: String)
1718
case catalogSizeTooLarge(totalCount: Int, limit: Int)
1819
case catalogSizeCheckFailed(underlyingError: String)
1920
}

Modules/Sources/Yosemite/Tools/POS/POSLocalCatalogEligibilityService.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import Foundation
22
import Alamofire
3+
import WooFoundationCore
34

45
public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServiceProtocol {
56
private let catalogSizeChecker: POSCatalogSizeCheckerProtocol
7+
private let systemStatusService: POSSystemStatusServiceProtocol
68
private let catalogSizeLimit: Int
79
private let isLocalCatalogFeatureFlagEnabled: Bool
810

@@ -15,14 +17,17 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
1517
/// Initialize eligibility service
1618
/// - Parameters:
1719
/// - catalogSizeChecker: Service to check catalog size for sites
20+
/// - systemStatusService: Service to check WooCommerce plugin version
1821
/// - isLocalCatalogFeatureFlagEnabled: Whether the local catalog feature flag is enabled
1922
/// - catalogSizeLimit: Maximum allowed catalog size (products + variations)
2023
public init(
2124
catalogSizeChecker: POSCatalogSizeCheckerProtocol,
25+
systemStatusService: POSSystemStatusServiceProtocol,
2226
isLocalCatalogFeatureFlagEnabled: Bool,
2327
catalogSizeLimit: Int? = nil
2428
) {
2529
self.catalogSizeChecker = catalogSizeChecker
30+
self.systemStatusService = systemStatusService
2631
self.isLocalCatalogFeatureFlagEnabled = isLocalCatalogFeatureFlagEnabled
2732
self.catalogSizeLimit = catalogSizeLimit ?? Constants.defaultCatalogSizeLimit
2833
}
@@ -76,6 +81,41 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
7681
return state
7782
}
7883

84+
// Check WooCommerce version - local catalog requires 10.3.0 or higher
85+
do {
86+
let pluginInfo = try await systemStatusService.loadWooCommercePluginAndPOSFeatureSwitch(siteID: siteID)
87+
88+
guard let wcPlugin = pluginInfo.wcPlugin, wcPlugin.active else {
89+
let state = POSLocalCatalogEligibilityState.ineligible(reason: .posTabNotEligible)
90+
eligibilityStates[siteID] = state
91+
DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce plugin not found or inactive for site \(siteID)")
92+
return state
93+
}
94+
95+
guard VersionHelpers.isVersionSupported(version: wcPlugin.version,
96+
minimumRequired: Constants.wcPluginMinimumVersionForLocalCatalog) else {
97+
let state = POSLocalCatalogEligibilityState.ineligible(
98+
reason: .unsupportedWooCommerceVersion(minimumVersion: Constants.wcPluginMinimumVersionForLocalCatalog)
99+
)
100+
eligibilityStates[siteID] = state
101+
DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce version \(wcPlugin.version) below minimum" +
102+
"\(Constants.wcPluginMinimumVersionForLocalCatalog) for site \(siteID)")
103+
return state
104+
}
105+
106+
DDLogInfo("📋 POSLocalCatalogEligibilityService: WooCommerce version \(wcPlugin.version) meets minimum requirement for site \(siteID)")
107+
} catch AFError.explicitlyCancelled, is CancellationError {
108+
throw POSCatalogSyncError.requestCancelled
109+
} catch {
110+
let errorString = String(describing: error)
111+
let state = POSLocalCatalogEligibilityState.ineligible(
112+
reason: .catalogSizeCheckFailed(underlyingError: errorString)
113+
)
114+
eligibilityStates[siteID] = state
115+
DDLogError("📋 POSLocalCatalogEligibilityService: Failed to check WooCommerce version for site \(siteID): \(error)")
116+
return state
117+
}
118+
79119
// Fetch remote catalog size and check against limit
80120
do {
81121
let size = try await catalogSizeChecker.checkCatalogSize(for: siteID)
@@ -112,5 +152,6 @@ public actor POSLocalCatalogEligibilityService: POSLocalCatalogEligibilityServic
112152
private extension POSLocalCatalogEligibilityService {
113153
enum Constants {
114154
static let defaultCatalogSizeLimit = 1000
155+
static let wcPluginMinimumVersionForLocalCatalog = "10.3.0-beta"
115156
}
116157
}

Modules/Tests/NetworkingTests/Remote/POSCatalogSyncRemoteTests.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,6 @@ struct POSCatalogSyncRemoteTests {
584584
_ = try? await remote.getProductVariationCount(siteID: sampleSiteID)
585585

586586
// Then - verify API versions match the data endpoints
587-
// Products should use .mark3, variations should use .wcAnalytics (based on the load endpoints)
588587
// This is verified by checking that the correct paths are called
589588
let requests = network.requestsForResponseData.compactMap { $0 as? JetpackRequest }
590589
#expect(requests.contains { $0.path.contains("products") })
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import Foundation
2+
import Networking
3+
@testable import Yosemite
4+
5+
final class MockPOSSystemStatusService: POSSystemStatusServiceProtocol {
6+
var pluginInfoToReturn: Result<POSPluginAndFeatureInfo, Error>
7+
var loadPluginCallCount = 0
8+
var lastCheckedSiteID: Int64?
9+
10+
init(pluginInfoToReturn: Result<POSPluginAndFeatureInfo, Error> = .success(
11+
POSPluginAndFeatureInfo(
12+
wcPlugin: SystemPlugin(
13+
siteID: 123,
14+
plugin: "woocommerce/woocommerce.php",
15+
name: "WooCommerce",
16+
version: "10.3.0",
17+
versionLatest: "10.3.0",
18+
url: "https://woocommerce.com",
19+
authorName: "WooCommerce",
20+
authorUrl: "https://woocommerce.com",
21+
networkActivated: false,
22+
active: true
23+
),
24+
featureValue: true
25+
)
26+
)) {
27+
self.pluginInfoToReturn = pluginInfoToReturn
28+
}
29+
30+
func loadWooCommercePluginAndPOSFeatureSwitch(siteID: Int64) async throws -> POSPluginAndFeatureInfo {
31+
loadPluginCallCount += 1
32+
lastCheckedSiteID = siteID
33+
switch pluginInfoToReturn {
34+
case .success(let info):
35+
return info
36+
case .failure(let error):
37+
throw error
38+
}
39+
}
40+
}

0 commit comments

Comments
 (0)