vitess.io/vitess@v0.16.2/web/vtadmin/src/components/placeholders/QueryErrorPlaceholder.test.tsx (about) 1 /** 2 * Copyright 2022 The Vitess Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 import { fireEvent, render, screen, within } from '@testing-library/react'; 17 import { renderHook } from '@testing-library/react-hooks'; 18 import { QueryClient, QueryClientProvider } from 'react-query'; 19 20 import { QueryErrorPlaceholder } from './QueryErrorPlaceholder'; 21 import * as httpAPI from '../../api/http'; 22 import { useClusters } from '../../hooks/api'; 23 24 jest.mock('../../api/http'); 25 26 const queryHelper = () => { 27 const queryClient = new QueryClient({ 28 defaultOptions: { queries: { retry: false } }, 29 }); 30 31 const wrapper: React.FC = ({ children }) => ( 32 <QueryClientProvider client={queryClient}>{children}</QueryClientProvider> 33 ); 34 35 return renderHook(() => useClusters(), { wrapper }); 36 }; 37 38 describe('QueryErrorPlaceholder', () => { 39 beforeEach(() => { 40 jest.clearAllMocks(); 41 }); 42 43 it('renders an error message', async () => { 44 const errorMessage = 'nope'; 45 (httpAPI.fetchClusters as any).mockRejectedValueOnce(new Error(errorMessage)); 46 47 const { result, waitFor } = queryHelper(); 48 await waitFor(() => result.current.isError); 49 50 render(<QueryErrorPlaceholder query={result.current} />); 51 52 const placeholder = await screen.findByRole('status'); 53 expect(placeholder).not.toBeNull(); 54 55 const button = within(placeholder).getByRole('button'); 56 expect(button).not.toBeNull(); 57 58 const message = within(placeholder).getByTestId('error-message'); 59 expect(message.textContent).toEqual(errorMessage); 60 }); 61 62 it('refetches', async () => { 63 (httpAPI.fetchClusters as any).mockRejectedValueOnce(new Error()).mockRejectedValueOnce(new Error()); 64 65 expect((httpAPI.fetchClusters as any).mock.calls.length).toEqual(0); 66 67 const { result, waitFor } = queryHelper(); 68 await waitFor(() => result.current.isError); 69 70 render(<QueryErrorPlaceholder query={result.current} />); 71 72 expect((httpAPI.fetchClusters as any).mock.calls.length).toEqual(1); 73 74 let placeholder = await screen.findByRole('status'); 75 let button = within(placeholder).getByRole('button'); 76 expect(button).not.toBeNull(); 77 expect(button.textContent).toEqual('Try again'); 78 79 fireEvent.click(button); 80 81 await waitFor(() => result.current.isFetching); 82 expect((httpAPI.fetchClusters as any).mock.calls.length).toEqual(2); 83 }); 84 85 it('does not render when no error', async () => { 86 (httpAPI.fetchClusters as any).mockResolvedValueOnce({ clusters: [] }); 87 const { result, waitFor } = queryHelper(); 88 89 render(<QueryErrorPlaceholder query={result.current} />); 90 91 await waitFor(() => result.current.isSuccess); 92 93 const placeholder = screen.queryByRole('status'); 94 expect(placeholder).toBeNull(); 95 }); 96 97 it('does not render when loading', async () => { 98 (httpAPI.fetchClusters as any).mockRejectedValueOnce(new Error()); 99 const { result, waitFor } = queryHelper(); 100 101 const { rerender } = render(<QueryErrorPlaceholder query={result.current} />); 102 await waitFor(() => result.current.isLoading); 103 104 let placeholder = screen.queryByRole('status'); 105 expect(placeholder).toBeNull(); 106 107 await waitFor(() => !result.current.isLoading); 108 109 rerender(<QueryErrorPlaceholder query={result.current} />); 110 placeholder = screen.queryByRole('status'); 111 expect(placeholder).not.toBeNull(); 112 }); 113 });