Skip to content

Commit

Permalink
Update ProductsRemote.loadProductsForPointOfSale to return `PagedIt…
Browse files Browse the repository at this point in the history
…ems` that contains both the items and whether there are more pages.
  • Loading branch information
jaclync committed Dec 19, 2024
1 parent 3300238 commit a7e4cf3
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 15 deletions.
5 changes: 3 additions & 2 deletions Networking/Networking/Remote/ProductsRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
///
public func loadProductsForPointOfSale(for siteID: Int64,
productTypes: [ProductType] = [.simple],
pageNumber: Int = 1) async throws -> (products: [Product], totalPagesCount: Int?) {
pageNumber: Int = 1) async throws -> PagedItems<Product> {
let parameters = [
ParameterKey.page: String(pageNumber),
ParameterKey.perPage: POSConstants.productsPerPage,
Expand All @@ -231,8 +231,9 @@ public final class ProductsRemote: Remote, ProductsRemoteProtocol {
// Response header names are case insensitive.
let totalPages = responseHeaders?.first(where: { $0.key.lowercased() == Remote.PaginationHeaderKey.totalPagesCount.lowercased() })
.flatMap { Int($0.value) }
let hasMorePages = totalPages.map { pageNumber < $0 } ?? true

return (products: products, totalPagesCount: totalPages)
return .init(items: products, hasMorePages: hasMorePages)
}

/// Retrieves a specific list of `Product`s by `productID`.
Expand Down
6 changes: 6 additions & 0 deletions Networking/Networking/Remote/Remote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,12 @@ private extension Remote {
}
}

/// Contains the result of a paginated request.
public struct PagedItems<T> {
public let items: [T]
public let hasMorePages: Bool
}

// MARK: - Constants!
//
public extension Remote {
Expand Down
44 changes: 34 additions & 10 deletions Networking/NetworkingTests/Remote/ProductsRemoteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,10 @@ final class ProductsRemoteTests: XCTestCase {
// When
network.simulateResponse(requestUrlSuffix: "products", filename: "products-load-all-type-simple")

let (products, _) = try await remote.loadProductsForPointOfSale(for: sampleSiteID)
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID)

// Then
let products = pagedProducts.items
XCTAssertEqual(products.count, expectedProductsFromResponse)
for product in products {
XCTAssertEqual(try XCTUnwrap(product).productType, .simple)
Expand Down Expand Up @@ -970,9 +971,10 @@ final class ProductsRemoteTests: XCTestCase {
// When
network.simulateResponse(requestUrlSuffix: "products", filename: "products-load-all-type-simple")

let (products, _) = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: initialPageNumber)
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: initialPageNumber)

// Then
let products = pagedProducts.items
XCTAssertEqual(products.count, expectedProductsFromResponse)
for product in products {
XCTAssertEqual(try XCTUnwrap(product).productType, .simple)
Expand All @@ -988,24 +990,46 @@ final class ProductsRemoteTests: XCTestCase {
// When
network.simulateResponse(requestUrlSuffix: "products", filename: "empty-data-array")

let (products, _) = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: pageNumber)
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: pageNumber)

// Then
XCTAssertEqual(products.count, expectedProductsFromResponse)
XCTAssertEqual(pagedProducts.items.count, expectedProductsFromResponse)
}

func test_loadProductsForPointOfSale_returns_total_pages_count_from_headers_case_insensitive_name() async throws {
func test_loadProductsForPointOfSale_returns_hasMorePages_based_on_header_with_case_insensitive_name() async throws {
// Given
let remote = ProductsRemote(network: network)

// When
network.responseHeaders = ["X-WP-TotalPages": "17"]
network.responseHeaders = ["X-WP-TotalPages": "5"]
network.simulateResponse(requestUrlSuffix: "products", filename: "empty-data-array")

let (_, totalPagesCount) = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: 2)
// When loading page 1 to 4
for pageNumber in 1...4 {
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: pageNumber)

// Then
XCTAssertTrue(pagedProducts.hasMorePages)
}

// When loading page 17
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: 5)

// Then
XCTAssertEqual(totalPagesCount, 17)
XCTAssertFalse(pagedProducts.hasMorePages)
}

func test_loadProductsForPointOfSale_returns_hasMorePages_true_when_header_is_not_set() async throws {
// Given
let remote = ProductsRemote(network: network)
network.responseHeaders = nil
network.simulateResponse(requestUrlSuffix: "products", filename: "empty-data-array")

// When loading the first 5 pages
for pageNumber in 1...5 {
let pagedProducts = try await remote.loadProductsForPointOfSale(for: sampleSiteID, pageNumber: pageNumber)

// Then
XCTAssertTrue(pagedProducts.hasMorePages)
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions Yosemite/Yosemite/PointOfSale/PointOfSaleProductService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public final class PointOfSaleProductService: PointOfSaleItemServiceProtocol {
public func providePointOfSaleItems(pageNumber: Int = 1) async throws -> (items: [POSItem], hasNextPage: Bool) {
let productTypes: [ProductType] = isVariableProductsFeatureEnabled ?
[.simple, .variable] : [.simple]
let (products, totalPagesCount) = try await productsRemote.loadProductsForPointOfSale(for: siteID, productTypes: productTypes, pageNumber: pageNumber)
let pagedProducts = try await productsRemote.loadProductsForPointOfSale(for: siteID, productTypes: productTypes, pageNumber: pageNumber)
let products = pagedProducts.items

if pageNumber != 1 && products.count == 0 {
return ([], false)
Expand All @@ -56,8 +57,7 @@ public final class PointOfSaleProductService: PointOfSaleItemServiceProtocol {
]
let filteredProducts = filterProducts(products: products, using: eligibilityCriteria)

let hasNextPage = totalPagesCount.map { pageNumber < $0 } ?? true
return (items: mapProductsToPOSItems(products: filteredProducts), hasNextPage: hasNextPage)
return (items: mapProductsToPOSItems(products: filteredProducts), hasNextPage: pagedProducts.hasMorePages)
}

// Maps result to POSItem, and populate the output with:
Expand Down

0 comments on commit a7e4cf3

Please sign in to comment.