]> source.dussan.org Git - sonarqube.git/blob
562ef915d5ebee7e15127705fbf9acef7185ba8d
[sonarqube.git] /
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 userEvent from '@testing-library/user-event';
21 import React from 'react';
22 import AlmSettingsServiceMock from '../../../../api/mocks/AlmSettingsServiceMock';
23 import UserTokensMock from '../../../../api/mocks/UserTokensMock';
24 import { mockAlmSettingsInstance } from '../../../../helpers/mocks/alm-settings';
25 import { mockComponent } from '../../../../helpers/mocks/component';
26 import { mockLanguage, mockLoggedInUser } from '../../../../helpers/testMocks';
27 import { RenderContext, renderApp } from '../../../../helpers/testReactTestingUtils';
28 import { byRole } from '../../../../sonar-aligned/helpers/testSelector';
29 import { AlmKeys } from '../../../../types/alm-settings';
30 import { Feature } from '../../../../types/features';
31 import {
32   getCommonNodes,
33   getCopyToClipboardValue,
34   getTutorialActionButtons,
35   getTutorialBuildButtons,
36 } from '../../test-utils';
37 import { GradleBuildDSL, TutorialModes } from '../../types';
38 import GitHubActionTutorial, { GitHubActionTutorialProps } from '../GitHubActionTutorial';
39
40 jest.mock('../../../../api/settings', () => ({
41   getAllValues: jest.fn().mockResolvedValue([]),
42 }));
43
44 const tokenMock = new UserTokensMock();
45 const almMock = new AlmSettingsServiceMock();
46
47 afterEach(() => {
48   tokenMock.reset();
49   almMock.reset();
50 });
51
52 const ui = {
53   ...getCommonNodes(TutorialModes.GitHubActions),
54   ...getTutorialActionButtons(),
55   ...getTutorialBuildButtons(),
56 };
57
58 it('should follow and complete all steps', async () => {
59   const user = userEvent.setup();
60   renderGithubActionTutorial();
61
62   expect(await ui.secretsStepTitle.find()).toBeInTheDocument();
63
64   // Env variables step
65   expect(getCopyToClipboardValue(0, 'Copy to clipboard')).toMatchSnapshot('sonar token key');
66   expect(getCopyToClipboardValue(1, 'Copy to clipboard')).toMatchSnapshot('sonarqube host url key');
67   expect(getCopyToClipboardValue(2, 'Copy to clipboard')).toMatchSnapshot(
68     'sonarqube host url value',
69   );
70
71   // Create/update configuration file step
72   // Maven
73   await user.click(ui.mavenBuildButton.get());
74   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Maven: .github/workflows/build.yml');
75
76   // Gradle
77   await user.click(ui.gradleBuildButton.get());
78   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Groovy: build.gradle');
79   await user.click(ui.gradleDSLButton(GradleBuildDSL.Kotlin).get());
80   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Kotlin: build.gradle.kts');
81   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot('Gradle: .github/workflows/build.yml');
82
83   // .NET
84   await user.click(ui.dotnetBuildButton.get());
85   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('.NET: .github/workflows/build.yml');
86
87   // Cpp
88   await user.click(ui.cppBuildButton.get());
89   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
90     'C++ (automatic) and other: sonar-project.properties',
91   );
92   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
93     'C++ (automatic) and other: .github/workflows/build.yml',
94   );
95
96   await user.click(ui.autoConfigManual.get());
97   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('C++: sonar-project.properties');
98   await user.click(ui.linuxButton.get());
99   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
100     'C++ Linux: .github/workflows/build.yml',
101   );
102   await user.click(ui.arm64Button.get());
103   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
104     'C++ Linux arm64: .github/workflows/build.yml',
105   );
106   await user.click(ui.windowsButton.get());
107   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
108     'C++ Windows: .github/workflows/build.yml',
109   );
110   await user.click(ui.macosButton.get());
111   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
112     'C++ MacOS: .github/workflows/build.yml',
113   );
114
115   // Objective-C
116   await user.click(ui.objCBuildButton.get());
117   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
118     'Objective-C: sonar-project.properties',
119   );
120
121   await user.click(ui.linuxButton.get());
122   await user.click(ui.x86_64Button.get());
123   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
124     'Objective-C Linux: .github/workflows/build.yml',
125   );
126   await user.click(ui.arm64Button.get());
127   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
128     'Objective-C Linux arm64: .github/workflows/build.yml',
129   );
130   await user.click(ui.windowsButton.get());
131   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
132     'Objective-C Windows: .github/workflows/build.yml',
133   );
134   await user.click(ui.macosButton.get());
135   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
136     'Objective-C MacOS: .github/workflows/build.yml',
137   );
138
139   // Dart
140   await user.click(ui.dartBuildButton.get());
141   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot('Dart: .github/workflows/build.yml');
142
143   // Other
144   await user.click(ui.otherBuildButton.get());
145   expect(getCopyToClipboardValue(0, 'Copy')).toMatchSnapshot(
146     'C++ (automatic) and other: sonar-project.properties',
147   );
148   expect(getCopyToClipboardValue(1, 'Copy')).toMatchSnapshot(
149     'C++ (automatic) and other: .github/workflows/build.yml',
150   );
151
152   expect(ui.allSetSentence.get()).toBeInTheDocument();
153 });
154
155 it('should generate/delete a new token or use existing one', async () => {
156   const user = userEvent.setup();
157   renderGithubActionTutorial();
158
159   expect(await ui.secretsStepTitle.find()).toBeInTheDocument();
160
161   // Generate token
162   await user.click(ui.genTokenDialogButton.get());
163   await user.click(ui.generateTokenButton.get());
164   expect(getCopyToClipboardValue()).toEqual('generatedtoken2');
165
166   // Revoke current token and create new one
167   await user.click(ui.deleteTokenButton.get());
168   await user.type(ui.tokenNameInput.get(), 'newtoken');
169
170   await user.click(ui.expiresInSelect.get());
171   await user.click(byRole('option', { name: 'users.tokens.expiration.365' }).get());
172
173   await user.click(ui.generateTokenButton.get());
174   expect(ui.tokenValue.get()).toBeInTheDocument();
175   await user.click(ui.continueButton.getAll()[0]);
176   expect(ui.tokenValue.query()).not.toBeInTheDocument();
177 });
178
179 it('navigates between steps', async () => {
180   const user = userEvent.setup();
181   almMock.handleSetProjectBinding(AlmKeys.GitHub, {
182     almSetting: 'my-project',
183     project: 'my-project',
184     repository: 'my-project',
185     monorepo: true,
186   });
187   renderGithubActionTutorial({
188     almBinding: mockAlmSettingsInstance({
189       alm: AlmKeys.GitHub,
190       url: 'http://localhost/qube',
191     }),
192   });
193
194   // If project is bound, link to repo is visible
195   expect(await ui.linkToRepo.find()).toBeInTheDocument();
196
197   await user.click(ui.mavenBuildButton.get());
198   expect(ui.allSetSentence.get()).toBeInTheDocument();
199
200   await user.click(ui.ymlFileStepTitle.get());
201   expect(ui.mavenBuildButton.get()).toBeInTheDocument();
202   await user.click(ui.secretsStepTitle.get());
203   expect(ui.genTokenDialogButton.get()).toBeInTheDocument();
204 });
205
206 function renderGithubActionTutorial(
207   overrides: Partial<GitHubActionTutorialProps> = {},
208   { languages = { c: mockLanguage({ key: 'c' }) } }: RenderContext = {},
209 ) {
210   return renderApp(
211     '/',
212     <GitHubActionTutorial
213       baseUrl="http://localhost:9000"
214       mainBranchName="main"
215       component={mockComponent()}
216       currentUser={mockLoggedInUser()}
217       {...overrides}
218     />,
219     { languages, featureList: [Feature.BranchSupport] },
220   );
221 }