|
| 1 | +import Foundation |
| 2 | +import Testing |
| 3 | +@testable import Yosemite |
| 4 | + |
| 5 | +struct PersistedProductConversionsTests { |
| 6 | + |
| 7 | + @Test("PersistedProduct init(from:) maps all POSProduct fields") |
| 8 | + func test_product_init_from_posProduct_maps_all_fields() throws { |
| 9 | + // Given |
| 10 | + let siteID: Int64 = 1 |
| 11 | + let productID: Int64 = 10 |
| 12 | + let images: [ProductImage] = [ |
| 13 | + ProductImage(imageID: 100, |
| 14 | + dateCreated: Date(timeIntervalSince1970: 1), |
| 15 | + dateModified: nil, |
| 16 | + src: "https://example.com/1.png", |
| 17 | + name: "img1", |
| 18 | + alt: "alt1"), |
| 19 | + ProductImage(imageID: 101, |
| 20 | + dateCreated: Date(timeIntervalSince1970: 2), |
| 21 | + dateModified: Date(timeIntervalSince1970: 3), |
| 22 | + src: "https://example.com/2.png", |
| 23 | + name: "img2", |
| 24 | + alt: nil) |
| 25 | + ] |
| 26 | + let attributes: [ProductAttribute] = [ |
| 27 | + ProductAttribute(siteID: siteID, attributeID: 0, name: "Color", position: 0, visible: true, variation: true, options: ["Red", "Blue"]), |
| 28 | + ProductAttribute(siteID: siteID, attributeID: 0, name: "Size", position: 1, visible: false, variation: false, options: ["S", "M"]) |
| 29 | + ] |
| 30 | + let pos = POSProduct( |
| 31 | + siteID: siteID, |
| 32 | + productID: productID, |
| 33 | + name: "Test Product", |
| 34 | + productTypeKey: "simple", |
| 35 | + fullDescription: "Full", |
| 36 | + shortDescription: "Short", |
| 37 | + sku: "SKU-123", |
| 38 | + globalUniqueID: "GID-1", |
| 39 | + price: "9.99", |
| 40 | + downloadable: false, |
| 41 | + parentID: 0, |
| 42 | + images: images, |
| 43 | + attributes: attributes, |
| 44 | + manageStock: true, |
| 45 | + stockQuantity: 5, |
| 46 | + stockStatusKey: "instock" |
| 47 | + ) |
| 48 | + |
| 49 | + // When |
| 50 | + let persisted = PersistedProduct(from: pos) |
| 51 | + |
| 52 | + // Then |
| 53 | + #expect(persisted.id == productID) |
| 54 | + #expect(persisted.siteID == siteID) |
| 55 | + #expect(persisted.name == pos.name) |
| 56 | + #expect(persisted.productTypeKey == pos.productTypeKey) |
| 57 | + #expect(persisted.fullDescription == nil) |
| 58 | + #expect(persisted.shortDescription == nil) |
| 59 | + #expect(persisted.sku == pos.sku) |
| 60 | + #expect(persisted.globalUniqueID == pos.globalUniqueID) |
| 61 | + #expect(persisted.price == pos.price) |
| 62 | + #expect(persisted.downloadable == pos.downloadable) |
| 63 | + #expect(persisted.parentID == pos.parentID) |
| 64 | + #expect(persisted.manageStock == pos.manageStock) |
| 65 | + #expect(persisted.stockQuantity == pos.stockQuantity) |
| 66 | + #expect(persisted.stockStatusKey == pos.stockStatusKey) |
| 67 | + } |
| 68 | + |
| 69 | + @Test("PersistedProduct toPOSProduct maps back with images and attributes") |
| 70 | + func test_product_toPOSProduct_maps_back_including_images_and_attributes() throws { |
| 71 | + // Given |
| 72 | + let siteID: Int64 = 2 |
| 73 | + let productID: Int64 = 20 |
| 74 | + let persisted = PersistedProduct( |
| 75 | + id: productID, |
| 76 | + siteID: siteID, |
| 77 | + name: "Prod", |
| 78 | + productTypeKey: "variable", |
| 79 | + fullDescription: "FullD", |
| 80 | + shortDescription: "ShortD", |
| 81 | + sku: nil, |
| 82 | + globalUniqueID: nil, |
| 83 | + price: "12.34", |
| 84 | + downloadable: true, |
| 85 | + parentID: 0, |
| 86 | + manageStock: false, |
| 87 | + stockQuantity: nil, |
| 88 | + stockStatusKey: "outofstock" |
| 89 | + ) |
| 90 | + |
| 91 | + let productImages = [ |
| 92 | + PersistedProductImage(id: 200, |
| 93 | + productID: productID, |
| 94 | + dateCreated: Date(timeIntervalSince1970: 10), |
| 95 | + dateModified: nil, |
| 96 | + src: "https://example.com/p1.png", |
| 97 | + name: "p1", |
| 98 | + alt: "a1"), |
| 99 | + PersistedProductImage(id: 201, |
| 100 | + productID: productID, |
| 101 | + dateCreated: Date(timeIntervalSince1970: 11), |
| 102 | + dateModified: Date(timeIntervalSince1970: 12), |
| 103 | + src: "https://example.com/p2.png", |
| 104 | + name: nil, |
| 105 | + alt: nil) |
| 106 | + ] |
| 107 | + |
| 108 | + let persistedAttributes = [ |
| 109 | + PersistedProductAttribute(productID: productID, name: "Material", position: 0, visible: true, variation: false, options: ["Cotton"]), |
| 110 | + PersistedProductAttribute(productID: productID, name: "Fit", position: 1, visible: true, variation: true, options: ["Slim", "Regular"]) |
| 111 | + ] |
| 112 | + |
| 113 | + // When |
| 114 | + let pos = persisted.toPOSProduct( |
| 115 | + images: productImages.map { $0.toProductImage() }, |
| 116 | + attributes: persistedAttributes.map { $0.toProductAttribute(siteID: siteID) } |
| 117 | + ) |
| 118 | + |
| 119 | + // Then |
| 120 | + #expect(pos.siteID == siteID) |
| 121 | + #expect(pos.productID == productID) |
| 122 | + #expect(pos.name == persisted.name) |
| 123 | + #expect(pos.productTypeKey == persisted.productTypeKey) |
| 124 | + #expect(pos.fullDescription == persisted.fullDescription) |
| 125 | + #expect(pos.shortDescription == persisted.shortDescription) |
| 126 | + #expect(pos.sku == persisted.sku) |
| 127 | + #expect(pos.globalUniqueID == persisted.globalUniqueID) |
| 128 | + #expect(pos.price == persisted.price) |
| 129 | + #expect(pos.downloadable == persisted.downloadable) |
| 130 | + #expect(pos.parentID == persisted.parentID) |
| 131 | + #expect(pos.manageStock == persisted.manageStock) |
| 132 | + #expect(pos.stockQuantity == persisted.stockQuantity) |
| 133 | + #expect(pos.stockStatusKey == persisted.stockStatusKey) |
| 134 | + #expect(pos.images.count == 2) |
| 135 | + #expect(pos.attributes.count == 2) |
| 136 | + #expect(pos.attributesForVariations.count == 1) |
| 137 | + } |
| 138 | + |
| 139 | + @Test("PersistedProductAttribute init(from:) and toProductAttribute round-trip") |
| 140 | + func test_product_attribute_round_trip() throws { |
| 141 | + // Given |
| 142 | + let siteID: Int64 = 3 |
| 143 | + let productID: Int64 = 30 |
| 144 | + let attribute = ProductAttribute(siteID: siteID, |
| 145 | + attributeID: 0, |
| 146 | + name: "Flavor", |
| 147 | + position: 2, |
| 148 | + visible: true, |
| 149 | + variation: true, |
| 150 | + options: ["Vanilla", "Chocolate"]) |
| 151 | + |
| 152 | + // When |
| 153 | + let persisted = PersistedProductAttribute(from: attribute, productID: productID) |
| 154 | + let back = persisted.toProductAttribute(siteID: siteID) |
| 155 | + |
| 156 | + // Then |
| 157 | + #expect(persisted.productID == productID) |
| 158 | + #expect(persisted.name == attribute.name) |
| 159 | + #expect(persisted.position == Int64(attribute.position)) |
| 160 | + #expect(persisted.visible == attribute.visible) |
| 161 | + #expect(persisted.variation == attribute.variation) |
| 162 | + #expect(persisted.options == attribute.options) |
| 163 | + |
| 164 | + #expect(back.siteID == siteID) |
| 165 | + #expect(back.name == attribute.name) |
| 166 | + #expect(back.position == attribute.position) |
| 167 | + #expect(back.visible == attribute.visible) |
| 168 | + #expect(back.variation == attribute.variation) |
| 169 | + #expect(back.options == attribute.options) |
| 170 | + } |
| 171 | + |
| 172 | + @Test("PersistedProductImage init(from:) and toProductImage round-trip") |
| 173 | + func test_product_image_round_trip() throws { |
| 174 | + // Given |
| 175 | + let productID: Int64 = 40 |
| 176 | + let image = ProductImage(imageID: 400, |
| 177 | + dateCreated: Date(timeIntervalSince1970: 100), |
| 178 | + dateModified: Date(timeIntervalSince1970: 200), |
| 179 | + src: "https://example.com/x.png", |
| 180 | + name: "x", |
| 181 | + alt: "y") |
| 182 | + |
| 183 | + // When |
| 184 | + let persisted = PersistedProductImage(from: image, productID: productID) |
| 185 | + let back = persisted.toProductImage() |
| 186 | + |
| 187 | + // Then |
| 188 | + #expect(persisted.id == image.imageID) |
| 189 | + #expect(persisted.productID == productID) |
| 190 | + #expect(persisted.dateCreated == image.dateCreated) |
| 191 | + #expect(persisted.dateModified == image.dateModified) |
| 192 | + #expect(persisted.src == image.src) |
| 193 | + #expect(persisted.name == image.name) |
| 194 | + #expect(persisted.alt == image.alt) |
| 195 | + |
| 196 | + #expect(back.imageID == image.imageID) |
| 197 | + #expect(back.dateCreated == image.dateCreated) |
| 198 | + #expect(back.dateModified == image.dateModified) |
| 199 | + #expect(back.src == image.src) |
| 200 | + #expect(back.name == image.name) |
| 201 | + #expect(back.alt == image.alt) |
| 202 | + } |
| 203 | +} |
0 commit comments