Skip to content

Commit

Permalink
[Shipping Labels] Get origin address (#14689)
Browse files Browse the repository at this point in the history
  • Loading branch information
rachelmcr authored Dec 30, 2024
2 parents 736979a + 137da8a commit 7c42ba8
Show file tree
Hide file tree
Showing 12 changed files with 332 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Fakes/Fakes/Networking.generated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2864,6 +2864,26 @@ extension Networking.WooShippingSavedPredefinedPackage {
)
}
}
extension Networking.WooShippingOriginAddress {
/// Returns a "ready to use" type filled with fake values.
///
public static func fake() -> Networking.WooShippingOriginAddress {
.init(id: .fake(),
company: .fake(),
address1: .fake(),
address2: .fake(),
city: .fake(),
state: .fake(),
postcode: .fake(),
country: .fake(),
phone: .fake(),
firstName: .fake(),
lastName: .fake(),
email: .fake(),
defaultAddress: .fake(),
isVerified: .fake())
}
}
extension Networking.WordPressMedia {
/// Returns a "ready to use" type filled with fake values.
///
Expand Down
12 changes: 12 additions & 0 deletions Networking/Networking.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -954,11 +954,14 @@
D8FBFF2422D52815006E3336 /* order-stats-v4-daily.json in Resources */ = {isa = PBXBuildFile; fileRef = D8FBFF2322D52815006E3336 /* order-stats-v4-daily.json */; };
D8FBFF2722D529F2006E3336 /* order-stats-v4-month.json in Resources */ = {isa = PBXBuildFile; fileRef = D8FBFF2622D529F2006E3336 /* order-stats-v4-month.json */; };
D8FBFF2922D52AFB006E3336 /* order-stats-v4-year.json in Resources */ = {isa = PBXBuildFile; fileRef = D8FBFF2822D52AFA006E3336 /* order-stats-v4-year.json */; };
DA2415292D10684D0008F69A /* wooshipping-get-origin-addresses-success.json in Resources */ = {isa = PBXBuildFile; fileRef = DA2415282D10684D0008F69A /* wooshipping-get-origin-addresses-success.json */; };
DA69CC972CEDDA1200CB7CEE /* wooshipping-get-account-settings-success.json in Resources */ = {isa = PBXBuildFile; fileRef = DA69CC962CEDDA1200CB7CEE /* wooshipping-get-account-settings-success.json */; };
DAA259AB2CEC86370035F028 /* WooShippingSavedPredefinedPackage.swift.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA259AA2CEC86360035F028 /* WooShippingSavedPredefinedPackage.swift.swift */; };
DAA259AD2CEC86BE0035F028 /* wooshipping-get-packages-success.json in Resources */ = {isa = PBXBuildFile; fileRef = DAA259AC2CEC86BE0035F028 /* wooshipping-get-packages-success.json */; };
DAA259AF2CECF4AF0035F028 /* WooShippingAccountSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA259AE2CECF4A70035F028 /* WooShippingAccountSettings.swift */; };
DAA259B12CECF5720035F028 /* WooShippingAccountSettingsMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAA259B02CECF56B0035F028 /* WooShippingAccountSettingsMapper.swift */; };
DAEE64282D1048A00031DCDC /* WooShippingOriginAddress.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEE64272D1048930031DCDC /* WooShippingOriginAddress.swift */; };
DAEE642A2D104B7C0031DCDC /* WooShippingOriginAddressesMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAEE64292D104B720031DCDC /* WooShippingOriginAddressesMapper.swift */; };
DAF367A22CE75B9E00D1B327 /* WooShippingPackagesMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF367A12CE75B9D00D1B327 /* WooShippingPackagesMapper.swift */; };
DAF367A42CE75C1B00D1B327 /* WooShippingPredefinedPackage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF367A32CE75C1900D1B327 /* WooShippingPredefinedPackage.swift */; };
DAF367A62CE75C2F00D1B327 /* WooShippingPredefinedSavedOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAF367A52CE75C2D00D1B327 /* WooShippingPredefinedSavedOption.swift */; };
Expand Down Expand Up @@ -2140,11 +2143,14 @@
D8FBFF2322D52815006E3336 /* order-stats-v4-daily.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "order-stats-v4-daily.json"; sourceTree = "<group>"; };
D8FBFF2622D529F2006E3336 /* order-stats-v4-month.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "order-stats-v4-month.json"; sourceTree = "<group>"; };
D8FBFF2822D52AFA006E3336 /* order-stats-v4-year.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "order-stats-v4-year.json"; sourceTree = "<group>"; };
DA2415282D10684D0008F69A /* wooshipping-get-origin-addresses-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "wooshipping-get-origin-addresses-success.json"; sourceTree = "<group>"; };
DA69CC962CEDDA1200CB7CEE /* wooshipping-get-account-settings-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "wooshipping-get-account-settings-success.json"; sourceTree = "<group>"; };
DAA259AA2CEC86360035F028 /* WooShippingSavedPredefinedPackage.swift.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingSavedPredefinedPackage.swift.swift; sourceTree = "<group>"; };
DAA259AC2CEC86BE0035F028 /* wooshipping-get-packages-success.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "wooshipping-get-packages-success.json"; sourceTree = "<group>"; };
DAA259AE2CECF4A70035F028 /* WooShippingAccountSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingAccountSettings.swift; sourceTree = "<group>"; };
DAA259B02CECF56B0035F028 /* WooShippingAccountSettingsMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingAccountSettingsMapper.swift; sourceTree = "<group>"; };
DAEE64272D1048930031DCDC /* WooShippingOriginAddress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingOriginAddress.swift; sourceTree = "<group>"; };
DAEE64292D104B720031DCDC /* WooShippingOriginAddressesMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingOriginAddressesMapper.swift; sourceTree = "<group>"; };
DAF367A12CE75B9D00D1B327 /* WooShippingPackagesMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingPackagesMapper.swift; sourceTree = "<group>"; };
DAF367A32CE75C1900D1B327 /* WooShippingPredefinedPackage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingPredefinedPackage.swift; sourceTree = "<group>"; };
DAF367A52CE75C2D00D1B327 /* WooShippingPredefinedSavedOption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WooShippingPredefinedSavedOption.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2573,6 +2579,7 @@
CEC7D5902CDD0C1C00111B79 /* WooShippingCreatePackageResponse.swift */,
DAF367A72CE75C5B00D1B327 /* WooShippingPackagesResponse.swift */,
CE1EA4BE2CEBA0AF0039F477 /* WooShippingPackagePurchase.swift */,
DAEE64272D1048930031DCDC /* WooShippingOriginAddress.swift */,
451A97C82609FF050059D135 /* ShippingLabelPackagesResponse.swift */,
451A97CC260A01A40059D135 /* ShippingLabelStoreOptions.swift */,
CCAAD10E2683974000909664 /* ShippingLabelPackagePurchase.swift */,
Expand Down Expand Up @@ -3539,6 +3546,7 @@
CE0F4ECC2CE375DD006339BD /* wooshipping-get-label-rates-error.json */,
DA69CC962CEDDA1200CB7CEE /* wooshipping-get-account-settings-success.json */,
DAA259AC2CEC86BE0035F028 /* wooshipping-get-packages-success.json */,
DA2415282D10684D0008F69A /* wooshipping-get-origin-addresses-success.json */,
CE1EA4BA2CEB78F60039F477 /* wooshipping-purchase-success.json */,
CE90E99B2CEFCAA50068D852 /* wooshipping-label-status-success.json */,
CE2FB3972CF74C5C0046201C /* wooshipping-label-print-success.json */,
Expand Down Expand Up @@ -3652,6 +3660,7 @@
CEC7D5942CDD164D00111B79 /* WooShippingCreatePackageMapper.swift */,
CE0F4ECE2CE37C4F006339BD /* WooShippingLabelRatesMapper.swift */,
DAF367A12CE75B9D00D1B327 /* WooShippingPackagesMapper.swift */,
DAEE64292D104B720031DCDC /* WooShippingOriginAddressesMapper.swift */,
CE90E99D2CEFCB100068D852 /* WooShippingStatusMapper.swift */,
CE606D8E2BE39426001CB424 /* ShippingMethodMapper.swift */,
FE28F6E326842848004465C7 /* UserMapper.swift */,
Expand Down Expand Up @@ -4521,6 +4530,7 @@
EE9826902B17189B00A3F57E /* product-subscription-sync-renewals-day-month-format.json in Resources */,
DEB387902C2D71A10025256E /* gla-campaign-list-with-data-envelope.json in Resources */,
7492FAE3217FBDBC00ED2C69 /* settings-general-alt.json in Resources */,
DA2415292D10684D0008F69A /* wooshipping-get-origin-addresses-success.json in Resources */,
93D8BBFF226BC1DA00AD2EB3 /* me-settings.json in Resources */,
74C947842193A6C70024CB60 /* comment-moderate-approved.json in Resources */,
DEC51AED2768A0AD009F3DF4 /* systemStatusWithPluginsOnly.json in Resources */,
Expand Down Expand Up @@ -5072,6 +5082,7 @@
45D685F823D0BC78005F87D0 /* ProductSkuMapper.swift in Sources */,
7412A8EA21B6E192005D182A /* ReportRemote.swift in Sources */,
CC01CE5A29B0FD61004FF537 /* ProductBundleItem.swift in Sources */,
DAEE642A2D104B7C0031DCDC /* WooShippingOriginAddressesMapper.swift in Sources */,
B5A2417D217F9ECC00595DEF /* MetaContainer.swift in Sources */,
025CA2C4238EBC4300B05C81 /* ProductShippingClassRemote.swift in Sources */,
D88D5A4B230BCF0A007B6E01 /* ProductReviewListMapper.swift in Sources */,
Expand Down Expand Up @@ -5211,6 +5222,7 @@
74D522B62113607F00042831 /* StatGranularity.swift in Sources */,
02C2549A25636E1500A04423 /* ShippingLabelAddress.swift in Sources */,
03DCB786262739D200C8953D /* CouponMapper.swift in Sources */,
DAEE64282D1048A00031DCDC /* WooShippingOriginAddress.swift in Sources */,
B518662220A097C200037A38 /* Network.swift in Sources */,
B572F69A21AC475C003EEFF0 /* DevicesRemote.swift in Sources */,
3192F220260D33BB0067FEF9 /* WCPayAccount.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

struct WooShippingOriginAddressesMapper: Mapper {
/// (Attempts) to convert a dictionary into WooShippingOriginAddress array.
///
func map(response: Data) throws -> [WooShippingOriginAddress] {
let decoder = JSONDecoder()
if hasDataEnvelope(in: response) {
return try decoder.decode(WooShippingOriginAddressesMapperEnvelope.self, from: response).data
} else {
return try decoder.decode([WooShippingOriginAddress].self, from: response)
}
}
}

/// WooShippingOriginAddressesMapperEnvelope Disposable Entity:
/// `Woo Shipping Origin Addresses` endpoint returns the shipping label origin addresses in the `data` key.
/// This entity allows us to do parse all the things with JSONDecoder.
///
private struct WooShippingOriginAddressesMapperEnvelope: Decodable {
let data: [WooShippingOriginAddress]

private enum CodingKeys: String, CodingKey {
case data = "data"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import Foundation
import Codegen

public struct WooShippingOriginAddress: Equatable, GeneratedFakeable, GeneratedCopiable {
public let id: String
public let company: String
public let address1: String
public let address2: String
public let city: String
public let state: String
public let postcode: String
public let country: String
public let phone: String
public let firstName: String
public let lastName: String
public let email: String
public let defaultAddress: Bool
public let isVerified: Bool

public init(id: String,
company: String,
address1: String,
address2: String,
city: String,
state: String,
postcode: String,
country: String,
phone: String,
firstName: String,
lastName: String,
email: String,
defaultAddress:
Bool,
isVerified: Bool) {
self.id = id
self.company = company
self.address1 = address1
self.address2 = address2
self.city = city
self.state = state
self.postcode = postcode
self.country = country
self.phone = phone
self.firstName = firstName
self.lastName = lastName
self.email = email
self.defaultAddress = defaultAddress
self.isVerified = isVerified
}
}

// MARK: Decodable
extension WooShippingOriginAddress: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)

let id = try container.decode(String.self, forKey: CodingKeys.id)
let company = try container.decodeIfPresent(String.self, forKey: CodingKeys.company) ?? ""
let address1 = try container.decodeIfPresent(String.self, forKey: CodingKeys.address1) ?? ""
let address2 = try container.decodeIfPresent(String.self, forKey: CodingKeys.address2) ?? ""
let city = try container.decodeIfPresent(String.self, forKey: CodingKeys.city) ?? ""
let state = try container.decodeIfPresent(String.self, forKey: CodingKeys.state) ?? ""
let postcode = try container.decodeIfPresent(String.self, forKey: CodingKeys.postcode) ?? ""
let country = try container.decodeIfPresent(String.self, forKey: CodingKeys.country) ?? ""
let phone = try container.decodeIfPresent(String.self, forKey: CodingKeys.phone) ?? ""
let firstName = try container.decodeIfPresent(String.self, forKey: CodingKeys.firstName) ?? ""
let lastName = try container.decodeIfPresent(String.self, forKey: CodingKeys.lastName) ?? ""
let email = try container.decodeIfPresent(String.self, forKey: CodingKeys.email) ?? ""

let defaultAddress = try container.decodeIfPresent(Bool.self, forKey: CodingKeys.defaultAddress) ?? false
let isVerified = try container.decodeIfPresent(Bool.self, forKey: CodingKeys.isVerified) ?? false

self.init(id: id,
company: company,
address1: address1,
address2: address2,
city: city,
state: state,
postcode: postcode,
country: country,
phone: phone,
firstName: firstName,
lastName: lastName,
email: email,
defaultAddress: defaultAddress,
isVerified: isVerified)
}

private enum CodingKeys: String, CodingKey {
case id
case company
case address1 = "address_1"
case address2 = "address_2"
case city
case state
case postcode
case country
case phone
case firstName = "first_name"
case lastName = "last_name"
case email
case defaultAddress = "default_address"
case isVerified = "is_verified"
}
}
20 changes: 20 additions & 0 deletions Networking/Networking/Remote/WooShippingRemote.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public protocol WooShippingRemoteProtocol {
labelIDs: [Int64],
paperSize: ShippingLabelPaperSize,
completion: @escaping (Result<ShippingLabelPrintData, Error>) -> Void)

func loadOriginAddresses(siteID: Int64,
completion: @escaping (Result<[WooShippingOriginAddress], Error>) -> Void)
}

/// Shipping Labels Remote Endpoints for the WooShipping Plugin.
Expand Down Expand Up @@ -268,6 +271,22 @@ public final class WooShippingRemote: Remote, WooShippingRemoteProtocol {

enqueue(request, mapper: mapper, completion: completion)
}

/// Loads origin addresses.
/// - Parameters:
/// - siteID: Remote ID of the site.
/// - completion: Closure to be executed upon completion.
public func loadOriginAddresses(siteID: Int64, completion: @escaping (Result<[WooShippingOriginAddress], any Error>) -> Void) {
let request = JetpackRequest(wooApiVersion: .wooShipping,
method: .get,
siteID: siteID,
path: Path.originAddresses,
parameters: nil,
availableAsRESTRequest: true)
let mapper = WooShippingOriginAddressesMapper()

enqueue(request, mapper: mapper, completion: completion)
}
}

// MARK: Constants
Expand All @@ -279,6 +298,7 @@ private extension WooShippingRemote {
static let purchase = "label/purchase"
static let status = "label/status"
static let print = "label/print"
static let originAddresses = "origin-addresses"
}

enum ParameterKey {
Expand Down
46 changes: 46 additions & 0 deletions Networking/NetworkingTests/Remote/WooShippingRemoteTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,52 @@ final class WooShippingRemoteTests: XCTestCase {
// Then
XCTAssertNotNil(result.failure)
}

func test_loadOriginAddresses_parses_success_response() throws {
// Given
let remote = WooShippingRemote(network: network)
network.simulateResponse(requestUrlSuffix: "origin-addresses", filename: "wooshipping-get-origin-addresses-success")

// When
let result: Result<[WooShippingOriginAddress], Error> = waitFor { promise in
remote.loadOriginAddresses(siteID: self.sampleSiteID) { result in
promise(result)
}
}

// Then
let addresses = try XCTUnwrap(result.get())
XCTAssertEqual(addresses.count, 1)
XCTAssertEqual(addresses.first?.company, "Superlative Centaur")
XCTAssertEqual(addresses.first?.city, "SAN FRANCISCO")
XCTAssertEqual(addresses.first?.state, "CA")
XCTAssertEqual(addresses.first?.postcode, "94110-4929")
XCTAssertEqual(addresses.first?.country, "US")
XCTAssertEqual(addresses.first?.phone, "12345678901")
XCTAssertEqual(addresses.first?.address1, "60 29TH ST PMB 343")
XCTAssertEqual(addresses.first?.firstName, "First")
XCTAssertEqual(addresses.first?.lastName, "Last")
XCTAssertEqual(addresses.first?.email, "email@automattic.com")
XCTAssertEqual(addresses.first?.id, "store_details")
XCTAssertEqual(addresses.first?.defaultAddress, true)
XCTAssertEqual(addresses.first?.isVerified, true)
}

func test_loadOriginAddresses_returns_error_on_failure() throws {
// Given
let remote = WooShippingRemote(network: network)
network.simulateResponse(requestUrlSuffix: "origin-addresses", filename: "generic_error")

// When
let result: Result<[WooShippingOriginAddress], Error> = waitFor { promise in
remote.loadOriginAddresses(siteID: self.sampleSiteID) { result in
promise(result)
}
}

// Then
XCTAssertNotNil(result.failure)
}
}

private extension WooShippingRemoteTests {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"data": [
{
"company": "Superlative Centaur",
"address_2": "",
"city": "SAN FRANCISCO",
"state": "CA",
"postcode": "94110-4929",
"country": "US",
"phone": "12345678901",
"address_1": "60 29TH ST PMB 343",
"first_name": "First",
"last_name": "Last",
"email": "email@automattic.com",
"id": "store_details",
"default_address": true,
"is_verified": true
}
]
}
5 changes: 5 additions & 0 deletions Yosemite/Yosemite/Actions/WooShippingAction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,9 @@ public enum WooShippingAction: Action {
labelIDs: [Int64],
paperSize: ShippingLabelPaperSize,
completion: (Result<ShippingLabelPrintData, Error>) -> Void)

/// Fetch list of origin addresses.
///
case loadOriginAddresses(siteID: Int64,
completion: (Result<[WooShippingOriginAddress], Error>) -> Void)
}
1 change: 1 addition & 0 deletions Yosemite/Yosemite/Model/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public typealias WooShippingCreatePackageResponse = Networking.WooShippingCreate
public typealias WooShippingPackagesResponse = Networking.WooShippingPackagesResponse
public typealias WooShippingPackagePurchase = Networking.WooShippingPackagePurchase
public typealias WooShippingPredefinedSavedOption = Networking.WooShippingPredefinedSavedOption
public typealias WooShippingOriginAddress = Networking.WooShippingOriginAddress
public typealias WPComPlan = Networking.WPComPlan
public typealias WPComSitePlan = Networking.WPComSitePlan
public typealias LoadSiteCurrentPlanError = Networking.LoadSiteCurrentPlanError
Expand Down
Loading

0 comments on commit 7c42ba8

Please sign in to comment.