github.com/freiheit-com/kuberpult@v1.24.2-0.20240328135542-315d5630abe6/services/frontend-service/src/ui/components/ServiceLane/EnvSelectionDialog.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, getByTestId } from '@testing-library/react';
    17  import { documentQuerySelectorSafe } from '../../../setupTests';
    18  import { EnvSelectionDialog, EnvSelectionDialogProps } from './EnvSelectionDialog';
    19  
    20  type TestDataSelection = {
    21      name: string;
    22      input: EnvSelectionDialogProps;
    23      expectedNumItems: number;
    24      clickOnButton: string;
    25      secondClick: string;
    26      expectedNumSelectedAfterClick: number;
    27      expectedNumDeselectedAfterClick: number;
    28      expectedNumSelectedAfterSecondClick: number;
    29  };
    30  
    31  const mySubmitSpy = jest.fn();
    32  const myCancelSpy = jest.fn();
    33  
    34  const confirmButtonTestId = 'test-confirm-button-confirm';
    35  const cancelButtonTestId = 'test-confirm-button-cancel';
    36  
    37  const dataSelection: TestDataSelection[] = [
    38      {
    39          name: 'renders 2 item list',
    40          input: {
    41              environments: ['dev', 'staging'],
    42              open: true,
    43              onSubmit: mySubmitSpy,
    44              onCancel: myCancelSpy,
    45              envSelectionDialog: true,
    46          },
    47          expectedNumItems: 2,
    48          clickOnButton: 'dev',
    49          expectedNumSelectedAfterClick: 1,
    50          expectedNumDeselectedAfterClick: 1,
    51          secondClick: 'staging',
    52          expectedNumSelectedAfterSecondClick: 2,
    53      },
    54      {
    55          name: 'renders 3 item list',
    56          input: {
    57              environments: ['dev', 'staging', 'prod'],
    58              open: true,
    59              onSubmit: mySubmitSpy,
    60              onCancel: myCancelSpy,
    61              envSelectionDialog: true,
    62          },
    63          expectedNumItems: 3,
    64          clickOnButton: 'staging',
    65          expectedNumSelectedAfterClick: 1,
    66          expectedNumDeselectedAfterClick: 2,
    67          secondClick: 'prod',
    68          expectedNumSelectedAfterSecondClick: 2,
    69      },
    70      {
    71          name: 'only one item allowed for release trains',
    72          input: {
    73              environments: ['dev', 'staging', 'prod'],
    74              open: true,
    75              onSubmit: mySubmitSpy,
    76              onCancel: myCancelSpy,
    77              envSelectionDialog: false,
    78          },
    79          expectedNumItems: 3,
    80          clickOnButton: 'staging',
    81          expectedNumSelectedAfterClick: 1,
    82          expectedNumDeselectedAfterClick: 2,
    83          secondClick: 'prod',
    84          expectedNumSelectedAfterSecondClick: 1,
    85      },
    86      {
    87          name: 'renders empty item list',
    88          input: {
    89              environments: [],
    90              open: true,
    91              onSubmit: mySubmitSpy,
    92              onCancel: myCancelSpy,
    93              envSelectionDialog: true,
    94          },
    95          expectedNumItems: 0,
    96          clickOnButton: '',
    97          expectedNumSelectedAfterClick: 0,
    98          expectedNumDeselectedAfterClick: 0,
    99          secondClick: '',
   100          expectedNumSelectedAfterSecondClick: 0,
   101      },
   102  ];
   103  
   104  type TestDataOpenClose = {
   105      name: string;
   106      input: EnvSelectionDialogProps;
   107      expectedNumElements: number;
   108  };
   109  const dataOpenClose: TestDataOpenClose[] = [
   110      {
   111          name: 'renders open dialog',
   112          input: {
   113              environments: ['dev', 'staging', 'prod'],
   114              open: true,
   115              onSubmit: mySubmitSpy,
   116              onCancel: myCancelSpy,
   117              envSelectionDialog: true,
   118          },
   119          expectedNumElements: 1,
   120      },
   121      {
   122          name: 'renders closed dialog',
   123          input: {
   124              environments: ['dev', 'staging', 'prod'],
   125              open: false,
   126              onSubmit: mySubmitSpy,
   127              onCancel: myCancelSpy,
   128              envSelectionDialog: true,
   129          },
   130          expectedNumElements: 0,
   131      },
   132  ];
   133  
   134  type TestDataCallbacks = {
   135      name: string;
   136      input: EnvSelectionDialogProps;
   137      clickThis: string;
   138      expectedCancelCallCount: number;
   139      expectedSubmitCallCount: number;
   140  };
   141  const dataCallbacks: TestDataCallbacks[] = [
   142      {
   143          name: 'renders open dialog',
   144          input: {
   145              environments: ['dev', 'staging', 'prod'],
   146              open: true,
   147              onSubmit: mySubmitSpy,
   148              onCancel: myCancelSpy,
   149              envSelectionDialog: true,
   150          },
   151          clickThis: cancelButtonTestId,
   152          expectedCancelCallCount: 1,
   153          expectedSubmitCallCount: 0,
   154      },
   155      {
   156          name: 'renders closed dialog',
   157          input: {
   158              environments: ['dev', 'staging', 'prod'],
   159              open: true,
   160              onSubmit: mySubmitSpy,
   161              onCancel: myCancelSpy,
   162              envSelectionDialog: true,
   163          },
   164          clickThis: confirmButtonTestId,
   165          expectedCancelCallCount: 0,
   166          expectedSubmitCallCount: 0,
   167      },
   168  ];
   169  
   170  const getNode = (overrides: EnvSelectionDialogProps) => <EnvSelectionDialog {...overrides} />;
   171  const getWrapper = (overrides: EnvSelectionDialogProps) => render(getNode(overrides));
   172  
   173  describe('EnvSelectionDialog', () => {
   174      describe.each(dataSelection)('Test checkbox enabled', (testcase) => {
   175          it(testcase.name, () => {
   176              mySubmitSpy.mockReset();
   177              myCancelSpy.mockReset();
   178              expect(mySubmitSpy).toHaveBeenCalledTimes(0);
   179              expect(myCancelSpy).toHaveBeenCalledTimes(0);
   180  
   181              getWrapper(testcase.input);
   182  
   183              expect(document.querySelectorAll('.envs-dropdown-select .test-button-checkbox').length).toEqual(
   184                  testcase.expectedNumItems
   185              );
   186              if (testcase.clickOnButton !== '') {
   187                  const result = documentQuerySelectorSafe('.id-' + testcase.clickOnButton);
   188                  act(() => {
   189                      result.click();
   190                  });
   191              } else {
   192                  expect(document.querySelector('.env-selection-dialog')?.textContent).toContain(
   193                      'There are no environments'
   194                  );
   195              }
   196              expect(document.querySelectorAll('.test-button-checkbox.enabled').length).toEqual(
   197                  testcase.expectedNumSelectedAfterClick
   198              );
   199              expect(document.querySelectorAll('.test-button-checkbox.disabled').length).toEqual(
   200                  testcase.expectedNumDeselectedAfterClick
   201              );
   202              if (testcase.secondClick !== '') {
   203                  const result = documentQuerySelectorSafe('.id-' + testcase.secondClick);
   204                  act(() => {
   205                      result.click();
   206                  });
   207              }
   208              expect(document.querySelectorAll('.test-button-checkbox.enabled').length).toEqual(
   209                  testcase.expectedNumSelectedAfterSecondClick
   210              );
   211          });
   212      });
   213      describe.each(dataOpenClose)('open/close', (testcase) => {
   214          it(testcase.name, () => {
   215              getWrapper(testcase.input);
   216              expect(document.querySelectorAll('.envs-dropdown-select').length).toEqual(testcase.expectedNumElements);
   217          });
   218      });
   219      describe.each(dataCallbacks)('submit/cancel callbacks', (testcase) => {
   220          it(testcase.name, () => {
   221              mySubmitSpy.mockReset();
   222              myCancelSpy.mockReset();
   223              expect(mySubmitSpy).toHaveBeenCalledTimes(0);
   224              expect(myCancelSpy).toHaveBeenCalledTimes(0);
   225  
   226              const { container } = getWrapper(testcase.input);
   227  
   228              const theButton = getByTestId(container, testcase.clickThis);
   229              act(() => {
   230                  theButton.click();
   231              });
   232              getByTestId(container, testcase.clickThis); // should not crash
   233  
   234              expect(myCancelSpy).toHaveBeenCalledTimes(testcase.expectedCancelCallCount);
   235              expect(mySubmitSpy).toHaveBeenCalledTimes(testcase.expectedSubmitCallCount);
   236          });
   237      });
   238  
   239      type TestDataAddTeam = {
   240          name: string;
   241          input: EnvSelectionDialogProps;
   242          clickTheseTeams: string[];
   243          expectedCancelCallCount: number;
   244          expectedSubmitCallCount: number;
   245          expectedSubmitCalledWith: string[];
   246      };
   247      const addTeamArray: TestDataAddTeam[] = [
   248          {
   249              name: '1 env',
   250              input: {
   251                  environments: ['dev', 'staging', 'prod'],
   252                  open: true,
   253                  onSubmit: mySubmitSpy,
   254                  onCancel: myCancelSpy,
   255                  envSelectionDialog: true,
   256              },
   257              clickTheseTeams: ['dev'],
   258              expectedCancelCallCount: 0,
   259              expectedSubmitCallCount: 1,
   260              expectedSubmitCalledWith: ['dev'],
   261          },
   262          {
   263              name: '2 envs',
   264              input: {
   265                  environments: ['dev', 'staging', 'prod'],
   266                  open: true,
   267                  onSubmit: mySubmitSpy,
   268                  onCancel: myCancelSpy,
   269                  envSelectionDialog: true,
   270              },
   271              clickTheseTeams: ['staging', 'prod'],
   272              expectedCancelCallCount: 0,
   273              expectedSubmitCallCount: 1,
   274              expectedSubmitCalledWith: ['staging', 'prod'],
   275          },
   276          {
   277              name: '1 env clicked twice',
   278              input: {
   279                  environments: ['dev', 'staging', 'prod'],
   280                  open: true,
   281                  onSubmit: mySubmitSpy,
   282                  onCancel: myCancelSpy,
   283                  envSelectionDialog: true,
   284              },
   285              clickTheseTeams: ['dev', 'staging', 'staging'],
   286              expectedCancelCallCount: 0,
   287              expectedSubmitCallCount: 1,
   288              expectedSubmitCalledWith: ['dev'],
   289          },
   290      ];
   291      describe.each(addTeamArray)('adding 2 teams works', (testcase) => {
   292          it(testcase.name, () => {
   293              mySubmitSpy.mockReset();
   294              myCancelSpy.mockReset();
   295              expect(mySubmitSpy).toHaveBeenCalledTimes(0);
   296              expect(myCancelSpy).toHaveBeenCalledTimes(0);
   297  
   298              const { container } = getWrapper(testcase.input);
   299  
   300              testcase.clickTheseTeams.forEach((value, index) => {
   301                  const teamButton = documentQuerySelectorSafe('.id-' + value);
   302                  act(() => {
   303                      teamButton.click();
   304                  });
   305              });
   306              const confirmButton = getByTestId(container, confirmButtonTestId);
   307              act(() => {
   308                  confirmButton.click();
   309              });
   310  
   311              expect(myCancelSpy).toHaveBeenCalledTimes(testcase.expectedCancelCallCount);
   312              expect(mySubmitSpy).toHaveBeenCalledTimes(testcase.expectedSubmitCallCount);
   313              expect(mySubmitSpy).toHaveBeenCalledWith(testcase.expectedSubmitCalledWith);
   314          });
   315      });
   316  });