diff --git a/public/chat_flyout.test.tsx b/public/chat_flyout.test.tsx new file mode 100644 index 00000000..85b00737 --- /dev/null +++ b/public/chat_flyout.test.tsx @@ -0,0 +1,149 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; + +import { ChatFlyout } from './chat_flyout'; +import * as chatContextExports from './contexts/chat_context'; +import { TAB_ID } from './utils/constants'; + +jest.mock('./tabs/chat/chat_page', () => ({ + ChatPage: () =>
, +})); + +jest.mock('./tabs/chat_window_header', () => ({ + ChatWindowHeader: () =>
, +})); + +jest.mock('./tabs/history/chat_history_page', () => ({ + ChatHistoryPage: () =>
, +})); + +jest.mock('./components/agent_framework_traces_flyout_body', () => ({ + AgentFrameworkTracesFlyoutBody: () => ( +
+ ), +})); + +describe('', () => { + beforeEach(() => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + selectedTabId: TAB_ID.CHAT, + traceId: 'chat_trace_id_mock', + }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should only display chat panel when current tab is TAB_ID.CHAT under non-fullscreen mode', () => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + selectedTabId: TAB_ID.CHAT, + traceId: 'chat_trace_id_mock', + }); + + render( + + ); + expect(screen.getByLabelText('chat panel').classList).not.toContain('llm-chat-hidden'); + expect(screen.getByLabelText('history panel').classList).toContain('llm-chat-hidden'); + }); + + it('should only display history panel when current tab is TAB_ID.HISTORY under non-fullscreen mode', () => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + selectedTabId: TAB_ID.HISTORY, + traceId: 'chat_trace_id_mock', + }); + + render( + + ); + expect(screen.getByLabelText('chat panel').classList).toContain('llm-chat-hidden'); + expect(screen.getByLabelText('history panel').classList).not.toContain('llm-chat-hidden'); + }); + + it('should display chat history page', () => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + selectedTabId: TAB_ID.HISTORY, + traceId: 'chat_trace_id_mock', + }); + + render( + + ); + + expect(screen.queryByLabelText('mock chat history page')).toBeInTheDocument(); + expect( + screen.queryByLabelText('mock agent framework traces flyout body') + ).not.toBeInTheDocument(); + }); + + it('should display traces page', () => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + selectedTabId: TAB_ID.TRACE, + traceId: 'chat_trace_id_mock', + }); + + render( + + ); + + expect(screen.queryByLabelText('mock chat history page')).not.toBeInTheDocument(); + expect(screen.queryByLabelText('mock agent framework traces flyout body')).toBeInTheDocument(); + }); + + it('should always display chat panel when in fullscreen mode', () => { + jest.spyOn(chatContextExports, 'useChatContext').mockReturnValue({ + setFlyoutVisible: jest.fn(), + // current tab is NOT chat + selectedTabId: TAB_ID.HISTORY, + traceId: 'chat_trace_id_mock', + }); + + render( + + ); + + expect(screen.getByLabelText('chat panel').classList).not.toContain('llm-chat-hidden'); + expect(screen.getByLabelText('history panel').classList).not.toContain('llm-chat-hidden'); + }); +}); diff --git a/public/chat_flyout.tsx b/public/chat_flyout.tsx index 42d6e32c..d4c2e234 100644 --- a/public/chat_flyout.tsx +++ b/public/chat_flyout.tsx @@ -5,7 +5,7 @@ import { EuiFlyout, EuiFlyoutHeader, EuiResizableContainer } from '@elastic/eui'; import cs from 'classnames'; -import React from 'react'; +import React, { useRef } from 'react'; import { useChatContext } from './contexts/chat_context'; import { ChatPage } from './tabs/chat/chat_page'; import { ChatWindowHeader } from './tabs/chat_window_header'; @@ -13,8 +13,6 @@ import { ChatHistoryPage } from './tabs/history/chat_history_page'; import { AgentFrameworkTracesFlyoutBody } from './components/agent_framework_traces_flyout_body'; import { TAB_ID } from './utils/constants'; -let chatHistoryPageLoaded = false; - interface ChatFlyoutProps { flyoutVisible: boolean; overrideComponent: React.ReactNode | null; @@ -25,6 +23,7 @@ interface ChatFlyoutProps { export const ChatFlyout: React.FC = (props) => { const chatContext = useChatContext(); + const chatHistoryPageLoadedRef = useRef(false); let chatPageVisible = false; let chatHistoryPageVisible = false; @@ -54,7 +53,8 @@ export const ChatFlyout: React.FC = (props) => { chatPageVisible = true; } - if (!chatHistoryPageLoaded && chatHistoryPageVisible) chatHistoryPageLoaded = true; + if (!chatHistoryPageLoadedRef.current && chatHistoryPageVisible) + chatHistoryPageLoadedRef.current = true; const resizable = props.flyoutFullScreen && (chatHistoryPageVisible || chatTraceVisible); const getLeftPanelSize = () => { @@ -107,6 +107,7 @@ export const ChatFlyout: React.FC = (props) => { {(Panel, Resizer) => ( <> = (props) => { <> {resizable && } = (props) => { initialSize={resizable ? 30 : undefined} paddingSize="none" > - {chatHistoryPageLoaded && ( + {chatHistoryPageLoadedRef.current && ( ', () => { + beforeEach(() => { + jest.spyOn(coreContextExports, 'useCore').mockReturnValue({ + services: { + uiSettings: { + get: jest.fn().mockReturnValue('MMM D, YYYY @ HH:mm:ss.SSS'), + }, + startDeps: { + dashboard: { + DashboardContainerByValueRenderer: () =>
, + }, + }, + }, + }); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it('should display visualization of last 15 minutes by default', () => { + render( + + ); + expect(screen.queryByText('Last 15 minutes')).toBeInTheDocument(); + }); +});