From a57bb80ea7d4c90e12c2410cb384d9152225c055 Mon Sep 17 00:00:00 2001 From: Wouter Admiraal Date: Thu, 27 Oct 2022 15:42:08 +0200 Subject: [PATCH] SONAR-17528 Update tutorials to use the actual main branch name --- .../main/js/api/mocks/SettingsServiceMock.ts | 39 +- .../components/__tests__/AuditApp-it.tsx | 8 +- .../tutorials/TutorialSelection.tsx | 37 +- .../tutorials/TutorialSelectionRenderer.tsx | 10 +- .../__tests__/TutorialSelection-it.tsx | 206 +++++ .../__tests__/TutorialSelection-test.tsx | 161 ---- .../TutorialSelectionRenderer-test.tsx | 177 ----- .../TutorialSelection-test.tsx.snap | 44 -- .../TutorialSelectionRenderer-test.tsx.snap | 738 ------------------ .../github-action/AnalysisCommand.tsx | 9 +- .../github-action/GitHubActionTutorial.tsx | 3 + .../__tests__/AnalysisCommand-test.tsx | 1 + .../__tests__/GitHubActionTutorial-test.tsx | 1 + .../AnalysisCommand-test.tsx.snap | 5 + .../github-action/commands/CFamily.tsx | 45 +- .../github-action/commands/DotNet.tsx | 29 +- .../github-action/commands/Gradle.tsx | 28 +- .../github-action/commands/JavaMaven.tsx | 29 +- .../github-action/commands/Others.tsx | 38 +- .../commands/__tests__/CFamily-test.tsx | 8 +- .../commands/__tests__/DotNet-test.tsx | 8 +- .../commands/__tests__/Gradle-test.tsx | 8 +- .../commands/__tests__/JavaMaven-test.tsx | 8 +- .../commands/__tests__/Others-test.tsx | 8 +- .../__snapshots__/CFamily-test.tsx.snap | 39 +- .../__snapshots__/DotNet-test.tsx.snap | 20 +- .../__snapshots__/Gradle-test.tsx.snap | 8 +- .../__snapshots__/JavaMaven-test.tsx.snap | 8 +- .../__snapshots__/Others-test.tsx.snap | 13 +- .../tutorials/github-action/constants.ts | 21 + .../tutorials/github-action/utils.ts | 42 + .../tutorials/gitlabci/GitLabCITutorial.tsx | 4 +- .../tutorials/gitlabci/ProjectKeyStep.tsx | 3 +- .../tutorials/gitlabci/YmlFileStep.tsx | 4 +- .../__tests__/GitLabCITutorial-test.tsx | 1 + .../gitlabci/__tests__/YmlFileStep-test.tsx | 1 + .../GitLabCITutorial-test.tsx.snap | 1 + .../__snapshots__/YmlFileStep-test.tsx.snap | 10 + .../gitlabci/commands/PipeCommand.tsx | 8 +- .../commands/__tests__/PipeCommand-test.tsx | 18 +- .../__snapshots__/PipeCommand-test.tsx.snap | 16 +- .../other/commands/AnalysisCommand.tsx | 12 +- .../other/commands/ClangGCCCommand.tsx | 5 +- .../tutorials/other/commands/DotNet.tsx | 2 +- .../tutorials/other/commands/DotNetCore.tsx | 4 +- .../other/commands/DotNetFramework.tsx | 4 +- .../tutorials/other/commands/ExecScanner.tsx | 6 +- .../tutorials/other/commands/JavaGradle.tsx | 11 +- .../tutorials/other/commands/JavaMaven.tsx | 6 +- .../tutorials/other/commands/Other.tsx | 12 +- .../__tests__/CLangGCCCommand-test.tsx | 1 - .../other/commands/__tests__/DotNet-test.tsx | 4 +- .../__tests__/DotNetFramework-test.tsx | 6 +- .../commands/__tests__/DotnetCore-test.tsx | 2 +- .../commands/__tests__/ExecScanner-test.tsx | 2 +- .../commands/__tests__/JavaGradle-test.tsx | 2 +- .../commands/__tests__/JavaMaven-test.tsx | 2 +- .../other/commands/__tests__/Other-test.tsx | 2 +- .../AnalysisCommand-test.tsx.snap | 9 +- .../CLangGCCCommand-test.tsx.snap | 2 +- .../__snapshots__/DotNet-test.tsx.snap | 2 +- .../__snapshots__/Other-test.tsx.snap | 2 +- .../src/main/js/components/tutorials/utils.ts | 3 +- .../src/main/js/helpers/constants.ts | 2 + 64 files changed, 606 insertions(+), 1362 deletions(-) create mode 100644 server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-it.tsx delete mode 100644 server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-test.tsx delete mode 100644 server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx delete mode 100644 server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelection-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap create mode 100644 server/sonar-web/src/main/js/components/tutorials/github-action/constants.ts create mode 100644 server/sonar-web/src/main/js/components/tutorials/github-action/utils.ts diff --git a/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts index 4ac206dbf5d..7d22006a564 100644 --- a/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/SettingsServiceMock.ts @@ -21,7 +21,7 @@ import { cloneDeep } from 'lodash'; import { HousekeepingPolicy } from '../../apps/audit-logs/utils'; import { BranchParameters } from '../../types/branch-like'; import { SettingsKey, SettingValue } from '../../types/settings'; -import { getValue } from '../settings'; +import { getAllValues, getValue, getValues } from '../settings'; export default class SettingsServiceMock { settingValues: SettingValue[]; @@ -34,28 +34,43 @@ export default class SettingsServiceMock { constructor() { this.settingValues = cloneDeep(this.defaultValues); - (getValue as jest.Mock).mockImplementation(this.handleGetValues); + (getValue as jest.Mock).mockImplementation(this.handleGetValue); + (getValues as jest.Mock).mockImplementation(this.handleGetValues); + (getAllValues as jest.Mock).mockImplementation(this.handleGetAllValues); } - handleGetValues = (data: { key: string; component?: string } & BranchParameters) => { + handleGetValue = (data: { key: string; component?: string } & BranchParameters) => { const setting = this.settingValues.find(s => s.key === data.key); - return this.reply(setting); }; - emptySettings() { + handleGetValues = (data: { keys: string[]; component?: string } & BranchParameters) => { + const settings = this.settingValues.filter(s => data.keys.includes(s.key)); + return this.reply(settings); + }; + + handleGetAllValues = () => { + return this.reply(this.settingValues); + }; + + emptySettings = () => { this.settingValues = []; - } + return this; + }; - setYearlyHousekeepingPolicy() { - const auditSetting = this.settingValues.find(s => s.key === SettingsKey.AuditHouseKeeping); - if (auditSetting) { - auditSetting.value = HousekeepingPolicy.Yearly; + set = (key: SettingsKey, value: string) => { + const setting = this.settingValues.find(s => s.key === key); + if (setting) { + setting.value = value; + } else { + this.settingValues.push({ key, value }); } - } + return this; + }; - resetSettingvalues = () => { + reset = () => { this.settingValues = cloneDeep(this.defaultValues); + return this; }; reply(response: T): Promise { diff --git a/server/sonar-web/src/main/js/apps/audit-logs/components/__tests__/AuditApp-it.tsx b/server/sonar-web/src/main/js/apps/audit-logs/components/__tests__/AuditApp-it.tsx index 813ede23e2d..1130413e4d6 100644 --- a/server/sonar-web/src/main/js/apps/audit-logs/components/__tests__/AuditApp-it.tsx +++ b/server/sonar-web/src/main/js/apps/audit-logs/components/__tests__/AuditApp-it.tsx @@ -27,7 +27,9 @@ import { now } from '../../../../helpers/dates'; import { getShortMonthName } from '../../../../helpers/l10n'; import { renderAppWithAdminContext } from '../../../../helpers/testReactTestingUtils'; import { AdminPageExtension } from '../../../../types/extension'; +import { SettingsKey } from '../../../../types/settings'; import routes from '../../routes'; +import { HousekeepingPolicy } from '../../utils'; jest.mock('../../../../api/settings'); @@ -73,11 +75,11 @@ beforeAll(() => { handler = new SettingsServiceMock(); }); -afterEach(() => handler.resetSettingvalues()); +afterEach(() => handler.reset()); it('should handle download button click', async () => { const user = userEvent.setup(); - handler.setYearlyHousekeepingPolicy(); + handler.set(SettingsKey.AuditHouseKeeping, HousekeepingPolicy.Yearly); renderAuditLogs(); const downloadButton = await ui.downloadButton.find(); expect(downloadButton).toBeInTheDocument(); @@ -152,7 +154,7 @@ it('should show right option when keeping log for month', async () => { }); it('should show right option when keeping log for year', async () => { - handler.setYearlyHousekeepingPolicy(); + handler.set(SettingsKey.AuditHouseKeeping, HousekeepingPolicy.Yearly); renderAuditLogs(); expect(await ui.pageTitle.find()).toBeInTheDocument(); expect(ui.todayRadio.get()).toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx b/server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx index 9888924b8e9..661ef43a318 100644 --- a/server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx @@ -21,9 +21,12 @@ import * as React from 'react'; import { getAlmSettingsNoCatch } from '../../api/alm-settings'; import { getScannableProjects } from '../../api/components'; import { getValue } from '../../api/settings'; +import { ComponentContext } from '../../app/components/componentContext/ComponentContext'; +import { isMainBranch } from '../../helpers/branch-like'; import { getHostUrl } from '../../helpers/urls'; import { hasGlobalPermission } from '../../helpers/users'; import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-settings'; +import { MainBranch } from '../../types/branch-like'; import { Permissions } from '../../types/permissions'; import { SettingsKey } from '../../types/settings'; import { Component } from '../../types/types'; @@ -48,6 +51,8 @@ interface State { loading: boolean; } +const DEFAULT_MAIN_BRANCH_NAME = 'main'; + export class TutorialSelection extends React.PureComponent { mounted = false; state: State = { @@ -134,18 +139,26 @@ export class TutorialSelection extends React.PureComponent { const selectedTutorial: TutorialModes | undefined = location.query?.selectedTutorial; return ( - + + {({ branchLikes }) => ( + isMainBranch(b)) as MainBranch | undefined)?.name || + DEFAULT_MAIN_BRANCH_NAME + } + onSelectTutorial={this.handleSelectTutorial} + projectBinding={projectBinding} + selectedTutorial={selectedTutorial} + willRefreshAutomatically={willRefreshAutomatically} + /> + )} + ); } } diff --git a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx index f08f088b801..fdaaeacad27 100644 --- a/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/TutorialSelectionRenderer.tsx @@ -40,6 +40,7 @@ export interface TutorialSelectionRendererProps { currentUser: LoggedInUser; currentUserCanScanProject: boolean; loading: boolean; + mainBranchName: string; onSelectTutorial: (mode: TutorialModes) => void; projectBinding?: ProjectAlmBindingResponse; selectedTutorial?: TutorialModes; @@ -77,13 +78,14 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender currentUser, currentUserCanScanProject, loading, + mainBranchName, projectBinding, selectedTutorial, willRefreshAutomatically } = props; if (loading) { - return ; + return ; } if (!currentUserCanScanProject) { @@ -99,7 +101,7 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender if (projectBinding !== undefined) { showGitHubActions = projectBinding.alm === AlmKeys.GitHub; showGitLabCICD = projectBinding.alm === AlmKeys.GitLab; - showBitbucketPipelines = projectBinding?.alm === AlmKeys.BitbucketCloud; + showBitbucketPipelines = projectBinding.alm === AlmKeys.BitbucketCloud; showAzurePipelines = [AlmKeys.Azure, AlmKeys.GitHub].includes(projectBinding.alm); showJenkins = [ AlmKeys.BitbucketCloud, @@ -233,6 +235,7 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender baseUrl={baseUrl} component={component} currentUser={currentUser} + mainBranchName={mainBranchName} projectBinding={projectBinding} willRefreshAutomatically={willRefreshAutomatically} /> @@ -253,13 +256,14 @@ export default function TutorialSelectionRenderer(props: TutorialSelectionRender baseUrl={baseUrl} component={component} currentUser={currentUser} + mainBranchName={mainBranchName} willRefreshAutomatically={willRefreshAutomatically} /> )} {selectedTutorial === TutorialModes.AzurePipelines && ( ({ + ...jest.requireActual('../../../helpers/urls'), + getHostUrl: jest.fn().mockReturnValue('http://host.url') +})); + +jest.mock('../../../api/alm-settings', () => ({ + getAlmSettingsNoCatch: jest.fn().mockRejectedValue(null) +})); + +jest.mock('../../../api/components', () => ({ + getScannableProjects: jest.fn().mockResolvedValue({ projects: [] }) +})); + +let settingsMock: SettingsServiceMock; +let tokenMock: UserTokensMock; + +beforeAll(() => { + settingsMock = new SettingsServiceMock(); + tokenMock = new UserTokensMock(); +}); + +afterEach(() => { + tokenMock.reset(); + settingsMock.reset(); +}); + +beforeEach(jest.clearAllMocks); + +const ui = { + loading: byLabelText('loading'), + noScanRights: byText('onboarding.tutorial.no_scan_rights'), + chooseTutorialBtn: (mode: TutorialModes) => + byRole('button', { name: `onboarding.tutorial.choose_method.${mode}` }) +}; + +it.each([ + [TutorialModes.Jenkins, 'onboarding.tutorial.with.jenkins.title'], + [TutorialModes.AzurePipelines, 'onboarding.tutorial.with.azure_pipelines.title'], + [ + TutorialModes.BitbucketPipelines, + 'onboarding.tutorial.with.bitbucket_pipelines.create_secret.title' + ], + [TutorialModes.GitHubActions, 'onboarding.tutorial.with.github_action.create_secret.title'], + [TutorialModes.GitLabCI, 'onboarding.tutorial.with.gitlab_ci.title'], + [TutorialModes.Local, 'onboarding.project_analysis.header'], + [TutorialModes.OtherCI, 'onboarding.project_analysis.header'] +])('should behave correctly for %s', async (mode, title) => { + const user = userEvent.setup(); + renderTutorialSelection(); + await waitOnDataLoaded(); + + expect(screen.getByText('onboarding.tutorial.choose_method')).toBeInTheDocument(); + + await user.click(ui.chooseTutorialBtn(mode).get()); + expect(screen.getByText(title)).toBeInTheDocument(); +}); + +it.each([ + [ + AlmKeys.GitHub, + [TutorialModes.GitHubActions, TutorialModes.Jenkins, TutorialModes.AzurePipelines] + ], + [AlmKeys.GitLab, [TutorialModes.GitLabCI, TutorialModes.Jenkins]], + [AlmKeys.Azure, [TutorialModes.AzurePipelines]], + [AlmKeys.BitbucketServer, [TutorialModes.Jenkins]], + [AlmKeys.BitbucketCloud, [TutorialModes.BitbucketPipelines, TutorialModes.Jenkins]] +])('should show correct buttons if project is bound to %s', async (alm, modes) => { + renderTutorialSelection({ projectBinding: mockProjectAlmBindingResponse({ alm }) }); + await waitOnDataLoaded(); + + modes.forEach(mode => expect(ui.chooseTutorialBtn(mode).get()).toBeInTheDocument()); +}); + +it('should correctly fetch the corresponding ALM setting', async () => { + (getAlmSettingsNoCatch as jest.Mock).mockResolvedValueOnce([ + mockGithubBindingDefinition({ key: 'binding', url: 'https://enterprise.github.com' }) + ]); + const user = userEvent.setup(); + renderTutorialSelection({ + projectBinding: mockProjectAlmBindingResponse({ alm: AlmKeys.GitHub, key: 'binding' }) + }); + await waitOnDataLoaded(); + + await startJenkinsTutorial(user); + expect(screen.getByText('https://enterprise.github.com', { exact: false })).toBeInTheDocument(); +}); + +it('should correctly fetch the instance URL', async () => { + settingsMock.set(SettingsKey.ServerBaseUrl, 'http://sq.example.com'); + const user = userEvent.setup(); + renderTutorialSelection(); + await waitOnDataLoaded(); + + await startLocalTutorial(user); + expect( + screen.getByText('-Dsonar.host.url=http://sq.example.com', { exact: false }) + ).toBeInTheDocument(); +}); + +it('should fallback on the host URL', async () => { + const user = userEvent.setup(); + renderTutorialSelection(); + await waitOnDataLoaded(); + + await startLocalTutorial(user); + expect( + screen.getByText('-Dsonar.host.url=http://host.url', { exact: false }) + ).toBeInTheDocument(); +}); + +it('should not display a warning if the user has no global scan permission, but can scan the project', async () => { + (getScannableProjects as jest.Mock).mockResolvedValueOnce({ projects: [{ key: 'foo' }] }); + renderTutorialSelection({ currentUser: mockLoggedInUser() }); + await waitOnDataLoaded(); + + expect(ui.noScanRights.query()).not.toBeInTheDocument(); +}); + +it('should correctly display a warning if the user has no scan permissions', async () => { + renderTutorialSelection({ currentUser: mockLoggedInUser() }); + await waitOnDataLoaded(); + + expect(ui.noScanRights.query()).toBeInTheDocument(); +}); + +async function waitOnDataLoaded() { + await waitFor(() => { + expect(ui.loading.query()).not.toBeInTheDocument(); + }); +} + +async function startLocalTutorial(user: UserEvent) { + await user.click(ui.chooseTutorialBtn(TutorialModes.Local).get()); + await user.click(screen.getByRole('button', { name: 'onboarding.token.generate' })); + await user.click(screen.getByRole('button', { name: 'continue' })); + await user.click(screen.getByRole('button', { name: 'onboarding.build.maven' })); +} + +async function startJenkinsTutorial(user: UserEvent) { + await user.click(ui.chooseTutorialBtn(TutorialModes.Jenkins).get()); + await user.click( + screen.getByRole('button', { name: 'onboarding.tutorial.with.jenkins.prereqs.done' }) + ); +} + +function renderTutorialSelection(props: Partial = {}) { + const Wrapper = withRouter(({ router, location, ...subProps }: TutorialSelection['props']) => { + return ; + }); + + return renderApp( + '/', + , + { featureList: [Feature.BranchSupport] } + ); +} diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-test.tsx b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-test.tsx deleted file mode 100644 index 80b92e0166b..00000000000 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-test.tsx +++ /dev/null @@ -1,161 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { getAlmSettingsNoCatch } from '../../../api/alm-settings'; -import { getScannableProjects } from '../../../api/components'; -import { getValue } from '../../../api/settings'; -import { - mockAlmSettingsInstance, - mockProjectBitbucketBindingResponse -} from '../../../helpers/mocks/alm-settings'; -import { mockComponent } from '../../../helpers/mocks/component'; -import { mockLocation, mockLoggedInUser, mockRouter } from '../../../helpers/testMocks'; -import { waitAndUpdate } from '../../../helpers/testUtils'; -import { getHostUrl } from '../../../helpers/urls'; -import { Permissions } from '../../../types/permissions'; -import { SettingsKey } from '../../../types/settings'; -import { TutorialSelection } from '../TutorialSelection'; -import { TutorialModes } from '../types'; - -jest.mock('../../../helpers/urls', () => ({ - getHostUrl: jest.fn().mockReturnValue('http://host.url') -})); - -jest.mock('../../../api/alm-settings', () => ({ - getAlmSettingsNoCatch: jest.fn().mockRejectedValue(null) -})); - -jest.mock('../../../api/settings', () => ({ - getValue: jest.fn().mockResolvedValue({}) -})); - -jest.mock('../../../api/components', () => ({ - getScannableProjects: jest.fn().mockResolvedValue({ projects: [] }) -})); - -beforeEach(jest.clearAllMocks); - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot(); -}); - -it('should correctly find the global ALM binding definition', async () => { - const key = 'foo'; - const almBinding = mockAlmSettingsInstance({ key }); - (getAlmSettingsNoCatch as jest.Mock).mockResolvedValueOnce([ - almBinding, - mockAlmSettingsInstance({ key: 'bar' }) - ]); - const wrapper = shallowRender({ projectBinding: mockProjectBitbucketBindingResponse({ key }) }); - await waitAndUpdate(wrapper); - expect(wrapper.state().almBinding).toBe(almBinding); -}); - -it('should handle selection', () => { - const push = jest.fn(); - const wrapper = shallowRender({ router: mockRouter({ push }) }); - const instance = wrapper.instance(); - - instance.handleSelectTutorial(TutorialModes.Local); - expect(push).toHaveBeenLastCalledWith( - expect.objectContaining({ - query: { selectedTutorial: TutorialModes.Local } - }) - ); - - instance.handleSelectTutorial(TutorialModes.Jenkins); - expect(push).toHaveBeenLastCalledWith( - expect.objectContaining({ - query: { selectedTutorial: TutorialModes.Jenkins } - }) - ); -}); - -it('should fetch the correct baseUrl', async () => { - (getValue as jest.Mock) - .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: '' }) - .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: 'http://sq.example.com' }) - .mockRejectedValueOnce(null); - - let wrapper = shallowRender(); - - expect(getValue).toHaveBeenCalled(); - expect(getHostUrl).toHaveBeenCalled(); - - // No baseURL, fallback to the URL in the browser. - await waitAndUpdate(wrapper); - expect(wrapper.state().baseUrl).toBe('http://host.url'); - - // A baseURL was set. - wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(wrapper.state().baseUrl).toBe('http://sq.example.com'); - - // Access denied, fallback to the URL in the browser. - wrapper = shallowRender(); - await waitAndUpdate(wrapper); - expect(wrapper.state().baseUrl).toBe('http://host.url'); -}); - -it("should correctly determine the user's permission", async () => { - const component = mockComponent({ key: 'bar', name: 'Bar' }); - (getScannableProjects as jest.Mock) - .mockResolvedValueOnce({ - projects: [ - { key: 'foo', name: 'Foo' }, - { key: component.key, name: component.name } - ] - }) - .mockResolvedValueOnce({ projects: [{ key: 'foo', name: 'Foo' }] }); - - // Global scan permission. - let wrapper = shallowRender({ - component, - currentUser: mockLoggedInUser({ permissions: { global: [Permissions.Scan] } }) - }); - await waitAndUpdate(wrapper); - expect(wrapper.state().currentUserCanScanProject).toBe(true); - expect(getScannableProjects).not.toHaveBeenCalled(); - - // Project scan permission. - wrapper = shallowRender({ component }); - await waitAndUpdate(wrapper); - expect(getScannableProjects).toHaveBeenCalled(); - expect(wrapper.state().currentUserCanScanProject).toBe(true); - - // No scan permission. - wrapper = shallowRender({ component }); - await waitAndUpdate(wrapper); - expect(getScannableProjects).toHaveBeenCalledTimes(2); - expect(wrapper.state().currentUserCanScanProject).toBe(false); -}); - -function shallowRender(props: Partial = {}) { - return shallow( - - ); -} diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx b/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx deleted file mode 100644 index b9200fbe082..00000000000 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelectionRenderer-test.tsx +++ /dev/null @@ -1,177 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2022 SonarSource SA - * mailto:info AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -import { shallow } from 'enzyme'; -import * as React from 'react'; -import { - mockAlmSettingsInstance, - mockProjectAzureBindingResponse, - mockProjectBitbucketBindingResponse, - mockProjectBitbucketCloudBindingResponse, - mockProjectGithubBindingResponse, - mockProjectGitLabBindingResponse -} from '../../../helpers/mocks/alm-settings'; -import { mockComponent } from '../../../helpers/mocks/component'; -import { mockLoggedInUser } from '../../../helpers/testMocks'; -import { click } from '../../../helpers/testUtils'; -import TutorialSelectionRenderer, { - TutorialSelectionRendererProps -} from '../TutorialSelectionRenderer'; -import { TutorialModes } from '../types'; - -it.each([ - ['bitbucket server', mockProjectBitbucketBindingResponse()], - ['github', mockProjectGithubBindingResponse()], - ['gitlab', mockProjectGitLabBindingResponse()], - ['azure', mockProjectAzureBindingResponse()] -])('should render correctly for %s', (_, projectBinding) => { - expect(shallowRender({ projectBinding })).toMatchSnapshot(); -}); - -it('should render correctly', () => { - expect(shallowRender()).toMatchSnapshot('selection'); - expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); - expect(shallowRender({ selectedTutorial: TutorialModes.Local })).toMatchSnapshot( - 'manual tutorial' - ); - expect( - shallowRender({ - selectedTutorial: TutorialModes.Jenkins, - projectBinding: mockProjectBitbucketBindingResponse() - }) - ).toMatchSnapshot('jenkins tutorial'); - expect( - shallowRender({ - selectedTutorial: TutorialModes.GitHubActions, - projectBinding: mockProjectGithubBindingResponse() - }) - ).toMatchSnapshot('github actions tutorial'); - expect( - shallowRender({ - selectedTutorial: TutorialModes.GitLabCI, - projectBinding: mockProjectGitLabBindingResponse() - }) - ).toMatchSnapshot('gitlab tutorial'); - expect( - shallowRender({ - selectedTutorial: TutorialModes.AzurePipelines, - projectBinding: mockProjectAzureBindingResponse() - }) - ).toMatchSnapshot('azure pipelines tutorial'); - expect(shallowRender({ currentUserCanScanProject: false })).toMatchSnapshot( - 'user has no scan permission' - ); -}); - -it('should allow mode selection for Bitbucket', () => { - const onSelectTutorial = jest.fn(); - const wrapper = shallowRender({ - onSelectTutorial, - projectBinding: mockProjectBitbucketBindingResponse() - }); - - click(wrapper.find('button.tutorial-mode-jenkins')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins); - - click(wrapper.find('button.tutorial-mode-local')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local); -}); - -it('should allow mode selection for Github', () => { - const onSelectTutorial = jest.fn(); - const wrapper = shallowRender({ - onSelectTutorial, - projectBinding: mockProjectGithubBindingResponse() - }); - - click(wrapper.find('button.tutorial-mode-jenkins')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins); - - click(wrapper.find('button.tutorial-mode-local')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local); - - click(wrapper.find('button.tutorial-mode-github-actions')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitHubActions); - - click(wrapper.find('button.tutorial-mode-azure-pipelines')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines); -}); - -it('should allow mode selection for GitLab', () => { - const onSelectTutorial = jest.fn(); - const wrapper = shallowRender({ - onSelectTutorial, - projectBinding: mockProjectGitLabBindingResponse() - }); - - click(wrapper.find('button.tutorial-mode-jenkins')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins); - - click(wrapper.find('button.tutorial-mode-gitlab-ci')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.GitLabCI); - - click(wrapper.find('button.tutorial-mode-local')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local); -}); - -it('should allow mode selection for Bitbucket pipepline', () => { - const onSelectTutorial = jest.fn(); - const wrapper = shallowRender({ - onSelectTutorial, - projectBinding: mockProjectBitbucketCloudBindingResponse() - }); - - click(wrapper.find('button.tutorial-mode-jenkins')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins); - - click(wrapper.find('button.tutorial-mode-bitbucket-pipelines')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.BitbucketPipelines); - - click(wrapper.find('button.tutorial-mode-local')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local); -}); - -it('should allow mode selection for Azure DevOps', () => { - const onSelectTutorial = jest.fn(); - const wrapper = shallowRender({ - onSelectTutorial, - projectBinding: mockProjectAzureBindingResponse() - }); - - click(wrapper.find('button.tutorial-mode-azure-pipelines')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.AzurePipelines); - - click(wrapper.find('button.tutorial-mode-local')); - expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Local); -}); - -function shallowRender(props: Partial = {}) { - return shallow( - - ); -} diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelection-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelection-test.tsx.snap deleted file mode 100644 index 6d0a8ba9332..00000000000 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelection-test.tsx.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly 1`] = ` - -`; diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap deleted file mode 100644 index 93fcf70abe1..00000000000 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap +++ /dev/null @@ -1,738 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should render correctly for azure 1`] = ` - -

- onboarding.tutorial.choose_method -

-
-

- onboarding.tutorial.choose_method.devops_platform.description -

-
- - -
-

- onboarding.tutorial.choose_method.local.description -

-
- -
-
-
-`; - -exports[`should render correctly for bitbucket server 1`] = ` - -

- onboarding.tutorial.choose_method -

-
-

- onboarding.tutorial.choose_method.devops_platform.description -

-
- - -
-

- onboarding.tutorial.choose_method.local.description -

-
- -
-
-
-`; - -exports[`should render correctly for github 1`] = ` - -

- onboarding.tutorial.choose_method -

-
-

- onboarding.tutorial.choose_method.devops_platform.description -

-
- - - - -
-

- onboarding.tutorial.choose_method.local.description -

-
- -
-
-
-`; - -exports[`should render correctly for gitlab 1`] = ` - -

- onboarding.tutorial.choose_method -

-
-

- onboarding.tutorial.choose_method.devops_platform.description -

-
- - - -
-

- onboarding.tutorial.choose_method.local.description -

-
- -
-
-
-`; - -exports[`should render correctly: azure pipelines tutorial 1`] = ` - - - -`; - -exports[`should render correctly: github actions tutorial 1`] = ` - - - -`; - -exports[`should render correctly: gitlab tutorial 1`] = ` - - - -`; - -exports[`should render correctly: jenkins tutorial 1`] = ` - - - -`; - -exports[`should render correctly: loading 1`] = ` - -`; - -exports[`should render correctly: manual tutorial 1`] = ` - - - -`; - -exports[`should render correctly: selection 1`] = ` - -

- onboarding.tutorial.choose_method -

-
-

- onboarding.tutorial.choose_method.devops_platform.description -

-
- - - - - - -
-

- onboarding.tutorial.choose_method.local.description -

-
- -
-
-
-`; - -exports[`should render correctly: user has no scan permission 1`] = ` - - onboarding.tutorial.no_scan_rights - -`; diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx index 256d7592b46..823ad58c8b9 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/AnalysisCommand.tsx @@ -32,12 +32,13 @@ import Others from './commands/Others'; export interface AnalysisCommandProps extends WithAvailableFeaturesProps { buildTool: BuildTools; + mainBranchName: string; component: Component; onDone: () => void; } export function AnalysisCommand(props: AnalysisCommandProps) { - const { buildTool, component } = props; + const { buildTool, component, mainBranchName } = props; const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); if (!buildTool) { @@ -49,6 +50,7 @@ export function AnalysisCommand(props: AnalysisCommandProps) { return ( @@ -57,6 +59,7 @@ export function AnalysisCommand(props: AnalysisCommandProps) { return ( @@ -65,6 +68,7 @@ export function AnalysisCommand(props: AnalysisCommandProps) { return ( @@ -73,6 +77,7 @@ export function AnalysisCommand(props: AnalysisCommandProps) { return ( @@ -81,12 +86,12 @@ export function AnalysisCommand(props: AnalysisCommandProps) { return ( ); } - return null; } export default withAvailableFeatures(AnalysisCommand); diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx index efa89c8d623..64a8ffd6e6c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/GitHubActionTutorial.tsx @@ -43,6 +43,7 @@ export interface GitHubActionTutorialProps { baseUrl: string; component: Component; currentUser: LoggedInUser; + mainBranchName: string; projectBinding?: ProjectAlmBindingResponse; willRefreshAutomatically?: boolean; } @@ -54,6 +55,7 @@ export default function GitHubActionTutorial(props: GitHubActionTutorialProps) { currentUser, component, projectBinding, + mainBranchName, willRefreshAutomatically } = props; @@ -86,6 +88,7 @@ export default function GitHubActionTutorial(props: GitHubActionTutorialProps) { {buildTool => ( setStep(Steps.ALL_SET)} /> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx index eeb4667d1f8..47f444fdd9c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/AnalysisCommand-test.tsx @@ -38,6 +38,7 @@ function shallowRender(props: Partial = {}) { return shallow( = {}) { baseUrl="test" currentUser={mockLoggedInUser()} component={mockComponent()} + mainBranchName="master" projectBinding={mockProjectGithubBindingResponse()} willRefreshAutomatically={true} {...props} diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap index 5543105efd6..01a9adb6013 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/__tests__/__snapshots__/AnalysisCommand-test.tsx.snap @@ -25,6 +25,7 @@ exports[`should render correctly for "cfamily" 1`] = ` "tags": Array [], } } + mainBranchName="main" onDone={[MockFunction]} /> `; @@ -54,6 +55,7 @@ exports[`should render correctly for "dotnet" 1`] = ` "tags": Array [], } } + mainBranchName="main" onDone={[MockFunction]} /> `; @@ -83,6 +85,7 @@ exports[`should render correctly for "gradle" 1`] = ` "tags": Array [], } } + mainBranchName="main" onDone={[MockFunction]} /> `; @@ -112,6 +115,7 @@ exports[`should render correctly for "maven" 1`] = ` "tags": Array [], } } + mainBranchName="main" onDone={[MockFunction]} /> `; @@ -141,6 +145,7 @@ exports[`should render correctly for "other" 1`] = ` "tags": Array [], } } + mainBranchName="main" onDone={[MockFunction]} /> `; diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx index c6e3e5bd27f..bccaf877ee4 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/CFamily.tsx @@ -27,20 +27,17 @@ import FinishButton from '../../components/FinishButton'; import GithubCFamilyExampleRepositories from '../../components/GithubCFamilyExampleRepositories'; import RenderOptions from '../../components/RenderOptions'; import { OSs, TutorialModes } from '../../types'; +import { generateGitHubActionsYaml } from '../utils'; export interface CFamilyProps { branchesEnabled?: boolean; + mainBranchName: string; component: Component; onDone: () => void; } const STEPS = { - [OSs.Linux]: `steps: - - name: Checkout code - uses: actions/checkout@v2 - with: - fetch-depth: 0 - + [OSs.Linux]: ` - name: Download and install the build wrapper, build the project run: | mkdir $HOME/.sonar @@ -64,12 +61,7 @@ const STEPS = { env: SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}`, - [OSs.MacOS]: `steps: - - name: Checkout code - uses: actions/checkout@v2 - with: - fetch-depth: 0 - + [OSs.MacOS]: ` - name: Download and install the build wrapper run: | mkdir $HOME/.sonar @@ -91,12 +83,7 @@ const STEPS = { env: SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}`, - [OSs.Windows]: `steps: - - name: Checkout code - uses: actions/checkout@v2 - with: - fetch-depth: 0 - + [OSs.Windows]: ` - name: Download and install the build wrapper shell: powershell run: | @@ -129,21 +116,8 @@ const STEPS = { SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }}` }; -const cfamilyYamlTemplate = (branchesEnabled: boolean, os: OSs) => `name: Build -on: - push: - branches: - - master # or the name of your main branch -${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''} - -jobs: - build: - runs-on: - ${STEPS[os]} -`; - export default function CFamily(props: CFamilyProps) { - const { component, branchesEnabled } = props; + const { component, branchesEnabled, mainBranchName } = props; const [os, setOs] = React.useState(); return ( @@ -170,7 +144,12 @@ export default function CFamily(props: CFamilyProps) { <> ', + STEPS[os] + )} /> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/DotNet.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/DotNet.tsx index 810d1236eb1..3a09a7e28e8 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/DotNet.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/DotNet.tsx @@ -21,31 +21,22 @@ import * as React from 'react'; import { Component } from '../../../../types/types'; import CreateYmlFile from '../../components/CreateYmlFile'; import FinishButton from '../../components/FinishButton'; +import { GITHUB_ACTIONS_RUNS_ON_WINDOWS } from '../constants'; +import { generateGitHubActionsYaml } from '../utils'; export interface DotNetProps { branchesEnabled?: boolean; + mainBranchName: string; component: Component; onDone: () => void; } -const dotnetYamlTemplate = (projectKey: string, branchesEnabled: boolean) => `name: Build -on: - push: - branches: - - master # or the name of your main branch -${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''} -jobs: - build: - name: Build - runs-on: windows-latest - steps: +function dotnetYamlSteps(projectKey: string) { + return ` - name: Set up JDK 11 uses: actions/setup-java@v1 with: java-version: 1.11 - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - name: Cache SonarQube packages uses: actions/cache@v1 with: @@ -73,14 +64,20 @@ jobs: .\\.sonar\\scanner\\dotnet-sonarscanner begin /k:"${projectKey}" /d:sonar.login="\${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="\${{ secrets.SONAR_HOST_URL }}" dotnet build .\\.sonar\\scanner\\dotnet-sonarscanner end /d:sonar.login="\${{ secrets.SONAR_TOKEN }}"`; +} export default function DotNet(props: DotNetProps) { - const { component, branchesEnabled } = props; + const { component, branchesEnabled, mainBranchName } = props; return ( <> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Gradle.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Gradle.tsx index 4d76a483c3d..e2b8d44eb67 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Gradle.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Gradle.tsx @@ -26,26 +26,17 @@ import CodeSnippet from '../../../common/CodeSnippet'; import CreateYmlFile from '../../components/CreateYmlFile'; import FinishButton from '../../components/FinishButton'; import { buildGradleSnippet } from '../../utils'; +import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants'; +import { generateGitHubActionsYaml } from '../utils'; export interface GradleProps { branchesEnabled?: boolean; + mainBranchName: string; component: Component; onDone: () => void; } -const gradleYamlTemplate = (branchesEnabled: boolean) => `name: Build -on: - push: - branches: - - master # or the name of your main branch -${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''} -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis + +const GRADLE_YAML_STEPS = ` - name: Set up JDK 11 uses: actions/setup-java@v1 with: @@ -70,7 +61,7 @@ jobs: run: ./gradlew build sonarqube --info`; export default function Gradle(props: GradleProps) { - const { component, branchesEnabled } = props; + const { component, branchesEnabled, mainBranchName } = props; return ( <> @@ -92,7 +83,12 @@ export default function Gradle(props: GradleProps) { diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/JavaMaven.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/JavaMaven.tsx index a3c69da85fa..706f66d27df 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/JavaMaven.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/JavaMaven.tsx @@ -21,27 +21,18 @@ import * as React from 'react'; import { Component } from '../../../../types/types'; import CreateYmlFile from '../../components/CreateYmlFile'; import FinishButton from '../../components/FinishButton'; +import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants'; +import { generateGitHubActionsYaml } from '../utils'; export interface JavaMavenProps { branchesEnabled?: boolean; + mainBranchName: string; component: Component; onDone: () => void; } -const mavenYamlTemplte = (branchesEnabled: boolean, projectKey: string) => `name: Build -on: - push: - branches: - - master # or the name of your main branch -${branchesEnabled ? ' pull_request:\n types: [opened, synchronize, reopened]' : ''} -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis +function mavenYamlSteps(projectKey: string) { + return ` - name: Set up JDK 11 uses: actions/setup-java@v1 with: @@ -64,14 +55,20 @@ jobs: SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }} SONAR_HOST_URL: \${{ secrets.SONAR_HOST_URL }} run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=${projectKey}`; +} export default function JavaMaven(props: JavaMavenProps) { - const { component, branchesEnabled } = props; + const { component, branchesEnabled, mainBranchName } = props; return ( <> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Others.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Others.tsx index 3d0d3825886..b100b775993 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Others.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/Others.tsx @@ -22,35 +22,18 @@ import { Component } from '../../../../types/types'; import CreateYmlFile from '../../components/CreateYmlFile'; import DefaultProjectKey from '../../components/DefaultProjectKey'; import FinishButton from '../../components/FinishButton'; +import { GITHUB_ACTIONS_RUNS_ON_LINUX } from '../constants'; +import { generateGitHubActionsYaml } from '../utils'; export interface OthersProps { branchesEnabled?: boolean; + mainBranchName: string; component: Component; onDone: () => void; } -const yamlTemplate = (branchesEnabled: boolean) => { - let output = `name: Build -on: - push: - branches: - - master # or the name of your main branch`; - - if (branchesEnabled) { - output += ` - pull_request: - types: [opened, synchronize, reopened]`; - } - - output += ` -jobs: - build: - name: Build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 +function otherYamlSteps(branchesEnabled: boolean) { + let output = ` - uses: sonarsource/sonarqube-scan-action@master env: SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }} @@ -71,16 +54,21 @@ jobs: # SONAR_TOKEN: \${{ secrets.SONAR_TOKEN }}`; return output; -}; +} export default function Others(props: OthersProps) { - const { component, branchesEnabled } = props; + const { component, branchesEnabled, mainBranchName } = props; return ( <> diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/CFamily-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/CFamily-test.tsx index 2bbbdf8fd09..dc4ea5ec120 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/CFamily-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/CFamily-test.tsx @@ -43,6 +43,12 @@ it.each([ function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/DotNet-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/DotNet-test.tsx index 85372435783..1dc3811dc32 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/DotNet-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/DotNet-test.tsx @@ -29,6 +29,12 @@ it('should render correctly', () => { function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Gradle-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Gradle-test.tsx index 0c9448ce285..a52cbb5d2f6 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Gradle-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Gradle-test.tsx @@ -29,6 +29,12 @@ it('should render correctly', () => { function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/JavaMaven-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/JavaMaven-test.tsx index 3eee022fe76..a042cedc600 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/JavaMaven-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/JavaMaven-test.tsx @@ -29,6 +29,12 @@ it('should render correctly', () => { function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Others-test.tsx b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Others-test.tsx index 1b4212ead6b..48b464822db 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Others-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/Others-test.tsx @@ -29,6 +29,12 @@ it('should render correctly', () => { function shallowRender(props: Partial = {}) { return shallow( - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/__snapshots__/CFamily-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/__snapshots__/CFamily-test.tsx.snap index 0bb3b8961db..15eeaf5e46e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/__snapshots__/CFamily-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/github-action/commands/__tests__/__snapshots__/CFamily-test.tsx.snap @@ -102,21 +102,21 @@ exports[`should render correctly for linux: branches disabled 1`] = ` void; open: boolean; projectKey: string; + mainBranchName: string; } export function YmlFileStep(props: YmlFileStepProps) { - const { buildTool, open, finished, projectKey } = props; + const { buildTool, open, finished, projectKey, mainBranchName } = props; const branchSupportEnabled = props.hasFeature(Feature.BranchSupport); const renderForm = () => ( @@ -79,6 +80,7 @@ export function YmlFileStep(props: YmlFileStepProps) { diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-test.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-test.tsx index a5b34b50822..49baf473898 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/GitLabCITutorial-test.tsx @@ -33,6 +33,7 @@ function shallowRender(props: Partial = {}) { baseUrl="http://localhost:9000" component={mockComponent()} currentUser={mockLoggedInUser()} + mainBranchName="main" willRefreshAutomatically={true} {...props} /> diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx index 9c6b0614afa..ac93bffa6cf 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/YmlFileStep-test.tsx @@ -49,6 +49,7 @@ function shallowRender(props: Partial = {}) { open={true} projectKey="test" finished={true} + mainBranchName="main" onDone={jest.fn()} onOpen={jest.fn()} {...props} diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-test.tsx.snap index d3fc71fa399..5d6322ac43e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/__tests__/__snapshots__/GitLabCITutorial-test.tsx.snap @@ -83,6 +83,7 @@ exports[`should render correctly 1`] = ` /> @@ -108,6 +109,7 @@ exports[`should render correctly for build tool cfamily: without branch support @@ -168,6 +170,7 @@ exports[`should render correctly for build tool dotnet: with branch support 1`] @@ -228,6 +231,7 @@ exports[`should render correctly for build tool dotnet: without branch support 1 @@ -288,6 +292,7 @@ exports[`should render correctly for build tool gradle: with branch support 1`] @@ -348,6 +353,7 @@ exports[`should render correctly for build tool gradle: without branch support 1 @@ -408,6 +414,7 @@ exports[`should render correctly for build tool maven: with branch support 1`] = @@ -468,6 +475,7 @@ exports[`should render correctly for build tool maven: without branch support 1` @@ -528,6 +536,7 @@ exports[`should render correctly for build tool other: with branch support 1`] = @@ -588,6 +597,7 @@ exports[`should render correctly for build tool other: without branch support 1` diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx index 9b78795ed09..4202cb2cd51 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/PipeCommand.tsx @@ -25,6 +25,7 @@ import { BuildTools } from '../../types'; export interface PipeCommandProps { branchesEnabled?: boolean; buildTool: BuildTools; + mainBranchName: string; projectKey: string; } @@ -55,7 +56,8 @@ const BUILD_TOOL_SPECIFIC = { } }; -export default function PipeCommand({ projectKey, branchesEnabled, buildTool }: PipeCommandProps) { +export default function PipeCommand(props: PipeCommandProps) { + const { projectKey, branchesEnabled, buildTool, mainBranchName } = props; let command: string; if (buildTool === BuildTools.CFamily) { command = `image: @@ -91,9 +93,9 @@ sonarqube-check: } else { const onlyBlock = branchesEnabled ? `- merge_requests - - master # or the name of your main branch + - ${mainBranchName} - develop` - : '- master # or the name of your main branch'; + : `- ${mainBranchName}`; const { image, script } = BUILD_TOOL_SPECIFIC[buildTool]; diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/PipeCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/PipeCommand-test.tsx index 1542dd14cf2..0304f125f47 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/PipeCommand-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/PipeCommand-test.tsx @@ -30,9 +30,23 @@ it.each([ [BuildTools.Other] ])('should render correctly for %s', buildTool => { expect( - shallow() + shallow( + + ) ).toMatchSnapshot('branches enabled'); expect( - shallow() + shallow( + + ) ).toMatchSnapshot('branches not enabled'); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/__snapshots__/PipeCommand-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/__snapshots__/PipeCommand-test.tsx.snap index 94a01df480b..9b66a6ec41e 100644 --- a/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/__snapshots__/PipeCommand-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/gitlabci/commands/__tests__/__snapshots__/PipeCommand-test.tsx.snap @@ -99,7 +99,7 @@ exports[`should render correctly for dotnet: branches enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -129,7 +129,7 @@ exports[`should render correctly for dotnet: branches not enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -152,7 +152,7 @@ exports[`should render correctly for gradle: branches enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -175,7 +175,7 @@ exports[`should render correctly for gradle: branches not enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -199,7 +199,7 @@ exports[`should render correctly for maven: branches enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -223,7 +223,7 @@ exports[`should render correctly for maven: branches not enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -249,7 +249,7 @@ exports[`should render correctly for other: branches enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> @@ -275,7 +275,7 @@ exports[`should render correctly for other: branches not enabled 1`] = ` allow_failure: true only: - merge_requests - - master # or the name of your main branch + - main - develop " /> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx index 3b47235be27..1f94552c9e3 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/AnalysisCommand.tsx @@ -18,7 +18,6 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { getHostUrl } from '../../../../helpers/urls'; import { Component } from '../../../../types/types'; import { BuildTools, ManualTutorialConfig } from '../../types'; import ClangGCCCustom from './ClangGCCCommand'; @@ -42,24 +41,21 @@ export default function AnalysisCommand(props: AnalysisCommandProps) { return null; } - const host = getHostUrl(); - switch (languageConfig.buildTool) { case BuildTools.Maven: - return ; + return ; case BuildTools.Gradle: - return ; + return ; case BuildTools.DotNet: - return ; + return ; case BuildTools.CFamily: return languageConfig.os !== undefined ? ( @@ -45,7 +44,7 @@ export default function ClangGCCCustom(props: ClangGCCCustomProps) { - + ); } diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/CLangGCCCommand-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/CLangGCCCommand-test.tsx index b1ecce6b02d..8bbc94e8270 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/CLangGCCCommand-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/CLangGCCCommand-test.tsx @@ -30,7 +30,6 @@ it('should render correctly', () => { os={OSs.Linux} baseUrl="http://example.com" isLocal={true} - host="host" component={mockComponent({ key: 'projectKey' })} token="token" /> diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNet-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNet-test.tsx index 1b40ad0419e..2a7411fdb72 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNet-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNet-test.tsx @@ -24,6 +24,8 @@ import DotNet from '../DotNet'; it('should render correctly', () => { expect( - shallow() + shallow( + + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNetFramework-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNetFramework-test.tsx index 12932520c37..c1dc010779f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNetFramework-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotNetFramework-test.tsx @@ -25,7 +25,11 @@ import DotNetFramework from '../DotNetFramework'; it('should render correctly', () => { expect( shallow( - + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotnetCore-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotnetCore-test.tsx index f40ad7f077f..a8998cf65d8 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotnetCore-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/DotnetCore-test.tsx @@ -25,7 +25,7 @@ import DotNetCore from '../DotNetCore'; it('should render correctly', () => { expect( shallow( - + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/ExecScanner-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/ExecScanner-test.tsx index dbea16d6b08..1fbe02bb25f 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/ExecScanner-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/ExecScanner-test.tsx @@ -38,7 +38,7 @@ it('should render correctly for remote execution', () => { function shallowRender(props: Partial = {}) { return shallow( { expect( shallow( - + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/JavaMaven-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/JavaMaven-test.tsx index 808712fe5eb..4eed77c8bea 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/JavaMaven-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/JavaMaven-test.tsx @@ -25,7 +25,7 @@ import JavaMaven from '../JavaMaven'; it('renders correctly', () => { expect( shallow( - + ) ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/Other-test.tsx b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/Other-test.tsx index 0beb634c1f9..14a43eaf93c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/Other-test.tsx +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/Other-test.tsx @@ -30,7 +30,7 @@ it('renders correctly', () => { function shallowRender(props: Partial = {}) { return shallow( `; @@ -54,7 +54,6 @@ exports[`renders correctly: CFamily 1`] = ` "tags": Array [], } } - host="HOST" isLocal={true} os="linux" token="myToken" @@ -65,6 +64,7 @@ exports[`renders correctly: Empty CFamily 1`] = `""`; exports[`renders correctly: gradle 1`] = ` `; exports[`renders correctly: maven 1`] = ` `; exports[`renders correctly: other 1`] = ` diff --git a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/__snapshots__/Other-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/__snapshots__/Other-test.tsx.snap index ffbf9f32605..a64504b17ef 100644 --- a/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/__snapshots__/Other-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/other/commands/__tests__/__snapshots__/Other-test.tsx.snap @@ -8,6 +8,7 @@ exports[`renders correctly 1`] = ` token="token" /> string { export function buildGradleSnippet(key: string) { return `plugins { - id "org.sonarqube" version "3.4.0.2513" + id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}" } sonarqube { diff --git a/server/sonar-web/src/main/js/helpers/constants.ts b/server/sonar-web/src/main/js/helpers/constants.ts index 0f73991916f..eb251b676ce 100644 --- a/server/sonar-web/src/main/js/helpers/constants.ts +++ b/server/sonar-web/src/main/js/helpers/constants.ts @@ -76,3 +76,5 @@ export const IMPORT_COMPATIBLE_ALMS = [ export const IMPORT_COMPATIBLE_ALM_COUNT = IMPORT_COMPATIBLE_ALMS.filter( a => a !== AlmKeys.BitbucketCloud ).length; + +export const GRADLE_SCANNER_VERSION = '3.4.0.2513'; -- 2.39.5