import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom';
import ToolCall from './ToolCall';
describe('ToolCall', () => {
const defaultProps = {
titleText: 'ToolCall Title',
loadingText: 'Loading ToolCall'
};
it('Renders with passed in titleText', () => {
render();
expect(screen.getByText(defaultProps.titleText)).toBeVisible();
});
it('Does not render with passed in loadingText when isLoading is false', () => {
render();
expect(screen.queryByText(defaultProps.loadingText)).not.toBeInTheDocument();
});
it('Renders with passed in loadingText when isLoading is true', () => {
render();
expect(screen.getByText(defaultProps.loadingText)).toBeVisible();
});
it('Does not render titleText when isLoading is true', () => {
render();
expect(screen.queryByText(defaultProps.titleText)).not.toBeInTheDocument();
});
it('Passes spinnerProps to Spinner', () => {
render();
expect(screen.getByRole('progressbar')).toHaveAttribute('id', 'spinner-test-id');
});
it('Does not render expandable toggle by default', () => {
render();
expect(screen.queryByRole('button', { name: defaultProps.titleText })).not.toBeInTheDocument();
});
it('Renders titleText inside expandable toggle when expandableContent is passed', () => {
render();
expect(screen.getByRole('button', { name: defaultProps.titleText })).toBeVisible();
});
it('Does not render expandable content when expandableContent is passed by default', () => {
render();
expect(screen.queryByText('Expandable Content')).not.toBeVisible();
});
it('Renders expandable content when expandableContent is passed and toggle is clicked', async () => {
const user = userEvent.setup();
render();
await user.click(screen.getByRole('button', { name: defaultProps.titleText }));
expect(screen.getByText('Expandable Content')).toBeVisible();
});
it('Passes expandableSectionProps to ExpandableSection', () => {
render(
);
expect(screen.getByRole('region').parentElement).toHaveAttribute('id', 'expandable-section-test-id');
});
it('Renders "run" action button by default', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' })).toBeVisible();
});
it('Renders "cancel" action button by default', () => {
render();
expect(screen.getByRole('button', { name: 'Cancel' })).toBeVisible();
});
it('Does not render "run" action button when isLoading is true', () => {
render();
expect(screen.queryByRole('button', { name: 'Run tool' })).not.toBeInTheDocument();
});
it('Does not render "cancel" action button when isLoading is true', () => {
render();
expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument();
});
it('Renders runButtonText when passed', () => {
render();
expect(screen.getByRole('button', { name: 'Run my custom tool' })).toBeVisible();
});
it('Renders cancelButtonText when passed', () => {
render();
expect(screen.getByRole('button', { name: 'Cancel my custom tool' })).toBeVisible();
});
it('Passes runButtonProps to Button', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' })).toHaveAttribute('id', 'run-button-test-id');
});
it('Passes cancelButtonProps to Button', () => {
render();
expect(screen.getByRole('button', { name: 'Cancel' })).toHaveAttribute('id', 'cancel-button-test-id');
});
it('Passes runActionItemProps to ActionListItem', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).parentElement).toHaveAttribute(
'id',
'run-action-item-test-id'
);
});
it('Passes cancelActionItemProps to ActionListItem', () => {
render();
expect(screen.getByRole('button', { name: 'Cancel' }).parentElement).toHaveAttribute(
'id',
'cancel-action-item-test-id'
);
});
it('Passes actionListProps to ActionList', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).closest('#action-list-test-id')).toBeVisible();
});
it('Passes actionListGroupProps to ActionListGroup', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).closest('#action-list-group-test-id')).toBeVisible();
});
it('Passes actionListItemProps to ActionListItem for default actions', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).parentElement).toHaveClass('action-list-item-test-class');
expect(screen.getByRole('button', { name: 'Cancel' }).parentElement).toHaveClass('action-list-item-test-class');
});
it('Renders custom actions instead of default actions when actions are passed', () => {
render(
Custom action 1, Custom action 2
]}
/>
);
expect(screen.getByText('Custom action 1')).toBeVisible();
expect(screen.getByText('Custom action 2')).toBeVisible();
expect(screen.queryByRole('button', { name: 'Run tool' })).not.toBeInTheDocument();
expect(screen.queryByRole('button', { name: 'Cancel' })).not.toBeInTheDocument();
});
it('Passes actionListItemProps to ActionListItem for custom actions', () => {
render(
Custom action 1, Custom action 2
]}
actionListItemProps={{ className: 'action-list-item-test-class' }}
/>
);
expect(screen.getByText('Custom action 1').parentElement).toHaveClass('action-list-item-test-class');
expect(screen.getByText('Custom action 2').parentElement).toHaveClass('action-list-item-test-class');
});
it('Passes cardProps to Card', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).closest('#card-test-id')).toBeVisible();
});
it('Passes cardBodyProps to CardBody', () => {
render();
expect(screen.getByText(defaultProps.titleText).closest('#card-body-test-id')).toBeVisible();
});
it('Passes cardFooterProps to CardFooter', () => {
render();
expect(screen.getByRole('button', { name: 'Run tool' }).closest('#card-footer-test-id')).toBeVisible();
});
it('Renders collapsed by default when expandableContent is provided', () => {
render();
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'false');
expect(screen.queryByText('Expandable Content')).not.toBeVisible();
});
it('Renders expanded when isDefaultExpanded is true', () => {
render();
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'true');
expect(screen.getByText('Expandable Content')).toBeVisible();
});
it('expandableSectionProps.isExpanded overrides isDefaultExpanded', () => {
render(
);
expect(screen.getByRole('button', { name: defaultProps.titleText })).toHaveAttribute('aria-expanded', 'true');
expect(screen.getByText('Expandable Content')).toBeVisible();
});
it('expandableSectionProps.onToggle overrides internal onToggle behavior', async () => {
const user = userEvent.setup();
const customOnToggle = jest.fn();
render(
);
const toggleButton = screen.getByRole('button', { name: defaultProps.titleText });
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
await user.click(toggleButton);
expect(customOnToggle).toHaveBeenCalledTimes(1);
expect(toggleButton).toHaveAttribute('aria-expanded', 'false');
expect(screen.queryByText('Expandable Content')).not.toBeVisible();
});
it('should render titleText as markdown when isTitleMarkdown is true', () => {
const titleText = '**Bold title**';
const { container } = render();
expect(container.querySelector('strong')).toBeTruthy();
expect(screen.getByText('Bold title')).toBeTruthy();
});
it('should not render titleText as markdown when isTitleMarkdown is false', () => {
const titleText = '**Bold title**';
render();
expect(screen.getByText('**Bold title**')).toBeTruthy();
});
it('should render expandableContent as markdown when isExpandableContentMarkdown is true', async () => {
const user = userEvent.setup();
const expandableContent = '**Bold expandable content**';
const { container } = render(
);
await user.click(screen.getByRole('button', { name: defaultProps.titleText }));
expect(container.querySelector('strong')).toBeTruthy();
expect(screen.getByText('Bold expandable content')).toBeTruthy();
});
it('should not render expandableContent as markdown when isExpandableContentMarkdown is false', async () => {
const user = userEvent.setup();
const expandableContent = '**Bold expandable content**';
render();
await user.click(screen.getByRole('button', { name: defaultProps.titleText }));
expect(screen.getByText('**Bold expandable content**')).toBeTruthy();
});
it('should pass markdownContentProps to MarkdownContent component', () => {
const titleText = '**Bold title**';
const { container } = render(
);
expect(container.querySelector('.pf-m-primary')).toBeTruthy();
});
});