Skip to content

Commit

Permalink
feat: Add metadata parsing and tests
Browse files Browse the repository at this point in the history
- Update `MetaDataMapper.swift` to support mapping from a nested data response.
- Add tests in `MetaDataMapperTests.swift` for the new mapping functionality.
- Create `meta-data-products-and-orders_nested_in_data.json` for testing.
- Modify function signatures in `MetaDataStore.swift` for consistency.
  • Loading branch information
pmusolino committed Sep 12, 2024
1 parent c7cde4a commit b1928b6
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 7 deletions.
4 changes: 4 additions & 0 deletions Networking/Networking.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@
45B204B82489095100FE6526 /* ProductCategoryMapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B204B72489095100FE6526 /* ProductCategoryMapper.swift */; };
45B204BA24890A8C00FE6526 /* ProductCategoryMapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B204B924890A8C00FE6526 /* ProductCategoryMapperTests.swift */; };
45B204BC24890B1200FE6526 /* category.json in Resources */ = {isa = PBXBuildFile; fileRef = 45B204BB24890B1200FE6526 /* category.json */; };
45B79AC62C9355F800DCCB2C /* meta-data-products-and-orders_nested_in_data.json in Resources */ = {isa = PBXBuildFile; fileRef = 45B79AC52C9355F800DCCB2C /* meta-data-products-and-orders_nested_in_data.json */; };
45C6D0E429B9F327009CE29C /* CookieNonceAuthenticatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C6D0E329B9F327009CE29C /* CookieNonceAuthenticatorTests.swift */; };
45CCFCE227A2C9BF0012E8CB /* InboxNote.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CCFCE127A2C9BF0012E8CB /* InboxNote.swift */; };
45CCFCE427A2DC270012E8CB /* InboxAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CCFCE327A2DC270012E8CB /* InboxAction.swift */; };
Expand Down Expand Up @@ -1635,6 +1636,7 @@
45B204B72489095100FE6526 /* ProductCategoryMapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductCategoryMapper.swift; sourceTree = "<group>"; };
45B204B924890A8C00FE6526 /* ProductCategoryMapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductCategoryMapperTests.swift; sourceTree = "<group>"; };
45B204BB24890B1200FE6526 /* category.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = category.json; sourceTree = "<group>"; };
45B79AC52C9355F800DCCB2C /* meta-data-products-and-orders_nested_in_data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "meta-data-products-and-orders_nested_in_data.json"; sourceTree = "<group>"; };
45C6D0E329B9F327009CE29C /* CookieNonceAuthenticatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieNonceAuthenticatorTests.swift; sourceTree = "<group>"; };
45CCFCE127A2C9BF0012E8CB /* InboxNote.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboxNote.swift; sourceTree = "<group>"; };
45CCFCE327A2DC270012E8CB /* InboxAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboxAction.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3457,6 +3459,7 @@
68255E432C60C6AA00090EBD /* products-load-all-for-eligibility-criteria.json */,
CE21FB132C2AC87000303832 /* google-ads-reports-programs-without-data.json */,
CE21FB232C2C16DA00303832 /* google-ads-reports-programs.json */,
45B79AC52C9355F800DCCB2C /* meta-data-products-and-orders_nested_in_data.json */,
453954D12C90D84200A3E64A /* meta-data-products-and-orders.json */,
453954D52C9193BC00A3E64A /* meta-data-products-orders-update.json */,
);
Expand Down Expand Up @@ -4440,6 +4443,7 @@
029B86902A6FBBE000E944D1 /* wcpay-account-null-isLive.json in Resources */,
02AED9D82AA03F3F006DC460 /* order-with-all-addon-types.json in Resources */,
CEF2DD9D2B56E04F00A3DD0B /* jetpack-settings-invalid-module.json in Resources */,
45B79AC62C9355F800DCCB2C /* meta-data-products-and-orders_nested_in_data.json in Resources */,
DE9D6BCC270D769C00BA6562 /* shipping-label-address-without-name-validation-success.json in Resources */,
74A1D263211898F000931DFA /* site-visits-day.json in Resources */,
31054710262E2EE400C5C02B /* wcpay-payment-intent-succeeded.json in Resources */,
Expand Down
18 changes: 13 additions & 5 deletions Networking/Networking/Mapper/MetaDataMapper.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import Foundation


/// Mapper: MetaData List
///
struct MetaDataMapper: Mapper {
Expand All @@ -9,13 +8,22 @@ struct MetaDataMapper: Mapper {
///
func map(response: Data) throws -> [MetaData] {
let decoder = JSONDecoder()
let envelope = try decoder.decode(MetaDataEnvelope.self, from: response)

// Filter out metadata if the key is prefixed with an underscore (internal meta keys)
return envelope.metadata.filter { !$0.key.hasPrefix("_") }
if hasDataEnvelope(in: response) {
let envelope = try decoder.decode(DataEnvelope.self, from: response)
return envelope.data.metadata.filter { !$0.key.hasPrefix("_") }
} else {
let envelope = try decoder.decode(MetaDataEnvelope.self, from: response)
return envelope.metadata.filter { !$0.key.hasPrefix("_") }
}
}
}

/// DataEnvelope Entity:
/// This entity allows us to parse the metadata from the JSON response using JSONDecoder.
///
private struct DataEnvelope: Decodable {
let data: MetaDataEnvelope
}

/// MetaDataEnvelope Entity:
/// This entity allows us to parse the metadata from the JSON response using JSONDecoder.
Expand Down
42 changes: 42 additions & 0 deletions Networking/NetworkingTests/Mapper/MetaDataMapperTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import XCTest

final class MetaDataMapperTests: XCTestCase {

/// Tests that MetaData is correctly mapped from a meta_data response.
///
/// - Throws: An error if the mapping fails.
func test_it_maps_MetaData_correctly_from_meta_data_response() throws {
// Given
let data = try retrieveMetaDataResponse()
Expand Down Expand Up @@ -30,6 +33,37 @@ final class MetaDataMapperTests: XCTestCase {
XCTAssertEqual(metadata[3].key, "sit_key_4")
XCTAssertEqual(metadata[3].value, "Nisi ut aliquip")
}

/// Tests that MetaData is correctly mapped from a meta_data nested in data response.
///
/// - Throws: An error if the mapping fails.
func test_it_maps_MetaData_correctly_from_meta_data_nested_in_data_response() throws {
// Given
let data = try retrieveMetaDataResponseNestedInData()
let mapper = MetaDataMapper()

// When
let metadata = try mapper.map(response: data)

// Then
XCTAssertEqual(metadata.count, 4)

XCTAssertEqual(metadata[0].metadataID, 1)
XCTAssertEqual(metadata[0].key, "lorem_key_1")
XCTAssertEqual(metadata[0].value, "Lorem ipsum")

XCTAssertEqual(metadata[1].metadataID, 2)
XCTAssertEqual(metadata[1].key, "ipsum_key_2")
XCTAssertEqual(metadata[1].value, "dolor sit amet")

XCTAssertEqual(metadata[2].metadataID, 3)
XCTAssertEqual(metadata[2].key, "dolor_key_3")
XCTAssertEqual(metadata[2].value, "consectetur adipiscing elit")

XCTAssertEqual(metadata[3].metadataID, 4)
XCTAssertEqual(metadata[3].key, "sit_key_4")
XCTAssertEqual(metadata[3].value, "Nisi ut aliquip")
}
}

// MARK: - Test Helpers
Expand All @@ -43,5 +77,13 @@ private extension MetaDataMapperTests {
return response
}

func retrieveMetaDataResponseNestedInData() throws -> Data {
guard let response = Loader.contentsOf("meta-data-products-and-orders_nested_in_data") else {
throw FileNotFoundError()
}

return response
}

struct FileNotFoundError: Error {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"data":{
"meta_data":[
{
"id":1,
"key":"lorem_key_1",
"value":"Lorem ipsum"
},
{
"id":2,
"key":"ipsum_key_2",
"value":"dolor sit amet"
},
{
"id":3,
"key":"dolor_key_3",
"value":"consectetur adipiscing elit"
},
{
"id":4,
"key":"sit_key_4",
"value":"Nisi ut aliquip"
},
{
"id":5,
"key":"_internal_key",
"value":"In voluptate velit"
}
]
}
}
4 changes: 2 additions & 2 deletions Yosemite/Yosemite/Stores/MetaDataStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private extension MetaDataStore {
/// - siteID: Site id of the order.
/// - onCompletion: Callback called when the action is finished.
///
func upsertStoredOrderMetaDataInBackground(readOnlyOrderMetaDatas: [Networking.MetaData],
func upsertStoredOrderMetaDataInBackground(readOnlyOrderMetaDatas: [Networking.MetaData],
orderID: Int64,
siteID: Int64,
onCompletion: @escaping () -> Void) {
Expand Down Expand Up @@ -166,7 +166,7 @@ private extension MetaDataStore {
/// - siteID: Site id of the product.
/// - onCompletion: Callback called when the action is finished.
///
func upsertStoredProductMetaDataInBackground(readOnlyProductMetaDatas: [Networking.MetaData],
func upsertStoredProductMetaDataInBackground(readOnlyProductMetaDatas: [Networking.MetaData],
productID: Int64,
siteID: Int64,
onCompletion: @escaping () -> Void) {
Expand Down

0 comments on commit b1928b6

Please sign in to comment.