From b30882bd2b4636a535e7f6c93e63ab1228bb6d84 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Wed, 25 Aug 2021 14:27:04 +0100 Subject: [PATCH] Sidemenu: Refactor `DropDownChild` (#38509) * DropDownChild: Refactor DropDownChild to be more component-like * Rewrite tests in RTL * Let's not do this just yet... --- .../sidemenu/DropDownChild.test.tsx | 65 +++++++++++-------- .../components/sidemenu/DropDownChild.tsx | 25 +++---- .../components/sidemenu/SideMenuDropDown.tsx | 14 ++-- .../__snapshots__/DropDownChild.test.tsx.snap | 22 ------- .../SideMenuDropDown.test.tsx.snap | 27 -------- 5 files changed, 62 insertions(+), 91 deletions(-) delete mode 100644 public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap diff --git a/public/app/core/components/sidemenu/DropDownChild.test.tsx b/public/app/core/components/sidemenu/DropDownChild.test.tsx index 6a15ca5b23f..ab8c0027a15 100644 --- a/public/app/core/components/sidemenu/DropDownChild.test.tsx +++ b/public/app/core/components/sidemenu/DropDownChild.test.tsx @@ -1,35 +1,48 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { render, screen } from '@testing-library/react'; +import { BrowserRouter } from 'react-router-dom'; import DropDownChild from './DropDownChild'; -const setup = (propOverrides?: object) => { - const props = Object.assign( - { - child: { - divider: true, - }, - }, - propOverrides - ); +describe('DropDownChild', () => { + const mockText = 'MyChildItem'; + const mockUrl = '/route'; + const mockIcon = 'home-alt'; - return shallow(); -}; - -describe('Render', () => { - it('should render component', () => { - const wrapper = setup(); - - expect(wrapper).toMatchSnapshot(); + it('displays the text', () => { + render(); + const text = screen.getByText(mockText); + expect(text).toBeInTheDocument(); }); - it('should render icon if exists', () => { - const wrapper = setup({ - child: { - divider: false, - icon: 'icon-test', - }, - }); + it('attaches the link to the text if provided', () => { + render( + + + + ); + const link = screen.getByRole('link', { name: mockText }); + expect(link).toBeInTheDocument(); + }); - expect(wrapper).toMatchSnapshot(); + it('displays an icon if a valid icon is provided', () => { + render(); + const icon = screen.getByTestId('dropdown-child-icon'); + expect(icon).toBeInTheDocument(); + }); + + it('displays a divider instead when isDivider is true', () => { + render(); + + // Check the divider is shown + const divider = screen.getByTestId('dropdown-child-divider'); + expect(divider).toBeInTheDocument(); + + // Check nothing else is rendered + const text = screen.queryByText(mockText); + const icon = screen.queryByTestId('dropdown-child-icon'); + const link = screen.queryByRole('link', { name: mockText }); + expect(text).not.toBeInTheDocument(); + expect(icon).not.toBeInTheDocument(); + expect(link).not.toBeInTheDocument(); }); }); diff --git a/public/app/core/components/sidemenu/DropDownChild.tsx b/public/app/core/components/sidemenu/DropDownChild.tsx index d6ddecddd66..4c6e2c59311 100644 --- a/public/app/core/components/sidemenu/DropDownChild.tsx +++ b/public/app/core/components/sidemenu/DropDownChild.tsx @@ -1,29 +1,30 @@ -import React, { FC } from 'react'; +import React from 'react'; import { css } from '@emotion/css'; -import { Icon, IconName, Link, useTheme } from '@grafana/ui'; +import { Icon, IconName, Link, useTheme2 } from '@grafana/ui'; export interface Props { - child: any; + isDivider?: boolean; + icon?: IconName; + text: string; + url?: string; } -const DropDownChild: FC = (props) => { - const { child } = props; - const listItemClassName = child.divider ? 'divider' : ''; - const theme = useTheme(); +const DropDownChild = ({ isDivider = false, icon, text, url }: Props) => { + const theme = useTheme2(); const iconClassName = css` - margin-right: ${theme.spacing.sm}; + margin-right: ${theme.spacing(1)}; `; const linkContent = ( <> - {child.icon && } - {child.text} + {icon && } + {text} ); - const anchor = child.url ? {linkContent} : {linkContent}; + const anchor = url ? {linkContent} : {linkContent}; - return
  • {anchor}
  • ; + return isDivider ?
  • :
  • {anchor}
  • ; }; export default DropDownChild; diff --git a/public/app/core/components/sidemenu/SideMenuDropDown.tsx b/public/app/core/components/sidemenu/SideMenuDropDown.tsx index 58cb902cd28..d0b4fd9fbc7 100644 --- a/public/app/core/components/sidemenu/SideMenuDropDown.tsx +++ b/public/app/core/components/sidemenu/SideMenuDropDown.tsx @@ -2,7 +2,7 @@ import React, { FC } from 'react'; import { filter } from 'lodash'; import DropDownChild from './DropDownChild'; import { NavModelItem } from '@grafana/data'; -import { Link } from '@grafana/ui'; +import { IconName, Link } from '@grafana/ui'; interface Props { link: NavModelItem; @@ -30,9 +30,15 @@ const SideMenuDropDown: FC = (props) => { return (
    • {anchor}
    • - {childrenLinks.map((child, index) => { - return ; - })} + {childrenLinks.map((child, index) => ( + + ))}
    ); }; diff --git a/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap deleted file mode 100644 index 1c5cd7f16c4..00000000000 --- a/public/app/core/components/sidemenu/__snapshots__/DropDownChild.test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Render should render component 1`] = ` -
  • - -
  • -`; - -exports[`Render should render icon if exists 1`] = ` -
  • - - - -
  • -`; diff --git a/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap b/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap index d5f6440b899..250429f688d 100644 --- a/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap +++ b/public/app/core/components/sidemenu/__snapshots__/SideMenuDropDown.test.tsx.snap @@ -19,21 +19,9 @@ exports[`Render should not render hideFromMenu children 1`] = ` @@ -58,27 +46,12 @@ exports[`Render should render children 1`] = `