From b2881bb169fee05a901466d8c5d3f80d6b1e547c Mon Sep 17 00:00:00 2001 From: David Cook Date: Wed, 27 Mar 2024 16:35:04 +1100 Subject: [PATCH] Add JS specs Converted using https://www.codeconvert.ai/coffeescript-to-javascript-converter With plenty of manual fixes required too.. --- .../js/services/option_value_namer.js | 3 +- .../js/services/variant_unit_manager.js | 2 +- .../services/option_value_namer_test.js | 157 ++++++++++++++++++ .../services/variant_unit_manager_test.js | 71 ++++++++ 4 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 spec/javascripts/services/option_value_namer_test.js create mode 100644 spec/javascripts/services/variant_unit_manager_test.js diff --git a/app/webpacker/js/services/option_value_namer.js b/app/webpacker/js/services/option_value_namer.js index dbf74a0dbe..5bc10220ce 100644 --- a/app/webpacker/js/services/option_value_namer.js +++ b/app/webpacker/js/services/option_value_namer.js @@ -1,4 +1,4 @@ -import VariantUnitManager from "js/services/variant_unit_manager"; +import VariantUnitManager from "../../js/services/variant_unit_manager"; // Javascript clone of VariantUnits::OptionValueNamer, for bulk product editing. export default class OptionValueNamer { @@ -70,6 +70,7 @@ export default class OptionValueNamer { option_value_value_unit_scaled() { const [unit_scale, unit_name] = this.scale_for_unit_value(); + const value = Math.round((this.variant.unit_value / unit_scale) * 100) / 100; return [value, unit_name]; } diff --git a/app/webpacker/js/services/variant_unit_manager.js b/app/webpacker/js/services/variant_unit_manager.js index b9aa344992..13f963bdb6 100644 --- a/app/webpacker/js/services/variant_unit_manager.js +++ b/app/webpacker/js/services/variant_unit_manager.js @@ -21,7 +21,7 @@ export default class VariantUnitManager { .filter(([scale, scaleInfo]) => { return scaleInfo['system'] == scaleSystem; }) - .map(([scale, _]) => scale); + .map(([scale, _]) => parseFloat(scale)); } // private diff --git a/spec/javascripts/services/option_value_namer_test.js b/spec/javascripts/services/option_value_namer_test.js new file mode 100644 index 0000000000..b8535d488e --- /dev/null +++ b/spec/javascripts/services/option_value_namer_test.js @@ -0,0 +1,157 @@ +/** + * @jest-environment jsdom + */ + +import OptionValueNamer from "../../../app/webpacker/js/services/option_value_namer"; + +describe("OptionValueNamer", () => { + beforeAll(() => { + // Requires global var from page + global.ofn_available_units_sorted = {"weight":{"1.0":{"name":"g","system":"metric"},"1000.0":{"name":"kg","system":"metric"},"1000000.0":{"name":"T","system":"metric"}},"volume":{"0.001":{"name":"mL","system":"metric"},"1.0":{"name":"L","system":"metric"},"4.54609":{"name":"gal","system":"imperial"},"1000.0":{"name":"kL","system":"metric"}}}; + }) + + describe("generating option value name", function() { + var v, namer; + beforeEach(function() { + v = {}; + var ofn_available_units_sorted = ofn_available_units_sorted; + namer = new OptionValueNamer(v); + }); + + it("when description is blank", function() { + v.unit_description = null; + jest.spyOn(namer, "value_scaled").mockImplementation(() => true); + jest.spyOn(namer, "option_value_value_unit").mockImplementation(() => ["value", "unit"]); + expect(namer.name()).toBe("valueunit"); + }); + + it("when description is present", function() { + v.unit_description = 'desc'; + jest.spyOn(namer, "option_value_value_unit").mockImplementation(() => ["value", "unit"]); + jest.spyOn(namer, "value_scaled").mockImplementation(() => true); + expect(namer.name()).toBe("valueunit desc"); + }); + + it("when value is blank and description is present", function() { + v.unit_description = 'desc'; + jest.spyOn(namer, "option_value_value_unit").mockImplementation(() => [null, null]); + jest.spyOn(namer, "value_scaled").mockImplementation(() => true); + expect(namer.name()).toBe("desc"); + }); + + it("spaces value and unit when value is unscaled", function() { + v.unit_description = null; + jest.spyOn(namer, "option_value_value_unit").mockImplementation(() => ["value", "unit"]); + jest.spyOn(namer, "value_scaled").mockImplementation(() => false); + expect(namer.name()).toBe("value unit"); + }); + + describe("determining if a variant's value is scaled", function() { + var p; + beforeEach(function() { + p = {}; + v = { product: p }; + namer = new OptionValueNamer(v); + }); + it("returns true when the product has a scale", function() { + p.variant_unit_scale = 1000; + expect(namer.value_scaled()).toBe(true); + }); + it("returns false otherwise", function() { + expect(namer.value_scaled()).toBe(false); + }); + }); + + describe("generating option value's value and unit", function() { + var v, p, namer; + + // Mock I18n. TODO: moved to a shared helper + beforeAll(() => { + const mockedT = jest.fn(); + mockedT.mockImplementation((string, opts) => (string + ', ' + JSON.stringify(opts))); + + global.I18n = { t: mockedT }; + }) + // (jest still doesn't have aroundEach https://github.com/jestjs/jest/issues/4543 ) + afterAll(() => { + delete global.I18n; + }) + + beforeEach(function() { + p = {}; + v = { product: p }; + namer = new OptionValueNamer(v); + }); + it("generates simple values", function() { + p.variant_unit = 'weight'; + p.variant_unit_scale = 1.0; + v.unit_value = 100; + expect(namer.option_value_value_unit()).toEqual([100, 'g']); + }); + it("generates values when unit value is non-integer", function() { + p.variant_unit = 'weight'; + p.variant_unit_scale = 1.0; + v.unit_value = 123.45; + expect(namer.option_value_value_unit()).toEqual([123.45, 'g']); + }); + it("returns a value of 1 when unit value equals the scale", function() { + p.variant_unit = 'weight'; + p.variant_unit_scale = 1000.0; + v.unit_value = 1000.0; + expect(namer.option_value_value_unit()).toEqual([1, 'kg']); + }); + it("generates values for all weight scales", function() { + [[1.0, 'g'], [1000.0, 'kg'], [1000000.0, 'T']].forEach(([scale, unit]) => { + p.variant_unit = 'weight'; + p.variant_unit_scale = scale; + v.unit_value = 100 * scale; + expect(namer.option_value_value_unit()).toEqual([100, unit]); + }); + }); + it("generates values for all volume scales", function() { + [[0.001, 'mL'], [1.0, 'L'], [1000.0, 'kL']].forEach(([scale, unit]) => { + p.variant_unit = 'volume'; + p.variant_unit_scale = scale; + v.unit_value = 100 * scale; + expect(namer.option_value_value_unit()).toEqual([100, unit]); + }); + }); + it("generates right values for volume with rounded values", function() { + var unit; + unit = 'L'; + p.variant_unit = 'volume'; + p.variant_unit_scale = 1.0; + v.unit_value = 0.7; + expect(namer.option_value_value_unit()).toEqual([700, 'mL']); + }); + it("chooses the correct scale when value is very small", function() { + p.variant_unit = 'volume'; + p.variant_unit_scale = 0.001; + v.unit_value = 0.0001; + expect(namer.option_value_value_unit()).toEqual([0.1, 'mL']); + }); + it("generates values for item units", function() { + //TODO + // %w(packet box).each do |unit| + // p = double(:product, variant_unit: 'items', variant_unit_scale: nil, variant_unit_name: unit) + // v.stub(:product) { p } + // v.stub(:unit_value) { 100 } + // subject.option_value_value_unit.should == [100, unit.pluralize] + }); + it("generates singular values for item units when value is 1", function() { + p.variant_unit = 'items'; + p.variant_unit_scale = null; + p.variant_unit_name = 'packet'; + v.unit_value = 1; + expect(namer.option_value_value_unit()).toEqual([1, 'packet']); + }); + it("returns [null, null] when unit value is not set", function() { + p.variant_unit = 'items'; + p.variant_unit_scale = null; + p.variant_unit_name = 'foo'; + v.unit_value = null; + expect(namer.option_value_value_unit()).toEqual([null, null]); + }); + }); + }); +}); diff --git a/spec/javascripts/services/variant_unit_manager_test.js b/spec/javascripts/services/variant_unit_manager_test.js new file mode 100644 index 0000000000..3e1777b30b --- /dev/null +++ b/spec/javascripts/services/variant_unit_manager_test.js @@ -0,0 +1,71 @@ +/** + * @jest-environment jsdom + */ + +import VariantUnitManager from "../../../app/webpacker/js/services/variant_unit_manager"; + +describe("VariantUnitManager", function() { + let subject; + + describe("with default units", function() { + beforeAll(() => { + // Requires global var from page + global.ofn_available_units_sorted = { + "weight":{ + "1.0":{"name":"g","system":"metric"},"28.35":{"name":"oz","system":"imperial"},"453.6":{"name":"lb","system":"imperial"},"1000.0":{"name":"kg","system":"metric"},"1000000.0":{"name":"T","system":"metric"} + }, + "volume":{ + "0.001":{"name":"mL","system":"metric"},"1.0":{"name":"L","system":"metric"},"1000.0":{"name":"kL","system":"metric"} + }, + }; + }) + beforeEach(() => { + subject = new VariantUnitManager(); + }) + + describe("getUnitName", function() { + it("returns the unit name based on the scale and unit type (weight/volume) provided", function() { + expect(subject.getUnitName(1, "weight")).toEqual("g"); + expect(subject.getUnitName(1000, "weight")).toEqual("kg"); + expect(subject.getUnitName(1000000, "weight")).toEqual("T"); + expect(subject.getUnitName(0.001, "volume")).toEqual("mL"); + expect(subject.getUnitName(1, "volume")).toEqual("L"); + expect(subject.getUnitName(1000, "volume")).toEqual("kL"); + expect(subject.getUnitName(453.6, "weight")).toEqual("lb"); + expect(subject.getUnitName(28.35, "weight")).toEqual("oz"); + }); + }); + + describe("compatibleUnitScales", function() { + it("returns a sorted set of compatible scales based on the scale and unit type provided", function() { + expect(subject.compatibleUnitScales(1, "weight")).toEqual([1.0, 1000.0, 1000000.0]); + expect(subject.compatibleUnitScales(453.6, "weight")).toEqual([28.35, 453.6]); + }); + }); + }); + + describe("should only load available units", function() { + beforeAll(() => { + // Available units: "g,T,mL,L,kL,lb" + global.ofn_available_units_sorted = { + "weight":{ + "1.0":{"name":"g","system":"metric"},"453.6":{"name":"lb","system":"imperial"},"1000000.0":{"name":"T","system":"metric"} + }, + "volume":{ + "0.001":{"name":"mL","system":"metric"},"1.0":{"name":"L","system":"metric"},"1000.0":{"name":"kL","system":"metric"} + }, + }; + }) + beforeEach(() => { + subject = new VariantUnitManager(); + }) + + describe("compatibleUnitScales", function() { + it("returns a sorted set of compatible scales based on the scale and unit type provided", function() { + expect(subject.compatibleUnitScales(1, "weight")).toEqual([1.0, 1000000.0]); + expect(subject.compatibleUnitScales(453.6, "weight")).toEqual([453.6]); + }); + }); + }); +}); +