Skip to content

Commit

Permalink
Merge pull request #1775 from qdraw/feature/202410_code_smell_17
Browse files Browse the repository at this point in the history
mkdir move to separate component
  • Loading branch information
qdraw authored Oct 17, 2024
2 parents a9df46a + 37fc710 commit 93b49a4
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { fireEvent, render, screen } from "@testing-library/react";
import React from "react";
import { IArchiveProps } from "../../../interfaces/IArchiveProps";
import * as ModalArchiveRename from "../../organisms/modal-archive-rename/modal-archive-rename";
import { MenuOptionArchiveRename } from "./menu-option-archive-rename";

describe("MenuOptionArchiveRename", () => {
const mockDispatch = jest.fn();
const mockState = { fileIndexItem: {} } as unknown as IArchiveProps;
let modalSpy = jest.spyOn(ModalArchiveRename, "default");

function mockModalHandleExit() {
modalSpy.mockReset();
modalSpy = jest.spyOn(ModalArchiveRename, "default").mockImplementation((props) => {
props.handleExit();
return <h1 data-test="modal-archive-mkdir">test</h1>;
});
}

function mockModal() {
modalSpy.mockReset();
modalSpy = jest.spyOn(ModalArchiveRename, "default").mockImplementation(() => {
return <h1 data-test="modal-archive-rename">test</h1>;
});
}

const renderComponent = (readOnly = false) => {
return render(
<MenuOptionArchiveRename readOnly={readOnly} state={mockState} dispatch={mockDispatch} />
);
};

it("should not show the modal initially", () => {
mockModal();
const component = renderComponent();
expect(screen.queryByTestId("modal-archive-rename")).not.toBeTruthy();
expect(modalSpy).toHaveBeenCalledTimes(0);
component.unmount();
});

it("should open the modal when the button is clicked", () => {
mockModal();
const component = renderComponent();

fireEvent.click(screen.getByTestId("rename"));
expect(modalSpy).toHaveBeenCalledTimes(1);

expect(screen.getByTestId("modal-archive-rename")).toBeTruthy();
component.unmount();
});

it("should close the modal when the handleExit function is called", () => {
const stateSpy = jest.spyOn(React, "useState").mockReturnValueOnce([true, jest.fn()]);
mockModalHandleExit();

const component = renderComponent();
fireEvent.click(screen.getByTestId("rename"));
expect(screen.getByTestId("rename")).toBeTruthy();

expect(stateSpy).toHaveBeenCalledTimes(1);
expect(stateSpy).toHaveBeenCalledWith(false);
component.unmount();
});

it("should not open the modal if readOnly is true", () => {
mockModal();

const component = renderComponent(true);
fireEvent.click(screen.getByTestId("rename"));
expect(screen.queryByTestId("modal-archive-rename")).not.toBeTruthy();
component.unmount();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useState } from "react";
import { ArchiveAction } from "../../../contexts/archive-context";
import { IArchiveProps } from "../../../interfaces/IArchiveProps";
import localization from "../../../localization/localization.json";
import MenuOptionModal from "../../atoms/menu-option-modal/menu-option-modal";
import ModalArchiveRename from "../../organisms/modal-archive-rename/modal-archive-rename";

interface IMenuOptionArchiveRenameProps {
readOnly: boolean;
state: IArchiveProps;
dispatch: React.Dispatch<ArchiveAction>;
}

export const MenuOptionArchiveRename: React.FunctionComponent<IMenuOptionArchiveRenameProps> = ({
readOnly,
state,
dispatch
}) => {
const [isModalRenameFolder, setIsModalRenameFolder] = useState(false);

return (
<>
{isModalRenameFolder && !readOnly && state.subPath !== "/" ? (
<ModalArchiveRename
subPath={state.subPath}
dispatch={dispatch}
handleExit={() => {
setIsModalRenameFolder(!isModalRenameFolder);
}}
isOpen={isModalRenameFolder}
/>
) : null}

<MenuOptionModal
isReadOnly={readOnly || state.subPath === "/"}
isSet={isModalRenameFolder}
set={() => setIsModalRenameFolder(!isModalRenameFolder)}
localization={localization.MessageRenameDir}
testName="rename"
/>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { fireEvent, render, screen } from "@testing-library/react";
import React from "react";
import { IArchiveProps } from "../../../interfaces/IArchiveProps";
import * as ModalArchiveMkdir from "../../organisms/modal-archive-mkdir/modal-archive-mkdir";
import { MenuOptionMkdir } from "./menu-option-mkdir";

describe("MenuOptionMkdir", () => {
const mockDispatch = jest.fn();
const mockState = { fileIndexItem: {} } as unknown as IArchiveProps;
let modalSpy = jest.spyOn(ModalArchiveMkdir, "default");

function mockModalHandleExit() {
modalSpy.mockReset();
modalSpy = jest.spyOn(ModalArchiveMkdir, "default").mockImplementation((props) => {
props.handleExit();
return <h1 data-test="modal-archive-mkdir">test</h1>;
});
}

function mockModal() {
modalSpy.mockReset();
modalSpy = jest.spyOn(ModalArchiveMkdir, "default").mockImplementation(() => {
return <h1 data-test="modal-archive-mkdir">test</h1>;
});
}

const renderComponent = (readOnly = false) => {
return render(
<MenuOptionMkdir readOnly={readOnly} state={mockState} dispatch={mockDispatch} />
);
};

it("should not show the modal initially", () => {
mockModal();
const component = renderComponent();
expect(screen.queryByTestId("modal-archive-mkdir")).not.toBeTruthy();
expect(modalSpy).toHaveBeenCalledTimes(0);
component.unmount();
});

it("should open the modal when the button is clicked", () => {
mockModal();
const component = renderComponent();
fireEvent.click(screen.getByTestId("mkdir"));
expect(modalSpy).toHaveBeenCalledTimes(1);

expect(screen.getByTestId("modal-archive-mkdir")).toBeTruthy();
component.unmount();
});

it("should close the modal when the handleExit function is called", () => {
const stateSpy = jest.spyOn(React, "useState").mockReturnValueOnce([true, jest.fn()]);
mockModalHandleExit();

const component = renderComponent();
fireEvent.click(screen.getByTestId("mkdir"));
expect(screen.getByTestId("mkdir")).toBeTruthy();

// Simulate closing the modal
fireEvent.click(screen.getByTestId("mkdir"));

expect(stateSpy).toHaveBeenCalledTimes(1);
expect(stateSpy).toHaveBeenCalledWith(false);
component.unmount();
});

it("should not open the modal if readOnly is true", () => {
mockModal();

const component = renderComponent(true);
fireEvent.click(screen.getByTestId("mkdir"));
expect(screen.queryByTestId("modal-archive-mkdir")).not.toBeTruthy();
component.unmount();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useState } from "react";
import { ArchiveAction } from "../../../contexts/archive-context";
import { IArchiveProps } from "../../../interfaces/IArchiveProps";
import localization from "../../../localization/localization.json";
import MenuOptionModal from "../../atoms/menu-option-modal/menu-option-modal";
import ModalArchiveMkdir from "../../organisms/modal-archive-mkdir/modal-archive-mkdir";

interface IMenuOptionMkdirProps {
readOnly: boolean;
state: IArchiveProps;
dispatch: React.Dispatch<ArchiveAction>;
}

export const MenuOptionMkdir: React.FunctionComponent<IMenuOptionMkdirProps> = ({
readOnly,
state,
dispatch
}) => {
const [isModalMkdirOpen, setIsModalMkdirOpen] = useState(false);

return (
<>
{/* Modal new directory */}
{isModalMkdirOpen && !readOnly ? (
<ModalArchiveMkdir
state={state}
dispatch={dispatch}
handleExit={() => setIsModalMkdirOpen(!isModalMkdirOpen)}
isOpen={isModalMkdirOpen}
/>
) : null}

<MenuOptionModal
isReadOnly={readOnly}
isSet={isModalMkdirOpen}
set={() => setIsModalMkdirOpen(!isModalMkdirOpen)}
localization={localization.MessageMkdir}
testName="mkdir"
/>
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import HamburgerMenuToggle from "../../atoms/hamburger-menu-toggle/hamburger-men
import MenuOptionModal from "../../atoms/menu-option-modal/menu-option-modal";
import MoreMenu from "../../atoms/more-menu/more-menu";
import MenuSearchBar from "../../molecules/menu-inline-search/menu-inline-search";
import { MenuOptionArchiveRename } from "../../molecules/menu-option-archive-rename/menu-option-archive-rename.tsx";
import MenuOptionDesktopEditorOpenSelectionNoSelectWarning from "../../molecules/menu-option-desktop-editor-open-selection-no-select-warning/menu-option-desktop-editor-open-selection-no-select-warning";
import MenuOptionDesktopEditorOpenSelection from "../../molecules/menu-option-desktop-editor-open-selection/menu-option-desktop-editor-open-selection";
import { MenuOptionMkdir } from "../../molecules/menu-option-mkdir/menu-option-mkdir.tsx";
import MenuOptionMoveFolderToTrash from "../../molecules/menu-option-move-folder-to-trash/menu-option-move-folder-to-trash";
import MenuOptionMoveToTrash from "../../molecules/menu-option-move-to-trash/menu-option-move-to-trash";
import { MenuOptionSelectionAll } from "../../molecules/menu-option-selection-all/menu-option-selection-all";
import { MenuOptionSelectionUndo } from "../../molecules/menu-option-selection-undo/menu-option-selection-undo";
import { MenuSelectCount } from "../../molecules/menu-select-count/menu-select-count";
import { MenuSelectFurther } from "../../molecules/menu-select-further/menu-select-further";
import ModalDropAreaFilesAdded from "../../molecules/modal-drop-area-files-added/modal-drop-area-files-added";
import ModalArchiveMkdir from "../modal-archive-mkdir/modal-archive-mkdir";
import ModalArchiveRename from "../modal-archive-rename/modal-archive-rename";
import ModalArchiveSynchronizeManually from "../modal-archive-synchronize-manually/modal-archive-synchronize-manually";
import ModalDisplayOptions from "../modal-display-options/modal-display-options";
import ModalDownload from "../modal-download/modal-download";
import ModalPublishToggleWrapper from "../modal-publish/modal-publish-toggle-wrapper";
import NavContainer from "../nav-container/nav-container";
import { UploadMenuItem } from "./internal/upload-menu-item";
import { SelectMenuItem } from "./internal/select-menu-item.tsx";
import { UploadMenuItem } from "./internal/upload-menu-item";

interface IMenuArchiveProps {}

Expand All @@ -48,7 +48,7 @@ const MenuArchive: React.FunctionComponent<IMenuArchiveProps> = memo(() => {
const removeSidebarSelection = () =>
new Select(select, setSelect, state, history).removeSidebarSelection();

// Command + A for mac os || Ctrl + A for windows
// Command + A for macOS || Ctrl + A for windows
useHotKeys({ key: "a", ctrlKeyOrMetaKey: true }, allSelection, []);

/* only update when the state is changed */
Expand Down Expand Up @@ -80,8 +80,6 @@ const MenuArchive: React.FunctionComponent<IMenuArchiveProps> = memo(() => {

const [isDisplayOptionsOpen, setIsDisplayOptionsOpen] = React.useState(false);
const [isSynchronizeManuallyOpen, setIsSynchronizeManuallyOpen] = React.useState(false);
const [isModalMkdirOpen, setIsModalMkdirOpen] = React.useState(false);
const [isModalRenameFolder, setIsModalRenameFolder] = React.useState(false);
const [dropAreaUploadFilesList, setDropAreaUploadFilesList] =
React.useState(newIFileIndexItemArray());

Expand Down Expand Up @@ -117,27 +115,6 @@ const MenuArchive: React.FunctionComponent<IMenuArchiveProps> = memo(() => {
/>
) : null}

{/* Modal new directory */}
{isModalMkdirOpen && !readOnly ? (
<ModalArchiveMkdir
state={state}
dispatch={dispatch}
handleExit={() => setIsModalMkdirOpen(!isModalMkdirOpen)}
isOpen={isModalMkdirOpen}
/>
) : null}

{isModalRenameFolder && !readOnly && state.subPath !== "/" ? (
<ModalArchiveRename
subPath={state.subPath}
dispatch={dispatch}
handleExit={() => {
setIsModalRenameFolder(!isModalRenameFolder);
}}
isOpen={isModalRenameFolder}
/>
) : null}

{/* Upload drop Area */}
{dropAreaUploadFilesList.length !== 0 ? (
<ModalDropAreaFilesAdded
Expand Down Expand Up @@ -179,13 +156,7 @@ const MenuArchive: React.FunctionComponent<IMenuArchiveProps> = memo(() => {
{/* default more menu */}
{!select ? (
<MoreMenu setEnableMoreMenu={setEnableMoreMenu} enableMoreMenu={enableMoreMenu}>
<MenuOptionModal
isReadOnly={readOnly}
isSet={isModalMkdirOpen}
set={() => setIsModalMkdirOpen(!isModalMkdirOpen)}
localization={localization.MessageMkdir}
testName="mkdir"
/>
<MenuOptionMkdir dispatch={dispatch} readOnly={readOnly} state={state} />

<MenuOptionModal
isReadOnly={false}
Expand All @@ -211,13 +182,7 @@ const MenuArchive: React.FunctionComponent<IMenuArchiveProps> = memo(() => {
/>
) : null}

<MenuOptionModal
isReadOnly={readOnly || state.subPath === "/"}
isSet={isModalRenameFolder}
set={() => setIsModalRenameFolder(!isModalRenameFolder)}
localization={localization.MessageRenameDir}
testName="rename"
/>
<MenuOptionArchiveRename readOnly={readOnly} state={state} dispatch={dispatch} />

<MenuOptionMoveFolderToTrash
isReadOnly={readOnly || state.subPath === "/"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import Modal from "../../atoms/modal/modal";

interface IModalRenameFileProps {
isOpen: boolean;
handleExit: Function;
handleExit: () => void;
state: IArchiveProps;
dispatch: React.Dispatch<ArchiveAction>;
}
Expand Down

1 comment on commit 93b49a4

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.