Skip to content

Dynamic Dashboard: Update Yosemite to support loading product reports #12795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 21, 2024
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
23 changes: 23 additions & 0 deletions Yosemite/Yosemite/Actions/ProductAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,27 @@ public enum ProductAction: Action {
orderBy: ProductsRemote.OrderKey,
order: ProductsRemote.Order,
completion: (Result<[ProductStock], Error>) -> Void)

/// Fetches product reports for the given product ID of a site in a given time range.
/// - Parameter siteID: Site ID to fetch stock for.
/// - Parameter productIDs: IDs of the products of interest.
/// - Parameter timeZone: The timezone to consider for the given time range.
/// - Parameter earliestDateToInclude: The earliest date for the product reports.
/// - Parameter latestDateToInclude: The latest date for the product reports.
/// - Parameter pageNumber: The index of the content page to query.
/// - Parameter pageSize: The max amount of items to return per page.
/// - Parameter orderBy: The key to sort returned items.
/// - Parameter order: Whether to sort returned items ASC or DESC.
/// - Parameter completion: Closure to trigger when fetching completes.
///
case fetchProductReports(siteID: Int64,
productIDs: [Int64],
timeZone: TimeZone,
earliestDateToInclude: Date,
latestDateToInclude: Date,
pageSize: Int,
pageNumber: Int,
orderBy: ProductsRemote.OrderKey,
order: ProductsRemote.Order,
completion: (Result<[ProductReportSegment], Error>) -> Void)
}
2 changes: 2 additions & 0 deletions Yosemite/Yosemite/Model/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ public typealias ProductReview = Networking.ProductReview
public typealias ProductReviewStatus = Networking.ProductReviewStatus
public typealias ProductShippingClass = Networking.ProductShippingClass
public typealias ProductsReportItem = Networking.ProductsReportItem
public typealias ProductReportSegment = Networking.ProductReportSegment
public typealias ProductStatus = Networking.ProductStatus
public typealias ProductCatalogVisibility = Networking.ProductCatalogVisibility
public typealias ProductStock = Networking.ProductStock
public typealias ProductStockStatus = Networking.ProductStockStatus
public typealias ProductSubscription = Networking.ProductSubscription
public typealias ProductType = Networking.ProductType
Expand Down
39 changes: 39 additions & 0 deletions Yosemite/Yosemite/Stores/ProductStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ public class ProductStore: Store {
orderBy: orderBy,
order: order,
completion: completion)
case let .fetchProductReports(siteID, productIDs, timeZone, earliestDateToInclude, latestDateToInclude, pageSize, pageNumber, orderBy, order, completion):
fetchProductReports(siteID: siteID,
productIDs: productIDs,
timeZone: timeZone,
earliestDateToInclude: earliestDateToInclude,
latestDateToInclude: latestDateToInclude,
pageSize: pageSize,
pageNumber: pageNumber,
orderBy: orderBy,
order: order,
completion: completion)
}
}
}
Expand Down Expand Up @@ -761,6 +772,34 @@ private extension ProductStore {
}
}
}

func fetchProductReports(siteID: Int64,
productIDs: [Int64],
timeZone: TimeZone,
earliestDateToInclude: Date,
latestDateToInclude: Date,
pageSize: Int,
pageNumber: Int,
orderBy: ProductsRemote.OrderKey,
order: ProductsRemote.Order,
completion: @escaping (Result<[ProductReportSegment], Error>) -> Void) {
Task { @MainActor in
do {
let segments = try await remote.loadProductReports(for: siteID,
productIDs: productIDs,
timeZone: timeZone,
earliestDateToInclude: earliestDateToInclude,
latestDateToInclude: latestDateToInclude,
pageSize: pageSize,
pageNumber: pageNumber,
orderBy: orderBy,
order: order)
completion(.success(segments))
} catch {
completion(.failure(error))
}
}
}
}


Expand Down
63 changes: 63 additions & 0 deletions Yosemite/YosemiteTests/Stores/ProductStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2895,6 +2895,69 @@ final class ProductStoreTests: XCTestCase {
XCTAssertTrue(result.isFailure)
XCTAssertEqual(result.failure as? NetworkError, .timeout())
}

// MARK: - Fetch product reports

func test_fetchProductReports_returns_segments_on_success() throws {
// Given
let segment = ProductReportSegment.fake().copy(productID: 123, productName: "Steamed bun", subtotals: .fake().copy(itemsSold: 10))
let mockRemote = MockProductsRemote()
mockRemote.whenFetchingProductReports(thenReturn: .success([segment]))
let productStore = ProductStore(dispatcher: dispatcher,
storageManager: storageManager,
network: network,
remote: mockRemote)

// When
let result = waitFor { promise in
productStore.onAction(ProductAction.fetchProductReports(siteID: self.sampleSiteID,
productIDs: [119, 134],
timeZone: .gmt,
earliestDateToInclude: Date(timeIntervalSinceNow: -3600*24*7),
latestDateToInclude: Date(),
pageSize: 3,
pageNumber: 1,
orderBy: .itemsSold,
order: .descending) { result in
promise(result)
})
}

// Then
let receivedSegments = try XCTUnwrap(result.get())
XCTAssertEqual(receivedSegments.count, 1)
XCTAssertEqual(receivedSegments.first, segment)
}

func test_fetchProductReports_returns_error_on_failure() throws {
// Given
let mockRemote = MockProductsRemote()
mockRemote.whenFetchingProductReports(thenReturn: .failure(NetworkError.timeout()))
let productStore = ProductStore(dispatcher: dispatcher,
storageManager: storageManager,
network: network,
remote: mockRemote)

// When
let result = waitFor { promise in
productStore.onAction(ProductAction.fetchProductReports(siteID: self.sampleSiteID,
productIDs: [119, 134],
timeZone: .gmt,
earliestDateToInclude: Date(timeIntervalSinceNow: -3600*24*7),
latestDateToInclude: Date(),
pageSize: 3,
pageNumber: 1,
orderBy: .itemsSold,
order: .descending,
completion: { result in
promise(result)
}))
}

// Then
XCTAssertTrue(result.isFailure)
XCTAssertEqual(result.failure as? NetworkError, .timeout())
}
}

// MARK: - Private Helpers
Expand Down