import * as React from 'react'; import { render, screen, userEvent } from '../../../../test-utils/testing-library'; import AppliedByAiClassificationReason from '../AppliedByAiClassificationReason'; import messages from '../messages'; describe('features/classification/applied-by-ai-classification-reason/AppliedByAiClassificationReason', () => { let defaultProps; let modifiedAtDisplayDate; beforeEach(() => { defaultProps = { answer: 'This file is marked as Internal Only because it contains non-public financial results.', modifiedAt: '2024-01-15T10:30:00Z', }; modifiedAtDisplayDate = 'January 15, 2024'; }); const renderComponent = (props = {}) => { return render(); }; test('should render AI classification reason with icon, applied date, and reasoning', () => { const expectedIconSize = '1.25rem'; renderComponent(); const boxAiIcon = screen.getByTestId('box-ai-icon'); const appliedByWithDate = screen.getByRole('heading', { level: 3, name: messages.appliedByBoxAiOnDate.defaultMessage.replace('{modifiedAt}', modifiedAtDisplayDate), }); const reasonText = screen.getByText(defaultProps.answer); const citationsLabel = screen.queryByTestId('content-answers-references-label'); const noReferencesIconContainer = screen.queryByTestId('content-answers-references-no-references'); expect(boxAiIcon).toBeVisible(); expect(boxAiIcon).toHaveAttribute('height', expectedIconSize); expect(boxAiIcon).toHaveAttribute('width', expectedIconSize); expect(appliedByWithDate).toBeVisible(); expect(reasonText).toBeVisible(); // Assert none of the Reference components are rendered expect(citationsLabel).toBeNull(); expect(noReferencesIconContainer).toBeNull(); }); test('should render no references icon and display tooltip on hover when provided empty citations array', async () => { const user = userEvent(); renderComponent({ citations: [] }); const noReferencesIconContainer = screen.getByTestId('content-answers-references-no-references'); const noReferencesIcon = noReferencesIconContainer.querySelector('svg'); // Verify the icon is visible expect(noReferencesIcon).toBeVisible(); // Verify tooltip appears on hover await user.hover(noReferencesIconContainer); const tooltip = await screen.findByRole('tooltip'); expect(tooltip).toBeVisible(); expect(tooltip).toHaveTextContent('Response based on general document analysis'); }); test('should render references when provided non-empty citations', () => { const expectedCitationsCount = 5; const expectedCitations = Array.from({ length: expectedCitationsCount }, () => ({ content: 'file content for citation', fileId: 'fileId', location: 'cited location', title: 'file title', })); renderComponent({ citations: expectedCitations }); const citationsLabel = screen.queryByTestId('content-answers-references-label'); const citationElements = screen.getAllByTestId('content-answers-citation-status'); expect(citationsLabel).toBeVisible(); expect(citationElements).toHaveLength(expectedCitationsCount); }); test.each([null, undefined, 'invalid date str'])( 'should render applied by without date when modifiedAt is invalid: %s', invalidModifiedAt => { renderComponent({ modifiedAt: invalidModifiedAt }); const appliedByWithoutDate = screen.getByRole('heading', { level: 3, name: messages.appliedByBoxAi.defaultMessage, }); expect(appliedByWithoutDate).toBeVisible(); }, ); test('should render long answer text correctly', () => { const longAnswer = 'A'.repeat(1000); renderComponent({ answer: longAnswer }); expect(screen.getByText(longAnswer)).toBeVisible(); }); test('should render answer with special and unicode characters correctly', () => { const nonPlainAnswer = 'Answer with special characters and unicode !@#$%^&*()_+-=[]{}|;:,.<>? πŸš€πŸŒŸπŸŽ‰δΈ­ζ–‡ζ—₯本θͺž'; renderComponent({ answer: nonPlainAnswer }); const reasonText = screen.getByText(nonPlainAnswer); expect(reasonText).toBeVisible(); }); test('should render title and citations only when answer is not provided', () => { const expectedCitations = [ { content: 'file content for citation', fileId: 'fileId', location: 'cited location', title: 'file title', }, ]; const { container } = renderComponent({ answer: undefined, citations: expectedCitations, }); const boxAiIcon = screen.getByTestId('box-ai-icon'); const appliedByWithDate = screen.getByRole('heading', { level: 3, name: messages.appliedByBoxAiOnDate.defaultMessage.replace('{modifiedAt}', modifiedAtDisplayDate), }); const citationsLabel = screen.getByTestId('content-answers-references-label'); const answerContent = container.querySelector('.bdl-AppliedByAiClassificationReason-answer'); expect(boxAiIcon).toBeVisible(); expect(appliedByWithDate).toBeVisible(); expect(citationsLabel).toBeVisible(); expect(answerContent).toBeNull(); }); test.each` answerValue | description ${undefined} | ${'undefined'} ${null} | ${'null'} ${''} | ${'empty string'} `('should not render AnswerContent when answer is $description', ({ answerValue }) => { const { container } = renderComponent({ answer: answerValue }); const answerContent = container.querySelector('.bdl-AppliedByAiClassificationReason-answer'); expect(answerContent).toBeNull(); }); test('should render minimal label when no props are provided', () => { const { container } = renderComponent({ answer: undefined, citations: undefined, modifiedAt: undefined, }); const boxAiIcon = screen.getByTestId('box-ai-icon'); const appliedByWithoutDate = screen.getByRole('heading', { level: 3, name: messages.appliedByBoxAi.defaultMessage, }); const answerContent = container.querySelector('.bdl-AppliedByAiClassificationReason-answer'); const citationsLabel = screen.queryByTestId('content-answers-references-label'); expect(boxAiIcon).toBeVisible(); expect(appliedByWithoutDate).toBeVisible(); expect(answerContent).toBeNull(); expect(citationsLabel).toBeNull(); }); });