diff --git a/Fakes/Fakes/Networking.generated.swift b/Fakes/Fakes/Networking.generated.swift index 15ccac9bba7..a00b4d148dd 100644 --- a/Fakes/Fakes/Networking.generated.swift +++ b/Fakes/Fakes/Networking.generated.swift @@ -2761,6 +2761,23 @@ extension Networking.WooShippingAccountSettings { ) } } +extension Networking.WooShippingAddress { + /// Returns a "ready to use" type filled with fake values. + /// + public static func fake() -> Networking.WooShippingAddress { + .init( + company: .fake(), + name: .fake(), + phone: .fake(), + country: .fake(), + state: .fake(), + address1: .fake(), + address2: .fake(), + city: .fake(), + postcode: .fake() + ) + } +} extension Networking.WooShippingCarrierPredefinedOptions { /// Returns a "ready to use" type filled with fake values. /// diff --git a/Networking/Networking/Model/ShippingLabel/WooShippingAddress.swift b/Networking/Networking/Model/ShippingLabel/WooShippingAddress.swift index cebb68bd114..ca4112cc77d 100644 --- a/Networking/Networking/Model/ShippingLabel/WooShippingAddress.swift +++ b/Networking/Networking/Model/ShippingLabel/WooShippingAddress.swift @@ -3,7 +3,7 @@ import Codegen /// Represents an address for the WooCommerce Shipping extension. /// -public struct WooShippingAddress: Equatable { +public struct WooShippingAddress: Equatable, GeneratedFakeable { /// The name of the company at the address. public let company: String diff --git a/Yosemite/Yosemite/Actions/WooShippingAction.swift b/Yosemite/Yosemite/Actions/WooShippingAction.swift index 0619fa4f0ea..cd05635daaf 100644 --- a/Yosemite/Yosemite/Actions/WooShippingAction.swift +++ b/Yosemite/Yosemite/Actions/WooShippingAction.swift @@ -56,4 +56,10 @@ public enum WooShippingAction: Action { /// case loadOriginAddresses(siteID: Int64, completion: (Result<[WooShippingOriginAddress], Error>) -> Void) + + /// Validate a shipping address. + /// + case validateAddress(siteID: Int64, + address: ShippingLabelAddress, + completion: (Result) -> Void) } diff --git a/Yosemite/Yosemite/Model/Model.swift b/Yosemite/Yosemite/Model/Model.swift index 03babf05e7c..6fda298dc7f 100644 --- a/Yosemite/Yosemite/Model/Model.swift +++ b/Yosemite/Yosemite/Model/Model.swift @@ -181,6 +181,8 @@ public typealias TopEarnerStats = Networking.TopEarnerStats public typealias TopEarnerStatsItem = Networking.TopEarnerStatsItem public typealias User = Networking.User public typealias WooAPIVersion = Networking.WooAPIVersion +public typealias WooShippingAddressValidationSuccess = Networking.WooShippingAddressValidationSuccess +public typealias WooShippingAddressValidationError = Networking.WooShippingAddressValidationError public typealias WooShippingCustomPackage = Networking.WooShippingCustomPackage public typealias WooShippingSavedPredefinedPackage = Networking.WooShippingSavedPredefinedPackage public typealias WooShippingPredefinedOption = Networking.WooShippingPredefinedOption diff --git a/Yosemite/Yosemite/Stores/WooShippingStore.swift b/Yosemite/Yosemite/Stores/WooShippingStore.swift index 62e3b8d47f1..a40fda559c7 100644 --- a/Yosemite/Yosemite/Stores/WooShippingStore.swift +++ b/Yosemite/Yosemite/Stores/WooShippingStore.swift @@ -67,6 +67,8 @@ public final class WooShippingStore: Store { printLabel(siteID: siteID, labelIDs: labelIDs, paperSize: paperSize, completion: completion) case .loadOriginAddresses(let siteID, let completion): loadOriginAddresses(siteID: siteID, completion: completion) + case let .validateAddress(siteID, address, completion): + validateAddress(siteID: siteID, address: address, completion: completion) } } } @@ -250,6 +252,12 @@ private extension WooShippingStore { } } } + + func validateAddress(siteID: Int64, + address: ShippingLabelAddress, + completion: @escaping (Result) -> Void) { + remote.addressValidation(siteID: siteID, address: address, completion: completion) + } } // MARK: - Storage diff --git a/Yosemite/YosemiteTests/Stores/WooShippingStoreTests.swift b/Yosemite/YosemiteTests/Stores/WooShippingStoreTests.swift index 5736a925ebd..b42d707abaf 100644 --- a/Yosemite/YosemiteTests/Stores/WooShippingStoreTests.swift +++ b/Yosemite/YosemiteTests/Stores/WooShippingStoreTests.swift @@ -604,6 +604,52 @@ final class WooShippingStoreTests: XCTestCase { // Then XCTAssertEqual(error as? NetworkError, expectedError) } + + // MARK: `validateAddress` + + func test_validateAddress_returns_WooShippingAddressValidationSuccess_on_success() throws { + // Given + let remote = MockWooShippingRemote() + let expectedResult = WooShippingAddressValidationSuccess(normalizedAddress: WooShippingAddress.fake(), + originalAddress: WooShippingAddress.fake(), + isTrivialNormalization: true) + remote.whenAddressValidation(siteID: sampleSiteID, thenReturn: .success(expectedResult)) + let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote) + + // When + let result: Result = waitFor { promise in + let action = WooShippingAction.validateAddress(siteID: self.sampleSiteID, + address: ShippingLabelAddress.fake()) { result in + promise(result) + } + store.onAction(action) + } + + // Then + let validationSuccess = try XCTUnwrap(result.get()) + XCTAssertEqual(validationSuccess, expectedResult) + } + + func test_validateAddress_returns_error_on_failure() throws { + // Given + let remote = MockWooShippingRemote() + let expectedError = WooShippingAddressValidationError(addressError: "House number not found", generalError: nil, nameError: nil) + remote.whenAddressValidation(siteID: sampleSiteID, thenReturn: .failure(expectedError)) + let store = WooShippingStore(dispatcher: dispatcher, storageManager: storageManager, network: network, remote: remote) + + // When + let result: Result = waitFor { promise in + let action = WooShippingAction.validateAddress(siteID: self.sampleSiteID, + address: ShippingLabelAddress.fake()) { result in + promise(result) + } + store.onAction(action) + } + + // Then + let error = try XCTUnwrap(result.failure) + XCTAssertEqual(error as? WooShippingAddressValidationError, expectedError) + } } private extension WooShippingStoreTests {