import React from 'react';
import '@testing-library/jest-dom';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import { ChatbotDisplayMode } from '../Chatbot/Chatbot';
import ChatbotConversationHistoryNav, { Conversation } from './ChatbotConversationHistoryNav';
import { EmptyStateStatus, Spinner } from '@patternfly/react-core';
const ERROR = {
bodyText: (
<>
To try again, check your connection and reload this page. If the issue persists,{' '}
contact the support team.
>
),
buttonText: 'Reload',
buttonIcon: ,
hasButton: true,
titleText: 'Could not load chat history',
status: EmptyStateStatus.danger,
onClick: () => alert('Clicked Reload')
};
const ERROR_WITHOUT_BUTTON = {
bodyText: (
<>
To try again, check your connection and reload this page. If the issue persists,{' '}
contact the support team.
>
),
buttonText: 'Reload',
buttonIcon: ,
hasButton: false,
titleText: 'Could not load chat history',
status: EmptyStateStatus.danger,
onClick: () => alert('Clicked Reload')
};
describe('ChatbotConversationHistoryNav', () => {
const onDrawerToggle = jest.fn();
const initialConversations: Conversation[] = [
{
id: '1',
text: 'ChatBot documentation'
}
];
it('should open the conversation history navigation drawer', () => {
render(
);
expect(screen.queryByText('ChatBot documentation')).toBeInTheDocument();
});
it('should display the conversations for grouped conversations', () => {
const groupedConversations: { [key: string]: Conversation[] } = {
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
};
render(
);
expect(screen.queryByText('Chatbot extension')).toBeInTheDocument();
});
it('should apply the reversed class when reverseButtonOrder is true', () => {
render(
);
expect(screen.getByTestId('chatbot-nav-drawer-actions')).toHaveClass('pf-v6-c-drawer__actions--reversed');
});
it('should not apply the reversed class when reverseButtonOrder is false', () => {
render(
);
expect(screen.getByTestId('chatbot-nav-drawer-actions')).not.toHaveClass('pf-v6-c-drawer__actions--reversed');
});
it('should invoke handleTextInputChange callback when user searches for conversations', () => {
const handleSearch = jest.fn();
const groupedConversations: { [key: string]: Conversation[] } = {
Today: [...initialConversations, { id: '2', text: 'Chatbot extension' }]
};
render(
);
const searchInput = screen.getByPlaceholderText(/Search/i);
fireEvent.change(searchInput, { target: { value: 'Chatbot' } });
expect(handleSearch).toHaveBeenCalledWith('Chatbot');
});
it('should close the drawer when escape key is pressed', async () => {
render(
);
fireEvent.keyDown(screen.getByPlaceholderText(/Search/i), {
key: 'Escape',
code: 'Escape',
keyCode: 27,
charCode: 27
});
waitFor(() => {
expect(screen.queryByText('ChatBot documentation')).not.toBeInTheDocument();
});
});
it('should be resizable', () => {
render(
);
expect(screen.getByRole('dialog', { name: /Resize/i })).toBeTruthy();
expect(screen.getByRole('separator', { name: /Resize/i })).toBeTruthy();
expect(screen.getByRole('dialog', { name: /Resize/i })).toHaveAttribute(
'style',
'--pf-v6-c-drawer__panel--md--FlexBasis: 384px; --pf-v6-c-drawer__panel--md--FlexBasis--min: 200px;'
);
});
it('should accept drawerContentProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should accept drawerContentBodyProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should accept drawerHeadProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should accept drawerActionsProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should accept drawerCloseButtonProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should accept drawerPanelBodyProps', () => {
const { container } = render(
);
const element = container.querySelector('.test');
expect(element).toBeInTheDocument();
});
it('should show loading state if triggered', () => {
render(
);
expect(screen.getByRole('dialog', { name: /Loading chatbot conversation history/i })).toBeTruthy();
expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
});
it('should pass alternative aria label to loading state', () => {
render(
);
expect(screen.getByRole('dialog', { name: /I am a test/i })).toBeTruthy();
});
it('should accept errorState', () => {
render(
);
expect(
screen.getByRole('dialog', {
name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team . Loading... Reload/i
})
).toBeTruthy();
expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
expect(screen.getByRole('button', { name: /Loading... Reload/i })).toBeTruthy();
expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
});
it('should accept errorState without button', () => {
render(
);
expect(
screen.getByRole('dialog', {
name: /Could not load chat history To try again, check your connection and reload this page. If the issue persists, contact the support team ./i
})
).toBeTruthy();
expect(screen.getByRole('button', { name: /Close drawer panel/i })).toBeTruthy();
expect(screen.queryByRole('button', { name: /Loading... Reload/i })).toBeFalsy();
expect(screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
expect(screen.getByRole('heading', { name: /Could not load chat history/i })).toBeTruthy();
});
it('should show loading state over error state if both are supplied', () => {
render(
);
expect(screen.getByRole('dialog', { name: /Loading/i })).toBeTruthy();
});
});