From ad7ec9d9a7e754259aac8316651a3e6060a12455 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 6 Sep 2023 13:52:10 -0400 Subject: [PATCH 1/5] chore(Chip): updated unit tests --- .../react-core/src/components/Chip/Chip.tsx | 3 +- .../components/Chip/__tests__/Chip.test.tsx | 239 +++++++++++++++--- .../__snapshots__/Chip.test.tsx.snap | 215 +--------------- 3 files changed, 216 insertions(+), 241 deletions(-) diff --git a/packages/react-core/src/components/Chip/Chip.tsx b/packages/react-core/src/components/Chip/Chip.tsx index a05cfe85986..52c6c62d518 100644 --- a/packages/react-core/src/components/Chip/Chip.tsx +++ b/packages/react-core/src/components/Chip/Chip.tsx @@ -140,12 +140,13 @@ class Chip extends React.Component { tooltipPosition, component, ouiaId, + textMaxWidth, ...props } = this.props; const Component = component as any; return ( { - test('overflow', () => { - const { asFragment } = render( - - 4 more +['default chip', 'overflow chip'].forEach((chipType) => { + const isOverflowChip = chipType === 'overflow chip'; + + test(`Renders without children for ${chipType}`, () => { + render( +
+ +
+ ); + + expect(screen.getByTestId('container').firstChild).toBeVisible(); + }); + + test(`Renders with class ${styles.chip} on the ${chipType} container element`, () => { + render( + + Chip text + + ); + + expect(screen.getByTestId('container')).toHaveClass(styles.chip); + }); + + test(`Renders with class ${styles.chipContent} around the ${chipType} content`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container').firstChild).toHaveClass(styles.chipContent); + }); + + test(`Renders ${chipType} children with class ${styles.chipText}`, () => { + render(Chip text); + + expect(screen.getByText('Chip text')).toHaveClass(styles.chipText); + }); + + test(`Renders with custom class on the ${chipType} container element`, () => { + render( + + Chip text + + ); + + expect(screen.getByTestId('container')).toHaveClass('custom-class'); }); - test('closable', () => { - const { asFragment } = render( - - Chip + test(`Renders a badge when badge prop is passed to ${chipType}`, () => { + render( + Badge content}> + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByText('Badge content')).toBeVisible(); }); - test('closable with tooltip', () => { - const { asFragment } = render( - - 1234567890123456789 + test(`Renders with div container on ${chipType} by default`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container').tagName).toBe('DIV'); }); - test('readonly', () => { - const { asFragment } = render( - - 4 more + test(`Renders with custom container on ${chipType} when component prop is passed`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container').tagName).toBe('BUTTON'); }); - test('custom max-width text', () => { - const { asFragment } = render( - - 4 more + test(`Renders maxWidth css var in style attribute when textMaxWidth is passed for ${chipType}`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container')).toHaveAttribute('style', '--pf-v5-c-chip__text--MaxWidth: 10px;'); }); - test("with role='gridcell'", () => { - const { asFragment } = render( - - I'm a roled chip + test(`Spreads additional props to container for ${chipType}`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container')).toHaveAttribute('role', 'button'); }); }); + +test(`Renders id prop on ${styles.chipText} container for default chip`, () => { + render(Chip text); + + expect(screen.getByText('Chip text')).toHaveAttribute('id', 'custom-id'); +}); + +test(`Does not render id prop on ${styles.chipText} container for overflow chip`, () => { + render( + + Chip text + + ); + + expect(screen.getByText('Chip text')).not.toHaveAttribute('id'); +}); + +test(`Renders actions container with class ${styles.chipActions} when isReadOnly is false`, () => { + render(Chip text); + + expect(screen.getByRole('button').parentElement).toHaveClass(styles.chipActions); +}); + +test(`Renders aria-labelledby on action close button by default`, () => { + render(Chip text); + + expect(screen.getByRole('button')).toHaveAttribute( + 'aria-labelledby', + expect.stringMatching(/remove_pf-random-id-\d+ pf-random-id-\d+/) + ); +}); + +test(`Renders aria-labelledby on action close button with custom id passed`, () => { + render(Chip text); + + expect(screen.getByRole('button')).toHaveAttribute('aria-labelledby', 'remove_custom-id custom-id'); +}); + +test(`Renders concatenated aria-label on action close button by default`, () => { + render(Chip text); + + expect(screen.getByRole('button')).toHaveAccessibleName('close Chip text'); +}); + +test(`Renders custom aria-label on action close button when closeBtnAriaLabel is passed`, () => { + render(Chip text); + + expect(screen.getByRole('button')).toHaveAccessibleName('custom label Chip text'); +}); + +test(`Does not render close button action when isOverflowChip is true`, () => { + render(Chip text); + + // Because overflow chip renders as a button, we need to add the accessible name to the query + expect(screen.queryByRole('button', { name: 'close Chip text' })).not.toBeInTheDocument(); +}); + +test(`Does not render close button action when isReadOnly is true`, () => { + render(Chip text); + + expect(screen.queryByRole('button')).not.toBeInTheDocument(); +}); + +test(`Does not render with class ${styles.modifiers.overflow} when isOverflowChip is not passed`, () => { + render(Chip text); + + expect(screen.getByTestId('container')).not.toHaveClass(styles.modifiers.overflow); +}); + +test(`Renders with class ${styles.modifiers.overflow} when isOverflowChip is true`, () => { + render( + + Chip text + + ); + + expect(screen.getByTestId('container')).toHaveClass(styles.modifiers.overflow); +}); + +test(`Does not render with type attribute when isOverflowChip is true and component is not button`, () => { + render( + + Chip text + + ); + + expect(screen.getByTestId('container')).not.toHaveAttribute('type'); +}); + +test(`Renders with type attribute when isOverflowChip is true and component is button`, () => { + render( + + Chip text + + ); + + expect(screen.getByTestId('container')).toHaveAttribute('type', 'button'); +}); + +test(`Calls onClick when close button action is clicked for default chip`, async () => { + const user = userEvent.setup(); + const onClickMock = jest.fn(); + + render(Chip text); + + await user.click(screen.getByRole('button', { name: 'close Chip text' })); + + expect(onClickMock).toHaveBeenCalledTimes(1); +}); + +test(`Calls onClick when chip is clicked for overflow chip`, async () => { + const user = userEvent.setup(); + const onClickMock = jest.fn(); + + render( + + Chip text + + ); + + await user.click(screen.getByRole('button', { name: 'Chip text' })); + + expect(onClickMock).toHaveBeenCalledTimes(1); +}); + +test('Matches snapshot', () => { + const { asFragment } = render(Chip text); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap b/packages/react-core/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap index 00b63d8b8fd..638d7a0f662 100644 --- a/packages/react-core/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap +++ b/packages/react-core/src/components/Chip/__tests__/__snapshots__/Chip.test.tsx.snap @@ -1,22 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Chip closable 1`] = ` +exports[`Matches snapshot 1`] = `
- Chip + Chip text - - - -
-
-`; - -exports[`Chip closable with tooltip 1`] = ` - -
- - - 1234567890123456789 - - - - - -
-
-`; - -exports[`Chip custom max-width text 1`] = ` - -
- - - 4 more - - - - - -
-
-`; - -exports[`Chip overflow 1`] = ` - -
- - - 4 more - - -
-
-`; - -exports[`Chip readonly 1`] = ` - -
- - - 4 more - - -
-
-`; - -exports[`Chip with role='gridcell' 1`] = ` - -
- - - I'm a roled chip - - - -