diff options
Diffstat (limited to 'browser/components/aboutwelcome/tests/unit/MultiSelect.test.jsx')
-rw-r--r-- | browser/components/aboutwelcome/tests/unit/MultiSelect.test.jsx | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/browser/components/aboutwelcome/tests/unit/MultiSelect.test.jsx b/browser/components/aboutwelcome/tests/unit/MultiSelect.test.jsx new file mode 100644 index 0000000000..b42964f906 --- /dev/null +++ b/browser/components/aboutwelcome/tests/unit/MultiSelect.test.jsx @@ -0,0 +1,221 @@ +import React from "react"; +import { mount } from "enzyme"; +import { MultiSelect } from "content-src/components/MultiSelect"; + +describe("MultiSelect component", () => { + let sandbox; + let MULTISELECT_SCREEN_PROPS; + let setScreenMultiSelects; + let setActiveMultiSelect; + beforeEach(() => { + sandbox = sinon.createSandbox(); + setScreenMultiSelects = sandbox.stub(); + setActiveMultiSelect = sandbox.stub(); + MULTISELECT_SCREEN_PROPS = { + id: "multiselect-screen", + content: { + position: "split", + split_narrow_bkg_position: "-60px", + image_alt_text: { + string_id: "mr2022-onboarding-default-image-alt", + }, + background: + "url('chrome://activity-stream/content/data/content/assets/mr-settodefault.svg') var(--mr-secondary-position) no-repeat var(--mr-screen-background-color)", + progress_bar: true, + logo: {}, + title: "Test Title", + tiles: { + type: "multiselect", + label: "Test Subtitle", + data: [ + { + id: "checkbox-1", + defaultValue: true, + label: { + string_id: "mr2022-onboarding-set-default-primary-button-label", + }, + action: { + type: "SET_DEFAULT_BROWSER", + }, + }, + { + id: "checkbox-2", + defaultValue: true, + label: "Test Checkbox 2", + action: { + type: "SHOW_MIGRATION_WIZARD", + data: {}, + }, + }, + { + id: "checkbox-3", + defaultValue: false, + label: "Test Checkbox 3", + action: { + type: "SHOW_MIGRATION_WIZARD", + data: {}, + }, + }, + ], + }, + primary_button: { + label: "Save and Continue", + action: { + type: "MULTI_ACTION", + collectSelect: true, + navigate: true, + data: { actions: [] }, + }, + }, + secondary_button: { + label: "Skip", + action: { + navigate: true, + }, + has_arrow_icon: true, + }, + }, + setScreenMultiSelects, + setActiveMultiSelect, + }; + }); + afterEach(() => { + sandbox.restore(); + }); + + it("should call setScreenMultiSelects with all ids of checkboxes", () => { + mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + + assert.calledOnce(setScreenMultiSelects); + assert.calledWith(setScreenMultiSelects, [ + "checkbox-1", + "checkbox-2", + "checkbox-3", + ]); + }); + + it("should not call setScreenMultiSelects if it's already set", () => { + let map = sandbox + .stub() + .returns(MULTISELECT_SCREEN_PROPS.content.tiles.data); + + mount( + <MultiSelect screenMultiSelects={{ map }} {...MULTISELECT_SCREEN_PROPS} /> + ); + + assert.notCalled(setScreenMultiSelects); + assert.calledOnce(map); + assert.calledWith(map, sinon.match.func); + }); + + it("should call setActiveMultiSelect with ids of checkboxes with defaultValue true", () => { + const wrapper = mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + + wrapper.setProps({ activeMultiSelect: null }); + assert.calledOnce(setActiveMultiSelect); + assert.calledWith(setActiveMultiSelect, ["checkbox-1", "checkbox-2"]); + }); + + it("should use activeMultiSelect ids to set checked state for respective checkbox", () => { + const wrapper = mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + + wrapper.setProps({ activeMultiSelect: ["checkbox-1", "checkbox-2"] }); + const checkBoxes = wrapper.find(".checkbox-container input"); + assert.strictEqual(checkBoxes.length, 3); + + assert.strictEqual(checkBoxes.first().props().checked, true); + assert.strictEqual(checkBoxes.at(1).props().checked, true); + assert.strictEqual(checkBoxes.last().props().checked, false); + }); + + it("cover the randomize property", async () => { + MULTISELECT_SCREEN_PROPS.content.tiles.data.forEach( + item => (item.randomize = true) + ); + + const wrapper = mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + + const checkBoxes = wrapper.find(".checkbox-container input"); + assert.strictEqual(checkBoxes.length, 3); + + // We don't want to actually test the randomization, just that it doesn't + // throw. We _could_ render the component until we get a different order, + // and that should work the vast majority of the time, but it's + // theoretically possible that we get the same order over and over again + // until we hit the 2 second timeout. That would be an extremely low failure + // rate, but we already know Math.random() works, so we don't really need to + // test it anyway. It's not worth the added risk of false failures. + }); + + it("should filter out id when checkbox is unchecked", () => { + const wrapper = mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + wrapper.setProps({ activeMultiSelect: ["checkbox-1", "checkbox-2"] }); + + const ckbx1 = wrapper.find(".checkbox-container input").at(0); + assert.strictEqual(ckbx1.prop("value"), "checkbox-1"); + ckbx1.getDOMNode().checked = false; + ckbx1.simulate("change"); + assert.calledWith(setActiveMultiSelect, ["checkbox-2"]); + }); + + it("should add id when checkbox is checked", () => { + const wrapper = mount(<MultiSelect {...MULTISELECT_SCREEN_PROPS} />); + wrapper.setProps({ activeMultiSelect: ["checkbox-1", "checkbox-2"] }); + + const ckbx3 = wrapper.find(".checkbox-container input").at(2); + assert.strictEqual(ckbx3.prop("value"), "checkbox-3"); + ckbx3.getDOMNode().checked = true; + ckbx3.simulate("change"); + assert.calledWith(setActiveMultiSelect, [ + "checkbox-1", + "checkbox-2", + "checkbox-3", + ]); + }); + + it("should render radios and checkboxes with correct styles", async () => { + const SCREEN_PROPS = { ...MULTISELECT_SCREEN_PROPS }; + SCREEN_PROPS.content.tiles.style = { flexDirection: "row", gap: "24px" }; + SCREEN_PROPS.content.tiles.data = [ + { + id: "checkbox-1", + defaultValue: true, + label: { raw: "Test1" }, + action: { type: "OPEN_PROTECTION_REPORT" }, + style: { color: "red" }, + icon: { style: { color: "blue" } }, + }, + { + id: "radio-1", + type: "radio", + group: "radios", + defaultValue: true, + label: { raw: "Test3" }, + action: { type: "OPEN_PROTECTION_REPORT" }, + style: { color: "purple" }, + icon: { style: { color: "yellow" } }, + }, + ]; + const wrapper = mount(<MultiSelect {...SCREEN_PROPS} />); + + // wait for effect hook + await new Promise(resolve => queueMicrotask(resolve)); + // activeMultiSelect was called on effect hook with default values + assert.calledWith(setActiveMultiSelect, ["checkbox-1", "radio-1"]); + + const container = wrapper.find(".multi-select-container"); + assert.strictEqual(container.prop("style").flexDirection, "row"); + assert.strictEqual(container.prop("style").gap, "24px"); + + // checkboxes/radios are rendered with correct styles + const checkBoxes = wrapper.find(".checkbox-container"); + assert.strictEqual(checkBoxes.length, 2); + assert.strictEqual(checkBoxes.first().prop("style").color, "red"); + assert.strictEqual(checkBoxes.at(1).prop("style").color, "purple"); + + const checks = wrapper.find(".checkbox-container input"); + assert.strictEqual(checks.length, 2); + assert.strictEqual(checks.first().prop("style").color, "blue"); + assert.strictEqual(checks.at(1).prop("style").color, "yellow"); + }); +}); |