From a583f7e160caad67397b7401805ccbea2a0e4a7e Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Thu, 26 Aug 2021 14:08:27 +0100 Subject: [PATCH] Sidemenu: Refactor SideMenuDropDown (#38554) * SideMenuDropDown: Refactor to be more component-ey + rewrite tests in RTL * SideMenuDropDown: Rename childLinks -> items * Rename mockChildLinks -> mockItems as well --- .../sidemenu/SideMenuDropDown.test.tsx | 75 +++++++++--------- .../components/sidemenu/SideMenuDropDown.tsx | 47 ++++++----- .../components/sidemenu/TopSectionItem.tsx | 2 +- .../SideMenuDropDown.test.tsx.snap | 79 ------------------- 4 files changed, 61 insertions(+), 142 deletions(-) delete mode 100644 public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap diff --git a/public/app/core/components/sidemenu/SideMenuDropDown.test.tsx b/public/app/core/components/sidemenu/SideMenuDropDown.test.tsx index 3b8a2df2aec..f00cc4913f8 100644 --- a/public/app/core/components/sidemenu/SideMenuDropDown.test.tsx +++ b/public/app/core/components/sidemenu/SideMenuDropDown.test.tsx @@ -1,50 +1,51 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { BrowserRouter } from 'react-router-dom'; import SideMenuDropDown from './SideMenuDropDown'; -const setup = (propOverrides?: object) => { - const props = Object.assign( +describe('SideMenuDropDown', () => { + const mockHeaderText = 'MyHeaderText'; + const mockHeaderUrl = '/route'; + const mockOnHeaderClick = jest.fn(); + const mockItems = [ { - link: { - text: 'link', - }, + text: 'First link', }, - propOverrides - ); + { + text: 'Second link', + }, + ]; - return shallow(); -}; - -describe('Render', () => { - it('should render component', () => { - const wrapper = setup(); - - expect(wrapper).toMatchSnapshot(); + it('displays the header text', () => { + render(); + const text = screen.getByText(mockHeaderText); + expect(text).toBeInTheDocument(); }); - it('should render children', () => { - const wrapper = setup({ - link: { - text: 'link', - children: [{ id: 1 }, { id: 2 }, { id: 3 }], - }, - }); - - expect(wrapper).toMatchSnapshot(); + it('attaches the link to the header text if provided', () => { + render( + + + + ); + const link = screen.getByRole('link', { name: mockHeaderText }); + expect(link).toBeInTheDocument(); }); - it('should not render hideFromMenu children', () => { - const wrapper = setup({ - link: { - text: 'link', - children: [ - { id: 1, hideFromMenu: false }, - { id: 2, hideFromMenu: true }, - { id: 3, hideFromMenu: false }, - ], - }, - }); + it('calls the onHeaderClick function when the header is clicked', () => { + render(); + const text = screen.getByText(mockHeaderText); + expect(text).toBeInTheDocument(); + userEvent.click(text); + expect(mockOnHeaderClick).toHaveBeenCalled(); + }); - expect(wrapper).toMatchSnapshot(); + it('displays the items', () => { + render(); + mockItems.forEach(({ text }) => { + const childItem = screen.getByText(text); + expect(childItem).toBeInTheDocument(); + }); }); }); diff --git a/public/app/core/components/sidemenu/SideMenuDropDown.tsx b/public/app/core/components/sidemenu/SideMenuDropDown.tsx index d0b4fd9fbc7..3387f20ef43 100644 --- a/public/app/core/components/sidemenu/SideMenuDropDown.tsx +++ b/public/app/core/components/sidemenu/SideMenuDropDown.tsx @@ -1,44 +1,41 @@ -import React, { FC } from 'react'; -import { filter } from 'lodash'; +import React from 'react'; import DropDownChild from './DropDownChild'; import { NavModelItem } from '@grafana/data'; import { IconName, Link } from '@grafana/ui'; interface Props { - link: NavModelItem; + items?: NavModelItem[]; + headerText: string; + headerUrl?: string; onHeaderClick?: () => void; } -const SideMenuDropDown: FC = (props) => { - const { link, onHeaderClick } = props; - let childrenLinks: NavModelItem[] = []; - if (link.children) { - childrenLinks = filter(link.children, (item) => !item.hideFromMenu); - } - - const linkContent = {link.text}; - const anchor = link.url ? ( - - {linkContent} +const SideMenuDropDown = ({ items = [], headerText, headerUrl, onHeaderClick }: Props) => { + const headerContent = {headerText}; + const header = headerUrl ? ( + + {headerContent} ) : ( - {linkContent} + {headerContent} ); return (
    -
  • {anchor}
  • - {childrenLinks.map((child, index) => ( - - ))} +
  • {header}
  • + {items + .filter((item) => !item.hideFromMenu) + .map((child, index) => ( + + ))}
); }; diff --git a/public/app/core/components/sidemenu/TopSectionItem.tsx b/public/app/core/components/sidemenu/TopSectionItem.tsx index ef05287d8c6..19c8f63715d 100644 --- a/public/app/core/components/sidemenu/TopSectionItem.tsx +++ b/public/app/core/components/sidemenu/TopSectionItem.tsx @@ -43,7 +43,7 @@ const TopSectionItem: FC = ({ link, onClick }) => { return (
{anchor} - +
); }; diff --git a/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap deleted file mode 100644 index 250429f688d..00000000000 --- a/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap +++ /dev/null @@ -1,79 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Render should not render hideFromMenu children 1`] = ` - -`; - -exports[`Render should render children 1`] = ` - -`; - -exports[`Render should render component 1`] = ` - -`;