github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/components/EnvironmentConfigDialog/EnvironmentConfigDialog.test.tsx (about) 1 /*This file is part of kuberpult. 2 3 Kuberpult is free software: you can redistribute it and/or modify 4 it under the terms of the Expat(MIT) License as published by 5 the Free Software Foundation. 6 7 Kuberpult is distributed in the hope that it will be useful, 8 but WITHOUT ANY WARRANTY; without even the implied warranty of 9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 MIT License for more details. 11 12 You should have received a copy of the MIT License 13 along with kuberpult. If not, see <https://directory.fsf.org/wiki/License:Expat>. 14 15 Copyright 2023 freiheit.com*/ 16 import { act, fireEvent, render } from '@testing-library/react'; 17 import { MemoryRouter } from 'react-router-dom'; 18 import { 19 EnvironmentConfigDialog, 20 environmentConfigDialogClass, 21 environmentConfigDialogCloseClass, 22 environmentConfigDialogConfigClass, 23 } from './EnvironmentConfigDialog'; 24 25 jest.mock('../../../api/api').mock('../../utils/GrpcApi'); 26 27 const configContent = 'config content'; 28 const configLoadError = new Error('error loading config'); 29 const mockGetEnvironmentConfigPretty = jest.fn(); 30 const mockShowSnackbarError = jest.fn(); 31 jest.mock('../../utils/store', () => ({ 32 GetEnvironmentConfigPretty: () => mockGetEnvironmentConfigPretty(), 33 showSnackbarError: () => mockShowSnackbarError(), 34 })); 35 36 const openEnvironmentDialog = 'open environment'; 37 const closedEnvironmentDialog = 'closed environment'; 38 const mockGetOpenEnvironmentConfigDialog = jest.fn(); 39 const mockSetOpenEnvironmentConfigDialog = jest.fn(); 40 jest.mock('../../utils/Links', () => ({ 41 getOpenEnvironmentConfigDialog: () => mockGetOpenEnvironmentConfigDialog(), 42 setOpenEnvironmentConfigDialog: () => mockSetOpenEnvironmentConfigDialog(), 43 })); 44 45 describe('EnvironmentConfigDialog', () => { 46 const getNode = (environmentName: string) => ( 47 <MemoryRouter> 48 <EnvironmentConfigDialog environmentName={environmentName} /> 49 </MemoryRouter> 50 ); 51 52 type TestData = { 53 name: string; 54 environmentName: string; 55 config: () => Promise<string>; 56 expectedNumDialogs: number; 57 expectedNumConfigs: number; 58 expectedConfig: string; 59 expectedNumSpinners: number; 60 expectedSnackbarErrorCalls: number; 61 expectedNumCloseButtons: number; 62 }; 63 64 const data: TestData[] = [ 65 { 66 name: 'closed environment config', 67 environmentName: closedEnvironmentDialog, 68 config: () => Promise.resolve(configContent), 69 expectedNumDialogs: 0, 70 expectedNumConfigs: 0, 71 expectedConfig: configContent, 72 expectedNumSpinners: 0, 73 expectedSnackbarErrorCalls: 0, 74 expectedNumCloseButtons: 0, 75 }, 76 { 77 name: 'open environment config', 78 environmentName: openEnvironmentDialog, 79 config: () => Promise.resolve(configContent), 80 expectedNumDialogs: 1, 81 expectedNumConfigs: 1, 82 expectedConfig: configContent, 83 expectedNumSpinners: 0, 84 expectedSnackbarErrorCalls: 0, 85 expectedNumCloseButtons: 1, 86 }, 87 { 88 name: 'loading environment config', 89 environmentName: openEnvironmentDialog, 90 config: () => new Promise(() => {}), // never resolves 91 expectedNumDialogs: 1, 92 expectedNumConfigs: 0, 93 expectedConfig: configContent, 94 expectedNumSpinners: 1, 95 expectedSnackbarErrorCalls: 0, 96 expectedNumCloseButtons: 1, 97 }, 98 { 99 name: 'failed loading environment config', 100 environmentName: openEnvironmentDialog, 101 config: () => Promise.reject(configLoadError), 102 expectedNumDialogs: 1, 103 expectedNumConfigs: 1, 104 expectedConfig: '', 105 expectedNumSpinners: 0, 106 expectedSnackbarErrorCalls: 1, 107 expectedNumCloseButtons: 1, 108 }, 109 ]; 110 111 it.each(data)(`Renders and tests an environment config dialog: %s`, async (testcase) => { 112 // when 113 mockGetEnvironmentConfigPretty.mockImplementation(testcase.config); 114 mockGetOpenEnvironmentConfigDialog.mockImplementation(() => openEnvironmentDialog); 115 const element = getNode(testcase.environmentName); 116 const container = render(element).container; 117 await act(global.nextTick); 118 119 // then 120 expect(container.getElementsByClassName(environmentConfigDialogClass)).toHaveLength( 121 testcase.expectedNumDialogs 122 ); 123 124 const configs = container.getElementsByClassName(environmentConfigDialogConfigClass); 125 expect(configs).toHaveLength(testcase.expectedNumConfigs); 126 for (const config of configs) { 127 expect(config.innerHTML).toContain(testcase.expectedConfig); 128 } 129 130 const spinners = container.getElementsByClassName('spinner-message'); 131 expect(spinners).toHaveLength(testcase.expectedNumSpinners); 132 expect(mockShowSnackbarError).toHaveBeenCalledTimes(testcase.expectedSnackbarErrorCalls); 133 134 const closers = container.getElementsByClassName(environmentConfigDialogCloseClass); 135 expect(closers).toHaveLength(testcase.expectedNumCloseButtons); 136 expect(mockSetOpenEnvironmentConfigDialog).toHaveBeenCalledTimes(0); 137 await act(async () => { 138 for (const closer of closers) { 139 fireEvent.click(closer); 140 } 141 }); 142 expect(mockSetOpenEnvironmentConfigDialog).toHaveBeenCalledTimes(testcase.expectedNumCloseButtons); 143 }); 144 });