From c60ec2e00383bc6c25dc15b4f7c14acbe2bdae77 Mon Sep 17 00:00:00 2001 From: Rebecca Alpert Date: Fri, 20 Dec 2024 10:37:00 -0500 Subject: [PATCH] Add more tests --- src/app/FlyoutError/FlyoutError.test.tsx | 24 +++++++ src/app/FlyoutFooter/FlyoutFooter.test.tsx | 33 +++++++++ .../FlyoutForm/ExpandingTextInputs.test.tsx | 71 +++++++++++++++++++ src/app/FlyoutForm/ExpandingTextInputs.tsx | 6 +- src/app/FlyoutForm/FlyoutForm.tsx | 2 +- src/app/FlyoutHeader.tsx/FlyoutHeader.tsx | 16 ----- src/app/FlyoutHeader/FlyoutHeader.test.tsx | 16 +++++ src/app/FlyoutHeader/FlyoutHeader.tsx | 4 +- src/app/FlyoutList/FlyoutList.tsx | 2 +- src/app/FlyoutLoading/FlyoutLoading.test.tsx | 11 +++ .../FlyoutStartScreen.test.tsx | 33 +++++++++ .../FlyoutStartScreen/FlyoutStartScreen.tsx | 2 +- 12 files changed, 195 insertions(+), 25 deletions(-) create mode 100644 src/app/FlyoutError/FlyoutError.test.tsx create mode 100644 src/app/FlyoutFooter/FlyoutFooter.test.tsx create mode 100644 src/app/FlyoutForm/ExpandingTextInputs.test.tsx delete mode 100644 src/app/FlyoutHeader.tsx/FlyoutHeader.tsx create mode 100644 src/app/FlyoutHeader/FlyoutHeader.test.tsx create mode 100644 src/app/FlyoutLoading/FlyoutLoading.test.tsx create mode 100644 src/app/FlyoutStartScreen/FlyoutStartScreen.test.tsx diff --git a/src/app/FlyoutError/FlyoutError.test.tsx b/src/app/FlyoutError/FlyoutError.test.tsx new file mode 100644 index 0000000..990f84f --- /dev/null +++ b/src/app/FlyoutError/FlyoutError.test.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import userEvent from '@testing-library/user-event'; +import { FlyoutError } from './FlyoutError'; + +describe('Flyout errror', () => { + it('should render correctly', async () => { + render(); + expect(screen.getByText('Test')).toBeTruthy(); + }); + it('should render correctly with subtitle', async () => { + render(); + expect(screen.getByText('Test')).toBeTruthy(); + expect(screen.getByText('Subtitle')).toBeTruthy(); + }); + it('should render correctly with button', async () => { + const spy = jest.fn(); + render(); + const toggle = screen.getByRole('button', { name: /Retry/i }); + await userEvent.click(toggle); + expect(spy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/app/FlyoutFooter/FlyoutFooter.test.tsx b/src/app/FlyoutFooter/FlyoutFooter.test.tsx new file mode 100644 index 0000000..9425f35 --- /dev/null +++ b/src/app/FlyoutFooter/FlyoutFooter.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import userEvent from '@testing-library/user-event'; +import { FlyoutFooter } from './FlyoutFooter'; + +describe('Flyout footer', () => { + it('should render correctly', async () => { + const spy = jest.fn(); + render(); + const toggle = screen.getByRole('button', { name: /New assistant/i }); + await userEvent.click(toggle); + expect(spy).toHaveBeenCalledTimes(1); + }); + it('should disable primary button', async () => { + render(); + expect(screen.getByRole('button', { name: /New assistant/i })).toBeDisabled(); + }); + it('should render second button', async () => { + const spy = jest.fn(); + render( + , + ); + const toggle = screen.getByRole('button', { name: /Cancel/i }); + await userEvent.click(toggle); + expect(spy).toHaveBeenCalledTimes(1); + }); +}); diff --git a/src/app/FlyoutForm/ExpandingTextInputs.test.tsx b/src/app/FlyoutForm/ExpandingTextInputs.test.tsx new file mode 100644 index 0000000..da408a1 --- /dev/null +++ b/src/app/FlyoutForm/ExpandingTextInputs.test.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { fireEvent, render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import userEvent from '@testing-library/user-event'; +import { ExpandingTextInputs } from './ExpandingTextInputs'; + +const MOCK_VALUES = ['What is an apple?', 'What is a pear?']; +Object.defineProperty(window.HTMLElement.prototype, 'scrollIntoView', { + value: jest.fn(), + writable: true, +}); + +describe('Expanding text inputs', () => { + it('should render correctly with no values', () => { + render(); + expect(screen.getByRole('textbox', { name: /Enter example question/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Add/i })).toBeTruthy(); + expect(screen.queryByRole('region', { name: /Example questions/i })).toBeFalsy(); + }); + it('should be able to input a value', async () => { + const spy = jest.fn(); + render(); + const input = screen.getByRole('textbox', { name: /Enter example question/i }) as HTMLTextAreaElement; + fireEvent.change(input, { target: { value: 'What is an apple?' } }); + expect(input.value).toBe('What is an apple?'); + await userEvent.click(screen.getByRole('button', { name: /Add/i })); + expect(spy).toHaveBeenCalledTimes(1); + }); + it('should render correctly with some pre-filled values', () => { + render( + , + ); + expect(screen.getByRole('textbox', { name: /Enter example question/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Add/i })).toBeTruthy(); + expect(screen.getByRole('region', { name: /Example questions/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Edit question What is an apple?/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Delete question What is an apple?/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Edit question What is a pear?/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Delete question What is a pear?/i })).toBeTruthy(); + }); + it('should be able to click edit button and see an input', async () => { + render( + , + ); + const edit = screen.getByRole('button', { name: /Edit question What is an apple?/i }); + await userEvent.click(edit); + expect(screen.getByRole('textbox', { name: /Edit example question What is an apple?/i })).toBeTruthy(); + expect(screen.getByRole('button', { name: /Save question What is an apple?/i })).toBeTruthy(); + }); + it('should be able to delete a value', async () => { + const spy = jest.fn(); + render( + , + ); + const btn = screen.getByRole('button', { name: /Delete question What is an apple?/i }); + await userEvent.click(btn); + expect(spy).toHaveBeenCalledTimes(1); + expect(screen.queryByRole('button', { name: /Edit example question What is an apple?/i })).toBeFalsy(); + expect(screen.queryByRole('button', { name: /Delete example question What is an apple?/i })).toBeFalsy(); + }); +}); diff --git a/src/app/FlyoutForm/ExpandingTextInputs.tsx b/src/app/FlyoutForm/ExpandingTextInputs.tsx index cbd2d1f..6776b51 100644 --- a/src/app/FlyoutForm/ExpandingTextInputs.tsx +++ b/src/app/FlyoutForm/ExpandingTextInputs.tsx @@ -65,9 +65,7 @@ export const ExpandingTextInputs: React.FunctionComponent setEditingInputValue(value)} tabIndex={editingIndex === index ? 0 : -1} - aria-label={ - editingInputValue === '' ? 'Edit example question' : `Edit example question ${editingInputValue}` - } + aria-label={`Edit example question ${value}`} />
@@ -83,7 +81,7 @@ export const ExpandingTextInputs: React.FunctionComponent diff --git a/src/app/FlyoutForm/FlyoutForm.tsx b/src/app/FlyoutForm/FlyoutForm.tsx index 87a7b8f..7e5418f 100644 --- a/src/app/FlyoutForm/FlyoutForm.tsx +++ b/src/app/FlyoutForm/FlyoutForm.tsx @@ -1,7 +1,7 @@ import { useAppData } from '@app/AppData/AppDataContext'; import { FlyoutError } from '@app/FlyoutError/FlyoutError'; import { FlyoutFooter } from '@app/FlyoutFooter/FlyoutFooter'; -import { FlyoutHeader } from '@app/FlyoutHeader.tsx/FlyoutHeader'; +import { FlyoutHeader } from '@app/FlyoutHeader/FlyoutHeader'; import { FlyoutLoading } from '@app/FlyoutLoading/FlyoutLoading'; import { useFlyoutWizard } from '@app/FlyoutWizard/FlyoutWizardContext'; import { ErrorObject } from '@app/types/ErrorObject'; diff --git a/src/app/FlyoutHeader.tsx/FlyoutHeader.tsx b/src/app/FlyoutHeader.tsx/FlyoutHeader.tsx deleted file mode 100644 index 169b8a5..0000000 --- a/src/app/FlyoutHeader.tsx/FlyoutHeader.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { Button } from '@patternfly/react-core'; -import { TimesIcon } from '@patternfly/react-icons'; -import * as React from 'react'; - -interface FlyoutHeaderProps { - title: string | React.ReactNode; - hideFlyout: () => void; -} -export const FlyoutHeader: React.FunctionComponent = ({ title, hideFlyout }: FlyoutHeaderProps) => { - return ( -
- {title} -
- ); -}; diff --git a/src/app/FlyoutHeader/FlyoutHeader.test.tsx b/src/app/FlyoutHeader/FlyoutHeader.test.tsx new file mode 100644 index 0000000..c12b2ef --- /dev/null +++ b/src/app/FlyoutHeader/FlyoutHeader.test.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import userEvent from '@testing-library/user-event'; +import { FlyoutHeader } from './FlyoutHeader'; + +describe('Flyout header', () => { + it('should render correctly', async () => { + const spy = jest.fn(); + render(); + const toggle = screen.getByRole('button', { name: /Close/i }); + await userEvent.click(toggle); + expect(spy).toHaveBeenCalledTimes(1); + expect(screen.getByText('Test')).toBeTruthy(); + }); +}); diff --git a/src/app/FlyoutHeader/FlyoutHeader.tsx b/src/app/FlyoutHeader/FlyoutHeader.tsx index d774ed2..169b8a5 100644 --- a/src/app/FlyoutHeader/FlyoutHeader.tsx +++ b/src/app/FlyoutHeader/FlyoutHeader.tsx @@ -3,14 +3,14 @@ import { TimesIcon } from '@patternfly/react-icons'; import * as React from 'react'; interface FlyoutHeaderProps { - title: React.ReactNode | string; + title: string | React.ReactNode; hideFlyout: () => void; } export const FlyoutHeader: React.FunctionComponent = ({ title, hideFlyout }: FlyoutHeaderProps) => { return (
{title} -
); }; diff --git a/src/app/FlyoutList/FlyoutList.tsx b/src/app/FlyoutList/FlyoutList.tsx index 3b1d676..b57b070 100644 --- a/src/app/FlyoutList/FlyoutList.tsx +++ b/src/app/FlyoutList/FlyoutList.tsx @@ -1,7 +1,7 @@ import { useAppData } from '@app/AppData/AppDataContext'; import { FlyoutError } from '@app/FlyoutError/FlyoutError'; import { FlyoutFooter } from '@app/FlyoutFooter/FlyoutFooter'; -import { FlyoutHeader } from '@app/FlyoutHeader.tsx/FlyoutHeader'; +import { FlyoutHeader } from '@app/FlyoutHeader/FlyoutHeader'; import { FlyoutLoading } from '@app/FlyoutLoading/FlyoutLoading'; import { useFlyoutWizard } from '@app/FlyoutWizard/FlyoutWizardContext'; import { CannedChatbot } from '@app/types/CannedChatbot'; diff --git a/src/app/FlyoutLoading/FlyoutLoading.test.tsx b/src/app/FlyoutLoading/FlyoutLoading.test.tsx new file mode 100644 index 0000000..49e0fb1 --- /dev/null +++ b/src/app/FlyoutLoading/FlyoutLoading.test.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { FlyoutLoading } from './FlyoutLoading'; + +describe('Flyout loading', () => { + it('should render correctly', async () => { + render(); + expect(screen.getByRole('progressbar')).toBeTruthy(); + }); +}); diff --git a/src/app/FlyoutStartScreen/FlyoutStartScreen.test.tsx b/src/app/FlyoutStartScreen/FlyoutStartScreen.test.tsx new file mode 100644 index 0000000..a91dc99 --- /dev/null +++ b/src/app/FlyoutStartScreen/FlyoutStartScreen.test.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import { FlyoutStartScreen } from './FlyoutStartScreen'; +import { FlyoutWizardProvider } from '@app/FlyoutWizard/FlyoutWizardContext'; + +describe('Flyout start screen', () => { + it('should render correctly with subtitle', async () => { + render( + + + , + ); + expect(screen.getByText('I am a subtitle')).toBeTruthy(); + }); + it('should render correctly with primary button', async () => { + render( + + + , + ); + expect(screen.getByRole('button', { name: /Get started/i })).toBeTruthy(); + }); + it('should render correctly with secondary button', async () => { + render( + + + , + ); + expect(screen.getByRole('button', { name: /Learn more/i })).toBeTruthy(); + expect(screen.getByText('or')).toBeTruthy(); + }); +}); diff --git a/src/app/FlyoutStartScreen/FlyoutStartScreen.tsx b/src/app/FlyoutStartScreen/FlyoutStartScreen.tsx index f73d4ec..0323598 100644 --- a/src/app/FlyoutStartScreen/FlyoutStartScreen.tsx +++ b/src/app/FlyoutStartScreen/FlyoutStartScreen.tsx @@ -1,4 +1,4 @@ -import { FlyoutHeader } from '@app/FlyoutHeader.tsx/FlyoutHeader'; +import { FlyoutHeader } from '@app/FlyoutHeader/FlyoutHeader'; import { useFlyoutWizard } from '@app/FlyoutWizard/FlyoutWizardContext'; import { Button } from '@patternfly/react-core'; import * as React from 'react';