/* Copyright 2024 New Vector Ltd. Copyright 2022 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ import React from "react"; import { render } from "@testing-library/react"; import ContextMenu, { ChevronFace } from "../../../../src/components/structures/ContextMenu"; import UIStore from "../../../../src/stores/UIStore"; import Modal from "../../../../src/Modal"; import BaseDialog from "../../../../src/components/views/dialogs/BaseDialog"; describe("", () => { // Hardcode window and menu dimensions const windowSize = 300; const menuSize = 200; jest.spyOn(UIStore, "instance", "get").mockImplementation( () => ({ windowWidth: windowSize, windowHeight: windowSize, }) as unknown as UIStore, ); window.Element.prototype.getBoundingClientRect = jest.fn().mockReturnValue({ width: menuSize, height: menuSize, }); const targetChevronOffset = 25; it("near top edge of window", () => { const targetY = -50; const onFinished = jest.fn(); render( , ); const chevron = document.querySelector(".mx_ContextualMenu_chevron_left")!; const bottomStyle = parseInt( document.querySelector(".mx_ContextualMenu_wrapper")!.style.getPropertyValue("bottom"), ); const actualY = windowSize - bottomStyle - menuSize; const actualChevronOffset = parseInt(chevron.style.getPropertyValue("top")); // stays within the window expect(actualY).toBeGreaterThanOrEqual(0); // positions the chevron correctly expect(actualChevronOffset).toEqual(targetChevronOffset + targetY - actualY); }); it("near right edge of window", () => { const targetX = windowSize - menuSize + 50; const onFinished = jest.fn(); render( , ); const chevron = document.querySelector(".mx_ContextualMenu_chevron_top")!; const actualX = parseInt( document.querySelector(".mx_ContextualMenu_wrapper")!.style.getPropertyValue("left"), ); const actualChevronOffset = parseInt(chevron.style.getPropertyValue("left")); // stays within the window expect(actualX + menuSize).toBeLessThanOrEqual(windowSize); // positions the chevron correctly expect(actualChevronOffset).toEqual(targetChevronOffset + targetX - actualX); }); it("near bottom edge of window", () => { const targetY = windowSize - menuSize + 50; const onFinished = jest.fn(); render( , ); const chevron = document.querySelector(".mx_ContextualMenu_chevron_right")!; const actualY = parseInt( document.querySelector(".mx_ContextualMenu_wrapper")!.style.getPropertyValue("top"), ); const actualChevronOffset = parseInt(chevron.style.getPropertyValue("top")); // stays within the window expect(actualY + menuSize).toBeLessThanOrEqual(windowSize); // positions the chevron correctly expect(actualChevronOffset).toEqual(targetChevronOffset + targetY - actualY); }); it("near left edge of window", () => { const targetX = -50; const onFinished = jest.fn(); render( , ); const chevron = document.querySelector(".mx_ContextualMenu_chevron_bottom")!; const rightStyle = parseInt( document.querySelector(".mx_ContextualMenu_wrapper")!.style.getPropertyValue("right"), ); const actualX = windowSize - rightStyle - menuSize; const actualChevronOffset = parseInt(chevron.style.getPropertyValue("left")); // stays within the window expect(actualX).toBeGreaterThanOrEqual(0); // positions the chevron correctly expect(actualChevronOffset).toEqual(targetChevronOffset + targetX - actualX); }); it("should automatically close when a modal is opened", () => { const targetX = -50; const onFinished = jest.fn(); render( , ); expect(onFinished).not.toHaveBeenCalled(); Modal.createDialog(BaseDialog); expect(onFinished).toHaveBeenCalled(); }); it("should not automatically close when a modal is opened under the existing one", () => { const targetX = -50; const onFinished = jest.fn(); Modal.createDialog(BaseDialog); render( , ); expect(onFinished).not.toHaveBeenCalled(); Modal.createDialog(BaseDialog, {}, "", false, true); expect(onFinished).not.toHaveBeenCalled(); Modal.appendDialog(BaseDialog); expect(onFinished).not.toHaveBeenCalled(); }); });