mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2026-01-07 03:26:00 +00:00
Added comprehensive unit test coverage for Container Copy jobs (#2275)
* copy job uts * unit test coverage * lint fix * normalize account dropdown id
This commit is contained in:
185
src/Explorer/ContainerCopy/CommandBar/CopyJobCommandBar.test.tsx
Normal file
185
src/Explorer/ContainerCopy/CommandBar/CopyJobCommandBar.test.tsx
Normal file
@@ -0,0 +1,185 @@
|
||||
import "@testing-library/jest-dom";
|
||||
import { render } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "../../Explorer";
|
||||
import * as CommandBarUtil from "../../Menus/CommandBar/CommandBarUtil";
|
||||
import CopyJobCommandBar from "./CopyJobCommandBar";
|
||||
import * as Utils from "./Utils";
|
||||
|
||||
jest.mock("../MonitorCopyJobs/MonitorCopyJobRefState");
|
||||
jest.mock("../../Menus/CommandBar/CommandBarUtil");
|
||||
jest.mock("./Utils");
|
||||
|
||||
describe("CopyJobCommandBar", () => {
|
||||
let mockExplorer: Explorer;
|
||||
let mockConvertButton: jest.MockedFunction<typeof CommandBarUtil.convertButton>;
|
||||
let mockGetCommandBarButtons: jest.MockedFunction<typeof Utils.getCommandBarButtons>;
|
||||
|
||||
beforeEach(() => {
|
||||
mockExplorer = {} as Explorer;
|
||||
|
||||
mockConvertButton = CommandBarUtil.convertButton as jest.MockedFunction<typeof CommandBarUtil.convertButton>;
|
||||
mockGetCommandBarButtons = Utils.getCommandBarButtons as jest.MockedFunction<typeof Utils.getCommandBarButtons>;
|
||||
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("should render without crashing", () => {
|
||||
mockGetCommandBarButtons.mockReturnValue([]);
|
||||
mockConvertButton.mockReturnValue([]);
|
||||
|
||||
const { container } = render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
expect(container.querySelector(".commandBarContainer")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should call getCommandBarButtons with explorer", () => {
|
||||
mockGetCommandBarButtons.mockReturnValue([]);
|
||||
mockConvertButton.mockReturnValue([]);
|
||||
|
||||
render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer);
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should call convertButton with command bar items and background color", () => {
|
||||
const mockCommandButtonProps: CommandButtonComponentProps[] = [
|
||||
{
|
||||
iconSrc: "icon.svg",
|
||||
iconAlt: "Test Icon",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Test Button",
|
||||
ariaLabel: "Test Button Aria Label",
|
||||
tooltipText: "Test Tooltip",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
mockGetCommandBarButtons.mockReturnValue(mockCommandButtonProps);
|
||||
mockConvertButton.mockReturnValue([]);
|
||||
|
||||
render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
|
||||
expect(mockConvertButton).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should render FluentCommandBar with correct aria label", () => {
|
||||
mockGetCommandBarButtons.mockReturnValue([]);
|
||||
mockConvertButton.mockReturnValue([]);
|
||||
|
||||
const { getByRole } = render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
|
||||
const commandBar = getByRole("menubar", { hidden: true });
|
||||
expect(commandBar).toHaveAttribute("aria-label", "Use left and right arrow keys to navigate between commands");
|
||||
});
|
||||
|
||||
it("should render FluentCommandBar with converted items", () => {
|
||||
const mockCommandButtonProps: CommandButtonComponentProps[] = [
|
||||
{
|
||||
iconSrc: "icon1.svg",
|
||||
iconAlt: "Test Icon 1",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Test Button 1",
|
||||
ariaLabel: "Test Button 1 Aria Label",
|
||||
tooltipText: "Test Tooltip 1",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: "icon2.svg",
|
||||
iconAlt: "Test Icon 2",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Test Button 2",
|
||||
ariaLabel: "Test Button 2 Aria Label",
|
||||
tooltipText: "Test Tooltip 2",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
const mockFluentItems = [
|
||||
{
|
||||
key: "button1",
|
||||
text: "Test Button 1",
|
||||
iconProps: { iconName: "Add" },
|
||||
},
|
||||
{
|
||||
key: "button2",
|
||||
text: "Test Button 2",
|
||||
iconProps: { iconName: "Feedback" },
|
||||
},
|
||||
];
|
||||
|
||||
mockGetCommandBarButtons.mockReturnValue(mockCommandButtonProps);
|
||||
mockConvertButton.mockReturnValue(mockFluentItems);
|
||||
|
||||
const { container } = render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
|
||||
expect(mockConvertButton).toHaveBeenCalledTimes(1);
|
||||
expect(container.querySelector(".commandBarContainer")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should handle multiple command bar buttons", () => {
|
||||
const mockCommandButtonProps: CommandButtonComponentProps[] = [
|
||||
{
|
||||
iconSrc: "create.svg",
|
||||
iconAlt: "Create",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Create Copy Job",
|
||||
ariaLabel: "Create Copy Job",
|
||||
tooltipText: "Create Copy Job",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: "refresh.svg",
|
||||
iconAlt: "Refresh",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Refresh",
|
||||
ariaLabel: "Refresh",
|
||||
tooltipText: "Refresh",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
{
|
||||
iconSrc: "feedback.svg",
|
||||
iconAlt: "Feedback",
|
||||
onCommandClick: jest.fn(),
|
||||
commandButtonLabel: "Feedback",
|
||||
ariaLabel: "Feedback",
|
||||
tooltipText: "Feedback",
|
||||
hasPopup: false,
|
||||
disabled: false,
|
||||
},
|
||||
];
|
||||
|
||||
mockGetCommandBarButtons.mockReturnValue(mockCommandButtonProps);
|
||||
mockConvertButton.mockReturnValue([
|
||||
{ key: "create", text: "Create Copy Job" },
|
||||
{ key: "refresh", text: "Refresh" },
|
||||
{ key: "feedback", text: "Feedback" },
|
||||
]);
|
||||
|
||||
render(<CopyJobCommandBar explorer={mockExplorer} />);
|
||||
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer);
|
||||
expect(mockConvertButton.mock.calls[0][0]).toEqual(mockCommandButtonProps);
|
||||
});
|
||||
|
||||
it("should re-render when explorer prop changes", () => {
|
||||
const mockExplorer1 = { id: "explorer1" } as unknown as Explorer;
|
||||
const mockExplorer2 = { id: "explorer2" } as unknown as Explorer;
|
||||
|
||||
mockGetCommandBarButtons.mockReturnValue([]);
|
||||
mockConvertButton.mockReturnValue([]);
|
||||
|
||||
const { rerender } = render(<CopyJobCommandBar explorer={mockExplorer1} />);
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer1);
|
||||
|
||||
rerender(<CopyJobCommandBar explorer={mockExplorer2} />);
|
||||
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledWith(mockExplorer2);
|
||||
expect(mockGetCommandBarButtons).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
@@ -28,4 +28,6 @@ const CopyJobCommandBar: React.FC<ContainerCopyProps> = ({ explorer }) => {
|
||||
);
|
||||
};
|
||||
|
||||
CopyJobCommandBar.displayName = "CopyJobCommandBar";
|
||||
|
||||
export default CopyJobCommandBar;
|
||||
|
||||
268
src/Explorer/ContainerCopy/CommandBar/Utils.test.ts
Normal file
268
src/Explorer/ContainerCopy/CommandBar/Utils.test.ts
Normal file
@@ -0,0 +1,268 @@
|
||||
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
|
||||
import Explorer from "../../Explorer";
|
||||
import * as Actions from "../Actions/CopyJobActions";
|
||||
import { MonitorCopyJobsRefState } from "../MonitorCopyJobs/MonitorCopyJobRefState";
|
||||
import { getCommandBarButtons } from "./Utils";
|
||||
|
||||
jest.mock("../../../ConfigContext", () => ({
|
||||
configContext: {
|
||||
platform: "Portal",
|
||||
},
|
||||
Platform: {
|
||||
Portal: "Portal",
|
||||
Emulator: "Emulator",
|
||||
Hosted: "Hosted",
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock("../Actions/CopyJobActions", () => ({
|
||||
openCreateCopyJobPanel: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock("../MonitorCopyJobs/MonitorCopyJobRefState", () => ({
|
||||
MonitorCopyJobsRefState: jest.fn(),
|
||||
}));
|
||||
|
||||
describe("CommandBar Utils", () => {
|
||||
let mockExplorer: Explorer;
|
||||
let mockOpenContainerCopyFeedbackBlade: jest.Mock;
|
||||
let mockRefreshJobList: jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
|
||||
mockOpenContainerCopyFeedbackBlade = jest.fn();
|
||||
mockRefreshJobList = jest.fn();
|
||||
|
||||
mockExplorer = {
|
||||
openContainerCopyFeedbackBlade: mockOpenContainerCopyFeedbackBlade,
|
||||
} as unknown as Explorer;
|
||||
|
||||
(MonitorCopyJobsRefState as unknown as jest.Mock).mockImplementation((selector) => {
|
||||
const state = {
|
||||
ref: {
|
||||
refreshJobList: mockRefreshJobList,
|
||||
},
|
||||
};
|
||||
return selector(state);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getCommandBarButtons", () => {
|
||||
it("should return an array of command button props", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
expect(buttons).toBeDefined();
|
||||
expect(Array.isArray(buttons)).toBe(true);
|
||||
expect(buttons.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it("should include create copy job button", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const createButton = buttons[0];
|
||||
|
||||
expect(createButton).toBeDefined();
|
||||
expect(createButton.commandButtonLabel).toBeUndefined();
|
||||
expect(createButton.ariaLabel).toBe("Create a new container copy job");
|
||||
expect(createButton.tooltipText).toBe("Create Copy Job");
|
||||
expect(createButton.hasPopup).toBe(false);
|
||||
expect(createButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it("should include refresh button", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const refreshButton = buttons[1];
|
||||
|
||||
expect(refreshButton).toBeDefined();
|
||||
expect(refreshButton.ariaLabel).toBe("Refresh copy jobs");
|
||||
expect(refreshButton.tooltipText).toBe("Refresh");
|
||||
expect(refreshButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it("should include feedback button when platform is Portal", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
expect(buttons.length).toBe(3);
|
||||
|
||||
const feedbackButton = buttons[2];
|
||||
expect(feedbackButton).toBeDefined();
|
||||
expect(feedbackButton.ariaLabel).toBe("Provide feedback on copy jobs");
|
||||
expect(feedbackButton.tooltipText).toBe("Feedback");
|
||||
expect(feedbackButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it("should not include feedback button when platform is not Portal", async () => {
|
||||
jest.resetModules();
|
||||
jest.doMock("../../../ConfigContext", () => ({
|
||||
configContext: {
|
||||
platform: "Emulator",
|
||||
},
|
||||
Platform: {
|
||||
Portal: "Portal",
|
||||
Emulator: "Emulator",
|
||||
Hosted: "Hosted",
|
||||
},
|
||||
}));
|
||||
|
||||
const { getCommandBarButtons: getCommandBarButtonsEmulator } = await import("./Utils");
|
||||
const buttons = getCommandBarButtonsEmulator(mockExplorer);
|
||||
|
||||
expect(buttons.length).toBe(2);
|
||||
});
|
||||
|
||||
it("should call openCreateCopyJobPanel when create button is clicked", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const createButton = buttons[0];
|
||||
|
||||
createButton.onCommandClick({} as React.SyntheticEvent);
|
||||
|
||||
expect(Actions.openCreateCopyJobPanel).toHaveBeenCalledWith(mockExplorer);
|
||||
expect(Actions.openCreateCopyJobPanel).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should call refreshJobList when refresh button is clicked", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const refreshButton = buttons[1];
|
||||
|
||||
refreshButton.onCommandClick({} as React.SyntheticEvent);
|
||||
|
||||
expect(mockRefreshJobList).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should call openContainerCopyFeedbackBlade when feedback button is clicked", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const feedbackButton = buttons[2];
|
||||
|
||||
feedbackButton.onCommandClick({} as React.SyntheticEvent);
|
||||
|
||||
expect(mockOpenContainerCopyFeedbackBlade).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should return buttons with correct icon sources", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
expect(buttons[0].iconSrc).toBeDefined();
|
||||
expect(buttons[0].iconAlt).toBe("Create Copy Job");
|
||||
|
||||
expect(buttons[1].iconSrc).toBeDefined();
|
||||
expect(buttons[1].iconAlt).toBe("Refresh");
|
||||
|
||||
expect(buttons[2].iconSrc).toBeDefined();
|
||||
expect(buttons[2].iconAlt).toBe("Feedback");
|
||||
});
|
||||
|
||||
it("should handle null MonitorCopyJobsRefState ref gracefully", () => {
|
||||
(MonitorCopyJobsRefState as unknown as jest.Mock).mockImplementationOnce((selector) => {
|
||||
const state: { ref: null } = { ref: null };
|
||||
return selector(state);
|
||||
});
|
||||
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
const refreshButton = buttons[1];
|
||||
|
||||
expect(() => refreshButton.onCommandClick({} as React.SyntheticEvent)).not.toThrow();
|
||||
});
|
||||
|
||||
it("should set hasPopup to false for all buttons", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.hasPopup).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("should set commandButtonLabel to undefined for all buttons", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.commandButtonLabel).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("should respect disabled state when provided", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.disabled).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("should return CommandButtonComponentProps with all required properties", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button: CommandButtonComponentProps) => {
|
||||
expect(button).toHaveProperty("iconSrc");
|
||||
expect(button).toHaveProperty("iconAlt");
|
||||
expect(button).toHaveProperty("onCommandClick");
|
||||
expect(button).toHaveProperty("commandButtonLabel");
|
||||
expect(button).toHaveProperty("ariaLabel");
|
||||
expect(button).toHaveProperty("tooltipText");
|
||||
expect(button).toHaveProperty("hasPopup");
|
||||
expect(button).toHaveProperty("disabled");
|
||||
});
|
||||
});
|
||||
|
||||
it("should maintain button order: create, refresh, feedback", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
expect(buttons[0].tooltipText).toBe("Create Copy Job");
|
||||
expect(buttons[1].tooltipText).toBe("Refresh");
|
||||
expect(buttons[2].tooltipText).toBe("Feedback");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Button click handlers", () => {
|
||||
it("should execute click handlers without errors", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(() => button.onCommandClick({} as React.SyntheticEvent)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
it("should call correct action for each button", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons[0].onCommandClick({} as React.SyntheticEvent);
|
||||
expect(Actions.openCreateCopyJobPanel).toHaveBeenCalledWith(mockExplorer);
|
||||
|
||||
buttons[1].onCommandClick({} as React.SyntheticEvent);
|
||||
expect(mockRefreshJobList).toHaveBeenCalled();
|
||||
|
||||
buttons[2].onCommandClick({} as React.SyntheticEvent);
|
||||
expect(mockOpenContainerCopyFeedbackBlade).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Accessibility", () => {
|
||||
it("should have aria labels for all buttons", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.ariaLabel).toBeDefined();
|
||||
expect(typeof button.ariaLabel).toBe("string");
|
||||
expect(button.ariaLabel.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("should have tooltip text for all buttons", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.tooltipText).toBeDefined();
|
||||
expect(typeof button.tooltipText).toBe("string");
|
||||
expect(button.tooltipText.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it("should have icon alt text for all buttons", () => {
|
||||
const buttons = getCommandBarButtons(mockExplorer);
|
||||
|
||||
buttons.forEach((button) => {
|
||||
expect(button.iconAlt).toBeDefined();
|
||||
expect(typeof button.iconAlt).toBe("string");
|
||||
expect(button.iconAlt.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -17,7 +17,7 @@ function getCopyJobBtns(explorer: Explorer): CopyJobCommandBarBtnType[] {
|
||||
iconSrc: AddIcon,
|
||||
label: ContainerCopyMessages.createCopyJobButtonLabel,
|
||||
ariaLabel: ContainerCopyMessages.createCopyJobButtonAriaLabel,
|
||||
onClick: Actions.openCreateCopyJobPanel.bind(null, explorer),
|
||||
onClick: () => Actions.openCreateCopyJobPanel(explorer),
|
||||
},
|
||||
{
|
||||
key: "refresh",
|
||||
|
||||
Reference in New Issue
Block a user