UNPKG

orcs-design-system

Version:
641 lines (633 loc) 21.1 kB
/* eslint-disable react/prop-types */ import React from "react"; import { render, screen } from "@testing-library/react"; import { BrowserRouter } from "react-router-dom"; import SideNavTeamsSection from "../sections/SideNavTeamsSection"; import SideNavPinnedSection from "../sections/SideNavPinnedSection"; import RenderCurrentViewSection from "../components/RenderCurrentViewSection"; import { SideNavStateProvider } from "../index"; // Mock the RenderCurrentViewSection component to avoid portal issues in tests import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; jest.mock("../components/RenderCurrentViewSection", () => { function MockRenderCurrentViewSection(_ref) { let { viewingState } = _ref; // Don't render anything if there's no valid viewing state or no name if (!viewingState || !viewingState.name) { return null; } return /*#__PURE__*/_jsxs("div", { "data-testid": "render-current-view-section", children: [/*#__PURE__*/_jsx("div", { "data-testid": "viewing-name", children: viewingState.name }), /*#__PURE__*/_jsx("div", { "data-testid": "viewing-team-link", children: viewingState.teamLink }), viewingState.avatar && viewingState.avatar !== "" && /*#__PURE__*/_jsx("div", { "data-testid": "viewing-avatar", children: viewingState.avatar }), viewingState.shape && viewingState.shape !== "" && /*#__PURE__*/_jsx("div", { "data-testid": "viewing-shape", children: viewingState.shape }), viewingState.subNav && viewingState.subNav.length > 0 && /*#__PURE__*/_jsx("div", { "data-testid": "viewing-subnav", children: viewingState.subNav.map((item, index) => /*#__PURE__*/_jsxs("div", { "data-testid": `subnav-item-${index}`, children: [item.name, ": ", item.link] }, index)) }), viewingState.badge && /*#__PURE__*/_jsx("div", { "data-testid": "viewing-badge", children: viewingState.badge })] }); } return MockRenderCurrentViewSection; }); // Mock components that might not be available in test environment jest.mock("../../Avatar", () => { function MockAvatar(_ref2) { let { image, customSize, shape } = _ref2; return /*#__PURE__*/_jsx("div", { "data-testid": "avatar", "data-image": image, "data-size": customSize, "data-shape": shape }); } return MockAvatar; }); jest.mock("../../Icon", () => { function MockIcon(_ref3) { let { icon, color, size } = _ref3; return /*#__PURE__*/_jsx("div", { "data-testid": "icon", "data-icon": icon.join(" "), "data-color": color, "data-size": size }); } return MockIcon; }); jest.mock("../../Button", () => { function MockButton(_ref4) { let { children, onClick, ...props } = _ref4; return /*#__PURE__*/_jsx("button", { "data-testid": "button", onClick: onClick, ...props, children: children }); } return MockButton; }); jest.mock("../../Popover", () => { function MockPopover(_ref5) { let { children, text, direction, width } = _ref5; return /*#__PURE__*/_jsx("div", { "data-testid": "popover", "data-text": text, "data-direction": direction, "data-width": width, children: children }); } return MockPopover; }); jest.mock("../../Divider", () => { function MockDivider(_ref6) { let { light, display } = _ref6; return /*#__PURE__*/_jsx("div", { "data-testid": "divider", "data-light": light, "data-display": JSON.stringify(display) }); } return MockDivider; }); jest.mock("../../Flex", () => { function MockFlex(_ref7) { let { children, flexDirection, gap, p, mt, ...props } = _ref7; return /*#__PURE__*/_jsx("div", { "data-testid": "flex", "data-direction": flexDirection, "data-gap": gap, "data-p": p, "data-mt": mt, ...props, children: children }); } return MockFlex; }); jest.mock("../../Typography", () => { function MockH5(_ref8) { let { children, fontWeight, ...props } = _ref8; return /*#__PURE__*/_jsx("h5", { "data-testid": "h5", "data-font-weight": fontWeight, ...props, children: children }); } function MockH6(_ref9) { let { children, sizing, color, ...props } = _ref9; return /*#__PURE__*/_jsx("h6", { "data-testid": "h6", "data-sizing": sizing, "data-color": color, ...props, children: children }); } return { H5: MockH5, H6: MockH6 }; }); const renderWithRouter = component => { return render(/*#__PURE__*/_jsx(BrowserRouter, { children: component })); }; describe("SideNavTeamsSection", () => { const mockTeams = [{ avatar: "team1.jpg", name: "Team Alpha", link: "/teams/alpha" }, { avatar: "team2.jpg", name: "Team Beta", link: "/teams/beta" }]; it("should render teams section when expanded", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: mockTeams, isExpanded: true })); expect(screen.getByText("Your Teams")).toBeInTheDocument(); expect(screen.getByText("Team Alpha")).toBeInTheDocument(); expect(screen.getByText("Team Beta")).toBeInTheDocument(); }); it("should not show title when collapsed", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: mockTeams, isExpanded: false })); expect(screen.queryByText("Your Teams")).not.toBeInTheDocument(); }); it("should render avatars for each team", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: mockTeams, isExpanded: true })); const avatars = screen.getAllByTestId("avatar"); expect(avatars).toHaveLength(2); expect(avatars[0]).toHaveAttribute("data-image", "team1.jpg"); expect(avatars[1]).toHaveAttribute("data-image", "team2.jpg"); }); // Prop validation tests it("should handle empty teams array", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: [], isExpanded: true })); expect(screen.getByText("Your Teams")).toBeInTheDocument(); // Should not crash with empty array }); it("should handle teams with missing optional props", () => { const teamsWithMissingProps = [{ name: "Team Alpha", link: "/teams/alpha" }, // missing avatar { avatar: "team2.jpg", name: "Team Beta", link: "/teams/beta" }]; renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: teamsWithMissingProps, isExpanded: true })); expect(screen.getByText("Your Teams")).toBeInTheDocument(); expect(screen.getByText("Team Alpha")).toBeInTheDocument(); expect(screen.getByText("Team Beta")).toBeInTheDocument(); }); it("should handle undefined isExpanded prop", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: mockTeams })); // When isExpanded is undefined, it defaults to false, so no text should be visible expect(screen.queryByText("Your Teams")).not.toBeInTheDocument(); expect(screen.queryByText("Team Alpha")).not.toBeInTheDocument(); // But avatars should still be rendered in popovers const avatars = screen.getAllByTestId("avatar"); expect(avatars).toHaveLength(2); }); it("should handle null teams prop", () => { // The component expects an array, so we need to provide a default or handle null expect(() => { renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: null, isExpanded: true })); }).toThrow(); }); it("should handle teams with invalid data", () => { const invalidTeams = [{ name: "Team Alpha", link: "/teams/alpha" }, { name: null, link: "/teams/beta" }, // invalid name { name: "Team Gamma" } // missing link ]; renderWithRouter(/*#__PURE__*/_jsx(SideNavTeamsSection, { teams: invalidTeams, isExpanded: true })); expect(screen.getByText("Your Teams")).toBeInTheDocument(); expect(screen.getByText("Team Alpha")).toBeInTheDocument(); // Should handle invalid data gracefully }); }); describe("SideNavPinnedSection", () => { const mockPinnedItems = [{ avatar: "user1.jpg", name: "John Doe", link: "/users/john", shape: "circle", onUnpin: jest.fn() }, { avatar: "user2.jpg", name: "Jane Smith", link: "/users/jane", shape: "square", onUnpin: jest.fn() }]; it("should render pinned section when expanded", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: mockPinnedItems, isExpanded: true })); expect(screen.getByText("Pinned")).toBeInTheDocument(); expect(screen.getByText("John Doe")).toBeInTheDocument(); expect(screen.getByText("Jane Smith")).toBeInTheDocument(); }); it("should not show title when collapsed", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: mockPinnedItems, isExpanded: false })); expect(screen.queryByText("Pinned")).not.toBeInTheDocument(); }); it("should render unpin buttons when expanded", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: mockPinnedItems, isExpanded: true })); const buttons = screen.getAllByTestId("button"); expect(buttons).toHaveLength(2); }); it("should render avatars with correct shapes", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: mockPinnedItems, isExpanded: true })); const avatars = screen.getAllByTestId("avatar"); expect(avatars[0]).toHaveAttribute("data-shape", "circle"); expect(avatars[1]).toHaveAttribute("data-shape", "square"); }); // Prop validation tests it("should handle empty items array", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: [], isExpanded: true })); expect(screen.getByText("Pinned")).toBeInTheDocument(); // Should not crash with empty array }); it("should handle items with missing optional props", () => { const itemsWithMissingProps = [{ name: "John Doe", link: "/users/john" }, // missing avatar, shape, onUnpin { avatar: "user2.jpg", name: "Jane Smith", link: "/users/jane", shape: "square" } // missing onUnpin ]; renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: itemsWithMissingProps, isExpanded: true })); expect(screen.getByText("Pinned")).toBeInTheDocument(); expect(screen.getByText("John Doe")).toBeInTheDocument(); expect(screen.getByText("Jane Smith")).toBeInTheDocument(); }); it("should handle undefined isExpanded prop", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: mockPinnedItems })); // When isExpanded is undefined, it defaults to false, so no text should be visible expect(screen.queryByText("Pinned")).not.toBeInTheDocument(); expect(screen.queryByText("John Doe")).not.toBeInTheDocument(); // But avatars should still be rendered in popovers const avatars = screen.getAllByTestId("avatar"); expect(avatars).toHaveLength(2); }); it("should handle null items prop", () => { // The component expects an array, so we need to provide a default or handle null expect(() => { renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: null, isExpanded: true })); }).toThrow(); }); it("should handle items with invalid data", () => { const invalidItems = [{ name: "John Doe", link: "/users/john" }, { name: null, link: "/users/jane" }, // invalid name { name: "Jane Smith" } // missing link ]; renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: invalidItems, isExpanded: true })); expect(screen.getByText("Pinned")).toBeInTheDocument(); expect(screen.getByText("John Doe")).toBeInTheDocument(); // Should handle invalid data gracefully }); it("should handle onUnpin callback", () => { const onUnpinMock = jest.fn(); const itemsWithCallback = [{ avatar: "user1.jpg", name: "John Doe", link: "/users/john", shape: "circle", onUnpin: onUnpinMock }]; renderWithRouter(/*#__PURE__*/_jsx(SideNavPinnedSection, { items: itemsWithCallback, isExpanded: true })); const buttons = screen.getAllByTestId("button"); expect(buttons).toHaveLength(1); // Test that the button exists and can be clicked expect(buttons[0]).toBeInTheDocument(); }); }); describe("RenderCurrentViewSection", () => { const mockViewingState = { name: "Test Team", teamLink: "/teams/test", avatar: "/avatars/test.jpg", shape: "square" }; it("should render current view section with basic data", () => { renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: mockViewingState }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-name")).toHaveTextContent("Test Team"); expect(screen.getByTestId("viewing-team-link")).toHaveTextContent("/teams/test"); expect(screen.getByTestId("viewing-avatar")).toHaveTextContent("/avatars/test.jpg"); expect(screen.getByTestId("viewing-shape")).toHaveTextContent("square"); }); it("should render current view section with subNav", () => { const viewingStateWithSubNav = { ...mockViewingState, subNav: [{ name: "Overview", link: "/teams/test/overview" }, { name: "Members", link: "/teams/test/members" }] }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithSubNav }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-subnav")).toBeInTheDocument(); expect(screen.getByTestId("subnav-item-0")).toHaveTextContent("Overview: /teams/test/overview"); expect(screen.getByTestId("subnav-item-1")).toHaveTextContent("Members: /teams/test/members"); }); it("should render current view section with badge", () => { const viewingStateWithBadge = { ...mockViewingState, badge: /*#__PURE__*/_jsx("div", { "data-testid": "badge", children: "Badge" }) }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithBadge }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-badge")).toBeInTheDocument(); }); it("should handle viewing state without avatar", () => { const viewingStateWithoutAvatar = { name: "Team No Avatar", teamLink: "/teams/no-avatar" }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithoutAvatar }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-name")).toHaveTextContent("Team No Avatar"); expect(screen.getByTestId("viewing-team-link")).toHaveTextContent("/teams/no-avatar"); expect(screen.queryByTestId("viewing-avatar")).not.toBeInTheDocument(); expect(screen.queryByTestId("viewing-shape")).not.toBeInTheDocument(); }); it("should not render when viewing state is null or undefined", () => { const { container } = renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: null }) })); expect(container.firstChild).toBeNull(); }); it("should not render when viewing state has no name", () => { const viewingStateWithoutName = { teamLink: "/teams/test", avatar: "/avatars/test.jpg" }; const { container } = renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithoutName }) })); expect(container.firstChild).toBeNull(); }); // Prop validation tests it("should handle viewing state with missing optional props", () => { const viewingStateWithMissingProps = { name: "Test Team", teamLink: "/teams/test" // missing avatar, shape, badge, subNav }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithMissingProps }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-name")).toHaveTextContent("Test Team"); expect(screen.getByTestId("viewing-team-link")).toHaveTextContent("/teams/test"); expect(screen.queryByTestId("viewing-avatar")).not.toBeInTheDocument(); expect(screen.queryByTestId("viewing-shape")).not.toBeInTheDocument(); expect(screen.queryByTestId("viewing-badge")).not.toBeInTheDocument(); expect(screen.queryByTestId("viewing-subnav")).not.toBeInTheDocument(); }); it("should handle viewing state with invalid subNav data", () => { const viewingStateWithInvalidSubNav = { ...mockViewingState, subNav: [{ name: "Overview", link: "/teams/test/overview" }, { name: null, link: "/teams/test/members" }, // invalid name { name: "Settings" } // missing link ] }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithInvalidSubNav }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-subnav")).toBeInTheDocument(); expect(screen.getByTestId("subnav-item-0")).toHaveTextContent("Overview: /teams/test/overview"); // Should handle invalid subNav data gracefully }); it("should handle viewing state with empty subNav array", () => { const viewingStateWithEmptySubNav = { ...mockViewingState, subNav: [] }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithEmptySubNav }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.queryByTestId("viewing-subnav")).not.toBeInTheDocument(); }); it("should handle viewing state with null subNav", () => { const viewingStateWithNullSubNav = { ...mockViewingState, subNav: null }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithNullSubNav }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.queryByTestId("viewing-subnav")).not.toBeInTheDocument(); }); it("should handle viewing state with undefined badge", () => { const viewingStateWithUndefinedBadge = { ...mockViewingState, badge: undefined }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithUndefinedBadge }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.queryByTestId("viewing-badge")).not.toBeInTheDocument(); }); it("should handle viewing state with empty string values", () => { const viewingStateWithEmptyStrings = { name: "Test Team", teamLink: "/teams/test", avatar: "", shape: "" }; renderWithRouter(/*#__PURE__*/_jsx(SideNavStateProvider, { children: /*#__PURE__*/_jsx(RenderCurrentViewSection, { viewingState: viewingStateWithEmptyStrings }) })); expect(screen.getByTestId("render-current-view-section")).toBeInTheDocument(); expect(screen.getByTestId("viewing-name")).toHaveTextContent("Test Team"); expect(screen.getByTestId("viewing-team-link")).toHaveTextContent("/teams/test"); // Empty strings should not render the elements expect(screen.queryByTestId("viewing-avatar")).not.toBeInTheDocument(); expect(screen.queryByTestId("viewing-shape")).not.toBeInTheDocument(); }); });