Skip to content

Commit 607f124

Browse files
authored
Merge pull request #8585 from woocommerce/feat/8582-customer-REST-migration
REST API: Migrate customer endpoints
2 parents ed6470e + ba52ee9 commit 607f124

File tree

9 files changed

+164
-7
lines changed

9 files changed

+164
-7
lines changed

Networking/Networking.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,8 @@
697697
DE42F9652967F34400D514C2 /* refund-single-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE42F9642967F34400D514C2 /* refund-single-without-data.json */; };
698698
DE42F9672967F61D00D514C2 /* refunds-all-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE42F9662967F61D00D514C2 /* refunds-all-without-data.json */; };
699699
DE42F96F296BC9A700D514C2 /* countries-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE42F96E296BC9A700D514C2 /* countries-without-data.json */; };
700+
DE42F96B296BC23800D514C2 /* customer-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE42F96A296BC23800D514C2 /* customer-without-data.json */; };
701+
DE42F96D296BC67E00D514C2 /* wc-analytics-customers-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE42F96C296BC67E00D514C2 /* wc-analytics-customers-without-data.json */; };
700702
DE50295928C5BD0200551736 /* JetpackUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE50295828C5BD0200551736 /* JetpackUser.swift */; };
701703
DE50295B28C5F99700551736 /* DotcomUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE50295A28C5F99700551736 /* DotcomUser.swift */; };
702704
DE50295D28C6068B00551736 /* JetpackUserMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE50295C28C6068B00551736 /* JetpackUserMapper.swift */; };
@@ -1509,6 +1511,8 @@
15091511
DE42F9642967F34400D514C2 /* refund-single-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "refund-single-without-data.json"; sourceTree = "<group>"; };
15101512
DE42F9662967F61D00D514C2 /* refunds-all-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "refunds-all-without-data.json"; sourceTree = "<group>"; };
15111513
DE42F96E296BC9A700D514C2 /* countries-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "countries-without-data.json"; sourceTree = "<group>"; };
1514+
DE42F96A296BC23800D514C2 /* customer-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "customer-without-data.json"; sourceTree = "<group>"; };
1515+
DE42F96C296BC67E00D514C2 /* wc-analytics-customers-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "wc-analytics-customers-without-data.json"; sourceTree = "<group>"; };
15121516
DE50295828C5BD0200551736 /* JetpackUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackUser.swift; sourceTree = "<group>"; };
15131517
DE50295A28C5F99700551736 /* DotcomUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DotcomUser.swift; sourceTree = "<group>"; };
15141518
DE50295C28C6068B00551736 /* JetpackUserMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JetpackUserMapper.swift; sourceTree = "<group>"; };
@@ -2130,6 +2134,8 @@
21302134
isa = PBXGroup;
21312135
children = (
21322136
DE42F96E296BC9A700D514C2 /* countries-without-data.json */,
2137+
DE42F96C296BC67E00D514C2 /* wc-analytics-customers-without-data.json */,
2138+
DE42F96A296BC23800D514C2 /* customer-without-data.json */,
21332139
DE42F9662967F61D00D514C2 /* refunds-all-without-data.json */,
21342140
DE42F9642967F34400D514C2 /* refund-single-without-data.json */,
21352141
EE80A24B29556F1D003591E4 /* Coupon */,
@@ -3035,6 +3041,7 @@
30353041
4515281F257A89B90076B03C /* product-attribute-create.json in Resources */,
30363042
CEF88DAF233E9F7E00BED485 /* order-details-partially-refunded.json in Resources */,
30373043
D823D9032237450A00C90817 /* shipment_tracking_new.json in Resources */,
3044+
DE42F96B296BC23800D514C2 /* customer-without-data.json in Resources */,
30383045
EE80A24729547F8B003591E4 /* coupons-all-without-data.json in Resources */,
30393046
7412A8F021B6E416005D182A /* report-orders.json in Resources */,
30403047
CCF4346A2906C9C300B4475A /* products-ids-only-empty.json in Resources */,
@@ -3129,6 +3136,7 @@
31293136
743E84F222172D0A00FAC9D7 /* shipment_tracking_plugin_not_active.json in Resources */,
31303137
68CB801628D8A39700E169F8 /* customer.json in Resources */,
31313138
EEA658402966C05D00112DF0 /* product-search-sku-without-data.json in Resources */,
3139+
DE42F96D296BC67E00D514C2 /* wc-analytics-customers-without-data.json in Resources */,
31323140
03EB99982907F4AA00F06A39 /* just-in-time-message-list-multiple.json in Resources */,
31333141
EE80A25029556FBD003591E4 /* coupon-reports-without-data.json in Resources */,
31343142
451A97DE260B59870059D135 /* shipping-label-packages-success.json in Resources */,

Networking/Networking/Mapper/CustomerMapper.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ struct CustomerMapper: Mapper {
1212
func map(response: Data) throws -> Customer {
1313
let decoder = JSONDecoder()
1414
decoder.userInfo = [.siteID: siteID]
15-
let customer = try decoder.decode(CustomerEnvelope.self, from: response).customer
16-
return customer
15+
do {
16+
return try decoder.decode(CustomerEnvelope.self, from: response).customer
17+
} catch {
18+
return try decoder.decode(Customer.self, from: response)
19+
}
1720
}
1821
}
1922

Networking/Networking/Mapper/WCAnalyticsCustomerMapper.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ struct WCAnalyticsCustomerMapper: Mapper {
1313
let decoder = JSONDecoder()
1414
decoder.dateDecodingStrategy = .formatted(DateFormatter.Defaults.dateTimeFormatter)
1515
decoder.userInfo = [.siteID: siteID]
16-
let customers = try decoder.decode(WCAnalyticsCustomerEnvelope.self, from: response).customer
17-
return customers
16+
do {
17+
return try decoder.decode(WCAnalyticsCustomerEnvelope.self, from: response).customer
18+
} catch {
19+
return try decoder.decode([WCAnalyticsCustomer].self, from: response)
20+
}
1821
}
1922
}
2023

Networking/Networking/Remote/CustomerRemote.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public class CustomerRemote: Remote {
1414
method: .get,
1515
siteID: siteID,
1616
path: path,
17-
parameters: nil
18-
)
17+
parameters: nil,
18+
availableAsRESTRequest: true)
1919

2020
let mapper = CustomerMapper(siteID: siteID)
2121
enqueue(request, mapper: mapper, completion: completion)

Networking/Networking/Remote/WCAnalyticsCustomerRemote.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ public class WCAnalyticsCustomerRemote: Remote {
2121
method: .get,
2222
siteID: siteID,
2323
path: path,
24-
parameters: ["search": name]
24+
parameters: ["search": name],
25+
availableAsRESTRequest: true
2526
)
2627

2728
let mapper = WCAnalyticsCustomerMapper(siteID: siteID)

Networking/NetworkingTests/Mapper/CustomerMapperTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class CustomerMapperTests: XCTestCase {
1212
/// Local file that holds Customer data representing the API endpoint
1313
///
1414
private let filename: String = "customer"
15+
private let fileNameWithoutDataEnvelope = "customer-without-data"
1516

1617
/// Verifies that the Customer object can be mapped fron the Encoded data
1718
///
@@ -62,6 +63,38 @@ class CustomerMapperTests: XCTestCase {
6263
XCTAssertEqual(address.country, "US")
6364
}
6465
}
66+
67+
/// Verifies that all of the Customer response values are parsed correctly
68+
///
69+
func test_Customer_response_values_are_correctly_parsed_when_response_has_no_data_envelope() throws {
70+
// Given
71+
guard let customer = try mapCustomer(from: fileNameWithoutDataEnvelope) else {
72+
XCTFail()
73+
return
74+
}
75+
76+
// Then
77+
XCTAssertNotNil(customer)
78+
XCTAssertEqual(customer.customerID, 25)
79+
XCTAssertEqual(customer.email, "[email protected]")
80+
XCTAssertEqual(customer.firstName, "John")
81+
XCTAssertEqual(customer.lastName, "Doe")
82+
83+
let dummyAddresses = [customer.shipping, customer.billing].compactMap({ $0 })
84+
XCTAssertEqual(dummyAddresses.count, 2)
85+
86+
for address in dummyAddresses {
87+
XCTAssertEqual(address.firstName, "John")
88+
XCTAssertEqual(address.lastName, "Doe")
89+
XCTAssertEqual(address.company, "")
90+
XCTAssertEqual(address.address1, "969 Market")
91+
XCTAssertEqual(address.address2, "")
92+
XCTAssertEqual(address.city, "San Francisco")
93+
XCTAssertEqual(address.state, "CA")
94+
XCTAssertEqual(address.postcode, "94103")
95+
XCTAssertEqual(address.country, "US")
96+
}
97+
}
6598
}
6699

67100
private extension CustomerMapperTests {

Networking/NetworkingTests/Mapper/WCAnalyticsCustomerMapperTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,22 @@ class WCAnalyticsCustomerMapperTests: XCTestCase {
5959
XCTAssertEqual(customers[3].userID, 3)
6060
XCTAssertEqual(customers[3].name, "John Doe")
6161
}
62+
63+
func test_WCAnalyticsCustomer_array_maps_all_available_entities_if_response_has_no_data_envelope() {
64+
// Given
65+
let mapper = WCAnalyticsCustomerMapper(siteID: dummySiteID)
66+
var customers: [WCAnalyticsCustomer] = []
67+
68+
XCTAssertEqual(customers.count, 0)
69+
70+
// When
71+
guard let data = Loader.contentsOf("wc-analytics-customers-without-data") else {
72+
XCTFail("Data couldn't be loaded")
73+
return
74+
}
75+
customers = try! mapper.map(response: data)
76+
77+
// Then
78+
XCTAssertEqual(customers.count, 2)
79+
}
6280
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"id": 25,
3+
"date_created": "2017-03-21T16:09:28",
4+
"date_created_gmt": "2017-03-21T19:09:28",
5+
"date_modified": "2017-03-21T16:09:30",
6+
"date_modified_gmt": "2017-03-21T19:09:30",
7+
"email": "[email protected]",
8+
"first_name": "John",
9+
"last_name": "Doe",
10+
"role": "customer",
11+
"username": "john.doe",
12+
"billing": {
13+
"first_name": "John",
14+
"last_name": "Doe",
15+
"company": "",
16+
"address_1": "969 Market",
17+
"address_2": "",
18+
"city": "San Francisco",
19+
"state": "CA",
20+
"postcode": "94103",
21+
"country": "US",
22+
"email": "[email protected]",
23+
"phone": "(555) 555-5555"
24+
},
25+
"shipping": {
26+
"first_name": "John",
27+
"last_name": "Doe",
28+
"company": "",
29+
"address_1": "969 Market",
30+
"address_2": "",
31+
"city": "San Francisco",
32+
"state": "CA",
33+
"postcode": "94103",
34+
"country": "US"
35+
},
36+
"is_paying_customer": false,
37+
"avatar_url": "https://secure.gravatar.com/avatar/8eb1b522f60d11fa897de1dc6351b7e8?s=96",
38+
"meta_data": [],
39+
"_links": {
40+
"self": [
41+
{
42+
"href": "https://example.com/wp-json/wc/v3/customers/25"
43+
}
44+
],
45+
"collection": [
46+
{
47+
"href": "https://example.com/wp-json/wc/v3/customers"
48+
}
49+
]
50+
}
51+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
[
2+
{
3+
"id":0,
4+
"user_id":0,
5+
"username":"Matt.the.unregistered",
6+
"name":"Matt The Unregistered",
7+
"email":"[email protected]",
8+
"country":"US",
9+
"city":"San Francisco",
10+
"state":"CA",
11+
"postcode":"94103",
12+
"date_registered":null,
13+
"date_last_active":"2022-07-12T08:36:54",
14+
"date_last_order":"2022-07-12 08:36:54",
15+
"orders_count":1,
16+
"total_spend":10,
17+
"avg_order_value":10,
18+
"date_registered_gmt":null,
19+
"date_last_active_gmt":"2022-07-12T08:36:54"
20+
},
21+
{
22+
"id":1,
23+
"user_id":1,
24+
"username":"John",
25+
"name":"John",
26+
"email":"[email protected]",
27+
"country":"US",
28+
"city":"San Francisco",
29+
"state":"CA",
30+
"postcode":"94103",
31+
"date_registered":null,
32+
"date_last_active":"2022-07-12T08:36:54",
33+
"date_last_order":"2022-07-12 08:36:54",
34+
"orders_count":1,
35+
"total_spend":10,
36+
"avg_order_value":10,
37+
"date_registered_gmt":null,
38+
"date_last_active_gmt":"2022-07-12T08:36:54"
39+
}
40+
]

0 commit comments

Comments
 (0)