From 55fd4a8c8b5db5d006ca105ad8e9bd3cfed314fe Mon Sep 17 00:00:00 2001 From: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> Date: Fri, 27 Oct 2023 13:40:22 -0400 Subject: [PATCH] chore(Chip): updated unit tests (#9572) * chore(Chip): updated unit tests * Added integration test files * Updated tests per Austin feedback * Tested props get passed to Tooltip * Replaced haveBeenCalledTimes with haveBeenCalled --- .../react-core/src/components/Chip/Chip.tsx | 3 +- .../components/Chip/__tests__/Chip.test.tsx | 281 ++++++++++++++++-- .../__snapshots__/Chip.test.tsx.snap | 218 +------------- .../cypress/integration/chip.spec.ts | 10 + .../demo-app-ts/src/Demos.ts | 5 + .../components/demos/ChipDemo/ChipDemo.tsx | 12 + .../demo-app-ts/src/components/demos/index.ts | 1 + 7 files changed, 288 insertions(+), 242 deletions(-) create mode 100644 packages/react-integration/cypress/integration/chip.spec.ts create mode 100644 packages/react-integration/demo-app-ts/src/components/demos/ChipDemo/ChipDemo.tsx 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 +jest.mock('../../Tooltip', () => ({ + Tooltip: ({ content, position }) => ( +
+

{`content: ${content}`}

+

{`position: ${position}`}

+
+ ) +})); + +['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 + + ); + + // Only a non-overflow chip will have exactly the class "pf-v5-c-chip", we test for + // additional classes on overflow chips elsewhere in the suite + expect(screen.getByTestId('container')).toHaveClass(styles.chip, { exact: !isOverflowChip }); + }); + + test(`Renders with class ${styles.chipContent} around the ${chipType} content`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container').firstChild).toHaveClass(styles.chipContent, { exact: true }); + }); + + test(`Renders ${chipType} children with class ${styles.chipText}`, () => { + render(Chip text); + + expect(screen.getByText('Chip text')).toHaveClass(styles.chipText, { exact: true }); }); - test('closable', () => { - const { asFragment } = render( - - Chip + test(`Renders with custom class on the ${chipType} container element`, () => { + render( + + Chip text ); - expect(asFragment()).toMatchSnapshot(); + + expect(screen.getByTestId('container')).toHaveClass('custom-class'); }); - test('closable with tooltip', () => { - const { asFragment } = render( - - 1234567890123456789 + 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(`Renders with div container on ${chipType} by default`, () => { + render( + + Chip text + + ); + + 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.getByRole('listitem')).toBeVisible(); }); - 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')).toHaveAccessibleName('close Chip text'); +}); + +test(`Renders aria-labelledby on action close button with custom id passed`, () => { + render(Chip text); + + expect(screen.getByRole('button')).toHaveAccessibleName('close Chip text'); +}); + +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(`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(`Does not call onClick when close button action is not clicked for default chip`, async () => { + const user = userEvent.setup(); + const onClickMock = jest.fn(); + + render( + <> + Chip text + + + ); + + await user.click(screen.getByRole('button', { name: 'Test clicker' })); + + expect(onClickMock).not.toHaveBeenCalled(); +}); + +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(`Does not call onClick when chip is not clicked for overflow chip`, async () => { + const user = userEvent.setup(); + const onClickMock = jest.fn(); + + render( + <> + + Chip text + + + + ); + + await user.click(screen.getByRole('button', { name: 'Test clicker' })); + + expect(onClickMock).not.toHaveBeenCalled(); +}); + +test('Passes position to Tooltip', () => { + Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { configurable: true, value: 500 }); + render(Test chip text); + + expect(screen.getByText('position: bottom')).toBeVisible(); + Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { configurable: true, value: 0 }); +}); + +test('Passes content to Tooltip', () => { + Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { configurable: true, value: 500 }); + render(Test chip text); + + expect(screen.getByText(`content: Test chip text`)).toBeVisible(); + Object.defineProperty(HTMLElement.prototype, 'scrollWidth', { configurable: true, value: 0 }); +}); + +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..2216d2e45cc 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,22 @@ // 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 - - - -