Skip to content

Commit

Permalink
[Shipping labels] Add Yosemite support for creating package (#14361)
Browse files Browse the repository at this point in the history
  • Loading branch information
rachelmcr authored Nov 11, 2024
2 parents f55c962 + de6aa9f commit cb4e6bd
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 2 deletions.
11 changes: 10 additions & 1 deletion Networking/Networking/Remote/WooShippingRemote.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
/// Protocol for `WooShippingRemote` mainly used for mocking.
///
public protocol WooShippingRemoteProtocol {
func createPackage(siteID: Int64,
customPackage: WooShippingCustomPackage?,
predefinedOption: WooShippingPredefinedOption?,
completion: @escaping (Result<WooShippingCreatePackageResponse, Error>) -> Void)
}

/// Shipping Labels Remote Endpoints for the WooShipping Plugin.
///
public final class WooShippingRemote: Remote {
public final class WooShippingRemote: Remote, WooShippingRemoteProtocol {

/// Creates a new custom package.
/// - Parameters:
Expand Down
3 changes: 2 additions & 1 deletion WooCommerce/Classes/Yosemite/AuthenticatedState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ class AuthenticatedState: StoresManagerState {
WordPressSiteStore(network: network, dispatcher: dispatcher),
StoreOnboardingTasksStore(dispatcher: dispatcher, storageManager: storageManager, network: network),
GoogleAdsStore(dispatcher: dispatcher, storageManager: storageManager, network: network),
MetaDataStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
MetaDataStore(dispatcher: dispatcher, storageManager: storageManager, network: network),
WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network)
]


Expand Down
16 changes: 16 additions & 0 deletions Yosemite/Yosemite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,10 @@
CE606D9E2BE3BE1B001CB424 /* ShippingMethodStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE606D9D2BE3BE1B001CB424 /* ShippingMethodStore.swift */; };
CE606DA02BE3BE75001CB424 /* ShippingMethodAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE606D9F2BE3BE75001CB424 /* ShippingMethodAction.swift */; };
CE606DA22BE3C331001CB424 /* ShippingMethodStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE606DA12BE3C331001CB424 /* ShippingMethodStoreTests.swift */; };
CEC7D5972CDE35AD00111B79 /* WooShippingAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC7D5962CDE35A700111B79 /* WooShippingAction.swift */; };
CEC7D5992CDE360E00111B79 /* WooShippingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC7D5982CDE360B00111B79 /* WooShippingStore.swift */; };
CEC7D59D2CDE3D9D00111B79 /* WooShippingStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC7D59C2CDE3D9D00111B79 /* WooShippingStoreTests.swift */; };
CEC7D59F2CDE692900111B79 /* MockWooShippingRemote.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC7D59E2CDE692400111B79 /* MockWooShippingRemote.swift */; };
CECC504023675DF4004540EA /* RefundStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECC503F23675DF4004540EA /* RefundStoreTests.swift */; };
CECE6BBE2BA9DE3200A57C1F /* WCAnalyticsCustomer+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CECE6BBD2BA9DE3200A57C1F /* WCAnalyticsCustomer+ReadOnlyConvertible.swift */; };
CEE9188C29F7F68C004B23FF /* OrderGiftCard+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEE9188B29F7F68C004B23FF /* OrderGiftCard+ReadOnlyConvertible.swift */; };
Expand Down Expand Up @@ -908,6 +912,10 @@
CE606D9D2BE3BE1B001CB424 /* ShippingMethodStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingMethodStore.swift; sourceTree = "<group>"; };
CE606D9F2BE3BE75001CB424 /* ShippingMethodAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingMethodAction.swift; sourceTree = "<group>"; };
CE606DA12BE3C331001CB424 /* ShippingMethodStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShippingMethodStoreTests.swift; sourceTree = "<group>"; };
CEC7D5962CDE35A700111B79 /* WooShippingAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingAction.swift; sourceTree = "<group>"; };
CEC7D5982CDE360B00111B79 /* WooShippingStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingStore.swift; sourceTree = "<group>"; };
CEC7D59C2CDE3D9D00111B79 /* WooShippingStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingStoreTests.swift; sourceTree = "<group>"; };
CEC7D59E2CDE692400111B79 /* MockWooShippingRemote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockWooShippingRemote.swift; sourceTree = "<group>"; };
CECC503F23675DF4004540EA /* RefundStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RefundStoreTests.swift; sourceTree = "<group>"; };
CECE6BBD2BA9DE3200A57C1F /* WCAnalyticsCustomer+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WCAnalyticsCustomer+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
CEE9188B29F7F68C004B23FF /* OrderGiftCard+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderGiftCard+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1401,6 +1409,7 @@
578CE7912475EC9200492EBF /* MockProductsRemote.swift */,
020C908024C7D71D001E2BEB /* MockProductVariationsRemote.swift */,
02E7FFD82562234F00C53030 /* MockShippingLabelRemote.swift */,
CEC7D59E2CDE692400111B79 /* MockWooShippingRemote.swift */,
03FBDA2D2632A9B400ACE257 /* MockCouponsRemote.swift */,
D4CBAE5F26D440FA00BBE6D1 /* MockAnnouncementsRemote.swift */,
02A26F1D2744FE97008E4EDB /* MockAccountRemote.swift */,
Expand Down Expand Up @@ -1666,6 +1675,7 @@
AEF945882729766D001DCCFB /* TelemetryStore.swift */,
02FF056423DE9C8B0058E6E7 /* MediaStore.swift */,
029BA556255E0CD4006171FD /* ShippingLabelStore.swift */,
CEC7D5982CDE360B00111B79 /* WooShippingStore.swift */,
DEFD6D9426443CA100E51E0D /* SitePluginStore.swift */,
077F39DF26A5A6F500ABEADC /* SystemStatusStore.swift */,
FE28F6EF26844231004465C7 /* UserStore.swift */,
Expand Down Expand Up @@ -1754,6 +1764,7 @@
DEDA8DB22B184B950076BF0F /* WordPressThemeStoreTests.swift */,
DEB387852C2C09A70025256E /* GoogleAdsStoreTests.swift */,
453954DB2C91F79B00A3E64A /* MetaDataStoreTests.swift */,
CEC7D59C2CDE3D9D00111B79 /* WooShippingStoreTests.swift */,
);
path = Stores;
sourceTree = "<group>";
Expand Down Expand Up @@ -1939,6 +1950,7 @@
026CF627237D8F30009563D4 /* ProductVariationAction.swift */,
025CA2CB238F518600B05C81 /* ProductShippingClassAction.swift */,
029BA55A255E0D39006171FD /* ShippingLabelAction.swift */,
CEC7D5962CDE35A700111B79 /* WooShippingAction.swift */,
45010694239A6CDE00E24722 /* TaxAction.swift */,
AEF945862729760F001DCCFB /* TelemetryAction.swift */,
022F00BF24725BC6008CD97F /* NotificationCountAction.swift */,
Expand Down Expand Up @@ -2451,6 +2463,7 @@
D4CBAE6426D4464500BBE6D1 /* AnnouncementsAction.swift in Sources */,
EEB4E2C929B0489800371C3C /* StoreOnboardingTasksStore.swift in Sources */,
CE43A90222A072D800A4FF29 /* ProductDownload+ReadOnlyConvertible.swift in Sources */,
CEC7D5972CDE35AD00111B79 /* WooShippingAction.swift in Sources */,
B5C9DE182087FF0E006B910A /* Assert.swift in Sources */,
CE606DA02BE3BE75001CB424 /* ShippingMethodAction.swift in Sources */,
DE3C5B1D286AEDA10049E6AA /* MockOrderCardPresentPaymentEligibilityActionHandler.swift in Sources */,
Expand Down Expand Up @@ -2501,6 +2514,7 @@
247CE86825832BEE00F9D9D1 /* MockShippingLabelActionHandler.swift in Sources */,
0232372922F7DA6E00715FAB /* StatsTimeRangeV4.swift in Sources */,
247CE85C25832A5000F9D9D1 /* MockProductVariationActionHandler.swift in Sources */,
CEC7D5992CDE360E00111B79 /* WooShippingStore.swift in Sources */,
B5F2AE9720EBB54A00FEDC59 /* FetchedResultsControllerDelegateWrapper.swift in Sources */,
247CE7C02582DC7200F9D9D1 /* ProductImage+Mocks.swift in Sources */,
7492FADF217FB11D00ED2C69 /* SettingAction.swift in Sources */,
Expand Down Expand Up @@ -2631,6 +2645,7 @@
B53A56A0211245E0000776C9 /* MockStorageManager+Sample.swift in Sources */,
453305FB245AEDCB00264E50 /* SitePostStoreTests.swift in Sources */,
744914F7224AD2AF00546DE4 /* ProductStoreTests.swift in Sources */,
CEC7D59F2CDE692900111B79 /* MockWooShippingRemote.swift in Sources */,
0218B4F2242E09E80083A847 /* MediaTypeTests.swift in Sources */,
578CE78C2475E7A500492EBF /* MockNotificationsRemote.swift in Sources */,
B5A01CA120D19C4700E3207E /* MockStorageManager.swift in Sources */,
Expand All @@ -2650,6 +2665,7 @@
D8C11A5A22DFC21600D4A88D /* StatsStoreV4Tests.swift in Sources */,
261CF2C7255C445A0090D8D3 /* PaymentGatewayStoreTests.swift in Sources */,
DE2E8EAF29541C32002E4B14 /* WordPressSiteStoreTests.swift in Sources */,
CEC7D59D2CDE3D9D00111B79 /* WooShippingStoreTests.swift in Sources */,
0286A1BC2A0CC4120099EF94 /* FeatureFlagStoreTests.swift in Sources */,
2685C121263E064200D9EE97 /* AddOnGroupStoreTests.swift in Sources */,
B9AECD482851F28E00E78584 /* Order+CardPresentPaymentTests.swift in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions Yosemite/Yosemite/Actions/WooShippingAction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Networking

public enum WooShippingAction: Action {
/// Creates a custom package or activated a carrier package with provided package details.
///
case createPackage(siteID: Int64,
customPackage: WooShippingCustomPackage? = nil,
predefinedOption: WooShippingPredefinedOption? = nil,
completion: (Result<WooShippingCreatePackageResponse, PackageCreationError>) -> Void)
}
53 changes: 53 additions & 0 deletions Yosemite/Yosemite/Stores/WooShippingStore.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import Foundation
import Networking
import Storage

/// Implements `WooShippingAction` actions
///
public final class WooShippingStore: Store {
private let remote: WooShippingRemoteProtocol

public override init(dispatcher: Dispatcher, storageManager: StorageManagerType, network: Network) {
self.remote = WooShippingRemote(network: network)
super.init(dispatcher: dispatcher, storageManager: storageManager, network: network)
}

init(dispatcher: Dispatcher, storageManager: StorageManagerType, network: Network, remote: WooShippingRemoteProtocol) {
self.remote = remote
super.init(dispatcher: dispatcher, storageManager: storageManager, network: network)
}

/// Registers for supported Actions.
override public func registerSupportedActions(in dispatcher: Dispatcher) {
dispatcher.register(processor: self, for: WooShippingAction.self)
}

/// Receives and executes Actions.
override public func onAction(_ action: Action) {
guard let action = action as? WooShippingAction else {
assertionFailure("WooShippingStore received an unsupported action")
return
}

switch action {
case .createPackage(let siteID, let customPackage, let predefinedOption, let completion):
createPackage(siteID: siteID, customPackage: customPackage, predefinedOption: predefinedOption, completion: completion)
}
}
}

private extension WooShippingStore {
func createPackage(siteID: Int64,
customPackage: WooShippingCustomPackage? = nil,
predefinedOption: WooShippingPredefinedOption? = nil,
completion: @escaping (Result<WooShippingCreatePackageResponse, PackageCreationError>) -> Void) {
remote.createPackage(siteID: siteID, customPackage: customPackage, predefinedOption: predefinedOption) { result in
switch result {
case .success(let packages):
completion(.success(packages))
case .failure(let error):
completion(.failure(PackageCreationError(error: error)))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Networking
import XCTest

/// Mock for `WooShippingRemote`.
///
final class MockWooShippingRemote {

private struct CreatePackageResultKey: Hashable {
let siteID: Int64
}

/// The results to return based on the given arguments in `createPackage`
private var createPackageResults = [CreatePackageResultKey: Result<WooShippingCreatePackageResponse, Error>]()

/// Set the value passed to the `completion` block if `createPackage` is called.
func whenCreatePackage(siteID: Int64,
thenReturn result: Result<WooShippingCreatePackageResponse, Error>) {
let key = CreatePackageResultKey(siteID: siteID)
createPackageResults[key] = result
}
}

// MARK: - WooShippingRemoteProtocol
extension MockWooShippingRemote: WooShippingRemoteProtocol {
func createPackage(siteID: Int64,
customPackage: Networking.WooShippingCustomPackage?,
predefinedOption: Networking.WooShippingPredefinedOption?,
completion: @escaping (Result<Networking.WooShippingCreatePackageResponse, any Error>) -> Void) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }

let key = CreatePackageResultKey(siteID: siteID)
if let result = self.createPackageResults[key] {
completion(result)
} else {
XCTFail("\(String(describing: self)) Could not find Result for \(key)")
}
}
}
}
78 changes: 78 additions & 0 deletions Yosemite/YosemiteTests/Stores/WooShippingStoreTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import XCTest
@testable import Yosemite
@testable import Networking

final class WooShippingStoreTests: XCTestCase {

/// Mock Dispatcher!
///
private var dispatcher: Dispatcher!

/// Mock Storage: InMemory
///
private var storageManager: MockStorageManager!

/// Mock Network: Allows us to inject predefined responses!
///
private var network: MockNetwork!

/// Testing SiteID
///
private let sampleSiteID: Int64 = 123

override func setUp() {
super.setUp()
dispatcher = Dispatcher()
storageManager = MockStorageManager()
network = MockNetwork()
}

// MARK: `createPackage`

func test_createPackage_returns_success_response() throws {
// Given
let remote = MockWooShippingRemote()
let response = WooShippingCreatePackageResponse.fake().copy(customPackages: [WooShippingCustomPackage.fake()])
remote.whenCreatePackage(siteID: sampleSiteID, thenReturn: .success(response))
let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote)

// When
let result: Result<WooShippingCreatePackageResponse, PackageCreationError> = waitFor { promise in
let action = WooShippingAction.createPackage(siteID: self.sampleSiteID,
customPackage: WooShippingCustomPackage.fake(),
predefinedOption: nil) { result in
promise(result)
}
store.onAction(action)
}

// Then
XCTAssertTrue(result.isSuccess)
let actualResponse = try result.get()
XCTAssertEqual(actualResponse, response)
}

func test_createPackage_returns_error_on_failure() throws {
// Given
let remote = MockWooShippingRemote()
let error = DotcomError.unknown(code: "duplicate_custom_package_names_of_existing_packages",
message: "At least one of the new custom packages has the same name as existing packages.")
remote.whenCreatePackage(siteID: sampleSiteID, thenReturn: .failure(error))
let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote)

// When
let result: Result<WooShippingCreatePackageResponse, PackageCreationError> = waitFor { promise in
let action = WooShippingAction.createPackage(siteID: self.sampleSiteID,
customPackage: WooShippingCustomPackage.fake(),
predefinedOption: nil) { result in
promise(result)
}
store.onAction(action)
}

// Then
XCTAssertTrue(result.isFailure)
XCTAssertEqual(result.failure, .duplicatePackageNames)
}

}

0 comments on commit cb4e6bd

Please sign in to comment.