From 358dc1baea06b56c3cd7a558e8b807a4529e50e9 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 18 Jan 2023 10:08:19 +0700 Subject: [PATCH 1/4] Add mock response for add-on groups without data envelope --- .../Networking.xcodeproj/project.pbxproj | 4 + .../Responses/add-on-groups-without-data.json | 113 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 Networking/NetworkingTests/Responses/add-on-groups-without-data.json diff --git a/Networking/Networking.xcodeproj/project.pbxproj b/Networking/Networking.xcodeproj/project.pbxproj index d95622e0543..9d874757c9c 100644 --- a/Networking/Networking.xcodeproj/project.pbxproj +++ b/Networking/Networking.xcodeproj/project.pbxproj @@ -717,6 +717,7 @@ DE5CA111288A3E080077BEF9 /* product-malformed-variations-and-image-alt.json in Resources */ = {isa = PBXBuildFile; fileRef = DE5CA110288A3E080077BEF9 /* product-malformed-variations-and-image-alt.json */; }; DE66C5552976662700DAA978 /* just-in-time-message-list-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE66C5542976662700DAA978 /* just-in-time-message-list-without-data.json */; }; DE66C5572976913C00DAA978 /* wcpay-charge-card-present-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE66C5562976913C00DAA978 /* wcpay-charge-card-present-without-data.json */; }; + DE66C559297799D000DAA978 /* add-on-groups-without-data.json in Resources */ = {isa = PBXBuildFile; fileRef = DE66C558297799CF00DAA978 /* add-on-groups-without-data.json */; }; DE6F308727966FEF004E1C9A /* CouponReportListMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6F308627966FEF004E1C9A /* CouponReportListMapperTests.swift */; }; DE74F29A27E08F5A0002FE59 /* SiteSettingMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE74F29927E08F5A0002FE59 /* SiteSettingMapper.swift */; }; DE74F29C27E0A1D00002FE59 /* setting-coupon.json in Resources */ = {isa = PBXBuildFile; fileRef = DE74F29B27E0A1D00002FE59 /* setting-coupon.json */; }; @@ -1547,6 +1548,7 @@ DE5CA110288A3E080077BEF9 /* product-malformed-variations-and-image-alt.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "product-malformed-variations-and-image-alt.json"; sourceTree = ""; }; DE66C5542976662700DAA978 /* just-in-time-message-list-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "just-in-time-message-list-without-data.json"; sourceTree = ""; }; DE66C5562976913C00DAA978 /* wcpay-charge-card-present-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "wcpay-charge-card-present-without-data.json"; sourceTree = ""; }; + DE66C558297799CF00DAA978 /* add-on-groups-without-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "add-on-groups-without-data.json"; sourceTree = ""; }; DE6F308627966FEF004E1C9A /* CouponReportListMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CouponReportListMapperTests.swift; sourceTree = ""; }; DE74F29927E08F5A0002FE59 /* SiteSettingMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteSettingMapper.swift; sourceTree = ""; }; DE74F29B27E0A1D00002FE59 /* setting-coupon.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "setting-coupon.json"; sourceTree = ""; }; @@ -2165,6 +2167,7 @@ B559EBA820A0B5B100836CD4 /* Responses */ = { isa = PBXGroup; children = ( + DE66C558297799CF00DAA978 /* add-on-groups-without-data.json */, DE66C5542976662700DAA978 /* just-in-time-message-list-without-data.json */, DE66C5562976913C00DAA978 /* wcpay-charge-card-present-without-data.json */, DE4F2A432975684900B0701C /* site-api-without-data.json */, @@ -3059,6 +3062,7 @@ 3158FE8026129EC300E566B9 /* wcpay-account-restricted-overdue.json in Resources */, 45AF57A924AB42CD0088E2F7 /* product-tags-extra.json in Resources */, 74AB5B4F21AF3F0E00859C12 /* site-api-no-woo.json in Resources */, + DE66C559297799D000DAA978 /* add-on-groups-without-data.json in Resources */, 265BCA02243056E3004E53EE /* categories-all.json in Resources */, D8FBFF2422D52815006E3336 /* order-stats-v4-daily.json in Resources */, CEC4BF91234E40B5008D9195 /* refund-single.json in Resources */, diff --git a/Networking/NetworkingTests/Responses/add-on-groups-without-data.json b/Networking/NetworkingTests/Responses/add-on-groups-without-data.json new file mode 100644 index 00000000000..9c8f79579ab --- /dev/null +++ b/Networking/NetworkingTests/Responses/add-on-groups-without-data.json @@ -0,0 +1,113 @@ +[ + { + "id": 422, + "name": "Gifts", + "priority": 10, + "restrict_to_categories": [], + "fields": [ + { + "name": "Gift Wrapping", + "title_format": "label", + "description_enable": 0, + "description": "", + "type": "multiple_choice", + "display": "select", + "position": 0, + "required": 0, + "restrictions": 0, + "restrictions_type": "any_text", + "adjust_price": 0, + "price_type": "flat_fee", + "price": "", + "min": 0, + "max": 0, + "options": [ + { + "label": "Basic", + "price": "5", + "image": "", + "price_type": "flat_fee" + }, + { + "label": "Complex", + "price": "7", + "image": "", + "price_type": "flat_fee" + } + ] + }, + { + "name": "Dedicatory Card", + "title_format": "label", + "description_enable": 0, + "description": "", + "type": "custom_textarea", + "display": "select", + "position": 1, + "required": 0, + "restrictions": 0, + "restrictions_type": "any_text", + "adjust_price": 1, + "price_type": "flat_fee", + "price": "1", + "min": 0, + "max": 0, + "options": [ + { + "label": "", + "price": "", + "image": "", + "price_type": "flat_fee" + } + ] + } + ] + }, + { + "id": 427, + "name": "Music", + "priority": 10, + "restrict_to_categories": { + "21": "Music" + }, + "fields": [ + { + "name": "Format", + "title_format": "label", + "description_enable": 0, + "description": "", + "type": "multiple_choice", + "display": "select", + "position": 0, + "required": 1, + "restrictions": 0, + "restrictions_type": "any_text", + "adjust_price": 0, + "price_type": "flat_fee", + "price": "", + "min": 0, + "max": 0, + "options": [ + { + "label": "MP3", + "price": "", + "image": "", + "price_type": "flat_fee" + }, + { + "label": "ACC", + "price": "", + "image": "", + "price_type": "flat_fee" + }, + { + "label": "WAV", + "price": "", + "image": "", + "price_type": "flat_fee" + } + ] + } + ] + } +] From 62ff08f7a98e7cd983839dfb0f3d135b2a266dff Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 18 Jan 2023 10:08:36 +0700 Subject: [PATCH 2/4] Update AddOnGroupMapper to parse contents without the data envelope --- Networking/Networking/Mapper/AddOnGroupMapper.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Networking/Networking/Mapper/AddOnGroupMapper.swift b/Networking/Networking/Mapper/AddOnGroupMapper.swift index 4efba867246..8746c045a9c 100644 --- a/Networking/Networking/Mapper/AddOnGroupMapper.swift +++ b/Networking/Networking/Mapper/AddOnGroupMapper.swift @@ -11,7 +11,11 @@ struct AddOnGroupMapper: Mapper { func map(response: Data) throws -> [AddOnGroup] { let decoder = JSONDecoder() decoder.userInfo = [.siteID: siteID] - return try decoder.decode(AddOnGroupEnvelope.self, from: response).data + do { + return try decoder.decode(AddOnGroupEnvelope.self, from: response).data + } catch { + return try decoder.decode([AddOnGroup].self, from: response) + } } } From 3a44184a9cfc9d70d1ae862996a75657c1ae99d1 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 18 Jan 2023 10:08:47 +0700 Subject: [PATCH 3/4] Update test for AddOnGroupMapper --- .../Mapper/AddOnGroupMapperTests.swift | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Networking/NetworkingTests/Mapper/AddOnGroupMapperTests.swift b/Networking/NetworkingTests/Mapper/AddOnGroupMapperTests.swift index 03db54db672..66ab9dc4ddc 100644 --- a/Networking/NetworkingTests/Mapper/AddOnGroupMapperTests.swift +++ b/Networking/NetworkingTests/Mapper/AddOnGroupMapperTests.swift @@ -24,6 +24,26 @@ class AddOnGroupMapperTests: XCTestCase { XCTAssertEqual(secondGroup.name, "Music") XCTAssertEqual(secondGroup.addOns.count, 1) } + + func test_addOnGroups_field_are_properly_parsed_when_response_has_no_data_envelope() throws { + // Given & When + let addOnGroups = try XCTUnwrap(mapLoadGroupAddOnsResponseWithoutDataEnvelope()) + + // Then + XCTAssertEqual(addOnGroups.count, 2) + + let firstGroup = addOnGroups[0] + XCTAssertEqual(firstGroup.siteID, dummySiteID) + XCTAssertEqual(firstGroup.groupID, 422) + XCTAssertEqual(firstGroup.name, "Gifts") + XCTAssertEqual(firstGroup.addOns.count, 2) + + let secondGroup = addOnGroups[1] + XCTAssertEqual(secondGroup.siteID, dummySiteID) + XCTAssertEqual(secondGroup.groupID, 427) + XCTAssertEqual(secondGroup.name, "Music") + XCTAssertEqual(secondGroup.addOns.count, 1) + } } // MARK: JSON Loading @@ -34,4 +54,11 @@ private extension AddOnGroupMapperTests { } return try? AddOnGroupMapper(siteID: dummySiteID).map(response: response) } + + func mapLoadGroupAddOnsResponseWithoutDataEnvelope() -> [AddOnGroup]? { + guard let response = Loader.contentsOf("add-on-groups-without-data") else { + return nil + } + return try? AddOnGroupMapper(siteID: dummySiteID).map(response: response) + } } From c1c38b852375a6664387da4319cfc62421d60908 Mon Sep 17 00:00:00 2001 From: Huong Do Date: Wed, 18 Jan 2023 10:08:59 +0700 Subject: [PATCH 4/4] Enable REST API for add-on group endpoint --- Networking/Networking/Remote/AddOnGroupRemote.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Networking/Networking/Remote/AddOnGroupRemote.swift b/Networking/Networking/Remote/AddOnGroupRemote.swift index 3b7b58a4c3c..7ecac0f22cf 100644 --- a/Networking/Networking/Remote/AddOnGroupRemote.swift +++ b/Networking/Networking/Remote/AddOnGroupRemote.swift @@ -7,7 +7,11 @@ public final class AddOnGroupRemote: Remote { /// Retrieves all the `AddOnGroups` available for a given `siteID` /// public func loadAddOnGroups(siteID: Int64, onCompletion: @escaping (Result<[AddOnGroup], Error>) -> ()) { - let request = JetpackRequest(wooApiVersion: .addOnsV1, method: .get, siteID: siteID, path: Path.addOnGroups) + let request = JetpackRequest(wooApiVersion: .addOnsV1, + method: .get, + siteID: siteID, + path: Path.addOnGroups, + availableAsRESTRequest: true) let mapper = AddOnGroupMapper(siteID: siteID) enqueue(request, mapper: mapper, completion: onCompletion) }