github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/Pages/Home/Home.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 { render, renderHook } from '@testing-library/react';
    17  import { Home } from './Home';
    18  import { searchCustomFilter, UpdateOverview, useApplicationsFilteredAndSorted, useTeamNames } from '../../utils/store';
    19  import { Spy } from 'spy4js';
    20  import { MemoryRouter } from 'react-router-dom';
    21  import { Application, UndeploySummary } from '../../../api/api';
    22  import { fakeLoadEverything } from '../../../setupTests';
    23  
    24  const mock_ServiceLane = Spy.mockReactComponents('../../components/ServiceLane/ServiceLane', 'ServiceLane');
    25  
    26  describe('App', () => {
    27      const getNode = (): JSX.Element | any => (
    28          <MemoryRouter>
    29              <Home />
    30          </MemoryRouter>
    31      );
    32      const getWrapper = () => render(getNode());
    33      it('Renders full app', () => {
    34          const buildTestApp = (suffix: string): Application => ({
    35              name: `test${suffix}`,
    36              releases: [],
    37              sourceRepoUrl: `http://test${suffix}.com`,
    38              team: `team${suffix}`,
    39              undeploySummary: UndeploySummary.NORMAL,
    40              warnings: [],
    41          });
    42          // when
    43          const sampleApps = {
    44              app1: buildTestApp('1'),
    45              app2: buildTestApp('2'),
    46              app3: buildTestApp('3'),
    47          };
    48          UpdateOverview.set({
    49              applications: sampleApps,
    50          });
    51          fakeLoadEverything(true);
    52          getWrapper();
    53  
    54          // then apps are sorted and Service Lane is called
    55          expect(mock_ServiceLane.ServiceLane.getCallArgument(0, 0)).toStrictEqual({ application: sampleApps.app1 });
    56          expect(mock_ServiceLane.ServiceLane.getCallArgument(1, 0)).toStrictEqual({ application: sampleApps.app2 });
    57          expect(mock_ServiceLane.ServiceLane.getCallArgument(2, 0)).toStrictEqual({ application: sampleApps.app3 });
    58      });
    59      it('Renders Spinner', () => {
    60          // given
    61          UpdateOverview.set({
    62              loaded: false,
    63          });
    64          // when
    65          const { container } = getWrapper();
    66          // then
    67          expect(container.getElementsByClassName('spinner')).toHaveLength(1);
    68      });
    69  });
    70  
    71  describe('Get teams from application list (useTeamNames)', () => {
    72      interface dataT {
    73          name: string;
    74          applications: { [key: string]: Application };
    75          expectedTeams: string[];
    76      }
    77  
    78      const data: dataT[] = [
    79          {
    80              name: 'right amount of teams - 4 sorted results',
    81              applications: {
    82                  foo: {
    83                      name: 'foo',
    84                      releases: [],
    85                      sourceRepoUrl: 'http://foo.com',
    86                      team: 'dummy',
    87                      undeploySummary: UndeploySummary.NORMAL,
    88                      warnings: [],
    89                  },
    90                  bar: {
    91                      name: 'bar',
    92                      releases: [],
    93                      sourceRepoUrl: 'http://bar.com',
    94                      team: 'test',
    95                      undeploySummary: UndeploySummary.NORMAL,
    96                      warnings: [],
    97                  },
    98                  example: {
    99                      name: 'example',
   100                      releases: [],
   101                      sourceRepoUrl: 'http://example.com',
   102                      team: 'test2',
   103                      undeploySummary: UndeploySummary.NORMAL,
   104                      warnings: [],
   105                  },
   106                  team: {
   107                      name: 'team',
   108                      releases: [],
   109                      sourceRepoUrl: 'http://team.com',
   110                      team: 'foo',
   111                      undeploySummary: UndeploySummary.NORMAL,
   112                      warnings: [],
   113                  },
   114              },
   115              expectedTeams: ['dummy', 'foo', 'test', 'test2'],
   116          },
   117          {
   118              name: "doesn't collect duplicate team names - 2 sorted results",
   119              applications: {
   120                  foo: {
   121                      name: 'foo',
   122                      releases: [],
   123                      sourceRepoUrl: 'http://foo.com',
   124                      team: 'dummy',
   125                      undeploySummary: UndeploySummary.NORMAL,
   126                      warnings: [],
   127                  },
   128                  bar: {
   129                      name: 'bar',
   130                      releases: [],
   131                      sourceRepoUrl: 'http://bar.com',
   132                      team: 'dummy',
   133                      undeploySummary: UndeploySummary.NORMAL,
   134                      warnings: [],
   135                  },
   136                  team: {
   137                      name: 'team',
   138                      releases: [],
   139                      sourceRepoUrl: 'http://team.com',
   140                      team: 'foo',
   141                      undeploySummary: UndeploySummary.NORMAL,
   142                      warnings: [],
   143                  },
   144              },
   145              expectedTeams: ['dummy', 'foo'],
   146          },
   147          {
   148              name: "doesn't collect empty team names and adds <No Team> option to dropdown - 2 sorted results",
   149              applications: {
   150                  foo: {
   151                      name: 'foo',
   152                      releases: [],
   153                      sourceRepoUrl: 'http://foo.com',
   154                      team: '',
   155                      undeploySummary: UndeploySummary.NORMAL,
   156                      warnings: [],
   157                  },
   158                  bar: {
   159                      name: 'bar',
   160                      releases: [],
   161                      sourceRepoUrl: 'http://bar.com',
   162                      team: 'test',
   163                      undeploySummary: UndeploySummary.NORMAL,
   164                      warnings: [],
   165                  },
   166                  example: {
   167                      name: 'example',
   168                      releases: [],
   169                      sourceRepoUrl: 'http://example.com',
   170                      team: '',
   171                      undeploySummary: UndeploySummary.NORMAL,
   172                      warnings: [],
   173                  },
   174                  team: {
   175                      name: 'team',
   176                      releases: [],
   177                      sourceRepoUrl: 'http://team.com',
   178                      team: 'foo',
   179                      undeploySummary: UndeploySummary.NORMAL,
   180                      warnings: [],
   181                  },
   182              },
   183              expectedTeams: ['<No Team>', 'foo', 'test'],
   184          },
   185      ];
   186  
   187      describe.each(data)(`Renders an Application Card`, (testcase) => {
   188          it(testcase.name, () => {
   189              // given
   190              UpdateOverview.set({ applications: testcase.applications });
   191              // when
   192              const teamNames = renderHook(() => useTeamNames()).result.current;
   193              expect(teamNames).toStrictEqual(testcase.expectedTeams);
   194          });
   195      });
   196  });
   197  
   198  describe('Get applications from selected teams (useApplicationsFilteredAndSorted)', () => {
   199      interface dataT {
   200          name: string;
   201          selectedTeams: string[];
   202          applications: { [key: string]: Application };
   203          expectedNumOfTeams: number;
   204      }
   205  
   206      const data: dataT[] = [
   207          {
   208              name: 'gets filtered apps by team - 2 results',
   209              selectedTeams: ['dummy', 'foo'],
   210              applications: {
   211                  foo: {
   212                      name: 'foo',
   213                      releases: [],
   214                      sourceRepoUrl: 'http://foo.com',
   215                      team: 'dummy',
   216                      undeploySummary: UndeploySummary.NORMAL,
   217                      warnings: [],
   218                  },
   219                  bar: {
   220                      name: 'bar',
   221                      releases: [],
   222                      sourceRepoUrl: 'http://bar.com',
   223                      team: 'test',
   224                      undeploySummary: UndeploySummary.NORMAL,
   225                      warnings: [],
   226                  },
   227                  example: {
   228                      name: 'example',
   229                      releases: [],
   230                      sourceRepoUrl: 'http://example.com',
   231                      team: 'test2',
   232                      undeploySummary: UndeploySummary.NORMAL,
   233                      warnings: [],
   234                  },
   235                  team: {
   236                      name: 'team',
   237                      releases: [],
   238                      sourceRepoUrl: 'http://team.com',
   239                      team: 'foo',
   240                      undeploySummary: UndeploySummary.NORMAL,
   241                      warnings: [],
   242                  },
   243              },
   244              expectedNumOfTeams: 2,
   245          },
   246          {
   247              name: 'shows both applications of the selected team - 2 results',
   248              selectedTeams: ['dummy'],
   249              applications: {
   250                  foo: {
   251                      name: 'foo',
   252                      releases: [],
   253                      sourceRepoUrl: 'http://foo.com',
   254                      team: 'dummy',
   255                      undeploySummary: UndeploySummary.NORMAL,
   256                      warnings: [],
   257                  },
   258                  bar: {
   259                      name: 'bar',
   260                      releases: [],
   261                      sourceRepoUrl: 'http://bar.com',
   262                      team: 'dummy',
   263                      undeploySummary: UndeploySummary.NORMAL,
   264                      warnings: [],
   265                  },
   266                  team: {
   267                      name: 'team',
   268                      releases: [],
   269                      sourceRepoUrl: 'http://team.com',
   270                      team: 'foo',
   271                      undeploySummary: UndeploySummary.NORMAL,
   272                      warnings: [],
   273                  },
   274              },
   275              expectedNumOfTeams: 2,
   276          },
   277          {
   278              name: 'no teams selected (shows every application) - 4 results',
   279              selectedTeams: [],
   280              applications: {
   281                  foo: {
   282                      name: 'foo',
   283                      releases: [],
   284                      sourceRepoUrl: 'http://foo.com',
   285                      team: '',
   286                      undeploySummary: UndeploySummary.NORMAL,
   287                      warnings: [],
   288                  },
   289                  bar: {
   290                      name: 'bar',
   291                      releases: [],
   292                      sourceRepoUrl: 'http://bar.com',
   293                      team: 'test',
   294                      undeploySummary: UndeploySummary.NORMAL,
   295                      warnings: [],
   296                  },
   297                  example: {
   298                      name: 'example',
   299                      releases: [],
   300                      sourceRepoUrl: 'http://example.com',
   301                      team: '',
   302                      undeploySummary: UndeploySummary.NORMAL,
   303                      warnings: [],
   304                  },
   305                  team: {
   306                      name: 'team',
   307                      releases: [],
   308                      sourceRepoUrl: 'http://team.com',
   309                      team: 'foo',
   310                      undeploySummary: UndeploySummary.NORMAL,
   311                      warnings: [],
   312                  },
   313              },
   314              expectedNumOfTeams: 4,
   315          },
   316          {
   317              name: 'selected team has no assigned applications - 0 results',
   318              selectedTeams: ['thisTeamDoesntExist'],
   319              applications: {
   320                  foo: {
   321                      name: 'foo',
   322                      releases: [],
   323                      sourceRepoUrl: 'http://foo.com',
   324                      team: 'dummy',
   325                      undeploySummary: UndeploySummary.NORMAL,
   326                      warnings: [],
   327                  },
   328                  bar: {
   329                      name: 'bar',
   330                      releases: [],
   331                      sourceRepoUrl: 'http://bar.com',
   332                      team: 'test',
   333                      undeploySummary: UndeploySummary.NORMAL,
   334                      warnings: [],
   335                  },
   336              },
   337              expectedNumOfTeams: 0,
   338          },
   339      ];
   340  
   341      describe.each(data)(`Renders an Application Card`, (testcase) => {
   342          it(testcase.name, () => {
   343              // given
   344              UpdateOverview.set({ applications: testcase.applications });
   345              // when
   346              const numOfTeams = renderHook(() => useApplicationsFilteredAndSorted(testcase.selectedTeams, false, ''))
   347                  .result.current.length;
   348              expect(numOfTeams).toStrictEqual(testcase.expectedNumOfTeams);
   349          });
   350      });
   351  });
   352  
   353  describe('Application Filter', () => {
   354      interface dataT {
   355          name: string;
   356          query: string;
   357          applications: string[];
   358          expectedLocks: number;
   359      }
   360  
   361      const data: dataT[] = [
   362          {
   363              name: 'filter applications - 1 result',
   364              applications: ['dummy', 'test', 'test2', 'foo'],
   365              query: 'dummy',
   366              expectedLocks: 1,
   367          },
   368          {
   369              name: 'filter applications - 0 results',
   370              applications: ['dummy', 'test', 'test2'],
   371              query: 'foo',
   372              expectedLocks: 0,
   373          },
   374          {
   375              name: 'filter applications - 2 results',
   376              applications: ['dummy', 'test', 'test2'],
   377              query: 'test',
   378              expectedLocks: 2,
   379          },
   380      ];
   381  
   382      describe.each(data)(`Renders an Application Card`, (testcase) => {
   383          it(testcase.name, () => {
   384              // when
   385              const nrLocks = testcase.applications.filter((val) => searchCustomFilter(testcase.query, val)).length;
   386              expect(nrLocks).toStrictEqual(testcase.expectedLocks);
   387          });
   388      });
   389  });