Skip to content

Commit

Permalink
Merge pull request woocommerce#7258 from woocommerce/issue/7234-metad…
Browse files Browse the repository at this point in the history
…ata-yosemite
  • Loading branch information
rachelmcr authored Jul 9, 2022
2 parents 3385f4a + 184d0df commit 0576bca
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 4 deletions.
4 changes: 4 additions & 0 deletions Yosemite/Yosemite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@
BAB3737927964A9500837B4A /* OrderTaxLine+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB3737827964A9500837B4A /* OrderTaxLine+ReadOnlyConvertible.swift */; };
CC2C036C262F316600928C9C /* ShippingLabelAccountSettings+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2C036B262F316600928C9C /* ShippingLabelAccountSettings+ReadOnlyConvertible.swift */; };
CC2C0372262F32D800928C9C /* ShippingLabelPaymentMethod+ReadonlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2C0371262F32D800928C9C /* ShippingLabelPaymentMethod+ReadonlyConvertible.swift */; };
CC6A054628773F75002C144E /* OrderMetaData+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC6A054528773F75002C144E /* OrderMetaData+ReadOnlyConvertible.swift */; };
CE01014F2368C41600783459 /* Refund+ReadOnlyType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE01014E2368C41600783459 /* Refund+ReadOnlyType.swift */; };
CE0DB6C0233EB3F300A27E7A /* OrderRefundCondensed+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE0DB6BF233EB3F300A27E7A /* OrderRefundCondensed+ReadOnlyConvertible.swift */; };
CE12FBDB221F406100C59248 /* OrderStatus+ReadOnlyConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE12FBDA221F406100C59248 /* OrderStatus+ReadOnlyConvertible.swift */; };
Expand Down Expand Up @@ -729,6 +730,7 @@
C25501C7F936D2FD32FAF3F4 /* Pods_Yosemite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Yosemite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
CC2C036B262F316600928C9C /* ShippingLabelAccountSettings+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ShippingLabelAccountSettings+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
CC2C0371262F32D800928C9C /* ShippingLabelPaymentMethod+ReadonlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ShippingLabelPaymentMethod+ReadonlyConvertible.swift"; sourceTree = "<group>"; };
CC6A054528773F75002C144E /* OrderMetaData+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderMetaData+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
CE01014E2368C41600783459 /* Refund+ReadOnlyType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Refund+ReadOnlyType.swift"; sourceTree = "<group>"; };
CE0DB6BF233EB3F300A27E7A /* OrderRefundCondensed+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderRefundCondensed+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
CE12FBDA221F406100C59248 /* OrderStatus+ReadOnlyConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrderStatus+ReadOnlyConvertible.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1214,6 +1216,7 @@
CE4FD4512350FB5400A16B31 /* OrderItemTaxRefund+ReadOnlyConvertible.swift */,
74B7D6AF20F910AF002667AC /* OrderNote+ReadOnlyConvertible.swift */,
CE0DB6BF233EB3F300A27E7A /* OrderRefundCondensed+ReadOnlyConvertible.swift */,
CC6A054528773F75002C144E /* OrderMetaData+ReadOnlyConvertible.swift */,
D8C11A5322DFAE9500D4A88D /* OrderStatsV4+ReadOnlyConvertible.swift */,
D8C11A5722DFB2FF00D4A88D /* OrderStatsV4Interval+ReadOnlyConvertible.swift */,
D8C11A5522DFB0BE00D4A88D /* OrderStatsV4Totals+ReadOnlyConvertible.swift */,
Expand Down Expand Up @@ -1847,6 +1850,7 @@
03F3AFE728097D6400E328BE /* CardPresentPaymentsPlugin.swift in Sources */,
B52E0032211A440D00700FDE /* Order+ReadOnlyType.swift in Sources */,
261F94E4242EFA6D00762B58 /* ProductCategoryAction.swift in Sources */,
CC6A054628773F75002C144E /* OrderMetaData+ReadOnlyConvertible.swift in Sources */,
029BA557255E0CD4006171FD /* ShippingLabelStore.swift in Sources */,
021EAA5C25493E9300AA8CCD /* OrderItemAttribute+ReadOnlyConvertible.swift in Sources */,
45AB8B1524AA4A1E00B5B36E /* ProductTagAction.swift in Sources */,
Expand Down
1 change: 1 addition & 0 deletions Yosemite/Yosemite/Model/Model.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public typealias OrderStatusEnum = Networking.OrderStatusEnum
public typealias OrderCouponLine = Networking.OrderCouponLine
public typealias OrderFeeLine = Networking.OrderFeeLine
public typealias OrderFeeTaxStatus = Networking.OrderFeeTaxStatus
public typealias OrderMetaData = Networking.OrderMetaData
public typealias OrderNote = Networking.OrderNote
public typealias OrderTaxLine = Networking.OrderTaxLine
public typealias OrderRefundCondensed = Networking.OrderRefundCondensed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ extension Storage.Order: ReadOnlyConvertible {
let orderShippingLines = shippingLines?.map { $0.toReadOnly() } ?? [Yosemite.ShippingLine]()
let orderFeeLines = fees?.map { $0.toReadOnly() } ?? [Yosemite.OrderFeeLine]()
let orderTaxLines = taxes?.map { $0.toReadOnly() } ?? [Yosemite.OrderTaxLine]()
let orderCustomFields = customFields?.map { $0.toReadOnly() } ?? [Yosemite.OrderMetaData]()

return Order(siteID: siteID,
orderID: orderID,
Expand Down Expand Up @@ -110,7 +111,7 @@ extension Storage.Order: ReadOnlyConvertible {
refunds: orderRefunds,
fees: orderFeeLines,
taxes: orderTaxLines,
customFields: []) // TODO: Handle custom fields (order meta data)
customFields: orderCustomFields)

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation
import Storage


// MARK: - Storage.OrderMetaData: ReadOnlyConvertible
//
extension Storage.OrderMetaData: ReadOnlyConvertible {

/// Updates the Storage.OrderMetaData with the ReadOnly.
///
public func update(with orderMetaData: Yosemite.OrderMetaData) {
metadataID = orderMetaData.metadataID
key = orderMetaData.key
value = orderMetaData.value
}

/// Returns a ReadOnly version of the receiver.
///
public func toReadOnly() -> Yosemite.OrderMetaData {
return OrderMetaData(metadataID: metadataID,
key: key ?? "",
value: value ?? "")
}
}
24 changes: 24 additions & 0 deletions Yosemite/Yosemite/Stores/Order/OrdersUpsertUseCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct OrdersUpsertUseCase {
handleOrderShippingLines(readOnlyOrder, storageOrder, storage)
handleOrderRefundsCondensed(readOnlyOrder, storageOrder, storage)
handleOrderTaxes(readOnlyOrder, storageOrder, storage)
handleOrderCustomFields(readOnlyOrder, storageOrder, storage)

return storageOrder
}
Expand Down Expand Up @@ -282,4 +283,27 @@ struct OrdersUpsertUseCase {
}
}
}

/// Updates, inserts, or prunes the provided `storageOrder`'s custom fields using the provided `readOnlyOrder`'s custom fields
///
private func handleOrderCustomFields(_ readOnlyOrder: Networking.Order, _ storageOrder: Storage.Order, _ storage: StorageType) {
// Upsert the `customFields` from the `readOnlyOrder`
readOnlyOrder.customFields.forEach { readOnlyCustomField in
if let existingStorageMetaData = storage.loadOrderMetaData(siteID: readOnlyOrder.siteID, metadataID: readOnlyCustomField.metadataID) {
existingStorageMetaData.update(with: readOnlyCustomField)
} else {
let newStorageMetaData = storage.insertNewObject(ofType: Storage.OrderMetaData.self)
newStorageMetaData.update(with: readOnlyCustomField)
storageOrder.addToCustomFields(newStorageMetaData)
}
}

// Now, remove any objects that exist in `storageOrder.customFields` but not in `readOnlyOrder.customFields`
storageOrder.customFields?.forEach { storageCustomField in
if readOnlyOrder.customFields.first(where: { $0.metadataID == storageCustomField.metadataID } ) == nil {
storageOrder.removeFromCustomFields(storageCustomField)
storage.deleteObject(storageCustomField)
}
}
}
}
30 changes: 30 additions & 0 deletions Yosemite/YosemiteTests/Stores/Order/OrdersUpsertUseCaseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,36 @@ final class OrdersUpsertUseCaseTests: XCTestCase {
let storageOrderItem = try XCTUnwrap(viewStorage.loadOrderItem(siteID: 3, orderID: 98, itemID: 76))
XCTAssertEqual(storageOrderItem.toReadOnly(), orderItem)
}

func test_it_persists_order_custom_field_in_storage() throws {
// Given
let customField = OrderMetaData(metadataID: 1, key: "Key", value: "Value")
let order = makeOrder().copy(siteID: 3, customFields: [customField])
let useCase = OrdersUpsertUseCase(storage: viewStorage)

// When
useCase.upsert([order])

// Then
let storageCustomField = try XCTUnwrap(viewStorage.loadOrderMetaData(siteID: 3, metadataID: 1))
XCTAssertEqual(storageCustomField.toReadOnly(), customField)
}

func test_it_replaces_existing_order_custom_field_in_storage() throws {
// Given
let originalCustomField = OrderMetaData(metadataID: 1, key: "Key", value: "Value")
let order = makeOrder().copy(siteID: 3, customFields: [originalCustomField])
let useCase = OrdersUpsertUseCase(storage: viewStorage)
useCase.upsert([order])

// When
let customField = OrderMetaData(metadataID: 1, key: "Key", value: "New Value")
useCase.upsert([order.copy(customFields: [customField])])

// Then
let storageCustomField = try XCTUnwrap(viewStorage.loadOrderMetaData(siteID: 3, metadataID: 1))
XCTAssertEqual(storageCustomField.toReadOnly(), customField)
}
}

private extension OrdersUpsertUseCaseTests {
Expand Down
22 changes: 19 additions & 3 deletions Yosemite/YosemiteTests/Stores/OrderStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,15 @@ final class OrderStoreTests: XCTestCase {
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderItemTax.self), 0)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderCoupon.self), 0)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderTaxLine.self), 0)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderMetaData.self), 0)

orderStore.upsertStoredOrder(readOnlyOrder: sampleOrder(), in: viewStorage)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.Order.self), 1)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderItem.self), 2)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderItemTax.self), 2)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderCoupon.self), 1)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderTaxLine.self), 1)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderMetaData.self), 1)

orderStore.upsertStoredOrder(readOnlyOrder: sampleOrderMutated(), in: viewStorage)
let storageOrder1 = viewStorage.loadOrder(siteID: sampleSiteID, orderID: sampleOrderMutated().orderID)
Expand All @@ -357,6 +359,7 @@ final class OrderStoreTests: XCTestCase {
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderItemTax.self), 3)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderCoupon.self), 2)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderTaxLine.self), 2)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderMetaData.self), 2)

orderStore.upsertStoredOrder(readOnlyOrder: sampleOrderMutated2(), in: viewStorage)
let storageOrder2 = viewStorage.loadOrder(siteID: sampleSiteID, orderID: sampleOrderMutated2().orderID)
Expand All @@ -366,6 +369,7 @@ final class OrderStoreTests: XCTestCase {
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderItemTax.self), 4)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderCoupon.self), 0)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderTaxLine.self), 0)
XCTAssertEqual(viewStorage.countObjects(ofType: Storage.OrderMetaData.self), 0)
}

/// Verifies that `upsertStoredOrder` effectively inserts a new Order, with the specified payload.
Expand Down Expand Up @@ -1149,7 +1153,8 @@ private extension OrderStoreTests {
shippingAddress: sampleAddress(),
shippingLines: sampleShippingLines(),
coupons: sampleCoupons(),
taxes: sampleOrderTaxLines())
taxes: sampleOrderTaxLines(),
customFields: sampleCustomFields())
}

func sampleOrderMutated() -> Networking.Order {
Expand All @@ -1158,7 +1163,8 @@ private extension OrderStoreTests {
total: "41.20",
items: sampleItemsMutated(),
coupons: sampleCouponsMutated(),
taxes: sampleOrderTaxLinesMutated())
taxes: sampleOrderTaxLinesMutated(),
customFields: sampleCustomFieldsMutated())
}

func sampleOrderMutated2() -> Networking.Order {
Expand All @@ -1167,7 +1173,8 @@ private extension OrderStoreTests {
total: "41.20",
items: sampleItemsMutated2(),
coupons: [],
taxes: [])
taxes: [],
customFields: [])
}

func sampleAddress() -> Networking.Address {
Expand Down Expand Up @@ -1345,4 +1352,13 @@ private extension OrderStoreTests {
[Networking.OrderItemTax(taxID: 73, subtotal: "0.9", total: "0.9"),
Networking.OrderItemTax(taxID: 75, subtotal: "0.45", total: "0.45")]
}

func sampleCustomFields() -> [Networking.OrderMetaData] {
return [Networking.OrderMetaData(metadataID: 18148, key: "Viewed Currency", value: "USD")]
}

func sampleCustomFieldsMutated() -> [Networking.OrderMetaData] {
return [Networking.OrderMetaData(metadataID: 18148, key: "Viewed Currency", value: "GBP"),
Networking.OrderMetaData(metadataID: 18149, key: "Converted Order Total", value: "223.71 GBP")]
}
}

0 comments on commit 0576bca

Please sign in to comment.