/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ // @nova-cleanup(move-directory): Move to test/unit/content-src/components/CustomizeMenu/ after Nova ships import React from "react"; import { mount } from "enzyme"; import { Provider } from "react-redux"; import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs"; import { combineReducers, createStore } from "redux"; import { WidgetsManagementPanel } from "content-src/components/Nova/CustomizeMenu/WidgetsManagementPanel/WidgetsManagementPanel"; function WrapWithProvider({ children, state = INITIAL_STATE }) { const store = createStore(combineReducers(reducers), state); return {children}; } describe("", () => { let wrapper; let sandbox; let DEFAULT_PROPS; beforeEach(() => { sandbox = sinon.createSandbox(); DEFAULT_PROPS = { exitEventFired: false, onSubpanelToggle: sandbox.stub(), togglePanel: sandbox.stub(), showPanel: false, enabledSections: { weatherEnabled: false }, enabledWidgets: { timerEnabled: false, listsEnabled: false, widgetsMaximized: false, widgetsMayBeMaximized: false, }, mayHaveWeather: true, mayHaveTimerWidget: true, mayHaveListsWidget: true, mayHaveWeatherForecast: false, weatherDisplay: "simple", setPref: sandbox.stub(), }; }); afterEach(() => { if (wrapper) { wrapper.unmount(); wrapper = null; } sandbox.restore(); }); it("should render the component", () => { wrapper = mount( ); assert.ok(wrapper.exists()); }); it("should render the manage widgets button", () => { wrapper = mount( ); assert.ok(wrapper.find("moz-box-button").exists()); }); it("should call togglePanel when button is clicked", () => { wrapper = mount( ); wrapper.find("moz-box-button").simulate("click"); assert.calledOnce(DEFAULT_PROPS.togglePanel); }); it("should render the panel when showPanel is true", () => { wrapper = mount( ); assert.ok(wrapper.find(".widgets-mgmt-panel").exists()); }); it("should not render the panel when showPanel is false", () => { wrapper = mount( ); assert.isFalse(wrapper.find(".widgets-mgmt-panel").exists()); }); it("should call onSubpanelToggle when panel opens", () => { wrapper = mount( ); wrapper.setProps({ children: ( ), }); assert.called(DEFAULT_PROPS.onSubpanelToggle); }); it("should call togglePanel when exitEventFired becomes true and showPanel is true", () => { wrapper = mount( ); wrapper.setProps({ children: ( ), }); assert.called(DEFAULT_PROPS.togglePanel); }); it("should not call togglePanel when exitEventFired becomes true but showPanel is false", () => { wrapper = mount( ); wrapper.setProps({ children: ( ), }); assert.notCalled(DEFAULT_PROPS.togglePanel); }); it("should call togglePanel when arrow button is clicked", () => { wrapper = mount( ); wrapper.find(".arrow-button").simulate("click"); assert.calledOnce(DEFAULT_PROPS.togglePanel); }); it("should render panel title", () => { wrapper = mount( ); const panel = wrapper.find(".widgets-mgmt-panel"); assert.ok(panel.exists()); assert.equal(panel.find("h1").length, 1); }); describe("widget toggles", () => { it("should render weather toggle when mayHaveWeather is true", () => { wrapper = mount( ); assert.ok(wrapper.find("#weather-toggle").exists()); }); it("should not render weather toggle when mayHaveWeather is false", () => { wrapper = mount( ); assert.isFalse(wrapper.find("#weather-toggle").exists()); }); it("should render timer toggle when mayHaveTimerWidget is true", () => { wrapper = mount( ); assert.ok(wrapper.find("#timer-toggle").exists()); }); it("should not render timer toggle when mayHaveTimerWidget is false", () => { wrapper = mount( ); assert.isFalse(wrapper.find("#timer-toggle").exists()); }); it("should render lists toggle when mayHaveListsWidget is true", () => { wrapper = mount( ); assert.ok(wrapper.find("#lists-toggle").exists()); }); it("should not render lists toggle when mayHaveListsWidget is false", () => { wrapper = mount( ); assert.isFalse(wrapper.find("#lists-toggle").exists()); }); it("should reflect weatherEnabled in weather toggle pressed state", () => { wrapper = mount( ); assert.isTrue(wrapper.find("#weather-toggle").prop("pressed")); }); it("should reflect timerEnabled in timer toggle pressed state", () => { wrapper = mount( ); assert.isTrue(wrapper.find("#timer-toggle").prop("pressed")); }); it("should reflect listsEnabled in lists toggle pressed state", () => { wrapper = mount( ); assert.isTrue(wrapper.find("#lists-toggle").prop("pressed")); }); }); describe("dispatch on toggle", () => { it("should dispatch PREF_CHANGED and WIDGETS_ENABLED when weather toggle is fired", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "TELEMETRY_USER_EVENT" }) ); assert.calledWith(dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED" })); }); it("should call setPref when a toggle is fired", () => { wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: true, }, }); assert.calledOnce(DEFAULT_PROPS.setPref); assert.calledWith(DEFAULT_PROPS.setPref, "showWeather", true); }); it("should dispatch PREF_CHANGED and WIDGETS_ENABLED when lists toggle is fired", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#lists-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.lists.enabled", eventSource: "WIDGET_LISTS", }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "TELEMETRY_USER_EVENT" }) ); assert.calledWith(dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED" })); }); it("should call setPref when lists toggle is fired", () => { wrapper = mount( ); wrapper.find("#lists-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.lists.enabled", eventSource: "WIDGET_LISTS", }, pressed: true, }, }); assert.calledOnce(DEFAULT_PROPS.setPref); assert.calledWith(DEFAULT_PROPS.setPref, "widgets.lists.enabled", true); }); it("should dispatch PREF_CHANGED and WIDGETS_ENABLED when timer toggle is fired", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#timer-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.focusTimer.enabled", eventSource: "WIDGET_TIMER", }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "TELEMETRY_USER_EVENT" }) ); assert.calledWith(dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED" })); }); it("should call setPref when timer toggle is fired", () => { wrapper = mount( ); wrapper.find("#timer-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.focusTimer.enabled", eventSource: "WIDGET_TIMER", }, pressed: true, }, }); assert.calledOnce(DEFAULT_PROPS.setPref); assert.calledWith( DEFAULT_PROPS.setPref, "widgets.focusTimer.enabled", true ); }); it("should dispatch WIDGETS_ENABLED with enabled: false when toggled off", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: false, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ enabled: false }), }) ); }); it("should dispatch WIDGETS_ENABLED with widget_size: 'mini' for weather when not detailed forecast", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ widget_size: "mini" }), }) ); }); it("should dispatch WIDGETS_ENABLED with widget_size: 'small' for weather when detailed forecast and widgetsMayBeMaximized but not widgetsMaximized", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ widget_size: "small" }), }) ); }); it("should dispatch WIDGETS_ENABLED with widget_size: 'medium' for weather when detailed forecast and widgetsMaximized", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#weather-toggle").prop("ontoggle")({ target: { dataset: { preference: "showWeather", eventSource: "WEATHER" }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ widget_size: "medium" }), }) ); }); it("should dispatch WIDGETS_ENABLED with widget_size: 'small' for non-weather widget when widgetsMayBeMaximized and not widgetsMaximized", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#timer-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.focusTimer.enabled", eventSource: "WIDGET_TIMER", }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ widget_size: "small" }), }) ); }); it("should dispatch WIDGETS_ENABLED with widget_size: 'medium' for non-weather widget when widgetsMaximized", () => { const store = createStore(combineReducers(reducers), INITIAL_STATE); const dispatchSpy = sandbox.spy(store, "dispatch"); wrapper = mount( ); wrapper.find("#timer-toggle").prop("ontoggle")({ target: { dataset: { preference: "widgets.focusTimer.enabled", eventSource: "WIDGET_TIMER", }, pressed: true, }, }); assert.calledWith( dispatchSpy, sinon.match({ type: "WIDGETS_ENABLED", data: sinon.match({ widget_size: "medium" }), }) ); }); }); });