github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/components/ProductVersion/ProductVersion.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, render, screen } from '@testing-library/react'; 17 import { MemoryRouter } from 'react-router-dom'; 18 import { Environment, EnvironmentGroup, Priority, ProductSummary, TagData } from '../../../api/api'; 19 import { ProductVersion, TableFiltered } from './ProductVersion'; 20 import { Spy } from 'spy4js'; 21 22 const mock_UseEnvGroups = Spy('envGroup'); 23 const mock_UseTags = Spy('Overview'); 24 25 jest.mock('../../utils/store', () => ({ 26 refreshTags() { 27 return {}; 28 }, 29 useEnvironmentGroups() { 30 return mock_UseEnvGroups(); 31 }, 32 useTags() { 33 return mock_UseTags(); 34 }, 35 useEnvironments() { 36 return []; 37 }, 38 showSnackbarError() {}, 39 })); 40 41 jest.mock('../../utils/Links', () => ({ 42 DisplayManifestLink() { 43 return <></>; 44 }, 45 DisplaySourceLink() { 46 return <></>; 47 }, 48 })); 49 50 const mockGetProductSummary = jest.fn(); 51 52 jest.mock('../../utils/GrpcApi', () => ({ 53 get useApi() { 54 return { 55 gitService: () => ({ 56 GetProductSummary: () => mockGetProductSummary(), 57 }), 58 }; 59 }, 60 })); 61 const sampleEnvsA: Environment[] = [ 62 { 63 name: 'tester', 64 locks: {}, 65 applications: {}, 66 distanceToUpstream: 0, 67 priority: Priority.UPSTREAM, 68 }, 69 ]; 70 71 describe('Product Version Data', () => { 72 type TestData = { 73 name: string; 74 environmentName: string; 75 environmentGroups: EnvironmentGroup[]; 76 expectedDropDown: string; 77 tags: TagData[]; 78 productSummary: ProductSummary[]; 79 }; 80 const data: TestData[] = [ 81 { 82 name: 'No tags to Display', 83 environmentName: 'tester', 84 tags: [], 85 expectedDropDown: '', 86 productSummary: [], 87 environmentGroups: [ 88 { 89 environments: [sampleEnvsA[0]], 90 distanceToUpstream: 1, 91 environmentGroupName: 'g1', 92 priority: Priority.UNRECOGNIZED, 93 }, 94 ], 95 }, 96 { 97 name: 'tags to Display with summary', 98 environmentName: 'tester', 99 tags: [{ commitId: '123', tag: 'refs/tags/dummyTag' }], 100 expectedDropDown: 'dummyTag', 101 productSummary: [ 102 { 103 app: 'testing-app', 104 version: '4', 105 commitId: '123', 106 displayVersion: 'v1.2.3', 107 environment: 'dev', 108 team: 'sre-team', 109 }, 110 ], 111 environmentGroups: [ 112 { 113 environments: [sampleEnvsA[0]], 114 distanceToUpstream: 1, 115 environmentGroupName: 'g1', 116 priority: Priority.UNRECOGNIZED, 117 }, 118 ], 119 }, 120 { 121 name: 'table to be displayed with multiple rows of data', 122 environmentName: 'tester', 123 tags: [ 124 { commitId: '123', tag: 'refs/tags/dummyTag' }, 125 { commitId: '859', tag: 'refs/tags/dummyTag2' }, 126 ], 127 expectedDropDown: 'dummyTag', 128 productSummary: [ 129 { 130 app: 'testing-app', 131 version: '4', 132 commitId: '123', 133 displayVersion: 'v1.2.3', 134 environment: 'dev', 135 team: 'sre-team', 136 }, 137 { app: 'tester', version: '10', commitId: '4565', displayVersion: '', environment: 'dev', team: '' }, 138 ], 139 environmentGroups: [ 140 { 141 environments: [sampleEnvsA[0]], 142 distanceToUpstream: 1, 143 environmentGroupName: 'g1', 144 priority: Priority.UNRECOGNIZED, 145 }, 146 ], 147 }, 148 ]; 149 150 describe.each(data)(`Displays Product Version Page`, (testCase) => { 151 // given 152 it(testCase.name, async () => { 153 // replicate api calls 154 mock_UseEnvGroups.returns(testCase.environmentGroups); 155 mock_UseTags.returns({ response: { tagData: testCase.tags }, tagsReady: true }); 156 mockGetProductSummary.mockResolvedValue({ productSummary: testCase.productSummary }); 157 render( 158 <MemoryRouter> 159 <ProductVersion /> 160 </MemoryRouter> 161 ); 162 await act(global.nextTick); 163 expect(document.body).toMatchSnapshot(); 164 if (testCase.expectedDropDown !== '') { 165 expect(document.querySelector('.drop_down')?.textContent).toContain(testCase.expectedDropDown); 166 expect(document.querySelector('.env_drop_down')?.textContent).toContain(testCase.environmentName); 167 } 168 169 if (testCase.productSummary.length > 0) { 170 expect(document.querySelector('.table')?.textContent).toContain('App Name'); 171 } else { 172 expect(document.querySelector('.page_description')?.textContent).toContain( 173 'This page shows the version' 174 ); 175 } 176 const releaseTrainButton = screen.queryByText('Run Release Train'); 177 if (testCase.tags.length > 0) { 178 expect(releaseTrainButton).toBeInTheDocument(); 179 } 180 }); 181 }); 182 }); 183 184 describe('Test table filtering', () => { 185 type TestData = { 186 name: string; 187 productSummary: ProductSummary[]; 188 teams: string[]; 189 expectedApps: string[]; 190 filteredApps: string[]; 191 }; 192 const data: TestData[] = [ 193 { 194 name: 'no rows to display', 195 productSummary: [], 196 teams: [], 197 expectedApps: [], 198 filteredApps: [], 199 }, 200 { 201 name: 'no teams to filter out', 202 productSummary: [ 203 { 204 app: 'testing-app', 205 version: '4', 206 commitId: '123', 207 displayVersion: 'v1.2.3', 208 environment: 'dev', 209 team: 'sre-team', 210 }, 211 ], 212 teams: [], 213 expectedApps: ['testing-app'], 214 filteredApps: [], 215 }, 216 { 217 name: 'a team to filter out', 218 productSummary: [ 219 { 220 app: 'testing-app', 221 version: '4', 222 commitId: '123', 223 displayVersion: 'v1.2.3', 224 environment: 'dev', 225 team: 'sre-team', 226 }, 227 { 228 app: 'testing-app2', 229 version: '4', 230 commitId: '123', 231 displayVersion: 'v1.2.3', 232 environment: 'dev', 233 team: 'others', 234 }, 235 ], 236 teams: ['sre-team'], 237 expectedApps: ['testing-app'], 238 filteredApps: ['testing-app2'], 239 }, 240 { 241 name: 'no teams to filter out', 242 productSummary: [ 243 { 244 app: 'testing-app', 245 version: '4', 246 commitId: '123', 247 displayVersion: 'v1.2.3', 248 environment: 'dev', 249 team: 'sre-team', 250 }, 251 { 252 app: 'testing-app 2', 253 version: '4', 254 commitId: '123', 255 displayVersion: 'v1.2.3', 256 environment: 'dev', 257 team: 'others', 258 }, 259 { 260 app: 'testing-app 3', 261 version: '4', 262 commitId: '123', 263 displayVersion: 'v1.2.3', 264 environment: 'dev', 265 team: 'others', 266 }, 267 ], 268 teams: ['sre-team', 'others'], 269 expectedApps: ['testing-app', 'testing-app 2', 'testing-app 3'], 270 filteredApps: [], 271 }, 272 { 273 name: 'bigger example', 274 productSummary: [ 275 { 276 app: 'testing-app', 277 version: '4', 278 commitId: '123', 279 displayVersion: 'v1.2.3', 280 environment: 'dev', 281 team: 'sre-team', 282 }, 283 { 284 app: 'testing-app 2', 285 version: '4', 286 commitId: '123', 287 displayVersion: 'v1.2.3', 288 environment: 'dev', 289 team: 'others', 290 }, 291 { 292 app: 'testing-app 3', 293 version: '4', 294 commitId: '123', 295 displayVersion: 'v1.2.3', 296 environment: 'dev', 297 team: 'others', 298 }, 299 { 300 app: 'testing-app 4', 301 version: '4', 302 commitId: '123', 303 displayVersion: 'v1.2.3', 304 environment: 'dev', 305 team: 'another', 306 }, 307 { 308 app: 'testing-app 5', 309 version: '4', 310 commitId: '123', 311 displayVersion: 'v1.2.3', 312 environment: 'dev', 313 team: 'last team', 314 }, 315 ], 316 teams: ['sre-team', 'others'], 317 expectedApps: ['testing-app', 'testing-app 2', 'testing-app 3'], 318 filteredApps: ['testing-app 4', 'testing-app 5'], 319 }, 320 ]; 321 describe.each(data)(`Displays Product Version Table`, (testCase) => { 322 it(testCase.name, () => { 323 render(<TableFiltered productSummary={testCase.productSummary} teams={testCase.teams} />); 324 expect(document.querySelector('.table')?.textContent).toContain('App Name'); 325 for (let i = 0; i < testCase.expectedApps.length; i++) { 326 expect(document.querySelector('.table')?.textContent).toContain(testCase.expectedApps[i]); 327 } 328 for (let i = 0; i < testCase.filteredApps.length; i++) { 329 expect(screen.queryByText(testCase.filteredApps[i])).not.toBeInTheDocument(); 330 } 331 }); 332 }); 333 });