From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- .../content-src/components/ContextMenu.test.jsx | 227 +++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx (limited to 'browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx') diff --git a/browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx b/browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx new file mode 100644 index 0000000000..4f7edadc41 --- /dev/null +++ b/browser/components/newtab/test/unit/content-src/components/ContextMenu.test.jsx @@ -0,0 +1,227 @@ +import { + ContextMenu, + ContextMenuItem, + _ContextMenuItem, +} from "content-src/components/ContextMenu/ContextMenu"; +import { ContextMenuButton } from "content-src/components/ContextMenu/ContextMenuButton"; +import { mount, shallow } from "enzyme"; +import React from "react"; +import { INITIAL_STATE, reducers } from "common/Reducers.sys.mjs"; +import { Provider } from "react-redux"; +import { combineReducers, createStore } from "redux"; + +const DEFAULT_PROPS = { + onUpdate: () => {}, + options: [], + tabbableOptionsLength: 0, +}; + +const DEFAULT_MENU_OPTIONS = [ + "MoveUp", + "MoveDown", + "Separator", + "ManageSection", +]; + +const FakeMenu = props => { + return
{props.children}
; +}; + +describe("", () => { + function mountWithProps(options) { + const store = createStore(combineReducers(reducers), INITIAL_STATE); + return mount( + + + + + + ); + } + + let sandbox; + beforeEach(() => { + sandbox = sinon.createSandbox(); + }); + afterEach(() => { + sandbox.restore(); + }); + it("should call onUpdate when clicked", () => { + const onUpdate = sandbox.spy(); + const wrapper = mount( + + + + ); + wrapper.find(".context-menu-button").simulate("click"); + assert.calledOnce(onUpdate); + }); + it("should call onUpdate when activated with Enter", () => { + const onUpdate = sandbox.spy(); + const wrapper = mount( + + + + ); + wrapper.find(".context-menu-button").simulate("keydown", { key: "Enter" }); + assert.calledOnce(onUpdate); + }); + it("should call onClick", () => { + const onClick = sandbox.spy(ContextMenuButton.prototype, "onClick"); + const wrapper = mount( + + + + ); + wrapper.find("button").simulate("click"); + assert.calledOnce(onClick); + }); + it("should have a default keyboardAccess prop of false", () => { + const wrapper = mountWithProps(DEFAULT_MENU_OPTIONS); + wrapper.find(ContextMenuButton).setState({ showContextMenu: true }); + assert.equal(wrapper.find(ContextMenu).prop("keyboardAccess"), false); + }); + it("should pass the keyboardAccess prop down to ContextMenu", () => { + const wrapper = mountWithProps(DEFAULT_MENU_OPTIONS); + wrapper + .find(ContextMenuButton) + .setState({ showContextMenu: true, contextMenuKeyboard: true }); + assert.equal(wrapper.find(ContextMenu).prop("keyboardAccess"), true); + }); + it("should call focusFirst when keyboardAccess is true", () => { + const options = [{ label: "item1", first: true }]; + const wrapper = mountWithProps(options); + const focusFirst = sandbox.spy(_ContextMenuItem.prototype, "focusFirst"); + wrapper + .find(ContextMenuButton) + .setState({ showContextMenu: true, contextMenuKeyboard: true }); + assert.calledOnce(focusFirst); + }); +}); + +describe("", () => { + function mountWithProps(props) { + const store = createStore(combineReducers(reducers), INITIAL_STATE); + return mount( + + + + ); + } + + it("should render all the options provided", () => { + const options = [ + { label: "item1" }, + { type: "separator" }, + { label: "item2" }, + ]; + const wrapper = shallow( + + ); + assert.lengthOf(wrapper.find(".context-menu-list").children(), 3); + }); + it("should not add a link for a separator", () => { + const options = [{ label: "item1" }, { type: "separator" }]; + const wrapper = shallow( + + ); + assert.lengthOf(wrapper.find(".separator"), 1); + }); + it("should add a link for all types that are not separators", () => { + const options = [{ label: "item1" }, { type: "separator" }]; + const wrapper = shallow( + + ); + assert.lengthOf(wrapper.find(ContextMenuItem), 1); + }); + it("should not add an icon to any items", () => { + const props = Object.assign({}, DEFAULT_PROPS, { + options: [{ label: "item1", icon: "icon1" }, { type: "separator" }], + }); + const wrapper = mountWithProps(props); + assert.lengthOf(wrapper.find(".icon-icon1"), 0); + }); + it("should be tabbable", () => { + const props = { + options: [{ label: "item1", icon: "icon1" }, { type: "separator" }], + }; + const wrapper = mountWithProps(props); + assert.equal( + wrapper.find(".context-menu-item").props().role, + "presentation" + ); + }); + it("should call onUpdate with false when an option is clicked", () => { + const onUpdate = sinon.spy(); + const onClick = sinon.spy(); + const props = Object.assign({}, DEFAULT_PROPS, { + onUpdate, + options: [{ label: "item1", onClick }], + }); + const wrapper = mountWithProps(props); + wrapper.find(".context-menu-item button").simulate("click"); + assert.calledOnce(onUpdate); + assert.calledOnce(onClick); + }); + it("should not have disabled className by default", () => { + const props = Object.assign({}, DEFAULT_PROPS, { + options: [{ label: "item1", icon: "icon1" }, { type: "separator" }], + }); + const wrapper = mountWithProps(props); + assert.lengthOf(wrapper.find(".context-menu-item a.disabled"), 0); + }); + it("should add disabled className to any disabled options", () => { + const options = [ + { label: "item1", icon: "icon1", disabled: true }, + { type: "separator" }, + ]; + const props = Object.assign({}, DEFAULT_PROPS, { options }); + const wrapper = mountWithProps(props); + assert.lengthOf(wrapper.find(".context-menu-item button.disabled"), 1); + }); + it("should have the context-menu-item class", () => { + const options = [{ label: "item1", icon: "icon1" }]; + const props = Object.assign({}, DEFAULT_PROPS, { options }); + const wrapper = mountWithProps(props); + assert.lengthOf(wrapper.find(".context-menu-item"), 1); + }); + it("should call onClick when onKeyDown is called with Enter", () => { + const onClick = sinon.spy(); + const props = Object.assign({}, DEFAULT_PROPS, { + options: [{ label: "item1", onClick }], + }); + const wrapper = mountWithProps(props); + wrapper + .find(".context-menu-item button") + .simulate("keydown", { key: "Enter" }); + assert.calledOnce(onClick); + }); + it("should call focusSibling when onKeyDown is called with ArrowUp", () => { + const props = Object.assign({}, DEFAULT_PROPS, { + options: [{ label: "item1" }], + }); + const wrapper = mountWithProps(props); + const focusSibling = sinon.stub( + wrapper.find(_ContextMenuItem).instance(), + "focusSibling" + ); + wrapper + .find(".context-menu-item button") + .simulate("keydown", { key: "ArrowUp" }); + assert.calledOnce(focusSibling); + }); + it("should call focusSibling when onKeyDown is called with ArrowDown", () => { + const props = Object.assign({}, DEFAULT_PROPS, { + options: [{ label: "item1" }], + }); + const wrapper = mountWithProps(props); + const focusSibling = sinon.stub( + wrapper.find(_ContextMenuItem).instance(), + "focusSibling" + ); + wrapper + .find(".context-menu-item button") + .simulate("keydown", { key: "ArrowDown" }); + assert.calledOnce(focusSibling); + }); +}); -- cgit v1.2.3