You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GitLab-it.tsx 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { screen, within } from '@testing-library/react';
  21. import userEvent from '@testing-library/user-event';
  22. import * as React from 'react';
  23. import selectEvent from 'react-select-event';
  24. import { getGitlabProjects } from '../../../../api/alm-integrations';
  25. import AlmIntegrationsServiceMock from '../../../../api/mocks/AlmIntegrationsServiceMock';
  26. import DopTranslationServiceMock from '../../../../api/mocks/DopTranslationServiceMock';
  27. import NewCodeDefinitionServiceMock from '../../../../api/mocks/NewCodeDefinitionServiceMock';
  28. import { renderApp } from '../../../../helpers/testReactTestingUtils';
  29. import { byLabelText, byRole, byText } from '../../../../helpers/testSelector';
  30. import CreateProjectPage from '../CreateProjectPage';
  31. jest.mock('../../../../api/alm-integrations');
  32. jest.mock('../../../../api/alm-settings');
  33. let almIntegrationHandler: AlmIntegrationsServiceMock;
  34. let dopTranslationHandler: DopTranslationServiceMock;
  35. let newCodePeriodHandler: NewCodeDefinitionServiceMock;
  36. const ui = {
  37. gitlabCreateProjectButton: byText('onboarding.create_project.select_method.gitlab'),
  38. personalAccessTokenInput: byRole('textbox', {
  39. name: /onboarding.create_project.enter_pat/,
  40. }),
  41. instanceSelector: byLabelText(/alm.configuration.selector.label/),
  42. };
  43. const original = window.location;
  44. beforeAll(() => {
  45. Object.defineProperty(window, 'location', {
  46. configurable: true,
  47. value: { replace: jest.fn() },
  48. });
  49. almIntegrationHandler = new AlmIntegrationsServiceMock();
  50. dopTranslationHandler = new DopTranslationServiceMock();
  51. newCodePeriodHandler = new NewCodeDefinitionServiceMock();
  52. });
  53. beforeEach(() => {
  54. jest.clearAllMocks();
  55. almIntegrationHandler.reset();
  56. dopTranslationHandler.reset();
  57. newCodePeriodHandler.reset();
  58. });
  59. afterAll(() => {
  60. Object.defineProperty(window, 'location', { configurable: true, value: original });
  61. });
  62. it('should ask for PAT when it is not set yet and show the import project feature afterwards', async () => {
  63. const user = userEvent.setup();
  64. renderCreateProject();
  65. expect(await screen.findByText('onboarding.create_project.gitlab.title')).toBeInTheDocument();
  66. expect(ui.instanceSelector.get()).toBeInTheDocument();
  67. expect(screen.getByText('onboarding.create_project.enter_pat')).toBeInTheDocument();
  68. expect(
  69. screen.getByText('onboarding.create_project.pat_help.instructions.gitlab'),
  70. ).toBeInTheDocument();
  71. expect(screen.getByRole('button', { name: 'save' })).toBeInTheDocument();
  72. await user.click(ui.personalAccessTokenInput.get());
  73. await user.keyboard('secret');
  74. await user.click(screen.getByRole('button', { name: 'save' }));
  75. expect(screen.getByText('Gitlab project 1')).toBeInTheDocument();
  76. expect(screen.getByText('Gitlab project 2')).toBeInTheDocument();
  77. expect(screen.getAllByText('onboarding.create_project.import')).toHaveLength(2);
  78. expect(screen.getByText('onboarding.create_project.repository_imported')).toBeInTheDocument();
  79. });
  80. it('should show import project feature when PAT is already set', async () => {
  81. const user = userEvent.setup();
  82. let projectItem;
  83. renderCreateProject();
  84. expect(await screen.findByText('onboarding.create_project.gitlab.title')).toBeInTheDocument();
  85. await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]);
  86. expect(await screen.findByText('Gitlab project 1')).toBeInTheDocument();
  87. expect(screen.getByText('Gitlab project 2')).toBeInTheDocument();
  88. projectItem = screen.getByRole('listitem', { name: /Gitlab project 1/ });
  89. expect(
  90. within(projectItem).getByText('onboarding.create_project.repository_imported'),
  91. ).toBeInTheDocument();
  92. expect(within(projectItem).getByRole('link', { name: /Gitlab project 1/ })).toBeInTheDocument();
  93. expect(within(projectItem).getByRole('link', { name: /Gitlab project 1/ })).toHaveAttribute(
  94. 'href',
  95. '/dashboard?id=key',
  96. );
  97. projectItem = screen.getByRole('listitem', { name: /Gitlab project 2/ });
  98. const importButton = within(projectItem).getByRole('button', {
  99. name: 'onboarding.create_project.import',
  100. });
  101. await user.click(importButton);
  102. expect(
  103. screen.getByRole('heading', { name: 'onboarding.create_x_project.new_code_definition.title1' }),
  104. ).toBeInTheDocument();
  105. await user.click(screen.getByRole('radio', { name: 'new_code_definition.global_setting' }));
  106. await user.click(
  107. screen.getByRole('button', {
  108. name: 'onboarding.create_project.new_code_definition.create_x_projects1',
  109. }),
  110. );
  111. expect(await screen.findByText('/dashboard?id=key')).toBeInTheDocument();
  112. });
  113. it('should show search filter when PAT is already set', async () => {
  114. const user = userEvent.setup();
  115. renderCreateProject();
  116. expect(await screen.findByText('onboarding.create_project.gitlab.title')).toBeInTheDocument();
  117. await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]);
  118. const inputSearch = await screen.findByRole('searchbox');
  119. await user.click(inputSearch);
  120. await user.keyboard('sea');
  121. expect(getGitlabProjects).toHaveBeenLastCalledWith({
  122. almSetting: 'conf-final-2',
  123. page: 1,
  124. pageSize: 20,
  125. query: 'sea',
  126. });
  127. });
  128. it('should have load more', async () => {
  129. const user = userEvent.setup();
  130. almIntegrationHandler.createRandomGitlabProjectsWithLoadMore(10, 20);
  131. renderCreateProject();
  132. expect(await screen.findByText('onboarding.create_project.gitlab.title')).toBeInTheDocument();
  133. await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]);
  134. const loadMore = await screen.findByRole('button', { name: 'show_more' });
  135. expect(loadMore).toBeInTheDocument();
  136. /*
  137. * Next api call response will simulate reaching the last page so we can test the
  138. * loadmore button disapperance.
  139. */
  140. almIntegrationHandler.createRandomGitlabProjectsWithLoadMore(20, 20);
  141. await user.click(loadMore);
  142. expect(getGitlabProjects).toHaveBeenLastCalledWith({
  143. almSetting: 'conf-final-2',
  144. page: 2,
  145. pageSize: 20,
  146. query: '',
  147. });
  148. expect(loadMore).not.toBeInTheDocument();
  149. });
  150. it('should show no result message when there are no projects', async () => {
  151. almIntegrationHandler.setGitlabProjects([]);
  152. renderCreateProject();
  153. expect(await screen.findByText('onboarding.create_project.gitlab.title')).toBeInTheDocument();
  154. await selectEvent.select(ui.instanceSelector.get(), [/conf-final-2/]);
  155. expect(
  156. await screen.findByText('onboarding.create_project.gitlab.no_projects'),
  157. ).toBeInTheDocument();
  158. });
  159. function renderCreateProject() {
  160. renderApp('project/create', <CreateProjectPage />, {
  161. navigateTo: 'project/create?mode=gitlab',
  162. });
  163. }