diff --git a/Networking/Networking.xcodeproj/project.pbxproj b/Networking/Networking.xcodeproj/project.pbxproj index d33cb2c30a2..8372f28ca85 100644 --- a/Networking/Networking.xcodeproj/project.pbxproj +++ b/Networking/Networking.xcodeproj/project.pbxproj @@ -719,6 +719,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 */; }; DE66C5532976508300DAA978 /* CookieNonceAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE66C5522976508300DAA978 /* CookieNonceAuthenticator.swift */; }; DE6F308727966FEF004E1C9A /* CouponReportListMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE6F308627966FEF004E1C9A /* CouponReportListMapperTests.swift */; }; DE74F29A27E08F5A0002FE59 /* SiteSettingMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE74F29927E08F5A0002FE59 /* SiteSettingMapper.swift */; }; @@ -1559,6 +1560,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 = ""; }; DE66C5522976508300DAA978 /* CookieNonceAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieNonceAuthenticator.swift; 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 = ""; }; @@ -2189,6 +2191,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 */, @@ -3113,6 +3116,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/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) + } } } 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) } 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) + } } 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" + } + ] + } + ] + } +]