Skip to content

Commit 277063a

Browse files
committed
Added some tests, imported css helper for QuickResponse
1 parent c16601f commit 277063a

File tree

4 files changed

+176
-6
lines changed

4 files changed

+176
-6
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { render, screen } from '@testing-library/react';
2+
import '@testing-library/jest-dom';
3+
import ErrorMessage from './ErrorMessage';
4+
5+
test('Renders with title', () => {
6+
render(<ErrorMessage title="Error occurred" />);
7+
8+
expect(screen.getByText('Error occurred')).toBeVisible();
9+
});
10+
11+
test('Renders with children', () => {
12+
render(<ErrorMessage title="Error occurred">This is the error message body</ErrorMessage>);
13+
14+
expect(screen.getByText('This is the error message body')).toBeVisible();
15+
});
16+
17+
test('Renders with action links', () => {
18+
const actionLinks = (
19+
<a href="#retry" data-testid="retry-link">
20+
Retry action link
21+
</a>
22+
);
23+
render(<ErrorMessage title="Error occurred" actionLinks={actionLinks} />);
24+
25+
expect(screen.getByText('Retry action link')).toBeVisible();
26+
});
27+
28+
test('Renders with custom className', () => {
29+
render(<ErrorMessage title="Error occurred" className="custom-error-class" />);
30+
31+
expect(screen.getByText('Error occurred').parentElement).toHaveClass('custom-error-class');
32+
});
33+
34+
test('Renders with spread props', () => {
35+
render(<ErrorMessage title="Error occurred" id="test-error-id" />);
36+
37+
expect(screen.getByText('Error occurred').parentElement).toHaveAttribute('id', 'test-error-id');
38+
});

packages/module/src/Message/ErrorMessage/ErrorMessage.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ import { Alert, AlertProps } from '@patternfly/react-core';
99
* Use this component when passing children to Message to display error information.
1010
*/
1111
export interface ErrorMessageProps extends Partial<AlertProps> {
12-
/** Title of the error alert */
13-
title?: React.ReactNode;
14-
/** Action links to display in the alert footer */
15-
actionLinks?: React.ReactNode;
1612
/** Content to display in the error alert body */
1713
children?: React.ReactNode;
1814
/** Additional classes for the error alert */
1915
className?: string;
16+
/** Title of the error alert */
17+
title?: React.ReactNode;
18+
/** Action links to display in the alert footer */
19+
actionLinks?: React.ReactNode;
2020
}
2121

2222
export const ErrorMessage = ({ title, actionLinks, children, className, ...props }: ErrorMessageProps) => (
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import { render, screen } from '@testing-library/react';
2+
import userEvent from '@testing-library/user-event';
3+
import '@testing-library/jest-dom';
4+
import QuickResponse from './QuickResponse';
5+
6+
test('Renders with quick responses', () => {
7+
const quickResponses = [
8+
{ id: '1', content: 'Response 1' },
9+
{ id: '2', content: 'Response 2' },
10+
{ id: '3', content: 'Response 3' }
11+
];
12+
render(<QuickResponse quickResponses={quickResponses} />);
13+
14+
expect(screen.getByText('Response 1')).toBeVisible();
15+
expect(screen.getByText('Response 2')).toBeVisible();
16+
expect(screen.getByText('Response 3')).toBeVisible();
17+
});
18+
19+
test('Renders with compact styling', () => {
20+
const quickResponses = [{ id: '1', content: 'Compact response' }];
21+
render(<QuickResponse quickResponses={quickResponses} isCompact />);
22+
23+
expect(screen.getByText('Compact response').closest('.pf-v6-c-label')).toHaveClass('pf-m-compact');
24+
});
25+
26+
test('Renders with custom className on response', () => {
27+
const quickResponses = [{ id: '1', content: 'Custom class response', className: 'custom-response-class' }];
28+
render(<QuickResponse quickResponses={quickResponses} />);
29+
30+
expect(screen.getByText('Custom class response').closest('.pf-v6-c-label')).toHaveClass('custom-response-class');
31+
});
32+
33+
test('Renders with custom container className', () => {
34+
const quickResponses = [
35+
{ id: '1', content: 'Response 1' },
36+
{ id: '2', content: 'Response 2' }
37+
];
38+
render(
39+
<QuickResponse
40+
quickResponses={quickResponses}
41+
quickResponseContainerProps={{ className: 'custom-container-class' }}
42+
/>
43+
);
44+
45+
expect(screen.getByText('Response 1').closest('.pf-v6-c-label-group')).toHaveClass('custom-container-class');
46+
});
47+
48+
test('Spreads additional custom container props', () => {
49+
const quickResponses = [
50+
{ id: '1', content: 'Response 1' },
51+
{ id: '2', content: 'Response 2' }
52+
];
53+
render(<QuickResponse quickResponses={quickResponses} quickResponseContainerProps={{ id: 'custom-container-id' }} />);
54+
55+
expect(screen.getByText('Response 1').closest('.pf-v6-c-label-group__list')).toHaveAttribute(
56+
'id',
57+
'custom-container-id'
58+
);
59+
});
60+
61+
test('Renders with pf-chatbot__message-quick-response--selected class after click', async () => {
62+
const user = userEvent.setup();
63+
const quickResponses = [
64+
{ id: '1', content: 'Response 1' },
65+
{ id: '2', content: 'Response 2' }
66+
];
67+
render(<QuickResponse quickResponses={quickResponses} />);
68+
69+
await user.click(screen.getByText('Response 1'));
70+
71+
expect(screen.getByText('Response 1').closest('.pf-v6-c-label')).toHaveClass(
72+
'pf-chatbot__message-quick-response--selected'
73+
);
74+
});
75+
76+
test('Does not calls onClick handler when not passed', async () => {
77+
const user = userEvent.setup();
78+
const handleClick = jest.fn();
79+
const quickResponses = [{ id: '1', content: 'Clickable response' }];
80+
render(<QuickResponse quickResponses={quickResponses} />);
81+
82+
await user.click(screen.getByText('Clickable response'));
83+
84+
expect(handleClick).not.toHaveBeenCalled();
85+
});
86+
87+
test('Calls onClick handler when passed', async () => {
88+
const user = userEvent.setup();
89+
const handleClick = jest.fn();
90+
const quickResponses = [{ id: '1', content: 'Clickable response', onClick: handleClick }];
91+
render(<QuickResponse quickResponses={quickResponses} />);
92+
93+
await user.click(screen.getByText('Clickable response'));
94+
95+
expect(handleClick).toHaveBeenCalled();
96+
});
97+
98+
test('Does not call onSelect when not passed', async () => {
99+
const user = userEvent.setup();
100+
const handleSelect = jest.fn();
101+
const quickResponses = [
102+
{ id: '1', content: 'Response 1' },
103+
{ id: '2', content: 'Response 2' }
104+
];
105+
render(<QuickResponse quickResponses={quickResponses} />);
106+
107+
await user.click(screen.getByText('Response 2'));
108+
109+
expect(handleSelect).not.toHaveBeenCalled();
110+
});
111+
112+
test('Calls onSelect when passed', async () => {
113+
const user = userEvent.setup();
114+
const handleSelect = jest.fn();
115+
const quickResponses = [
116+
{ id: '1', content: 'Response 1' },
117+
{ id: '2', content: 'Response 2' }
118+
];
119+
render(<QuickResponse quickResponses={quickResponses} onSelect={handleSelect} />);
120+
121+
await user.click(screen.getByText('Response 2'));
122+
123+
expect(handleSelect).toHaveBeenCalledWith('2');
124+
});
125+
126+
test('Spreads additional response props', () => {
127+
const quickResponses = [{ id: '1', content: 'Response with props', isCompact: true, 'aria-label': 'Test label' }];
128+
render(<QuickResponse quickResponses={quickResponses} />);
129+
130+
expect(screen.getByText('Response with props').closest('.pf-v6-c-label')).toHaveAttribute('aria-label', 'Test label');
131+
});

packages/module/src/Message/QuickResponse/QuickResponse.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { FunctionComponent } from 'react';
22
import { useState } from 'react';
33
import { Label, LabelGroup, LabelGroupProps, LabelProps } from '@patternfly/react-core';
44
import { CheckIcon } from '@patternfly/react-icons';
5+
import { css } from '@patternfly/react-styles';
56

67
export interface QuickResponse extends Omit<LabelProps, 'children'> {
78
content: string;
@@ -35,7 +36,7 @@ export const QuickResponse: FunctionComponent<QuickResponseProps> = ({
3536
};
3637
return (
3738
<LabelGroup
38-
className={`pf-chatbot__message-quick-response ${quickResponseContainerProps?.className ? quickResponseContainerProps?.className : ''}`}
39+
className={css('pf-chatbot__message-quick-response', quickResponseContainerProps?.className)}
3940
{...quickResponseContainerProps}
4041
>
4142
{quickResponses.map(({ id, onClick, content, className, ...props }: QuickResponse) => (
@@ -45,7 +46,7 @@ export const QuickResponse: FunctionComponent<QuickResponseProps> = ({
4546
color="blue"
4647
key={id}
4748
onClick={() => handleQuickResponseClick(id, onClick)}
48-
className={`${id === selectedQuickResponse ? 'pf-chatbot__message-quick-response--selected' : ''} ${className ? className : ''}`}
49+
className={css(id === selectedQuickResponse && 'pf-chatbot__message-quick-response--selected', className)}
4950
isCompact={isCompact}
5051
{...props}
5152
>

0 commit comments

Comments
 (0)