diff --git a/order-routing/rust/pickup-point-delivery-option-generators/default/src/run.rs b/order-routing/rust/pickup-point-delivery-option-generators/default/src/run.rs index 098a7689..88cbabee 100644 --- a/order-routing/rust/pickup-point-delivery-option-generators/default/src/run.rs +++ b/order-routing/rust/pickup-point-delivery-option-generators/default/src/run.rs @@ -138,7 +138,7 @@ fn build_business_hours( .map(|day| { let day_parts: Vec<&str> = day.as_str().unwrap().split(": ").collect(); let day_name = serde_json::from_str::( - format!("\"{}\"", &day_parts[0].to_uppercase()).as_str(), + format!("\"{}\"", day_parts[0].to_uppercase()).as_str(), ) .unwrap(); if day_parts[1] == "Closed" { diff --git a/sample-apps/update-line-item/extensions/update-line-item-js/src/run.js b/sample-apps/update-line-item/extensions/update-line-item-js/src/run.js index 159d2a5a..d19d80d6 100644 --- a/sample-apps/update-line-item/extensions/update-line-item-js/src/run.js +++ b/sample-apps/update-line-item/extensions/update-line-item-js/src/run.js @@ -51,24 +51,35 @@ export function run(input) { function optionallyBuildUpdateOperation( { id: cartLineId, merchandise, cost, fabricLength } ) { - const hasFabricLength = fabricLength && Number(fabricLength.value) > 0; + if (merchandise.__typename !== "ProductVariant" || !fabricLength) { + return null; + } - if ( - merchandise.__typename === "ProductVariant" && - hasFabricLength - ) { - return { - cartLineId, - title: `${merchandise.title} (${fabricLength.value}m)`, - price: { - adjustment: { - fixedPricePerUnit: { - amount: (Number(fabricLength.value) * cost.amountPerQuantity.amount).toFixed(2) - } - } - } - }; + // The fabric length is provided by the customer, so treat it as untrusted: + // only a positive, finite number is a valid length. + const length = Number(fabricLength.value); + if (!Number.isFinite(length) || length <= 0) { + return null; + } + + const amount = (length * cost.amountPerQuantity.amount).toFixed(2); + + // Rounding to cents happens after the multiplication, so a tiny positive + // length can still round the price down to "0.00". Never make the line free: + // leave it at its original price instead. + if (Number(amount) <= 0) { + return null; } - return null; + return { + cartLineId, + title: `${merchandise.title} (${fabricLength.value}m)`, + price: { + adjustment: { + fixedPricePerUnit: { + amount + } + } + } + }; } diff --git a/sample-apps/update-line-item/extensions/update-line-item-js/src/run.test.js b/sample-apps/update-line-item/extensions/update-line-item-js/src/run.test.js index b889ce91..7fdb5711 100644 --- a/sample-apps/update-line-item/extensions/update-line-item-js/src/run.test.js +++ b/sample-apps/update-line-item/extensions/update-line-item-js/src/run.test.js @@ -81,4 +81,104 @@ describe("cart transform function", () => { ], }); }); + + it("returns NO_CHANGES when the fabric length would round the price down to zero", () => { + expect( + run({ + cart: { + lines: [ + { + id: "1", + cost: { + amountPerQuantity: { + amount: "10.0", + currencyCode: "CAD" + } + }, + fabricLength: { + value: "0.0001" + }, + merchandise: { + __typename: "ProductVariant", + id: "gid://shopify/ProductVariant/2", + title: "Custom Fabric" + }, + }, + ], + }, + }) + ).toStrictEqual({ operations: [] }); + }); + + it("returns NO_CHANGES when the fabric length is not a finite number", () => { + expect( + run({ + cart: { + lines: [ + { + id: "1", + cost: { + amountPerQuantity: { + amount: "10.0", + currencyCode: "CAD" + } + }, + fabricLength: { + value: "Infinity" + }, + merchandise: { + __typename: "ProductVariant", + id: "gid://shopify/ProductVariant/2", + title: "Custom Fabric" + }, + }, + ], + }, + }) + ).toStrictEqual({ operations: [] }); + }); + + it("returns operations when the fabric length prices the line at the smallest chargeable amount", () => { + expect( + run({ + cart: { + lines: [ + { + id: "1", + cost: { + amountPerQuantity: { + amount: "10.0", + currencyCode: "CAD" + } + }, + fabricLength: { + value: "0.001" + }, + merchandise: { + __typename: "ProductVariant", + id: "gid://shopify/ProductVariant/2", + title: "Custom Fabric" + }, + }, + ], + }, + }) + ).toStrictEqual({ + operations: [ + { + update: { + cartLineId: "1", + title: "Custom Fabric (0.001m)", + price: { + adjustment: { + fixedPricePerUnit: { + amount: "0.01" + } + } + } + }, + }, + ], + }); + }); });