diff --git a/Modules/Sources/Storage/Tools/StorageType+Extensions.swift b/Modules/Sources/Storage/Tools/StorageType+Extensions.swift index 3057f8156c2..ae9c041e024 100644 --- a/Modules/Sources/Storage/Tools/StorageType+Extensions.swift +++ b/Modules/Sources/Storage/Tools/StorageType+Extensions.swift @@ -600,6 +600,13 @@ public extension StorageType { return allObjects(ofType: WooShippingCustomPackage.self, matching: predicate, sortedBy: [descriptor]) } + /// Returns all stored shipments for a site and order. + /// + func loadAllShipments(siteID: Int64, orderID: Int64) -> [WooShippingShipment] { + let predicate = \WooShippingShipment.siteID == siteID && \WooShippingShipment.orderID == orderID + return allObjects(ofType: WooShippingShipment.self, matching: predicate, sortedBy: nil) + } + // MARK: - BlazeCampaignListItem /// Returns a single BlazeCampaignListItem given a `siteID` and `campaignID` diff --git a/Modules/Sources/Yosemite/Actions/WooShippingAction.swift b/Modules/Sources/Yosemite/Actions/WooShippingAction.swift index 5e51861785a..783b47609fe 100644 --- a/Modules/Sources/Yosemite/Actions/WooShippingAction.swift +++ b/Modules/Sources/Yosemite/Actions/WooShippingAction.swift @@ -105,13 +105,13 @@ public enum WooShippingAction: Action { orderID: Int64, completion: (Result) -> Void) - /// Sync shipping labels for a given order. - /// This uses the same endpoint as `loadConfig` but also stores shipping labels to the storage + /// Sync shipments for a given order. + /// This uses the same endpoint as `loadConfig` but also stores shipments and shipping labels to the storage /// and returns them in the completion closure. /// - case syncShippingLabels(siteID: Int64, - orderID: Int64, - completion: (Result<[ShippingLabel], Error>) -> Void) + case syncShipments(siteID: Int64, + orderID: Int64, + completion: (Result<[WooShippingShipment], Error>) -> Void) /// Updates shipments for given order /// diff --git a/Modules/Sources/Yosemite/Stores/WooShippingStore.swift b/Modules/Sources/Yosemite/Stores/WooShippingStore.swift index 8dc2bfc4e94..ed683d48b0d 100644 --- a/Modules/Sources/Yosemite/Stores/WooShippingStore.swift +++ b/Modules/Sources/Yosemite/Stores/WooShippingStore.swift @@ -84,8 +84,8 @@ public final class WooShippingStore: Store { updateDestinationAddress(siteID: siteID, orderID: orderID, address: address, completion: completion) case let .loadConfig(siteID, orderID, completion): loadConfig(siteID: siteID, orderID: orderID, completion: completion) - case let .syncShippingLabels(siteID, orderID, completion): - syncShippingLabels(siteID: siteID, orderID: orderID, completion: completion) + case let .syncShipments(siteID, orderID, completion): + syncShipments(siteID: siteID, orderID: orderID, completion: completion) case let .updateShipment(siteID, orderID, shipmentToUpdate, completion): updateShipment(siteID: siteID, orderID: orderID, @@ -290,26 +290,23 @@ private extension WooShippingStore { remote.acceptUPSTermsOfService(siteID: siteID, originAddress: originAddress, completion: completion) } - func syncShippingLabels(siteID: Int64, - orderID: Int64, - completion: @escaping (Result<[ShippingLabel], Error>) -> Void) { - remote.loadConfig(siteID: siteID, orderID: orderID, completion: { [weak self] result in + func syncShipments(siteID: Int64, + orderID: Int64, + completion: @escaping (Result<[WooShippingShipment], Error>) -> Void) { + remote.loadConfig(siteID: siteID, orderID: orderID) { [weak self] result in guard let self else { return } - switch result { case .failure(let error): completion(.failure(error)) case .success(let config): - guard let labels = config.shippingLabelData?.currentOrderLabels else { - return completion(.success([])) - } - upsertShippingLabelsInBackground(siteID: siteID, - orderID: orderID, - shippingLabels: labels) { - completion(.success(labels)) + let shipments = config.shipments + upsertShipmentsInBackground(siteID: siteID, + orderID: orderID, + shipments: shipments) { + completion(.success(shipments)) } } - }) + } } } @@ -679,35 +676,60 @@ private extension WooShippingStore { }, completion: nil, on: .main) } - /// Updates/inserts the specified readonly shipping label entities *in a background thread*. + /// Updates/inserts the specified readonly shipments entities *in a background thread*. /// `onCompletion` will be called on the main thread! - func upsertShippingLabelsInBackground(siteID: Int64, - orderID: Int64, - shippingLabels: [ShippingLabel], - onCompletion: @escaping () -> Void) { - if shippingLabels.isEmpty { - return onCompletion() - } - + func upsertShipmentsInBackground(siteID: Int64, + orderID: Int64, + shipments: [WooShippingShipment], + onCompletion: @escaping () -> Void) { storageManager.performAndSave ({ [weak self] storage in guard let self else { return } guard let order = storage.loadOrder(siteID: siteID, orderID: orderID) else { return } - upsertShippingLabels(siteID: siteID, orderID: orderID, shippingLabels: shippingLabels, storageOrder: order, using: storage) + upsertShipments(siteID: siteID, + orderID: orderID, + shipments: shipments, + storageOrder: order, + using: storage) }, completion: onCompletion, on: .main) } - /// Updates/inserts the specified readonly ShippingLabel entities in the current thread. - func upsertShippingLabels(siteID: Int64, - orderID: Int64, - shippingLabels: [ShippingLabel], - storageOrder: StorageOrder, - using storage: StorageType) { - let storedLabels = storage.loadAllShippingLabels(siteID: siteID, orderID: orderID) - for shippingLabel in shippingLabels { - let storageShippingLabel = storedLabels.first(where: { $0.shippingLabelID == shippingLabel.shippingLabelID }) ?? - storage.insertNewObject(ofType: Storage.ShippingLabel.self) + /// Updates/inserts the specified readonly WooShippingShipments entities in the current thread. + func upsertShipments(siteID: Int64, + orderID: Int64, + shipments: [WooShippingShipment], + storageOrder: StorageOrder, + using storage: StorageType) { + let storedShipments = storage.loadAllShipments(siteID: siteID, orderID: orderID) + for shipment in shipments { + let storageShipment = storedShipments.first(where: { $0.index == shipment.index }) ?? + storage.insertNewObject(ofType: Storage.WooShippingShipment.self) + storageShipment.update(with: shipment) + storageShipment.order = storageOrder + + handleShipmentItems(shipment, storageShipment, storage) + update(storageShipment: storageShipment, + storageOrder: storageOrder, + shippingLabel: shipment.shippingLabel, + using: storage) + } + + // Now, remove any objects that exist in storage but not in shipments + let shipmentIndices = shipments.map(\.index) + storedShipments.filter { + !shipmentIndices.contains($0.index) + }.forEach { + storage.deleteObject($0) + } + } + + func update(storageShipment: StorageWooShippingShipment, + storageOrder: StorageOrder, + shippingLabel: ShippingLabel?, + using storage: StorageType) { + if let shippingLabel { + let storageShippingLabel = storageShipment.shippingLabel ?? storage.insertNewObject(ofType: Storage.ShippingLabel.self) storageShippingLabel.update(with: shippingLabel) storageShippingLabel.order = storageOrder @@ -720,14 +742,39 @@ private extension WooShippingStore { let destinationAddress = storageShippingLabel.destinationAddress ?? storage.insertNewObject(ofType: Storage.ShippingLabelAddress.self) destinationAddress.update(with: shippingLabel.destinationAddress) storageShippingLabel.destinationAddress = destinationAddress + + /// Set the shipping label to the shipment's relationship + storageShipment.shippingLabel = storageShippingLabel + } else { + storageShipment.shippingLabel = nil } + } - // Now, remove any objects that exist in storage but not in shippingLabels - let shippingLabelIDs = shippingLabels.map(\.shippingLabelID) - storedLabels.filter { - !shippingLabelIDs.contains($0.shippingLabelID) - }.forEach { - storage.deleteObject($0) + /// Updates, inserts, or prunes the provided StorageWooShippingShipment's items using the provided read-only WooShippingShipment's items + /// + private func handleShipmentItems(_ readOnlyShipment: Networking.WooShippingShipment, + _ storageShipment: Storage.WooShippingShipment, + _ storage: StorageType) { + + let storageItemsArray = Array(storageShipment.items ?? []) + + // Upsert the items from the read-only shipment + for readOnlyItem in readOnlyShipment.items { + if let existingStorageItem = storageItemsArray.first(where: { $0.id == readOnlyItem.id }) { + existingStorageItem.update(with: readOnlyItem) + } else { + let newStorageItem = storage.insertNewObject(ofType: Storage.WooShippingShipmentItem.self) + newStorageItem.update(with: readOnlyItem) + storageShipment.addToItems(newStorageItem) + } + } + + // Now, remove any objects that exist in storageShipment.items but not in readOnlyShipment.items + storageItemsArray.forEach { storageItem in + if readOnlyShipment.items.first(where: { $0.id == storageItem.id } ) == nil { + storageShipment.removeFromItems(storageItem) + storage.deleteObject(storageItem) + } } } diff --git a/Modules/Tests/YosemiteTests/Stores/WooShippingStoreTests.swift b/Modules/Tests/YosemiteTests/Stores/WooShippingStoreTests.swift index e7f3493aa8d..4e19f573f67 100644 --- a/Modules/Tests/YosemiteTests/Stores/WooShippingStoreTests.swift +++ b/Modules/Tests/YosemiteTests/Stores/WooShippingStoreTests.swift @@ -1035,80 +1035,6 @@ final class WooShippingStoreTests: XCTestCase { XCTAssertEqual(error as? NetworkError, expectedError) } - // MARK: `syncShippingLabels` - - func test_syncShippingLabels_persists_shipping_labels_on_success() throws { - // Given - let remote = MockWooShippingRemote() - let orderID: Int64 = 22 - let expectedShippingLabel: Yosemite.ShippingLabel = { - let origin = ShippingLabelAddress(company: "fun testing", - name: "Woo seller", - phone: "6501234567", - country: "US", - state: "CA", - address1: "9999 19TH AVE", - address2: "", - city: "SAN FRANCISCO", - postcode: "94121-2303") - let destination = ShippingLabelAddress(company: "", - name: "Woo buyer", - phone: "1650345689", - country: "TW", - state: "Taiwan", - address1: "No 70 RA St", - address2: "", - city: "Taipei", - postcode: "100") - let refund = ShippingLabelRefund(dateRequested: Date(timeIntervalSince1970: 1603716266.809), status: .pending) - return ShippingLabel(siteID: sampleSiteID, - orderID: orderID, - shippingLabelID: 1149, - carrierID: "usps", - shipmentID: "0", - dateCreated: Date(timeIntervalSince1970: 1603716274.809), - packageName: "box", - rate: 58.81, - currency: "USD", - trackingNumber: "CM199912222US", - serviceName: "USPS - Priority Mail International", - refundableAmount: 58.81, - status: .purchased, - refund: refund, - originAddress: origin, - destinationAddress: destination, - productIDs: [3013], - productNames: ["Password protected!"], - commercialInvoiceURL: nil, - usedDate: nil, - expiryDate: nil) - }() - let expectedResponse = WooShippingConfig.fake().copy( - shipments: [WooShippingShipment.fake()], - shippingLabelData: WooShippingLabelData(currentOrderLabels: [expectedShippingLabel]) - ) - remote.whenLoadingConfig(siteID: sampleSiteID, thenReturn: .success(expectedResponse)) - - let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote) - insertOrder(siteID: sampleSiteID, orderID: orderID) - - // When - let result: Result<[Yosemite.ShippingLabel], Error> = waitFor { promise in - let action = WooShippingAction.syncShippingLabels(siteID: self.sampleSiteID, orderID: orderID) { result in - promise(result) - } - store.onAction(action) - } - - // Then - XCTAssertTrue(result.isSuccess) - - let persistedOrder = try XCTUnwrap(viewStorage.loadOrder(siteID: sampleSiteID, orderID: orderID)) - let persistedShippingLabels = try XCTUnwrap(viewStorage.loadAllShippingLabels(siteID: sampleSiteID, orderID: orderID)) - XCTAssertEqual(persistedOrder.shippingLabels, Set(persistedShippingLabels)) - XCTAssertEqual(persistedShippingLabels.map { $0.toReadOnly() }, [expectedShippingLabel]) - } - // MARK: `updateShipment` func test_updateShipment_returns_success_response() throws { @@ -1309,6 +1235,96 @@ final class WooShippingStoreTests: XCTestCase { let error = try XCTUnwrap(result.failure) XCTAssertEqual(error as? NetworkError, expectedError) } + + // MARK: `syncShipments` + + func test_syncShipments_returns_shipments_on_success() throws { + // Given + let remote = MockWooShippingRemote() + let expectedShipments = [WooShippingShipment.fake(), WooShippingShipment.fake()] + let config = WooShippingConfig.fake().copy(shipments: expectedShipments) + remote.whenLoadingConfig(siteID: sampleSiteID, thenReturn: .success(config)) + let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote) + + // When + let result: Result<[WooShippingShipment], Error> = waitFor { promise in + let action = WooShippingAction.syncShipments(siteID: self.sampleSiteID, + orderID: self.sampleOrderID) { result in + promise(result) + } + store.onAction(action) + } + + // Then + let actualShipments = try XCTUnwrap(result.get()) + XCTAssertEqual(actualShipments, expectedShipments) + } + + func test_syncShipments_returns_error_on_failure() throws { + // Given + let remote = MockWooShippingRemote() + let expectedError = NetworkError.timeout() + remote.whenLoadingConfig(siteID: sampleSiteID, thenReturn: .failure(expectedError)) + let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote) + + // When + let result: Result<[WooShippingShipment], Error> = waitFor { promise in + let action = WooShippingAction.syncShipments(siteID: self.sampleSiteID, + orderID: self.sampleOrderID) { result in + promise(result) + } + store.onAction(action) + } + + // Then + let error = try XCTUnwrap(result.failure) + XCTAssertEqual(error as? NetworkError, expectedError) + } + + func test_syncShipments_persists_shipments_to_storage_on_success() throws { + // Given + let remote = MockWooShippingRemote() + insertOrder(siteID: sampleSiteID, orderID: sampleOrderID) + + let shippingLabel = ShippingLabel.fake().copy( + siteID: sampleSiteID, + orderID: sampleOrderID, + shippingLabelID: 123 + ) + let item = WooShippingShipmentItem(id: 11, subItems: []) + let expectedShipments = [WooShippingShipment.fake().copy( + siteID: sampleSiteID, + orderID: sampleOrderID, + index: "0", + items: [item], + shippingLabel: shippingLabel + )] + let config = WooShippingConfig.fake().copy(shipments: expectedShipments) + remote.whenLoadingConfig(siteID: sampleSiteID, thenReturn: .success(config)) + + let store = WooShippingStore(dispatcher: dispatcher, + storageManager: storageManager, + network: network, + remote: remote) + + // When + let result: Result<[WooShippingShipment], Error> = waitFor { promise in + let action = WooShippingAction.syncShipments(siteID: self.sampleSiteID, + orderID: self.sampleOrderID) { result in + promise(result) + } + store.onAction(action) + } + + // Then + XCTAssertTrue(result.isSuccess) + XCTAssertEqual(viewStorage.countObjects(ofType: StorageWooShippingShipment.self), expectedShipments.count) + let object = viewStorage.loadAllShipments(siteID: sampleSiteID, orderID: sampleOrderID).first + XCTAssertEqual(object?.order?.orderID, sampleOrderID) + XCTAssertEqual(object?.shippingLabel?.shippingLabelID, shippingLabel.shippingLabelID) + XCTAssertEqual(object?.items?.count, 1) + XCTAssertEqual(object?.items?.first?.id, item.id) + } } private extension WooShippingStoreTests { diff --git a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsResultsControllers.swift b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsResultsControllers.swift index 75dabaa0115..31fe2a2832c 100644 --- a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsResultsControllers.swift +++ b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsResultsControllers.swift @@ -75,6 +75,17 @@ final class OrderDetailsResultsControllers { return ResultsController(storageManager: storageManager, matching: predicate, sortedBy: []) }() + /// Shipments Results Controller. + /// + private lazy var shipmentResultsController: ResultsController = { + let predicate = NSPredicate(format: "siteID = %ld AND orderID = %ld", + self.order.siteID, + self.order.orderID) + let descriptor = NSSortDescriptor(keyPath: \StorageWooShippingShipment.index, ascending: true) + + return ResultsController(storageManager: storageManager, matching: predicate, sortedBy: [descriptor]) + }() + /// Order shipment tracking list /// var orderTracking: [ShipmentTracking] { @@ -108,7 +119,10 @@ final class OrderDetailsResultsControllers { /// Shipping labels for an Order /// var shippingLabels: [ShippingLabel] { - order.shippingLabels.sorted(by: { label1, label2 in + guard shipments.isEmpty else { + return shipments.compactMap { $0.shippingLabel } + } + return order.shippingLabels.sorted(by: { label1, label2 in if let shipmentID1 = label1.shipmentID, let shipmentID2 = label2.shipmentID { return shipmentID1.localizedStandardCompare(shipmentID2) == .orderedAscending @@ -117,6 +131,10 @@ final class OrderDetailsResultsControllers { }) } + var shipments: [WooShippingShipment] { + shipmentResultsController.fetchedObjects + } + /// Site's add-on groups. /// var addOnGroups: [AddOnGroup] { @@ -158,6 +176,7 @@ final class OrderDetailsResultsControllers { configureAddOnGroupResultsController(onReload: onReload) configureSitePluginsResultsController(onReload: onReload) configureShippingMethodsResultsController(onReload: onReload) + configureShipmentResultsController(onReload: onReload) } func update(order: Order) { @@ -182,6 +201,26 @@ private extension OrderDetailsResultsControllers { return ResultsController(storageManager: storageManager, matching: predicate, sortedBy: []) } + func configureShipmentResultsController(onReload: @escaping () -> Void) { + shipmentResultsController.onDidChangeContent = { + onReload() + } + + shipmentResultsController.onDidResetContent = { [weak self] in + guard let self = self else { + return + } + self.refetchAllResultsControllers() + onReload() + } + + do { + try shipmentResultsController.performFetch() + } catch { + DDLogError("⛔️ Unable to fetch Order Statuses: \(error)") + } + } + func configureStatusResultsController() { do { try statusResultsController.performFetch() diff --git a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift index d41ccfa2261..3ad3f05eb6d 100644 --- a/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift +++ b/WooCommerce/Classes/ViewModels/Order Details/OrderDetailsViewModel.swift @@ -282,11 +282,8 @@ extension OrderDetailsViewModel { taskGroup.addTask { [weak self] in guard let self else { return } - // Sync shipping labels and update order with the result if available - let shippingLabels = await syncShippingLabels() - // Update the order with the newly synced shipping labels - let updatedOrder = order.copy(shippingLabels: shippingLabels) - update(order: updatedOrder) + // Sync shipping labels or shipments and update order with the result if available + await syncShippingLabelsOrShipments() } } @@ -702,27 +699,32 @@ extension OrderDetailsViewModel { stores.dispatch(action) } - @discardableResult - @MainActor func syncShippingLabels() async -> [ShippingLabel] { + @MainActor func syncShippingLabelsOrShipments() async { let isRevampedFlow = featureFlagService.isFeatureFlagEnabled(.revampedShippingLabelCreation) guard isRevampedFlow else { /// old logic for syncing labels - if await localRequirementsForShippingLabelsAreFulfilled() { - return await syncShippingLabelsForLegacyPlugin(isRevampedFlow: isRevampedFlow) - } - return [] + let shippingLabels: [ShippingLabel] = await { + if await localRequirementsForShippingLabelsAreFulfilled() { + return await syncShippingLabelsForLegacyPlugin(isRevampedFlow: isRevampedFlow) + } + return [] + }() + // Update the order with the newly synced shipping labels + let updatedOrder = order.copy(shippingLabels: shippingLabels) + return update(order: updatedOrder) } guard !orderContainsOnlyVirtualProducts else { - return [] + return } if await isPluginActive(pluginPath: SitePlugin.SupportedPluginPath.WooShipping) { - return await syncShippingLabelsForWooShipping() + syncShipmentsForWooShipping() } else if await isPluginActive(pluginPath: SitePlugin.SupportedPluginPath.LegacyWCShip) { - return await syncShippingLabelsForLegacyPlugin(isRevampedFlow: isRevampedFlow) - } else { - return [] + let shippingLabels = await syncShippingLabelsForLegacyPlugin(isRevampedFlow: isRevampedFlow) + // Update the order with the newly synced shipping labels + let updatedOrder = order.copy(shippingLabels: shippingLabels) + update(order: updatedOrder) } } @@ -990,46 +992,46 @@ private extension OrderDetailsViewModel { } } - @MainActor func syncShippingLabelsForWooShipping() async -> [ShippingLabel] { - await withCheckedContinuation { continuation in - stores.dispatch(WooShippingAction.syncShippingLabels(siteID: order.siteID, orderID: order.orderID) { [weak self] result in - let labels = self?.handleShippingLabelSyncingResult(result: result, isRevampedFlow: true) ?? [] - continuation.resume(returning: labels) - }) - } + func syncShipmentsForWooShipping() { + stores.dispatch(WooShippingAction.syncShipments(siteID: order.siteID, orderID: order.orderID) { result in + switch result { + case .success(let shipments): + ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( + result: .success, + isRevampedFlow: true + )) + case .failure(let error): + ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( + result: .failed(error: error), + isRevampedFlow: true + )) + DDLogError("⛔️ Error synchronizing shipping labels: \(error)") + } + }) } @MainActor func syncShippingLabelsForLegacyPlugin(isRevampedFlow: Bool) async -> [ShippingLabel] { await withCheckedContinuation { continuation in - stores.dispatch(ShippingLabelAction.synchronizeShippingLabels(siteID: order.siteID, orderID: order.orderID) { [weak self] result in - let labels = self?.handleShippingLabelSyncingResult(result: result, isRevampedFlow: isRevampedFlow) ?? [] - continuation.resume(returning: labels) + stores.dispatch(ShippingLabelAction.synchronizeShippingLabels(siteID: order.siteID, orderID: order.orderID) { result in + switch result { + case .success(let shippingLabels): + ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( + result: .success, + isRevampedFlow: isRevampedFlow + )) + continuation.resume(returning: shippingLabels) + case .failure(let error): + ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( + result: .failed(error: error), + isRevampedFlow: isRevampedFlow + )) + DDLogError("⛔️ Error synchronizing shipping labels: \(error)") + continuation.resume(returning: []) + } }) } } - func handleShippingLabelSyncingResult(result: Result<[ShippingLabel], Error>, isRevampedFlow: Bool) -> [ShippingLabel] { - switch result { - case .success(let shippingLabels): - ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( - result: .success, - isRevampedFlow: isRevampedFlow - )) - return shippingLabels - case .failure(let error): - ServiceLocator.analytics.track(event: .shippingLabelsAPIRequest( - result: .failed(error: error), - isRevampedFlow: isRevampedFlow - )) - if error as? DotcomError == .noRestRoute { - DDLogError("⚠️ Endpoint for synchronizing shipping labels is unreachable. WC Shipping plugin may be missing.") - } else { - DDLogError("⛔️ Error synchronizing shipping labels: \(error)") - } - return [] - } - } - @MainActor func isPluginActive(_ plugin: String) async -> Bool { return await isPluginActive([plugin]) diff --git a/WooCommerce/WooCommerceTests/ViewRelated/OrderDetailsViewModelTests.swift b/WooCommerce/WooCommerceTests/ViewRelated/OrderDetailsViewModelTests.swift index a94cfacabdd..7e1342dc715 100644 --- a/WooCommerce/WooCommerceTests/ViewRelated/OrderDetailsViewModelTests.swift +++ b/WooCommerce/WooCommerceTests/ViewRelated/OrderDetailsViewModelTests.swift @@ -75,7 +75,7 @@ final class OrderDetailsViewModelTests: XCTestCase { XCTAssertEqual(status, .completed) } - // MARK: - `syncShippingLabels` + // MARK: - `syncShippingLabelsOrShipments` func test_syncShippingLabels_without_a_non_virtual_product_does_not_dispatch_actions() async throws { // Given @@ -83,7 +83,7 @@ final class OrderDetailsViewModelTests: XCTestCase { XCTAssertEqual(storesManager.receivedActions.count, 0) // When - await viewModel.syncShippingLabels() + await viewModel.syncShippingLabelsOrShipments() // Then no actions are dispatched XCTAssertEqual(storesManager.receivedActions.count, 0) @@ -107,7 +107,7 @@ final class OrderDetailsViewModelTests: XCTestCase { featureFlagService: featureFlagService) // When - await viewModel.syncShippingLabels() + await viewModel.syncShippingLabelsOrShipments() // Then XCTAssertEqual(storesManager.receivedActions.count, 3) @@ -152,7 +152,7 @@ final class OrderDetailsViewModelTests: XCTestCase { let plugin = insertSystemPlugin(path: SitePlugin.SupportedPluginPath.WooShipping, siteID: order.siteID, isActive: true) whenFetchingSystemPlugin(path: SitePlugin.SupportedPluginPath.WooShipping, thenReturn: plugin) - whenSyncingShippingLabels(thenReturn: .success([])) + whenSyncingShipments(thenReturn: .success([])) let featureFlagService = MockFeatureFlagService(revampedShippingLabelCreation: true) let viewModel = OrderDetailsViewModel(order: order, @@ -161,7 +161,7 @@ final class OrderDetailsViewModelTests: XCTestCase { featureFlagService: featureFlagService) // When - await viewModel.syncShippingLabels() + await viewModel.syncShippingLabelsOrShipments() // Then XCTAssertEqual(storesManager.receivedActions.count, 2) @@ -178,7 +178,7 @@ final class OrderDetailsViewModelTests: XCTestCase { // WooShippingAction.syncShippingLabels let secondAction = try XCTUnwrap(storesManager.receivedActions[1] as? WooShippingAction) - guard case let WooShippingAction.syncShippingLabels(siteID, orderID, _) = secondAction else { + guard case let WooShippingAction.syncShipments(siteID, orderID, _) = secondAction else { XCTFail("Expected \(secondAction) to be \(WooShippingAction.self)") return } @@ -205,7 +205,7 @@ final class OrderDetailsViewModelTests: XCTestCase { featureFlagService: featureFlagService) // When - await viewModel.syncShippingLabels() + await viewModel.syncShippingLabelsOrShipments() // Then XCTAssertEqual(storesManager.receivedActions.count, 3) @@ -789,10 +789,10 @@ private extension OrderDetailsViewModelTests { } } - func whenSyncingShippingLabels(thenReturn result: Result<[ShippingLabel], Error>) { + func whenSyncingShipments(thenReturn result: Result<[WooShippingShipment], Error>) { storesManager.whenReceivingAction(ofType: WooShippingAction.self) { action in switch action { - case let .syncShippingLabels(_, _, completion): + case let .syncShipments(_, _, completion): completion(result) default: break