github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/App/index.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 { App } from './index'; 17 import { render } from '@testing-library/react'; 18 import { Spy } from 'spy4js'; 19 import { AzureAuthSub } from '../utils/AzureAuthProvider'; 20 import { Observable } from 'rxjs'; 21 import { PanicOverview, UpdateOverview } from '../utils/store'; 22 import { MemoryRouter } from 'react-router-dom'; 23 24 Spy.mockModule('../components/NavigationBar/NavigationBar', 'NavigationBar'); 25 Spy.mockModule('../components/TopAppBar/TopAppBar', 'TopAppBar'); 26 Spy.mockModule('../components/ReleaseDialog/ReleaseDialog', 'ReleaseDialog'); 27 Spy.mockModule('./PageRoutes', 'PageRoutes'); 28 Spy.mockModule('../components/snackbar/snackbar', 'Snackbar'); 29 Spy.mockModule('../utils/AzureAuthProvider', 'AzureAuthProvider'); 30 31 const mock_GetConfig = Spy('Config'); 32 const mock_StreamOverview = Spy('Overview'); 33 const mock_StreamStatus = Spy('Status'); 34 35 jest.mock('../utils/GrpcApi', () => ({ 36 // useApi is a constant, so we mock it by mocking the module and spying on a getter method instead 37 get useApi() { 38 return { 39 configService: () => ({ 40 GetConfig: () => mock_GetConfig(), 41 }), 42 overviewService: () => ({ 43 StreamOverview: () => mock_StreamOverview(), 44 }), 45 rolloutService: () => ({ 46 StreamStatus: () => mock_StreamStatus(), 47 }), 48 }; 49 }, 50 })); 51 52 const getNode = (): JSX.Element => ( 53 <MemoryRouter> 54 <App /> 55 </MemoryRouter> 56 ); 57 const getWrapper = () => render(getNode()); 58 59 describe('App uses the API', () => { 60 beforeAll(() => { 61 jest.useFakeTimers(); 62 }); 63 64 afterAll(() => { 65 jest.runOnlyPendingTimers(); 66 jest.useRealTimers(); 67 }); 68 69 it('subscribes to StreamOverview', () => { 70 // given 71 mock_StreamOverview.returns( 72 new Observable((observer) => { 73 observer.next({ applications: 'test-application' }); 74 }) 75 ); 76 mock_GetConfig.returns(Promise.resolve('test-config')); 77 AzureAuthSub.set({ authReady: true }); 78 mock_StreamStatus.returns( 79 new Observable((observer) => { 80 observer.next({}); 81 }) 82 ); 83 84 // when 85 getWrapper(); 86 87 // then 88 expect(UpdateOverview.get().applications).toBe('test-application'); 89 }); 90 91 it('retries subscription to StreamOverview on Error', () => { 92 // given 93 let subscriptionCount = 0; 94 mock_StreamOverview.returns( 95 new Observable((observer) => { 96 observer.error('error'); 97 subscriptionCount++; 98 }) 99 ); 100 mock_StreamStatus.returns( 101 new Observable((observer) => { 102 observer.next({}); 103 }) 104 ); 105 mock_GetConfig.returns(Promise.resolve('test-config')); 106 AzureAuthSub.set({ authReady: true }); 107 108 // when 109 getWrapper(); 110 111 // when 112 jest.advanceTimersByTime(5000); 113 // then - 3 retries in 5s 114 expect(subscriptionCount).toBe(3); 115 // when 116 jest.advanceTimersByTime(5000); 117 // then - 4 retries in 10s 118 expect(subscriptionCount).toBe(4); 119 // when 120 jest.advanceTimersByTime(50000); 121 // then - 6 retries in 60s 122 expect(subscriptionCount).toBe(6); 123 124 // when - max attempts reached 125 jest.advanceTimersByTime(10000000); 126 // then - first attempt + 8 retries = 9 127 expect(subscriptionCount).toBe(9); 128 expect(PanicOverview.get().error).toContain('error in streamoverview'); 129 }); 130 });