import { fireEvent, mockMatchMedia, render, screen, userEvent, waitFor } from '../../test-utils';
import { resetLiveRegionAnnouncementQueue } from '../../common/liveRegion/LiveRegion';
import { InfoPrompt, InfoPromptProps } from './InfoPrompt';
mockMatchMedia();
const CUSTOM_MEDIA = Custom Media;
describe('InfoPrompt', () => {
const defaultProps: InfoPromptProps = {
description: 'Prompt description',
};
beforeEach(() => {
resetLiveRegionAnnouncementQueue();
});
it('renders description', () => {
render();
expect(screen.getByText('Prompt description')).toBeInTheDocument();
});
it('renders title when provided', () => {
render();
expect(screen.getByText('Test Title')).toBeInTheDocument();
expect(screen.getByText('Prompt description')).toBeInTheDocument();
});
it('renders with GiftBox icon as default for `proposition` sentiment', () => {
render();
expect(screen.getByText('Prompt description')).toBeInTheDocument();
// GiftBox icon should be rendered for proposition sentiment
const prompt = screen.getByTestId('info-prompt');
expect(prompt.querySelector('svg')).toBeInTheDocument();
});
describe('sentiments', () => {
[
{ sentiment: 'negative' as const, surfaceClass: 'wds-prompt--negative' },
{ sentiment: 'warning' as const, surfaceClass: 'wds-prompt--warning' },
{ sentiment: 'neutral' as const, surfaceClass: 'wds-prompt--neutral' },
{ sentiment: 'success' as const, surfaceClass: 'wds-prompt--success' },
{ sentiment: 'proposition' as const, surfaceClass: 'wds-prompt--proposition' },
].forEach(({ sentiment, surfaceClass }) => {
describe(sentiment, () => {
it('should apply correct styles', () => {
render();
expect(screen.getByTestId('info-prompt')).toHaveClass(surfaceClass);
});
});
});
});
describe('custom media', () => {
it('should render custom media when provided', () => {
render();
expect(screen.getByTestId('custom-media')).toBeInTheDocument();
});
it('should render custom media for any sentiment', () => {
render();
expect(screen.getByTestId('custom-media')).toBeInTheDocument();
});
});
describe('action', () => {
it('should render action link when action is provided with href', async () => {
render(
,
);
const actionLink = await screen.findByRole('link', { name: 'Learn more' });
expect(actionLink).toBeInTheDocument();
expect(actionLink).toHaveAttribute('href', '/learn-more');
});
it('should render action link with target when provided', async () => {
render(
,
);
const actionLink = await screen.findByRole('link', { name: /External link/i });
expect(actionLink).toHaveAttribute('target', '_blank');
});
it('should call onClick when action button is clicked', async () => {
const user = userEvent.setup();
const onClick = jest.fn();
render();
const actionButton = await screen.findByRole('button', { name: 'Click me' });
await user.click(actionButton);
expect(onClick).toHaveBeenCalledTimes(1);
});
it('should not render action when not provided', () => {
render();
expect(screen.queryByRole('link', { name: 'Learn more' })).not.toBeInTheDocument();
});
});
describe('HTML attributes', () => {
it('applies custom className, id, and data-testid', () => {
render(
,
);
const el = screen.getByTestId('custom-test');
expect(el).toHaveClass('custom-class');
expect(el).toHaveAttribute('id', 'custom-id');
});
});
describe('SentimentSurface integration', () => {
it('maps success sentiment correctly for SentimentSurface', () => {
render();
const el = screen.getByTestId('prompt');
expect(el).toHaveClass('wds-prompt--success');
expect(el).toHaveClass('wds-sentiment-surface');
});
it('passes through other sentiments unchanged', () => {
render();
const el = screen.getByTestId('prompt');
expect(el).toHaveClass('wds-prompt--negative');
expect(el).toHaveClass('wds-sentiment-surface');
});
});
describe('touch interactions', () => {
const originalLocation = window.location;
beforeAll(() => {
jest.spyOn(window, 'open').mockImplementation();
Object.defineProperty(window, 'location', {
configurable: true,
value: {
...originalLocation,
assign: jest.fn(),
},
});
});
afterEach(() => {
jest.clearAllMocks();
});
afterAll(() => {
Object.defineProperty(window, 'location', {
configurable: true,
value: originalLocation,
});
});
it('should navigate to action href on touch tap', () => {
render(
,
);
const prompt = screen.getByTestId('prompt');
fireEvent.touchStart(prompt);
expect(window.location.assign).not.toHaveBeenCalled();
fireEvent.touchEnd(prompt);
expect(window.location.assign).toHaveBeenCalledWith('/learn-more');
});
it('should open in new tab when action target is _blank', () => {
render(
,
);
const prompt = screen.getByTestId('prompt');
fireEvent.touchStart(prompt);
expect(window.open).not.toHaveBeenCalled();
fireEvent.touchEnd(prompt);
expect(window.open).toHaveBeenCalledWith(
'https://example.com',
'_blank',
'noopener, noreferrer',
);
});
it('should not navigate if touch move occurs (scrolling)', () => {
render(
,
);
const prompt = screen.getByTestId('prompt');
fireEvent.touchStart(prompt);
expect(window.location.assign).not.toHaveBeenCalled();
fireEvent.touchMove(prompt);
expect(window.location.assign).not.toHaveBeenCalled();
fireEvent.touchEnd(prompt);
expect(window.location.assign).not.toHaveBeenCalled();
});
it('should not navigate if no action href is provided', () => {
render(
,
);
const prompt = screen.getByTestId('prompt');
fireEvent.touchStart(prompt);
fireEvent.touchEnd(prompt);
expect(window.location.assign).not.toHaveBeenCalled();
expect(window.open).not.toHaveBeenCalled();
});
});
});