-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added test case of citation panel and chatMessageContainer
- Loading branch information
1 parent
fe316c7
commit a3aa421
Showing
3 changed files
with
270 additions
and
1 deletion.
There are no files selected for viewing
122 changes: 122 additions & 0 deletions
122
...hAssistant/App/frontend/src/components/ChatMessageContainer/ChatMessageContainer.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
import React from 'react' | ||
import { fireEvent, render, screen } from '@testing-library/react' | ||
import '@testing-library/jest-dom' | ||
import ChatMessageContainer, { parseCitationFromMessage } from './ChatMessageContainer' | ||
|
||
import { type ChatMessage } from '../../api' | ||
|
||
jest.mock('remark-supersub', () => () => {}) | ||
jest.mock('remark-gfm', () => () => {}) | ||
jest.mock('rehype-raw', () => () => {}) | ||
jest.mock('../Answer', () => ({ | ||
Answer: jest.fn((props: any) => <div> | ||
<p>{props.answer.answer}</p> | ||
<span>Mock Answer Component</span> | ||
{props.answer.answer === 'Generating answer...' | ||
? <button onClick={() => props.onCitationClicked()}>Mock Citation Loading</button> | ||
: <button onClick={() => props.onCitationClicked({ title: 'Test Citation' })}>Mock Citation</button> | ||
} | ||
|
||
</div>) | ||
})) | ||
|
||
const mockOnShowCitation = jest.fn() | ||
describe('ChatMessageContainer', () => { | ||
beforeEach(() => { | ||
global.fetch = jest.fn() | ||
jest.spyOn(console, 'error').mockImplementation(() => { }) | ||
}) | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks() | ||
}) | ||
|
||
const userMessage: ChatMessage = { | ||
role: 'user', | ||
content: 'User message', | ||
id: '1', | ||
date: new Date().toDateString() | ||
} | ||
|
||
const assistantMessage: ChatMessage = { | ||
role: 'assistant', | ||
content: 'Assistant message', | ||
id: '2', | ||
date: new Date().toDateString() | ||
} | ||
|
||
const errorMessage: ChatMessage = { | ||
role: 'error', | ||
content: 'Error message', | ||
id: '3', | ||
date: new Date().toDateString() | ||
} | ||
|
||
const nullMessage: ChatMessage = { | ||
role: '', | ||
content: 'Null role message', | ||
id: '4', | ||
date: '' | ||
} | ||
it('renders user messages correctly', () => { | ||
render(<ChatMessageContainer messages={[userMessage]} onShowCitation={mockOnShowCitation} showLoadingMessage={false} />) | ||
expect(screen.getByText('User message')).toBeInTheDocument() | ||
}) | ||
|
||
it('renders assistant messages correctly', () => { | ||
render(<ChatMessageContainer messages={[assistantMessage]} onShowCitation={mockOnShowCitation} showLoadingMessage={false} />) | ||
expect(screen.getByText('Assistant message')).toBeInTheDocument() | ||
}) | ||
|
||
it('renders an error message correctly', () => { | ||
render( | ||
<ChatMessageContainer | ||
messages={[errorMessage]} | ||
showLoadingMessage={false} | ||
onShowCitation={mockOnShowCitation} | ||
/> | ||
) | ||
|
||
// Check if error message is displayed with the error icon | ||
expect(screen.getByText('Error')).toBeInTheDocument() | ||
expect(screen.getByText('Error message')).toBeInTheDocument() | ||
}) | ||
|
||
it('returns citations when message role is "tool" and content is valid JSON', () => { | ||
const message: ChatMessage = { | ||
role: 'tool', | ||
content: JSON.stringify({ citations: [{ filepath: 'path/to/file', chunk_id: '1' }] }), | ||
id: '1', | ||
date: '' | ||
} | ||
const citations = parseCitationFromMessage(message) | ||
expect(citations).toEqual([{ filepath: 'path/to/file', chunk_id: '1' }]) | ||
}) | ||
|
||
it('returns an empty array when message role is "tool" and content is invalid JSON', () => { | ||
const message: ChatMessage = { | ||
role: 'tool', | ||
content: 'invalid JSON', | ||
id: '1', | ||
date: '' | ||
} | ||
const citations = parseCitationFromMessage(message) | ||
expect(citations).toEqual([]) | ||
}) | ||
|
||
it('returns an empty array when message role is not "tool"', () => { | ||
const message: ChatMessage = { | ||
role: 'user', | ||
content: JSON.stringify({ citations: [{ filepath: 'path/to/file', chunk_id: '1' }] }), | ||
id: '1', | ||
date: '' | ||
} | ||
const citations = parseCitationFromMessage(message) | ||
expect(citations).toEqual([]) | ||
}) | ||
|
||
it('handles null role messages correctly', () => { | ||
render(<ChatMessageContainer messages={[nullMessage]} onShowCitation={mockOnShowCitation} showLoadingMessage={false} />) | ||
expect(screen.queryByText('Null role message')).not.toBeInTheDocument() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
ResearchAssistant/App/frontend/src/components/CitationPanel/CitationPanel.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// CitationPanel.test.tsx | ||
import React from 'react' | ||
import { render, screen, fireEvent } from '@testing-library/react' | ||
import CitationPanel from './CitationPanel' | ||
import { type Citation } from '../../api' | ||
|
||
jest.mock('remark-gfm', () => jest.fn()) | ||
jest.mock('rehype-raw', () => jest.fn()) | ||
const mockIsCitationPanelOpen = jest.fn() | ||
const mockOnViewSource = jest.fn() | ||
const mockOnClickAddFavorite = jest.fn() | ||
|
||
const mockCitation = { | ||
id: '123', | ||
title: 'Sample Citation', | ||
content: 'This is a sample citation content.', | ||
url: 'https://example.com/sample-citation', | ||
filepath: 'path', | ||
metadata: '', | ||
chunk_id: '', | ||
reindex_id: '' | ||
} | ||
|
||
describe('CitationPanel', () => { | ||
beforeEach(() => { | ||
// Reset mocks before each test | ||
mockIsCitationPanelOpen.mockClear() | ||
mockOnViewSource.mockClear() | ||
}) | ||
|
||
test('renders CitationPanel with citation title and content', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={mockCitation} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={function (flag: boolean): void { | ||
throw new Error('Function not implemented.') | ||
} } onClickAddFavorite={function (): void { | ||
throw new Error('Function not implemented.') | ||
} } /> | ||
) | ||
|
||
// Check if title is rendered | ||
expect(screen.getByRole('heading', { name: /Sample Citation/i })).toBeInTheDocument() | ||
}) | ||
|
||
test('renders CitationPanel with citation title and content without url ', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={{ ...mockCitation, url: null, title: null }} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={mockIsCitationPanelOpen} onClickAddFavorite={mockOnClickAddFavorite} /> | ||
) | ||
|
||
expect(screen.getByRole('heading', { name: '' })).toBeInTheDocument() | ||
}) | ||
|
||
test('renders CitationPanel with citation title and content includes blob.core in url ', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={{ ...mockCitation, url: 'blob.core', title: null }} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={mockIsCitationPanelOpen} onClickAddFavorite={mockOnClickAddFavorite} /> | ||
) | ||
|
||
expect(screen.getByRole('heading', { name: '' })).toBeInTheDocument() | ||
}) | ||
|
||
test('renders CitationPanel with citation title and content title is null ', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={{ ...mockCitation, title: null }} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={mockIsCitationPanelOpen} onClickAddFavorite={mockOnClickAddFavorite} /> | ||
) | ||
|
||
expect(screen.getByRole('heading', { name: 'https://example.com/sample-citation' })).toBeInTheDocument() | ||
}) | ||
|
||
test('calls IsCitationPanelOpen with false when close button is clicked', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={mockCitation} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={mockIsCitationPanelOpen} onClickAddFavorite={mockOnClickAddFavorite}/> | ||
) | ||
const closeButton = screen.getByRole('button', { name: /Close citations panel/i }) | ||
fireEvent.click(closeButton) | ||
|
||
expect(mockIsCitationPanelOpen).toHaveBeenCalledWith(false) | ||
}) | ||
|
||
test('calls onViewSource with citation when title is clicked', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={mockCitation} | ||
setIsCitationPanelOpen={mockIsCitationPanelOpen} | ||
onViewSource={mockOnViewSource} onClickAddFavorite={mockOnClickAddFavorite}/> | ||
) | ||
|
||
const title = screen.getByRole('heading', { name: /Sample Citation/i }) | ||
fireEvent.click(title) | ||
|
||
expect(mockOnViewSource).toHaveBeenCalledWith(mockCitation) | ||
}) | ||
|
||
test('renders the title correctly and sets the correct title attribute for non-blob URL', () => { | ||
render( | ||
<CitationPanel | ||
activeCitation={mockCitation} setIsCitationPanelOpen={mockIsCitationPanelOpen} onViewSource={mockOnViewSource} onClickAddFavorite={mockOnClickAddFavorite} | ||
/> | ||
) | ||
|
||
const titleElement = screen.getByRole('heading', { name: /Sample Citation/i }) | ||
|
||
// Ensure the title is rendered | ||
expect(titleElement).toBeInTheDocument() | ||
|
||
// Ensure the title attribute is set to the URL since it's not a blob URL | ||
expect(titleElement).toHaveAttribute('title', 'https://example.com/sample-citation') | ||
|
||
// Trigger the onClick event and ensure onViewSource is called with the correct citation | ||
fireEvent.click(titleElement) | ||
expect(mockOnViewSource).toHaveBeenCalledWith(mockCitation) | ||
}) | ||
|
||
test('renders the title correctly and sets the title attribute to the citation title for blob URL', () => { | ||
const mockCitationWithBlobUrl: Citation = { | ||
...mockCitation, | ||
title: 'Test Citation with Blob URL', | ||
url: 'https://blob.core.example.com/resource', | ||
content: '' | ||
} | ||
render( | ||
<CitationPanel | ||
activeCitation={mockCitationWithBlobUrl} | ||
onViewSource={mockOnViewSource} setIsCitationPanelOpen={mockIsCitationPanelOpen} onClickAddFavorite={mockOnClickAddFavorite}/> | ||
) | ||
|
||
const titleElement = screen.getByRole('heading', { name: /Test Citation with Blob URL/i }) | ||
|
||
// Ensure the title is rendered | ||
expect(titleElement).toBeInTheDocument() | ||
|
||
// Ensure the title attribute is set to the citation title since the URL contains "blob.core" | ||
expect(titleElement).toHaveAttribute('title', 'Test Citation with Blob URL') | ||
|
||
// Trigger the onClick event and ensure onViewSource is called with the correct citation | ||
fireEvent.click(titleElement) | ||
expect(mockOnViewSource).toHaveBeenCalledWith(mockCitationWithBlobUrl) | ||
}) | ||
}) |