Skip to content

Commit 5df989c

Browse files
committed
Make full catalog syncs respect cellular setting
1 parent f9d6100 commit 5df989c

File tree

4 files changed

+95
-31
lines changed

4 files changed

+95
-31
lines changed

Modules/Sources/Networking/Remote/POSCatalogSyncRemote.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ public protocol POSCatalogSyncRemoteProtocol {
3030
/// - Parameters:
3131
/// - siteID: Site ID to generate catalog for.
3232
/// - forceGeneration: Whether to always generate a catalog.
33+
/// - allowCellular: Should cellular data be used if required.
3334
/// - Returns: Catalog job response with job ID.
3435
///
3536
// periphery:ignore - TODO - remove this periphery ignore comment when this endpoint is integrated with catalog sync
36-
func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool) async throws -> POSCatalogRequestResponse
37+
func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool, allowCellular: Bool) async throws -> POSCatalogRequestResponse
3738

3839
/// Downloads the generated catalog at the specified download URL.
3940
/// - Parameters:
@@ -50,16 +51,18 @@ public protocol POSCatalogSyncRemoteProtocol {
5051
/// - Parameters:
5152
/// - siteID: Site ID to load products from.
5253
/// - pageNumber: Page number for pagination.
54+
/// - allowCellular: Should cellular data be used if required.
5355
/// - Returns: Paginated list of POS products.
54-
func loadProducts(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProduct>
56+
func loadProducts(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProduct>
5557

5658
/// Loads POS product variations for full sync.
5759
///
5860
/// - Parameters:
5961
/// - siteID: Site ID to load variations from.
6062
/// - pageNumber: Page number for pagination.
63+
/// - allowCellular: Should cellular data be used if required.
6164
/// - Returns: Paginated list of POS product variations.
62-
func loadProductVariations(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProductVariation>
65+
func loadProductVariations(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProductVariation>
6366

6467
/// Gets the total count of products for the specified site.
6568
///
@@ -151,9 +154,11 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
151154
///
152155
/// - Parameters:
153156
/// - siteID: Site ID to generate catalog for.
157+
/// - forceGeneration: Whether to always generate a catalog.
158+
/// - allowCellular: Should cellular data be used if required.
154159
/// - Returns: Catalog job response with job ID.
155160
///
156-
public func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool) async throws -> POSCatalogRequestResponse {
161+
public func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool, allowCellular: Bool) async throws -> POSCatalogRequestResponse {
157162
let path = "products/catalog"
158163
let parameters: [String: Any] = [
159164
ParameterKey.fullSyncFields: POSProduct.requestFields,
@@ -165,7 +170,8 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
165170
siteID: siteID,
166171
path: path,
167172
parameters: parameters,
168-
availableAsRESTRequest: true
173+
availableAsRESTRequest: true,
174+
allowsCellularAccess: allowCellular
169175
)
170176
let mapper = SingleItemMapper<POSCatalogRequestResponse>(siteID: siteID)
171177
return try await enqueue(request, mapper: mapper)
@@ -200,9 +206,10 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
200206
/// - Parameters:
201207
/// - siteID: Site ID to load products from.
202208
/// - pageNumber: Page number for pagination.
209+
/// - allowCellular: Should cellular data be used if required.
203210
/// - Returns: Paginated list of POS products.
204211
///
205-
public func loadProducts(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProduct> {
212+
public func loadProducts(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProduct> {
206213
let path = Path.products
207214
let parameters = [
208215
ParameterKey.page: String(pageNumber),
@@ -216,7 +223,8 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
216223
siteID: siteID,
217224
path: path,
218225
parameters: parameters,
219-
availableAsRESTRequest: true
226+
availableAsRESTRequest: true,
227+
allowsCellularAccess: allowCellular
220228
)
221229
let mapper = ListMapper<POSProduct>(siteID: siteID)
222230
let (products, responseHeaders) = try await enqueueWithResponseHeaders(request, mapper: mapper)
@@ -229,9 +237,10 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
229237
/// - Parameters:
230238
/// - siteID: Site ID to load variations from.
231239
/// - pageNumber: Page number for pagination.
240+
/// - allowCellular: Should cellular data be used if required.
232241
/// - Returns: Paginated list of POS product variations.
233242
///
234-
public func loadProductVariations(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProductVariation> {
243+
public func loadProductVariations(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProductVariation> {
235244
let path = Path.variations
236245
let parameters = [
237246
ParameterKey.page: String(pageNumber),
@@ -245,7 +254,8 @@ public class POSCatalogSyncRemote: Remote, POSCatalogSyncRemoteProtocol {
245254
siteID: siteID,
246255
path: path,
247256
parameters: parameters,
248-
availableAsRESTRequest: true
257+
availableAsRESTRequest: true,
258+
allowsCellularAccess: allowCellular
249259
)
250260
let mapper = ListMapper<POSProductVariation>(siteID: siteID)
251261
let (variations, responseHeaders) = try await enqueueWithResponseHeaders(request, mapper: mapper)

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
8484
regenerateCatalog: regenerateCatalog,
8585
allowCellular: allowCellular)
8686
} else {
87-
catalog = try await loadCatalog(for: siteID, syncRemote: syncRemote)
87+
catalog = try await loadCatalog(for: siteID, syncRemote: syncRemote, allowCellular: allowCellular)
8888
}
8989
DDLogInfo("✅ Loaded \(catalog.products.count) products and \(catalog.variations.count) variations for siteID \(siteID)")
9090

@@ -103,17 +103,17 @@ public final class POSCatalogFullSyncService: POSCatalogFullSyncServiceProtocol
103103
// MARK: - Remote Loading
104104

105105
private extension POSCatalogFullSyncService {
106-
func loadCatalog(for siteID: Int64, syncRemote: POSCatalogSyncRemoteProtocol) async throws -> POSCatalog {
106+
func loadCatalog(for siteID: Int64, syncRemote: POSCatalogSyncRemoteProtocol, allowCellular: Bool) async throws -> POSCatalog {
107107
let syncStartDate = Date.now
108108
// Loads products and variations in batches in parallel.
109109
async let productsTask = batchedLoader.loadAll(
110110
makeRequest: { pageNumber in
111-
try await syncRemote.loadProducts(siteID: siteID, pageNumber: pageNumber)
111+
try await syncRemote.loadProducts(siteID: siteID, pageNumber: pageNumber, allowCellular: allowCellular)
112112
}
113113
)
114114
async let variationsTask = batchedLoader.loadAll(
115115
makeRequest: { pageNumber in
116-
try await syncRemote.loadProductVariations(siteID: siteID, pageNumber: pageNumber)
116+
try await syncRemote.loadProductVariations(siteID: siteID, pageNumber: pageNumber, allowCellular: allowCellular)
117117
}
118118
)
119119

@@ -145,13 +145,15 @@ private extension POSCatalogFullSyncService {
145145
DDLogInfo("🟣 Starting catalog request...")
146146

147147
// 1. Requests catalog until download URL is available.
148-
let response = try await syncRemote.requestCatalogGeneration(for: siteID, forceGeneration: regenerateCatalog)
148+
let response = try await syncRemote.requestCatalogGeneration(for: siteID, forceGeneration: regenerateCatalog, allowCellular: allowCellular)
149149
let downloadURL: String?
150150
if let url = response.downloadURL {
151151
downloadURL = url
152152
} else {
153153
// 2. Polls for completion until download URL is available.
154-
downloadURL = try await pollForCatalogCompletion(siteID: siteID, syncRemote: syncRemote)
154+
downloadURL = try await pollForCatalogCompletion(siteID: siteID,
155+
syncRemote: syncRemote,
156+
allowCellular: allowCellular)
155157
}
156158

157159
// 3. Downloads catalog using the provided URL.
@@ -162,13 +164,17 @@ private extension POSCatalogFullSyncService {
162164
return try await syncRemote.downloadCatalog(for: siteID, downloadURL: downloadURL, allowCellular: allowCellular)
163165
}
164166

165-
func pollForCatalogCompletion(siteID: Int64, syncRemote: POSCatalogSyncRemoteProtocol) async throws -> String {
167+
func pollForCatalogCompletion(siteID: Int64,
168+
syncRemote: POSCatalogSyncRemoteProtocol,
169+
allowCellular: Bool) async throws -> String {
166170
// Each attempt is made 1 second after the last one completes.
167171
let maxAttempts = 1000
168172
var attempts = 0
169173

170174
while attempts < maxAttempts {
171-
let response = try await syncRemote.requestCatalogGeneration(for: siteID, forceGeneration: false)
175+
let response = try await syncRemote.requestCatalogGeneration(for: siteID,
176+
forceGeneration: false,
177+
allowCellular: allowCellular)
172178

173179
switch response.status {
174180
case .complete:

Modules/Tests/NetworkingTests/Remote/POSCatalogSyncRemoteTests.swift

Lines changed: 58 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ struct POSCatalogSyncRemoteTests {
290290
network.simulateResponse(requestUrlSuffix: "products", filename: "empty-data-array")
291291

292292
// When loading page 1
293-
let pagedProducts = try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1)
293+
let pagedProducts = try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
294294

295295
// Then there are more pages
296296
#expect(pagedProducts.hasMorePages == true)
@@ -304,7 +304,7 @@ struct POSCatalogSyncRemoteTests {
304304
let pageNumber = 2
305305

306306
// When
307-
_ = try? await remote.loadProducts(siteID: sampleSiteID, pageNumber: pageNumber)
307+
_ = try? await remote.loadProducts(siteID: sampleSiteID, pageNumber: pageNumber, allowCellular: true)
308308

309309
// Then
310310
let queryParametersDictionary = try #require(network.queryParametersDictionary as? [String: any Hashable])
@@ -321,7 +321,7 @@ struct POSCatalogSyncRemoteTests {
321321

322322
// When
323323
network.simulateResponse(requestUrlSuffix: "products", filename: "products-load-pos")
324-
let pagedProducts = try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1)
324+
let pagedProducts = try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
325325

326326
// Then
327327
#expect(pagedProducts.items.count == expectedProductsCount)
@@ -338,7 +338,7 @@ struct POSCatalogSyncRemoteTests {
338338

339339
// When/Then
340340
await #expect(throws: NetworkError.notFound()) {
341-
try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1)
341+
try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
342342
}
343343
}
344344

@@ -350,7 +350,7 @@ struct POSCatalogSyncRemoteTests {
350350
let pageNumber = 3
351351

352352
// When
353-
_ = try? await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: pageNumber)
353+
_ = try? await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: pageNumber, allowCellular: true)
354354

355355
// Then
356356
let queryParametersDictionary = try #require(network.queryParametersDictionary as? [String: any Hashable])
@@ -366,7 +366,7 @@ struct POSCatalogSyncRemoteTests {
366366

367367
// When
368368
network.simulateResponse(requestUrlSuffix: "variations", filename: "product-variations-load-pos")
369-
let pagedVariations = try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1)
369+
let pagedVariations = try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
370370

371371
// Then
372372
#expect(pagedVariations.items.count == 1)
@@ -383,7 +383,7 @@ struct POSCatalogSyncRemoteTests {
383383

384384
// When/Then
385385
await #expect(throws: NetworkError.notFound()) {
386-
try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1)
386+
try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
387387
}
388388
}
389389

@@ -394,7 +394,7 @@ struct POSCatalogSyncRemoteTests {
394394
network.simulateResponse(requestUrlSuffix: "variations", filename: "empty-data-array")
395395

396396
// When loading page 1
397-
let pagedVariations = try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1)
397+
let pagedVariations = try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1, allowCellular: true)
398398

399399
// Then there are more pages
400400
#expect(pagedVariations.hasMorePages == true)
@@ -598,7 +598,7 @@ struct POSCatalogSyncRemoteTests {
598598
let remote = POSCatalogSyncRemote(network: network)
599599

600600
// When
601-
_ = try? await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false)
601+
_ = try? await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false, allowCellular: true)
602602

603603
// Then
604604
let queryParametersDictionary = try #require(network.queryParametersDictionary as? [String: any Hashable])
@@ -612,7 +612,7 @@ struct POSCatalogSyncRemoteTests {
612612

613613
// When
614614
network.simulateResponse(requestUrlSuffix: "catalog", filename: "pos-catalog-generation")
615-
let response = try await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false)
615+
let response = try await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false, allowCellular: true)
616616

617617
// Then
618618
#expect(response.status == .complete)
@@ -625,7 +625,7 @@ struct POSCatalogSyncRemoteTests {
625625

626626
// When/Then
627627
await #expect(throws: NetworkError.notFound()) {
628-
try await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false)
628+
try await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false, allowCellular: true)
629629
}
630630
}
631631

@@ -743,4 +743,51 @@ struct POSCatalogSyncRemoteTests {
743743
let urlRequest = try #require(network.requestsForResponseData.last as? URLRequest)
744744
#expect(urlRequest.allowsCellularAccess == allowCellular)
745745
}
746+
747+
// MARK: - Full Sync allowCellular Tests
748+
749+
@Test(arguments: [true, false])
750+
func requestCatalogGeneration_sets_allowsCellularAccess_on_request(allowCellular: Bool) async throws {
751+
// Given
752+
let remote = POSCatalogSyncRemote(network: network)
753+
network.simulateResponse(requestUrlSuffix: "catalog", filename: "pos-catalog-generation")
754+
755+
// When
756+
_ = try await remote.requestCatalogGeneration(for: sampleSiteID, forceGeneration: false, allowCellular: allowCellular)
757+
758+
// Then
759+
let jetpackRequest = try #require(network.requestsForResponseData.last as? JetpackRequest)
760+
let urlRequest = try jetpackRequest.asURLRequest()
761+
#expect(urlRequest.allowsCellularAccess == allowCellular)
762+
}
763+
764+
@Test(arguments: [true, false])
765+
func loadProducts_fullSync_sets_allowsCellularAccess_on_request(allowCellular: Bool) async throws {
766+
// Given
767+
let remote = POSCatalogSyncRemote(network: network)
768+
network.simulateResponse(requestUrlSuffix: "products", filename: "empty-data-array")
769+
770+
// When
771+
_ = try await remote.loadProducts(siteID: sampleSiteID, pageNumber: 1, allowCellular: allowCellular)
772+
773+
// Then
774+
let jetpackRequest = try #require(network.requestsForResponseData.last as? JetpackRequest)
775+
let urlRequest = try jetpackRequest.asURLRequest()
776+
#expect(urlRequest.allowsCellularAccess == allowCellular)
777+
}
778+
779+
@Test(arguments: [true, false])
780+
func loadProductVariations_fullSync_sets_allowsCellularAccess_on_request(allowCellular: Bool) async throws {
781+
// Given
782+
let remote = POSCatalogSyncRemote(network: network)
783+
network.simulateResponse(requestUrlSuffix: "variations", filename: "empty-data-array")
784+
785+
// When
786+
_ = try await remote.loadProductVariations(siteID: sampleSiteID, pageNumber: 1, allowCellular: allowCellular)
787+
788+
// Then
789+
let jetpackRequest = try #require(network.requestsForResponseData.last as? JetpackRequest)
790+
let urlRequest = try jetpackRequest.asURLRequest()
791+
#expect(urlRequest.allowsCellularAccess == allowCellular)
792+
}
746793
}

Modules/Tests/YosemiteTests/Mocks/MockPOSCatalogSyncRemote.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ final class MockPOSCatalogSyncRemote: POSCatalogSyncRemoteProtocol {
103103

104104
// MARK: - Protocol Methods - Full Sync
105105

106-
func loadProducts(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProduct> {
106+
func loadProducts(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProduct> {
107107
await loadProductsCallCount.increment()
108108

109109
if let result = productResults[pageNumber] {
@@ -117,7 +117,7 @@ final class MockPOSCatalogSyncRemote: POSCatalogSyncRemoteProtocol {
117117
return fallbackResult
118118
}
119119

120-
func loadProductVariations(siteID: Int64, pageNumber: Int) async throws -> PagedItems<POSProductVariation> {
120+
func loadProductVariations(siteID: Int64, pageNumber: Int, allowCellular: Bool) async throws -> PagedItems<POSProductVariation> {
121121
await loadProductVariationsCallCount.increment()
122122

123123
if let result = variationResults[pageNumber] {
@@ -133,8 +133,9 @@ final class MockPOSCatalogSyncRemote: POSCatalogSyncRemoteProtocol {
133133

134134
// MARK: - Protocol Methods - Catalog API
135135

136-
func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool) async throws -> POSCatalogRequestResponse {
136+
func requestCatalogGeneration(for siteID: Int64, forceGeneration: Bool, allowCellular: Bool) async throws -> POSCatalogRequestResponse {
137137
lastCatalogRequestForceGeneration = forceGeneration
138+
lastCatalogDownloadAllowCellular = allowCellular
138139
switch catalogRequestResult {
139140
case .success(let response):
140141
return response

0 commit comments

Comments
 (0)