import { NewUserToken, TokenType, UserToken } from '../../types/token';
import { generateToken, getTokens, revokeToken } from '../user-tokens';
-const RANDOM_RADIX = 36;
-const RANDOM_PREFIX = 2;
-
const defaultTokens = [
mockUserToken({
name: 'local-scanner',
type,
projectKey,
isExpired: false,
- token: Math.random().toString(RANDOM_RADIX).slice(RANDOM_PREFIX),
+ token: `generatedtoken${this.tokens.length}`,
createdAt: '2022-04-04T04:04:04+0000',
expirationDate,
};
onStepValidationChange={onStepValidationChange}
buildTool={buildTechnology}
projectKey={component.key}
+ projectName={component.name}
/>
</>
);
import { renderApp, RenderContext } from '../../../../helpers/testReactTestingUtils';
import { Permissions } from '../../../../types/permissions';
import { TokenType } from '../../../../types/token';
+import { getCopyToClipboardValue } from '../../test-utils';
import { OSs } from '../../types';
import AzurePipelinesTutorial, { AzurePipelinesTutorialProps } from '../AzurePipelinesTutorial';
async function goToNextStep(user: UserEvent) {
await clickButton(user, 'continue');
}
-
-function getCopyToClipboardValue(i = 0, name = 'copy_to_clipboard') {
- return screen.getAllByRole('button', { name })[i].getAttribute('data-clipboard-text');
-}
"# Additional properties that will be passed to the scanner,
# Put one key=value per line, example:
# sonar.exclusions=**/*.bin
-sonar.projectKey=foo"
+sonar.projectKey=foo
+sonar.projectName=MyProject
+"
`;
exports[`should render correctly and allow navigating between the different steps: maven, copy additional properties 1`] = `
"# Additional properties that will be passed to the scanner,
# Put one key=value per line, example:
# sonar.exclusions=**/*.bin
-sonar.projectKey=foo"
+sonar.projectKey=foo
+sonar.projectName=MyProject
+"
`;
export interface AnalysisCommandProps {
projectKey: string;
+ projectName: string;
buildTool?: BuildTools;
onStepValidationChange: (isValid: boolean) => void;
}
export default function AnalysisCommand(props: AnalysisCommandProps) {
- const { buildTool, projectKey } = props;
+ const { buildTool, projectKey, projectName } = props;
React.useEffect(() => {
if (buildTool && buildTool !== BuildTools.CFamily) {
}
switch (buildTool) {
case BuildTools.Maven:
- return <JavaMaven projectKey={projectKey} />;
+ return <JavaMaven projectKey={projectKey} projectName={projectName} />;
case BuildTools.Gradle:
- return <JavaGradle projectKey={projectKey} />;
+ return <JavaGradle projectKey={projectKey} projectName={projectName} />;
case BuildTools.DotNet:
return <DotNet projectKey={projectKey} />;
export interface JavaGradleProps {
projectKey: string;
+ projectName: string;
}
export default function JavaGradle(props: JavaGradleProps) {
- const { projectKey } = props;
+ const { projectKey, projectName } = props;
return (
<>
buildTool={BuildTools.Gradle}
kind={PrepareType.JavaMavenGradle}
projectKey={projectKey}
+ projectName={projectName}
/>
</li>
export interface JavaMavenProps {
projectKey: string;
+ projectName: string;
}
export default function JavaMaven(props: JavaMavenProps) {
- const { projectKey } = props;
+ const { projectKey, projectName } = props;
return (
<>
<AlertClassicEditor />
buildTool={BuildTools.Gradle}
kind={PrepareType.JavaMavenGradle}
projectKey={projectKey}
+ projectName={projectName}
/>
</li>
buildTool: BuildTools;
kind: PrepareType;
projectKey: string;
+ projectName?: string;
}
export default function PrepareAnalysisCommand(props: PrepareAnalysisCommandProps) {
- const { buildTool, kind, projectKey } = props;
+ const { buildTool, kind, projectKey, projectName } = props;
const ADDITIONAL_PROPERTY = 'sonar.cfamily.build-wrapper-output=bw-output';
const MAVEN_GRADLE_PROPS_SNIPPET = `# Additional properties that will be passed to the scanner,
# Put one key=value per line, example:
# sonar.exclusions=**/*.bin
-sonar.projectKey=${projectKey}`;
+sonar.projectKey=${projectKey}
+sonar.projectName=${projectName}
+`;
return (
<ul className="list-styled list-alpha spacer-top">
}
const YamlTemplate: Dictionary<
- (branchesEnabled?: boolean, mainBranchName?: string, projectKey?: string) => string
+ (
+ branchesEnabled?: boolean,
+ mainBranchName?: string,
+ projectKey?: string,
+ projectName?: string
+ ) => string
> = {
[BuildTools.Gradle]: gradleExample,
[BuildTools.Maven]: mavenExample,
return null;
}
- const yamlTemplate = YamlTemplate[buildTool](branchSupportEnabled, mainBranchName, component.key);
+ const yamlTemplate = YamlTemplate[buildTool](
+ branchSupportEnabled,
+ mainBranchName,
+ component.key,
+ component.name
+ );
return (
<>
sq: <code className="rule">org.sonarqube</code>,
}}
/>
- <CodeSnippet snippet={buildGradleSnippet(component.key)} />
+ <CodeSnippet snippet={buildGradleSnippet(component.key, component.name)} />
</li>
);
case BuildTools.CFamily:
- maven
- sonar
script:
- - mvn verify sonar:sonar -Dsonar.projectKey=my-project
+ - mvn verify sonar:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'
caches:
sonar: ~/.sonar
- maven
- sonar
script:
- - mvn verify sonar:sonar -Dsonar.projectKey=my-project
+ - mvn verify sonar:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'
caches:
sonar: ~/.sonar
sonar {
properties {
property "sonar.projectKey", "my-project"
+ property "sonar.projectName", "MyProject"
}
}"
/>
export default function mavenExample(
branchesEnabled: boolean,
mainBranchName: string,
- projectKey: string
+ projectKey: string,
+ projectName: string
) {
return `image: maven:3-openjdk-11
- maven
- sonar
script:
- - mvn verify sonar:sonar -Dsonar.projectKey=${projectKey}
+ - mvn verify sonar:sonar -Dsonar.projectKey=${projectKey} -Dsonar.projectName='${projectName}'
caches:
sonar: ~/.sonar
sq: <code className="rule">org.sonarqube</code>,
}}
/>
- <CodeSnippet snippet={buildGradleSnippet(component.key)} />
+ <CodeSnippet snippet={buildGradleSnippet(component.key, component.name)} />
</li>
<CreateYmlFile
yamlFileName=".github/workflows/build.yml"
onDone: () => void;
}
-function mavenYamlSteps(projectKey: string) {
+function mavenYamlSteps(projectKey: string, projectName: string) {
return `
- name: Set up JDK 11
uses: actions/setup-java@v1
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
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}`;
+ run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=${projectKey} -Dsonar.projectName='${projectName}'`;
}
export default function JavaMaven(props: JavaMavenProps) {
mainBranchName,
!!branchesEnabled,
GITHUB_ACTIONS_RUNS_ON_LINUX,
- mavenYamlSteps(component.key)
+ mavenYamlSteps(component.key, component.name)
)}
/>
<FinishButton onClick={props.onDone} />
sonar {
properties {
property "sonar.projectKey", "my-project"
+ property "sonar.projectName", "MyProject"
}
}"
/>
sonar {
properties {
property "sonar.projectKey", "my-project"
+ property "sonar.projectName", "MyProject"
}
}"
/>
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
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=my-project"
+ run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'"
/>
<FinishButton
onClick={[MockFunction]}
GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
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=my-project"
+ run: mvn -B verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'"
/>
<FinishButton
onClick={[MockFunction]}
onDone={() => setStep(Steps.ALL_SET)}
onOpen={() => setStep(Steps.YML)}
open={step === Steps.YML}
- projectKey={component.key}
/>
<AllSetStep
onDone: () => void;
onOpen: () => void;
open: boolean;
- projectKey: string;
mainBranchName: string;
}
<sonar.qualitygate.wait>true</sonar.qualitygate.wait>
</properties>`;
-const gradleSnippet = (key: string) => `plugins {
+const gradleSnippet = (key: string, name: string) => `plugins {
id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}"
}
sonar {
properties {
property "sonar.projectKey", "${key}"
+ property "sonar.projectName", "${name}"
property "sonar.qualitygate.wait", true
}
}`;
};
export function YmlFileStep(props: YmlFileStepProps) {
- const { open, finished, projectKey, mainBranchName, hasCLanguageFeature, component } = props;
+ const { open, finished, mainBranchName, hasCLanguageFeature, component } = props;
const branchSupportEnabled = props.hasFeature(Feature.BranchSupport);
const [buildTool, setBuildTool] = React.useState<BuildTools>();
),
}}
/>
- <CodeSnippet snippet={snippetForBuildTool[buildTool](component.key)} />
+ <CodeSnippet snippet={snippetForBuildTool[buildTool](component.key, component.name)} />
</li>
)}
{buildTool && (
buildTool={buildTool}
branchesEnabled={branchSupportEnabled}
mainBranchName={mainBranchName}
- projectKey={projectKey}
+ projectKey={component.key}
+ projectName={component.name}
/>
</div>
<p className="little-spacer-bottom">
component={mockComponent()}
hasFeature={jest.fn().mockReturnValue(true)}
open={true}
- projectKey="test"
finished={true}
mainBranchName="main"
onDone={jest.fn()}
onDone={[Function]}
onOpen={[Function]}
open={false}
- projectKey="my-project"
/>
<AllSetStep
alm="gitlab"
buildTool: BuildTools;
mainBranchName: string;
projectKey: string;
+ projectName: string;
}
const BUILD_TOOL_SPECIFIC = {
[BuildTools.Gradle]: { image: 'gradle:jre11-slim', script: () => 'gradle sonar' },
[BuildTools.Maven]: {
image: 'maven:3.6.3-jdk-11',
- script: (projectKey: string) => `
- - mvn verify sonar:sonar -Dsonar.projectKey=${projectKey}`,
+ script: (projectKey: string, projectName: string) => `
+ - mvn verify sonar:sonar -Dsonar.projectKey=${projectKey} -Dsonar.projectName='${projectName}'`,
},
[BuildTools.DotNet]: {
image: 'mcr.microsoft.com/dotnet/core/sdk:latest',
};
export default function PipeCommand(props: PipeCommandProps) {
- const { projectKey, branchesEnabled, buildTool, mainBranchName } = props;
+ const { projectKey, branchesEnabled, buildTool, mainBranchName, projectName } = props;
let command: string;
if (buildTool === BuildTools.CFamily) {
command = `image: <image ready for your build toolchain>
key: "\${CI_JOB_NAME}"
paths:
- .sonar/cache
- script: ${script(projectKey)}
+ script: ${script(projectKey, projectName)}
allow_failure: true
rules:
${onlyBlock}
branchesEnabled={true}
mainBranchName="main"
projectKey="test"
+ projectName="Test Project"
/>
)
).toMatchSnapshot('branches enabled');
branchesEnabled={true}
mainBranchName="main"
projectKey="test"
+ projectName="Test Project"
/>
)
).toMatchSnapshot('branches not enabled');
paths:
- .sonar/cache
script:
- - mvn verify sonar:sonar -Dsonar.projectKey=test
+ - mvn verify sonar:sonar -Dsonar.projectKey=test -Dsonar.projectName='Test Project'
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
paths:
- .sonar/cache
script:
- - mvn verify sonar:sonar -Dsonar.projectKey=test
+ - mvn verify sonar:sonar -Dsonar.projectKey=test -Dsonar.projectName='Test Project'
allow_failure: true
rules:
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
filename="build.gradle"
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2"
/>
- <CodeSnippet snippet={buildGradleSnippet(component.key)} />
+ <CodeSnippet snippet={buildGradleSnippet(component.key, component.name)} />
</li>
<CreateJenkinsfileBulletPoint snippet={JENKINSFILE_SNIPPET} />
<FinishButton onClick={props.onDone} />
import { LanguageProps } from '../JenkinsfileStep';
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint';
-function jenkinsfileSnippet(projectKey: string) {
+function jenkinsfileSnippet(projectKey: string, projectName: string) {
return `node {
stage('SCM') {
checkout scm
stage('SonarQube Analysis') {
def mvn = tool 'Default Maven';
withSonarQubeEnv() {
- sh "\${mvn}/bin/mvn clean verify sonar:sonar -Dsonar.projectKey=${projectKey}"
+ sh "\${mvn}/bin/mvn clean verify sonar:sonar -Dsonar.projectKey=${projectKey} -Dsonar.projectName='${projectName}'"
}
}
}`;
<>
<CreateJenkinsfileBulletPoint
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3"
- snippet={jenkinsfileSnippet(component.key)}
+ snippet={jenkinsfileSnippet(component.key, component.name)}
/>
<FinishButton onClick={onDone} />
</>
sonar {
properties {
property "sonar.projectKey", "my-project"
+ property "sonar.projectName", "MyProject"
}
}"
/>
stage('SonarQube Analysis') {
def mvn = tool 'Default Maven';
withSonarQubeEnv() {
- sh "\${mvn}/bin/mvn clean verify sonar:sonar -Dsonar.projectKey=my-project"
+ sh "\${mvn}/bin/mvn clean verify sonar:sonar -Dsonar.projectKey=my-project -Dsonar.projectName='MyProject'"
}
}
}"
{loading ? (
<i className="spinner text-middle" />
) : (
- <DeleteButton className="button-small text-middle" onClick={this.handleTokenRevoke} />
+ <DeleteButton
+ className="button-small text-middle"
+ aria-label={translate('onboarding.token.delete')}
+ onClick={this.handleTokenRevoke}
+ />
)}
</form>
) : (
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { BuildTools, OSs } from '../../types';
-import { BuildToolForm } from '../BuildToolForm';
-
-it('renders correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(shallowRender({ hasCLanguageFeature: false })).toMatchSnapshot('without C');
- expect(shallowRender().setState({ config: { buildTool: BuildTools.Maven } })).toMatchSnapshot(
- 'with "maven" selected'
- );
- expect(shallowRender().setState({ config: { buildTool: BuildTools.Other } })).toMatchSnapshot(
- 'with "other" selected'
- );
-});
-
-it('correctly calls the onDone prop', () => {
- const onDone = jest.fn();
- const wrapper = shallowRender({ onDone });
-
- wrapper.instance().handleBuildToolChange(BuildTools.Gradle);
- expect(onDone).toHaveBeenCalledWith(expect.objectContaining({ buildTool: BuildTools.Gradle }));
-
- wrapper.setState({ config: { buildTool: BuildTools.Other } });
- wrapper.instance().handleOSChange(OSs.Windows);
- expect(onDone).toHaveBeenCalledWith(
- expect.objectContaining({ os: OSs.Windows, buildTool: BuildTools.Other })
- );
-});
-
-function shallowRender(props: Partial<BuildToolForm['props']> = {}) {
- return shallow<BuildToolForm>(
- <BuildToolForm onDone={jest.fn()} hasCLanguageFeature={true} {...props} />
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockComponent } from '../../../../helpers/mocks/component';
-import DoneNextSteps, { DoneNextStepsProps } from '../DoneNextSteps';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
- expect(
- shallowRender({ component: mockComponent({ configuration: { showSettings: true } }) })
- ).toMatchSnapshot('project admin');
-});
-
-function shallowRender(props: Partial<DoneNextStepsProps> = {}) {
- return shallow<DoneNextStepsProps>(<DoneNextSteps component={mockComponent()} {...props} />);
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 userEvent from '@testing-library/user-event';
+import React from 'react';
+import selectEvent from 'react-select-event';
+import { byRole, byText } from 'testing-library-selector';
+import UserTokensMock from '../../../../api/mocks/UserTokensMock';
+import { mockComponent } from '../../../../helpers/mocks/component';
+import { mockLanguage, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { renderApp, RenderContext } from '../../../../helpers/testReactTestingUtils';
+import { getCopyToClipboardValue, getTutorialBuildButtons } from '../../test-utils';
+import OtherTutorial from '../OtherTutorial';
+
+jest.mock('../../../../api/user-tokens');
+
+jest.mock('../../../../api/settings', () => ({
+ getAllValues: jest.fn().mockResolvedValue([]),
+}));
+
+const tokenMock = new UserTokensMock();
+
+afterEach(() => {
+ tokenMock.reset();
+});
+
+const ui = {
+ provideTokenTitle: byRole('heading', { name: 'onboarding.token.header' }),
+ runAnalysisTitle: byRole('heading', { name: 'onboarding.analysis.header' }),
+ generateTokenRadio: byRole('radio', { name: 'onboarding.token.generate.PROJECT_ANALYSIS_TOKEN' }),
+ existingTokenRadio: byRole('radio', { name: 'onboarding.token.use_existing_token' }),
+ tokenNameInput: byRole('textbox', { name: 'onboarding.token.name.label' }),
+ expiresInSelect: byRole('combobox', { name: '' }),
+ generateTokenButton: byRole('button', { name: 'onboarding.token.generate' }),
+ deleteTokenButton: byRole('button', { name: 'onboarding.token.delete' }),
+ tokenValueInput: byRole('textbox', { name: 'onboarding.token.use_existing_token.label' }),
+ invalidTokenValueMessage: byText('onboarding.token.invalid_format'),
+ continueButton: byRole('button', { name: 'continue' }),
+ ...getTutorialBuildButtons(),
+};
+
+it('should generate/delete a new token or use existing one', async () => {
+ const user = userEvent.setup();
+ renderOtherTutorial();
+
+ // Verify that pages is rendered and includes 2 steps
+ expect(await ui.provideTokenTitle.find()).toBeInTheDocument();
+ expect(ui.runAnalysisTitle.get()).toBeInTheDocument();
+
+ // Generating token
+ user.type(ui.tokenNameInput.get(), 'Testing token');
+ await selectEvent.select(ui.expiresInSelect.get(), 'users.tokens.expiration.365');
+ await user.click(ui.generateTokenButton.get());
+
+ expect(ui.continueButton.get()).toBeEnabled();
+
+ // Deleting generated token & switchning to existing one
+ await user.click(ui.deleteTokenButton.get());
+
+ await user.click(ui.existingTokenRadio.get());
+ await user.type(ui.tokenValueInput.get(), 'INVALID TOKEN VALUE');
+ expect(ui.invalidTokenValueMessage.get()).toBeInTheDocument();
+
+ user.clear(ui.tokenValueInput.get());
+ await user.type(ui.tokenValueInput.get(), 'validtokenvalue');
+ expect(ui.continueButton.get()).toBeEnabled();
+
+ // navigate to 'Run analysis' step
+ await user.click(ui.continueButton.get());
+ expect(ui.describeBuildTitle.get()).toBeInTheDocument();
+
+ // navigate to previous step
+ await user.click(ui.provideTokenTitle.get());
+ expect(ui.continueButton.get()).toBeEnabled();
+});
+
+it('can choose build tools and copy provided settings', async () => {
+ const user = userEvent.setup();
+ renderOtherTutorial();
+
+ await user.click(ui.generateTokenButton.get());
+ await user.click(ui.continueButton.get());
+
+ // Maven
+ await user.click(ui.mavenBuildButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('maven: execute scanner');
+
+ // Gradle
+ await user.click(ui.gradleBuildButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('gradle: sonarqube plugin');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('gradle: execute scanner');
+
+ // Dotnet - Core
+ await user.click(ui.dotnetBuildButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('dotnet core: install scanner globally');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('dotnet core: execute command 1');
+ expect(getCopyToClipboardValue(2)).toMatchSnapshot('dotnet core: execute command 2');
+ expect(getCopyToClipboardValue(3)).toMatchSnapshot('dotnet core: execute command 3');
+
+ // Dotnet - Framework
+ await user.click(ui.dotnetFrameworkButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('dotnet framework: execute command 1');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('dotnet framework: execute command 2');
+ expect(getCopyToClipboardValue(2)).toMatchSnapshot('dotnet framework: execute command 3');
+
+ // C Family - Linux
+ await user.click(ui.cFamilyBuildButton.get());
+ await user.click(ui.linuxButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('cfamily linux: execute build wrapper');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('cfamily linux: execute scanner');
+
+ // C Family - Windows
+ await user.click(ui.windowsButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('cfamily windows: execute build wrapper');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('cfamily windows: execute scanner');
+
+ // C Family - MacOS
+ await user.click(ui.macosButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('cfamily macos: execute build wrapper');
+ expect(getCopyToClipboardValue(1)).toMatchSnapshot('cfamily macos: execute scanner');
+
+ // Other - Linux
+ await user.click(ui.otherBuildButton.get());
+ await user.click(ui.linuxButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('other linux: execute scanner');
+
+ // Other - Windows
+ await user.click(ui.windowsButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('other windows: execute scanner');
+
+ // Other - MacOS
+ await user.click(ui.macosButton.get());
+ expect(getCopyToClipboardValue()).toMatchSnapshot('other macos: execute scanner');
+});
+
+function renderOtherTutorial({
+ languages = { c: mockLanguage({ key: 'c' }) },
+}: RenderContext = {}) {
+ return renderApp(
+ '/',
+ <OtherTutorial
+ baseUrl="http://localhost:9000"
+ component={mockComponent()}
+ currentUser={mockLoggedInUser()}
+ />,
+ { languages }
+ );
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockComponent } from '../../../../helpers/mocks/component';
-import { mockLoggedInUser } from '../../../../helpers/testMocks';
-import OtherTutorial from '../OtherTutorial';
-import ProjectAnalysisStep from '../ProjectAnalysisStep';
-import TokenStep from '../TokenStep';
-
-it('renders correctly', () => {
- expect(shallowRender()).toMatchSnapshot('default');
-});
-
-it('allows to navigate between steps', () => {
- const wrapper = shallowRender();
- const instance = wrapper.instance();
-
- expect(wrapper.find(TokenStep).props().open).toBe(true);
-
- instance.handleTokenDone('foo');
- expect(wrapper.find(TokenStep).props().open).toBe(false);
- expect(wrapper.find(ProjectAnalysisStep).props().open).toBe(true);
-
- instance.handleTokenOpen();
- expect(wrapper.find(TokenStep).props().open).toBe(true);
- expect(wrapper.find(ProjectAnalysisStep).props().open).toBe(false);
-});
-
-function shallowRender(props: Partial<OtherTutorial['props']> = {}) {
- return shallow<OtherTutorial>(
- <OtherTutorial
- component={mockComponent()}
- baseUrl="http://example.com"
- currentUser={mockLoggedInUser()}
- {...props}
- />
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { mockComponent } from '../../../../helpers/mocks/component';
-import ProjectAnalysisStep from '../ProjectAnalysisStep';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender() {
- return shallow(
- <ProjectAnalysisStep
- component={mockComponent()}
- isLocal={true}
- baseUrl="http://example.com"
- open={true}
- stepNumber={2}
- />
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2023 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 { getTokens } from '../../../../api/user-tokens';
-import { mockLoggedInUser } from '../../../../helpers/testMocks';
-import { change, click, submit, waitAndUpdate } from '../../../../helpers/testUtils';
-import TokenStep from '../TokenStep';
-
-jest.mock('../../../../api/user-tokens', () => ({
- getTokens: jest.fn().mockResolvedValue([{ name: 'foo' }]),
- generateToken: jest.fn().mockResolvedValue({ token: 'abcd1234' }),
- revokeToken: jest.fn().mockResolvedValue(null),
-}));
-
-jest.mock('../../../../api/settings', () => {
- return {
- ...jest.requireActual('../../../../api/settings'),
- getAllValues: jest.fn().mockResolvedValue([
- {
- key: 'sonar.auth.token.max.allowed.lifetime',
- value: 'No expiration',
- },
- ]),
- };
-});
-
-it('sets an initial token name', async () => {
- (getTokens as jest.Mock).mockResolvedValueOnce([{ name: 'fôo' }]);
- const wrapper = shallowRender({ initialTokenName: 'fôo' });
- await waitAndUpdate(wrapper);
- expect(wrapper.dive().find('input').props().value).toBe('fôo 1');
-});
-
-it('generates token', async () => {
- const wrapper = shallowRender();
- await waitAndUpdate(wrapper);
- expect(wrapper.dive()).toMatchSnapshot();
- change(wrapper.dive().find('input'), 'my token');
- submit(wrapper.dive().find('form'));
- expect(wrapper.dive()).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper.dive()).toMatchSnapshot();
-});
-
-it('revokes token', async () => {
- const wrapper = shallowRender();
- await new Promise(setImmediate);
- wrapper.setState({ token: 'abcd1234', tokenName: 'my token' });
- expect(wrapper.dive()).toMatchSnapshot();
- (wrapper.dive().find('DeleteButton').prop('onClick') as Function)();
- wrapper.update();
- expect(wrapper.dive()).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper.dive()).toMatchSnapshot();
-});
-
-it('continues', async () => {
- const onContinue = jest.fn();
- const wrapper = shallowRender({ onContinue });
- await new Promise(setImmediate);
- wrapper.setState({ token: 'abcd1234', tokenName: 'my token' });
- click(wrapper.dive().find('[className="js-continue"]'));
- expect(onContinue).toHaveBeenCalledWith('abcd1234');
-});
-
-it('uses existing token', async () => {
- const onContinue = jest.fn();
- const wrapper = shallowRender({ onContinue });
- await new Promise(setImmediate);
- wrapper.setState({ existingToken: 'abcd1234', selection: 'use-existing' });
- click(wrapper.dive().find('[className="js-continue"]'));
- expect(onContinue).toHaveBeenCalledWith('abcd1234');
-});
-
-function shallowRender(props: Partial<TokenStep['props']> = {}) {
- return shallow<TokenStep>(
- <TokenStep
- currentUser={mockLoggedInUser({ login: 'user' })}
- finished={false}
- onContinue={jest.fn()}
- onOpen={jest.fn()}
- open={true}
- projectKey="foo"
- stepNumber={1}
- {...props}
- />
- );
-}
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly: default 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.build
- </h4>
- <ButtonToggle
- label="onboarding.build"
- onCheck={[Function]}
- options={
- [
- {
- "label": "onboarding.build.maven",
- "value": "maven",
- },
- {
- "label": "onboarding.build.gradle",
- "value": "gradle",
- },
- {
- "label": "onboarding.build.dotnet",
- "value": "dotnet",
- },
- {
- "label": "onboarding.build.cfamily",
- "value": "cfamily",
- },
- {
- "label": "onboarding.build.other",
- "value": "other",
- },
- ]
- }
- />
- </div>
-</Fragment>
-`;
-
-exports[`renders correctly: with "maven" selected 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.build
- </h4>
- <ButtonToggle
- label="onboarding.build"
- onCheck={[Function]}
- options={
- [
- {
- "label": "onboarding.build.maven",
- "value": "maven",
- },
- {
- "label": "onboarding.build.gradle",
- "value": "gradle",
- },
- {
- "label": "onboarding.build.dotnet",
- "value": "dotnet",
- },
- {
- "label": "onboarding.build.cfamily",
- "value": "cfamily",
- },
- {
- "label": "onboarding.build.other",
- "value": "other",
- },
- ]
- }
- value="maven"
- />
- </div>
-</Fragment>
-`;
-
-exports[`renders correctly: with "other" selected 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.build
- </h4>
- <ButtonToggle
- label="onboarding.build"
- onCheck={[Function]}
- options={
- [
- {
- "label": "onboarding.build.maven",
- "value": "maven",
- },
- {
- "label": "onboarding.build.gradle",
- "value": "gradle",
- },
- {
- "label": "onboarding.build.dotnet",
- "value": "dotnet",
- },
- {
- "label": "onboarding.build.cfamily",
- "value": "cfamily",
- },
- {
- "label": "onboarding.build.other",
- "value": "other",
- },
- ]
- }
- value="other"
- />
- </div>
- <RenderOptions
- label="onboarding.build.other.os"
- onCheck={[Function]}
- optionLabelKey="onboarding.build.other.os"
- options={
- [
- "linux",
- "win",
- "mac",
- ]
- }
- titleLabelKey="onboarding.build.other.os"
- />
-</Fragment>
-`;
-
-exports[`renders correctly: without C 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.build
- </h4>
- <ButtonToggle
- label="onboarding.build"
- onCheck={[Function]}
- options={
- [
- {
- "label": "onboarding.build.maven",
- "value": "maven",
- },
- {
- "label": "onboarding.build.gradle",
- "value": "gradle",
- },
- {
- "label": "onboarding.build.dotnet",
- "value": "dotnet",
- },
- {
- "label": "onboarding.build.other",
- "value": "other",
- },
- ]
- }
- />
- </div>
-</Fragment>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly: default 1`] = `
-<Fragment>
- <hr
- className="big-spacer-top big-spacer-bottom"
- />
- <p>
- <strong>
- onboarding.analysis.auto_refresh_after_analysis.done
- </strong>
-
- onboarding.analysis.auto_refresh_after_analysis.auto_refresh
- </p>
- <p
- className="big-spacer-top"
- >
- onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci
- </p>
- <p
- className="big-spacer-top"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
- id="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
- values={
- {
- "link_branches": <withAppStateContext(DocLink)
- to="/analyzing-source-code/branches/branch-analysis/"
- >
- onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches
- </withAppStateContext(DocLink)>,
- "link_pr_analysis": <withAppStateContext(DocLink)
- to="/analyzing-source-code/pull-request-analysis"
- >
- onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis
- </withAppStateContext(DocLink)>,
- }
- }
- />
- </p>
-</Fragment>
-`;
-
-exports[`should render correctly: project admin 1`] = `
-<Fragment>
- <hr
- className="big-spacer-top big-spacer-bottom"
- />
- <p>
- <strong>
- onboarding.analysis.auto_refresh_after_analysis.done
- </strong>
-
- onboarding.analysis.auto_refresh_after_analysis.auto_refresh
- </p>
- <p
- className="big-spacer-top"
- >
- onboarding.analysis.auto_refresh_after_analysis.set_up_pr_deco_and_ci.admin
- </p>
- <p
- className="big-spacer-top"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
- id="onboarding.analysis.auto_refresh_after_analysis.check_these_links"
- values={
- {
- "link_branches": <withAppStateContext(DocLink)
- to="/analyzing-source-code/branches/branch-analysis/"
- >
- onboarding.analysis.auto_refresh_after_analysis.check_these_links.branches
- </withAppStateContext(DocLink)>,
- "link_pr_analysis": <withAppStateContext(DocLink)
- to="/analyzing-source-code/pull-request-analysis"
- >
- onboarding.analysis.auto_refresh_after_analysis.check_these_links.pr_analysis
- </withAppStateContext(DocLink)>,
- }
- }
- />
- </p>
-</Fragment>
-`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`can choose build tools and copy provided settings: cfamily linux: execute build wrapper 1`] = `
+"curl --create-dirs -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip http://localhost:9000/static/cpp/build-wrapper-linux-x86.zip
+unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/
+export PATH=$HOME/.sonar/build-wrapper-linux-x86:$PATH
+"
+`;
+
+exports[`can choose build tools and copy provided settings: cfamily linux: execute scanner 1`] = `
+"export SONAR_SCANNER_VERSION=4.7.0.2747
+export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
+curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
+unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+export SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: cfamily macos: execute build wrapper 1`] = `
+"curl --create-dirs -sSLo $HOME/.sonar/build-wrapper-macosx-x86.zip http://localhost:9000/static/cpp/build-wrapper-macosx-x86.zip
+unzip -o $HOME/.sonar/build-wrapper-macosx-x86.zip -d $HOME/.sonar/
+export PATH=$HOME/.sonar/build-wrapper-macosx-x86:$PATH
+"
+`;
+
+exports[`can choose build tools and copy provided settings: cfamily macos: execute scanner 1`] = `
+"export SONAR_SCANNER_VERSION=4.7.0.2747
+export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-macosx
+curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-macosx.zip
+unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+export SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: cfamily windows: execute build wrapper 1`] = `
+"$env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
+rm "$env:SONAR_DIRECTORY/build-wrapper-win-x86" -Force -Recurse -ErrorAction SilentlyContinue
+New-Item -path $env:SONAR_DIRECTORY/build-wrapper-win-x86 -type directory
+(New-Object System.Net.WebClient).DownloadFile("http://localhost:9000/static/cpp/build-wrapper-win-x86.zip", "$env:SONAR_DIRECTORY/build-wrapper-win-x86.zip")
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:SONAR_DIRECTORY/build-wrapper-win-x86.zip", "$env:SONAR_DIRECTORY")
+$env:Path += ";$env:SONAR_DIRECTORY/build-wrapper-win-x86"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: cfamily windows: execute scanner 1`] = `
+"$env:SONAR_SCANNER_VERSION = "4.7.0.2747"
+$env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
+$env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
+rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
+New-Item -path $env:SONAR_SCANNER_HOME -type directory
+(New-Object System.Net.WebClient).DownloadFile("https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$env:SONAR_SCANNER_VERSION-windows.zip", "$env:SONAR_DIRECTORY/sonar-scanner.zip")
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:SONAR_DIRECTORY/sonar-scanner.zip", "$env:SONAR_DIRECTORY")
+rm ./.sonar/sonar-scanner.zip -Force -ErrorAction SilentlyContinue
+$env:Path += ";$env:SONAR_SCANNER_HOME/bin"
+$env:SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: dotnet core: execute command 1 1`] = `"dotnet sonarscanner begin /k:"my-project" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="generatedtoken2""`;
+
+exports[`can choose build tools and copy provided settings: dotnet core: execute command 2 1`] = `"dotnet build"`;
+
+exports[`can choose build tools and copy provided settings: dotnet core: execute command 3 1`] = `"dotnet sonarscanner end /d:sonar.login="generatedtoken2""`;
+
+exports[`can choose build tools and copy provided settings: dotnet core: install scanner globally 1`] = `"dotnet tool install --global dotnet-sonarscanner"`;
+
+exports[`can choose build tools and copy provided settings: dotnet framework: execute command 1 1`] = `"SonarScanner.MSBuild.exe begin /k:"my-project" /d:sonar.host.url="http://localhost:9000" /d:sonar.login="generatedtoken2""`;
+
+exports[`can choose build tools and copy provided settings: dotnet framework: execute command 2 1`] = `"MsBuild.exe /t:Rebuild"`;
+
+exports[`can choose build tools and copy provided settings: dotnet framework: execute command 3 1`] = `"SonarScanner.MSBuild.exe end /d:sonar.login="generatedtoken2""`;
+
+exports[`can choose build tools and copy provided settings: gradle: execute scanner 1`] = `
+"./gradlew sonar \\
+ -Dsonar.projectKey=my-project \\
+ -Dsonar.projectName='MyProject' \\
+ -Dsonar.host.url=http://localhost:9000 \\
+ -Dsonar.login=generatedtoken2"
+`;
+
+exports[`can choose build tools and copy provided settings: gradle: sonarqube plugin 1`] = `
+"plugins {
+ id "org.sonarqube" version "3.5.0.2730"
+}"
+`;
+
+exports[`can choose build tools and copy provided settings: maven: execute scanner 1`] = `
+"mvn clean verify sonar:sonar \\
+ -Dsonar.projectKey=my-project \\
+ -Dsonar.projectName='MyProject' \\
+ -Dsonar.host.url=http://localhost:9000 \\
+ -Dsonar.login=generatedtoken2"
+`;
+
+exports[`can choose build tools and copy provided settings: other linux: execute scanner 1`] = `
+"export SONAR_SCANNER_VERSION=4.7.0.2747
+export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-linux
+curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-linux.zip
+unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+export SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: other macos: execute scanner 1`] = `
+"export SONAR_SCANNER_VERSION=4.7.0.2747
+export SONAR_SCANNER_HOME=$HOME/.sonar/sonar-scanner-$SONAR_SCANNER_VERSION-macosx
+curl --create-dirs -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$SONAR_SCANNER_VERSION-macosx.zip
+unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/
+export PATH=$SONAR_SCANNER_HOME/bin:$PATH
+export SONAR_SCANNER_OPTS="-server"
+"
+`;
+
+exports[`can choose build tools and copy provided settings: other windows: execute scanner 1`] = `
+"$env:SONAR_SCANNER_VERSION = "4.7.0.2747"
+$env:SONAR_DIRECTORY = [System.IO.Path]::Combine($(get-location).Path,".sonar")
+$env:SONAR_SCANNER_HOME = "$env:SONAR_DIRECTORY/sonar-scanner-$env:SONAR_SCANNER_VERSION-windows"
+rm $env:SONAR_SCANNER_HOME -Force -Recurse -ErrorAction SilentlyContinue
+New-Item -path $env:SONAR_SCANNER_HOME -type directory
+(New-Object System.Net.WebClient).DownloadFile("https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-$env:SONAR_SCANNER_VERSION-windows.zip", "$env:SONAR_DIRECTORY/sonar-scanner.zip")
+Add-Type -AssemblyName System.IO.Compression.FileSystem
+[System.IO.Compression.ZipFile]::ExtractToDirectory("$env:SONAR_DIRECTORY/sonar-scanner.zip", "$env:SONAR_DIRECTORY")
+rm ./.sonar/sonar-scanner.zip -Force -ErrorAction SilentlyContinue
+$env:Path += ";$env:SONAR_SCANNER_HOME/bin"
+$env:SONAR_SCANNER_OPTS="-server"
+"
+`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly: default 1`] = `
-<Fragment>
- <div
- className="page-header big-spacer-bottom"
- >
- <h2
- className="page-title"
- >
- onboarding.project_analysis.header
- </h2>
- <p
- className="page-description"
- >
- <InstanceMessage
- message="onboarding.project_analysis.description"
- />
- </p>
- </div>
- <TokenStep
- currentUser={
- {
- "dismissedNotices": {
- "educationPrinciples": false,
- },
- "groups": [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": [],
- }
- }
- finished={false}
- initialTokenName="Analyze "MyProject""
- onContinue={[Function]}
- onOpen={[Function]}
- open={true}
- projectKey="my-project"
- stepNumber={1}
- />
- <ProjectAnalysisStep
- baseUrl="http://example.com"
- component={
- {
- "breadcrumbs": [],
- "key": "my-project",
- "name": "MyProject",
- "qualifier": "TRK",
- "qualityGate": {
- "isDefault": true,
- "key": "30",
- "name": "Sonar way",
- },
- "qualityProfiles": [
- {
- "deleted": false,
- "key": "my-qp",
- "language": "ts",
- "name": "Sonar way",
- },
- ],
- "tags": [],
- }
- }
- isLocal={false}
- open={false}
- stepNumber={2}
- />
-</Fragment>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`should render correctly 1`] = `
-<Step
- finished={false}
- onOpen={[Function]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={2}
- stepTitle="onboarding.analysis.header"
-/>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`generates token 1`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate.PROJECT_ANALYSIS_TOKEN
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- className="display-flex-center"
- onSubmit={[Function]}
- >
- <div
- className="display-flex-column"
- >
- <label
- className="h3"
- htmlFor="generate-token-input"
- >
- onboarding.token.name.label
- <DocumentationTooltip
- className="spacer-left"
- content="onboarding.token.name.help"
- links={
- [
- {
- "href": "/user-guide/user-account/generating-and-using-tokens/",
- "label": "learn_more",
- },
- ]
- }
- />
- </label>
- <input
- autoFocus={true}
- className="input-super-large spacer-right spacer-top text-middle"
- id="generate-token-input"
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="display-flex-column spacer-left big-spacer-right"
- >
- <label
- className="h3"
- htmlFor="token-select-expiration"
- >
- users.tokens.expires_in
- </label>
- <div
- className="display-flex-center"
- >
- <Select
- className="spacer-top abs-width-100 spacer-right"
- id="token-select-expiration"
- isSearchable={false}
- onChange={[Function]}
- options={
- [
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- },
- {
- "label": "users.tokens.expiration.90",
- "value": 90,
- },
- {
- "label": "users.tokens.expiration.365",
- "value": 365,
- },
- {
- "label": "users.tokens.expiration.0",
- "value": 0,
- },
- ]
- }
- value={
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- }
- }
- />
- <SubmitButton
- className="text-middle spacer-top"
- disabled={true}
- >
- onboarding.token.generate
- </SubmitButton>
- </div>
- </div>
- </form>
- <ProjectTokenScopeInfo
- className="width-50"
- />
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <Radio
- checked={false}
- onCheck={[Function]}
- value="use-existing"
- >
- onboarding.token.use_existing_token
- </Radio>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </div>
- </div>
-</div>
-`;
-
-exports[`generates token 2`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate.PROJECT_ANALYSIS_TOKEN
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- className="display-flex-center"
- onSubmit={[Function]}
- >
- <div
- className="display-flex-column"
- >
- <label
- className="h3"
- htmlFor="generate-token-input"
- >
- onboarding.token.name.label
- <DocumentationTooltip
- className="spacer-left"
- content="onboarding.token.name.help"
- links={
- [
- {
- "href": "/user-guide/user-account/generating-and-using-tokens/",
- "label": "learn_more",
- },
- ]
- }
- />
- </label>
- <input
- autoFocus={true}
- className="input-super-large spacer-right spacer-top text-middle"
- id="generate-token-input"
- onChange={[Function]}
- required={true}
- type="text"
- value="my token"
- />
- </div>
- <div
- className="display-flex-column spacer-left big-spacer-right"
- >
- <label
- className="h3"
- htmlFor="token-select-expiration"
- >
- users.tokens.expires_in
- </label>
- <div
- className="display-flex-center"
- >
- <Select
- className="spacer-top abs-width-100 spacer-right"
- id="token-select-expiration"
- isSearchable={false}
- onChange={[Function]}
- options={
- [
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- },
- {
- "label": "users.tokens.expiration.90",
- "value": 90,
- },
- {
- "label": "users.tokens.expiration.365",
- "value": 365,
- },
- {
- "label": "users.tokens.expiration.0",
- "value": 0,
- },
- ]
- }
- value={
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- }
- }
- />
- <i
- className="spinner text-middle"
- />
- </div>
- </div>
- </form>
- <ProjectTokenScopeInfo
- className="width-50"
- />
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <Radio
- checked={false}
- onCheck={[Function]}
- value="use-existing"
- >
- onboarding.token.use_existing_token
- </Radio>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </div>
- </div>
-</div>
-`;
-
-exports[`generates token 3`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <form
- onSubmit={[Function]}
- >
- <span
- className="text-middle"
- >
- my token
- :
- </span>
- <strong
- className="spacer-right text-middle"
- >
- abcd1234
- </strong>
- <DeleteButton
- className="button-small text-middle"
- onClick={[Function]}
- />
- </form>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- continue
- </Button>
- </div>
- </div>
- </div>
-</div>
-`;
-
-exports[`revokes token 1`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <form
- onSubmit={[Function]}
- >
- <span
- className="text-middle"
- >
- my token
- :
- </span>
- <strong
- className="spacer-right text-middle"
- >
- abcd1234
- </strong>
- <DeleteButton
- className="button-small text-middle"
- onClick={[Function]}
- />
- </form>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- continue
- </Button>
- </div>
- </div>
- </div>
-</div>
-`;
-
-exports[`revokes token 2`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <form
- onSubmit={[Function]}
- >
- <span
- className="text-middle"
- >
- my token
- :
- </span>
- <strong
- className="spacer-right text-middle"
- >
- abcd1234
- </strong>
- <i
- className="spinner text-middle"
- />
- </form>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- continue
- </Button>
- </div>
- </div>
- </div>
-</div>
-`;
-
-exports[`revokes token 3`] = `
-<div
- className="boxed-group onboarding-step is-open"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- onboarding.token.header
- </h2>
- </div>
- <div>
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate.PROJECT_ANALYSIS_TOKEN
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- className="display-flex-center"
- onSubmit={[Function]}
- >
- <div
- className="display-flex-column"
- >
- <label
- className="h3"
- htmlFor="generate-token-input"
- >
- onboarding.token.name.label
- <DocumentationTooltip
- className="spacer-left"
- content="onboarding.token.name.help"
- links={
- [
- {
- "href": "/user-guide/user-account/generating-and-using-tokens/",
- "label": "learn_more",
- },
- ]
- }
- />
- </label>
- <input
- autoFocus={true}
- className="input-super-large spacer-right spacer-top text-middle"
- id="generate-token-input"
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- </div>
- <div
- className="display-flex-column spacer-left big-spacer-right"
- >
- <label
- className="h3"
- htmlFor="token-select-expiration"
- >
- users.tokens.expires_in
- </label>
- <div
- className="display-flex-center"
- >
- <Select
- className="spacer-top abs-width-100 spacer-right"
- id="token-select-expiration"
- isSearchable={false}
- onChange={[Function]}
- options={
- [
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- },
- {
- "label": "users.tokens.expiration.90",
- "value": 90,
- },
- {
- "label": "users.tokens.expiration.365",
- "value": 365,
- },
- {
- "label": "users.tokens.expiration.0",
- "value": 0,
- },
- ]
- }
- value={
- {
- "label": "users.tokens.expiration.30",
- "value": 30,
- }
- }
- />
- <SubmitButton
- className="text-middle spacer-top"
- disabled={true}
- >
- onboarding.token.generate
- </SubmitButton>
- </div>
- </div>
- </form>
- <ProjectTokenScopeInfo
- className="width-50"
- />
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <Radio
- checked={false}
- onCheck={[Function]}
- value="use-existing"
- >
- onboarding.token.use_existing_token
- </Radio>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- <FormattedMessage
- defaultMessage="onboarding.token.text"
- id="onboarding.token.text"
- values={
- {
- "link": <ForwardRef(Link)
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </ForwardRef(Link)>,
- }
- }
- />
- </div>
- </div>
- </div>
-</div>
-`;
const command = [
'./gradlew sonar',
`-Dsonar.projectKey=${component.key}`,
+ `-Dsonar.projectName='${component.name}'`,
`-Dsonar.host.url=${baseUrl}`,
`-Dsonar.login=${token}`,
];
const command = [
'mvn clean verify sonar:sonar',
`-Dsonar.projectKey=${component.key}`,
+ `-Dsonar.projectName='${component.name}'`,
`-Dsonar.host.url=${baseUrl}`,
`-Dsonar.login=${token}`,
];
[
"./gradlew sonar",
"-Dsonar.projectKey=projectKey",
+ "-Dsonar.projectName='MyProject'",
"-Dsonar.host.url=host",
"-Dsonar.login=token",
]
[
"mvn clean verify sonar:sonar",
"-Dsonar.projectKey=projectKey",
+ "-Dsonar.projectName='MyProject'",
"-Dsonar.host.url=host",
"-Dsonar.login=token",
]
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { screen } from '@testing-library/react';
import { ShallowWrapper } from 'enzyme';
+import { byRole } from 'testing-library-selector';
import Step from './components/Step';
+import { BuildTools, OSs } from './types';
export function renderStepContent(wrapper: ShallowWrapper<React.ReactNode>, n = 0) {
return wrapper.find(Step).at(n).props().renderForm();
}
+
+export function getCopyToClipboardValue(i = 0, name = 'copy_to_clipboard') {
+ return screen.getAllByRole('button', { name })[i].getAttribute('data-clipboard-text');
+}
+
+export function getTutorialBuildButtons() {
+ return {
+ describeBuildTitle: byRole('heading', { name: 'onboarding.build' }),
+ mavenBuildButton: byRole('button', { name: `onboarding.build.${BuildTools.Maven}` }),
+ gradleBuildButton: byRole('button', { name: `onboarding.build.${BuildTools.Gradle}` }),
+ dotnetBuildButton: byRole('button', { name: `onboarding.build.${BuildTools.DotNet}` }),
+ cFamilyBuildButton: byRole('button', { name: `onboarding.build.${BuildTools.CFamily}` }),
+ otherBuildButton: byRole('button', { name: `onboarding.build.${BuildTools.Other}` }),
+ dotnetCoreButton: byRole('button', { name: 'onboarding.build.dotnet.variant.dotnet_core' }),
+ dotnetFrameworkButton: byRole('button', {
+ name: 'onboarding.build.dotnet.variant.dotnet_framework',
+ }),
+ linuxButton: byRole('button', { name: `onboarding.build.other.os.${OSs.Linux}` }),
+ windowsButton: byRole('button', { name: `onboarding.build.other.os.${OSs.Windows}` }),
+ macosButton: byRole('button', { name: `onboarding.build.other.os.${OSs.MacOS}` }),
+ };
+}
return os === 'win' ? (s: string) => `"${s}"` : (s: string) => s;
}
-export function buildGradleSnippet(key: string) {
+export function buildGradleSnippet(key: string, name: string) {
return `plugins {
id "org.sonarqube" version "${GRADLE_SCANNER_VERSION}"
}
sonar {
properties {
property "sonar.projectKey", "${key}"
+ property "sonar.projectName", "${name}"
}
}`;
}
onboarding.token.name.placeholder=Enter a name for your token
onboarding.token.name.help=Enter a name for your project token
onboarding.token.invalid_format=The token you have entered has invalid format.
+onboarding.token.delete=Delete the token
onboarding.tutorial.env_variables=In the {field} field, enter {value} {extra}
onboarding.tutorial.env_variables.field=Value