/* * Copyright OpenSearch Contributors * SPDX-License-Identifier: Apache-2.0 */ import React from 'react'; import userEvent from '@testing-library/user-event'; import { act, render, screen, waitFor } from '../../../../test/test_utils'; import { PreviewPanel } from '../'; import { APIProvider } from '../../../apis/api_provider'; const MODEL = { id: 'id1', name: 'test', planningWorkerNodes: ['node-1', 'node-2', 'node-3'], source: 'External', }; function setup({ model = MODEL, onClose = jest.fn() }) { const user = userEvent.setup({}); render(); return { user }; } describe('', () => { afterEach(() => { jest.clearAllMocks(); }); it('should render id, name and source in panel', () => { setup({}); expect(screen.getByText('test')).toBeInTheDocument(); expect(screen.getByText('id1')).toBeInTheDocument(); expect(screen.getByText('External')).toBeInTheDocument(); }); it('should call onClose when close panel', async () => { const onClose = jest.fn(); const { user } = setup({ onClose }); expect(onClose).not.toHaveBeenCalled(); await user.click(screen.getByTestId('euiFlyoutCloseButton')); expect(onClose).toHaveBeenCalled(); }); it('should render loading when not responding and render partially state when responding', async () => { const request = jest.spyOn(APIProvider.getAPI('profile'), 'getModel'); const mockResult = { id: 'model-1-id', target_worker_nodes: ['node-1', 'node-2', 'node-3'], worker_nodes: ['node-1', 'node-2'], not_worker_nodes: ['node-3'], }; request.mockResolvedValue(mockResult); setup({}); expect(screen.getByTestId('preview-panel-color-loading-text')).toBeInTheDocument(); await waitFor(() => expect(screen.getByText('Partially responding on 2 of 3 nodes')).toBeInTheDocument() ); }); it('should render not responding when no model profile API response', async () => { jest.spyOn(APIProvider.getAPI('profile'), 'getModel').mockResolvedValueOnce({}); setup({}); await waitFor(() => expect(screen.getByText('Not responding on 3 of 3 nodes')).toBeInTheDocument() ); }); it('should render not responding when model profile API return no worker nodes', async () => { jest.spyOn(APIProvider.getAPI('profile'), 'getModel').mockResolvedValueOnce({ id: 'model-1-id', target_worker_nodes: ['node-1', 'node-2', 'node-3'], worker_nodes: [], not_worker_nodes: ['node-1', 'node-2', 'node-3'], }); setup({}); await waitFor(() => expect(screen.getByText('Not responding on 3 of 3 nodes')).toBeInTheDocument() ); }); it('should render responding when model profile API return all worker node responding', async () => { jest.spyOn(APIProvider.getAPI('profile'), 'getModel').mockResolvedValueOnce({ id: 'model-1-id', target_worker_nodes: ['node-1', 'node-2', 'node-3'], worker_nodes: ['node-1', 'node-2', 'node-3'], not_worker_nodes: [], }); setup({}); await waitFor(() => expect(screen.getByText('Responding on 3 of 3 nodes')).toBeInTheDocument()); }); it('should NOT render nodes during model profile API loading', async () => { jest.useFakeTimers(); jest.spyOn(APIProvider.getAPI('profile'), 'getModel').mockReturnValue( new Promise((resolve) => { setTimeout(() => { resolve({ id: 'model-1-id', target_worker_nodes: ['node-1', 'node-2', 'node-3'], worker_nodes: ['node-1'], not_worker_nodes: ['node-2', 'node-3'], }); }, 3000); }) ); setup({}); expect(screen.queryByText('node-1')).not.toBeInTheDocument(); expect(screen.queryByText('node-2')).not.toBeInTheDocument(); expect(screen.queryByText('node-3')).not.toBeInTheDocument(); jest.advanceTimersByTime(3000); jest.useRealTimers(); waitFor(() => { expect(screen.getByText('node-1')).toBeInTheDocument(); expect(screen.getByText('node-2')).toBeInTheDocument(); expect(screen.getByText('node-3')).toBeInTheDocument(); }); }); });