AlmSettingsBindingDefinitions,
AlmSettingsInstance,
AzureBindingDefinition,
- AzureProjectAlmBinding,
+ AzureProjectAlmBindingParams,
BitbucketBindingDefinition,
- BitbucketProjectAlmBinding,
+ BitbucketProjectAlmBindingParams,
GithubBindingDefinition,
- GithubProjectAlmBinding,
+ GithubProjectAlmBindingParams,
GitlabBindingDefinition,
- GitlabProjectAlmBinding,
- ProjectAlmBinding
+ GitlabProjectAlmBindingParams,
+ ProjectAlmBindingResponse
} from '../types/alm-settings';
export function getAlmDefinitions(): Promise<AlmSettingsBindingDefinitions> {
.catch(throwGlobalError);
}
-export function getProjectAlmBinding(project: string): Promise<ProjectAlmBinding> {
+export function getProjectAlmBinding(project: string): Promise<ProjectAlmBindingResponse> {
return getJSON('/api/alm_settings/get_binding', { project });
}
return post('/api/alm_settings/delete_binding', { project }).catch(throwGlobalError);
}
-export function setProjectAzureBinding(data: AzureProjectAlmBinding) {
+export function setProjectAzureBinding(data: AzureProjectAlmBindingParams) {
return post('/api/alm_settings/set_azure_binding', data).catch(throwGlobalError);
}
-export function setProjectBitbucketBinding(data: BitbucketProjectAlmBinding) {
+export function setProjectBitbucketBinding(data: BitbucketProjectAlmBindingParams) {
return post('/api/alm_settings/set_bitbucket_binding', data).catch(throwGlobalError);
}
-export function setProjectGithubBinding(data: GithubProjectAlmBinding) {
+export function setProjectGithubBinding(data: GithubProjectAlmBindingParams) {
return post('/api/alm_settings/set_github_binding', data).catch(throwGlobalError);
}
-export function setProjectGitlabBinding(data: GitlabProjectAlmBinding) {
+export function setProjectGitlabBinding(data: GitlabProjectAlmBindingParams) {
return post('/api/alm_settings/set_gitlab_binding', data).catch(throwGlobalError);
}
import { getOrganizationUrl } from '../../../helpers/urls';
import { skipOnboarding } from '../../../store/users';
import { deleteOrganization } from '../../organizations/actions';
-import '../../tutorials/styles.css'; // TODO remove me
import { createOrganization } from './actions';
import AlmApplicationInstalling from './AlmApplicationInstalling';
import AutoOrganizationCreate from './AutoOrganizationCreate';
import * as React from 'react';
import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import Step from '../../tutorials/components/Step';
+import Step from '../../../components/tutorials/components/Step';
interface Props {
children: React.ReactNode;
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
+import Step from '../../../components/tutorials/components/Step';
import { getExtensionStart } from '../../../helpers/extensions';
-import Step from '../../tutorials/components/Step';
import BillingFormShim from '../components/BillingFormShim';
import PlanSelect, { Plan } from './PlanSelect';
import OnboardingAddMembersIcon from 'sonar-ui-common/components/icons/OnboardingAddMembersIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { Router, withRouter } from '../../../components/hoc/withRouter';
-import '../../tutorials/styles.css';
+import '../../../components/tutorials/styles.css';
import './OrganizationEmpty.css';
interface Props {
import { connect } from 'react-redux';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import AnalyzeTutorial from '../../../components/tutorials/manual/AnalyzeTutorial';
import { getBranchLikeDisplayName, isBranch, isMainBranch } from '../../../helpers/branch-like';
import { isLoggedIn } from '../../../helpers/users';
import { getCurrentUser, Store } from '../../../store/rootReducer';
import { BranchLike } from '../../../types/branch-like';
import { ComponentQualifier } from '../../../types/component';
-import AnalyzeTutorial from '../../tutorials/analyzeProject/AnalyzeTutorial';
interface Props {
branchLike?: BranchLike;
import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import { GithubBindingDefinition } from '../../../../../types/alm-settings';
import AlmBindingDefinitionForm from '../AlmBindingDefinitionForm';
});
it('should reset if the props change', () => {
- const bindingDefinition = mockGithubDefinition();
+ const bindingDefinition = mockGithubBindingDefinition();
const wrapper = shallowRender({ bindingDefinition });
wrapper.setState({ formData: { ...bindingDefinition, appId: 'newAppId' }, touched: true });
wrapper.setProps({ bindingDefinition: { ...bindingDefinition } });
expect(wrapper.state('touched')).toBe(true);
- wrapper.setProps({ bindingDefinition: mockGithubDefinition({ key: 'diffKey' }) });
+ wrapper.setProps({ bindingDefinition: mockGithubBindingDefinition({ key: 'diffKey' }) });
expect(wrapper.state('touched')).toBe(false);
});
onCancel
});
- wrapper.setState({ formData: mockGithubDefinition() });
+ wrapper.setState({ formData: mockGithubBindingDefinition() });
wrapper.instance().handleCancel();
expect(wrapper.state().formData).toBe(bindingDefinition);
it('should handle deleting', () => {
const onDelete = jest.fn();
- const bindingDefinition = mockGithubDefinition();
+ const bindingDefinition = mockGithubBindingDefinition();
const wrapper = shallowRender({
bindingDefinition,
onDelete
const wrapper = shallowRender();
expect(wrapper.instance().canSubmit()).toBe(false);
- wrapper.setState({ formData: mockGithubDefinition(), touched: true });
+ wrapper.setState({ formData: mockGithubBindingDefinition(), touched: true });
expect(wrapper.instance().canSubmit()).toBe(true);
- wrapper.setState({ formData: mockGithubDefinition({ key: '' }), touched: true });
+ wrapper.setState({ formData: mockGithubBindingDefinition({ key: '' }), touched: true });
wrapper.setProps({ hideKeyField: true });
expect(wrapper.instance().canSubmit()).toBe(true);
- wrapper.setState({ formData: mockGithubDefinition({ url: '' }), touched: true });
+ wrapper.setState({ formData: mockGithubBindingDefinition({ url: '' }), touched: true });
wrapper.setProps({ optionalFields: ['url'] });
expect(wrapper.instance().canSubmit()).toBe(true);
});
import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import { mockAzureDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockAzureBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import { AlmKeys, AzureBindingDefinition } from '../../../../../types/alm-settings';
import AlmTab from '../AlmTab';
const wrapper = shallowRender();
wrapper.setState({
- editedDefinition: mockAzureDefinition()
+ editedDefinition: mockAzureBindingDefinition()
});
wrapper.instance().handleCancel();
});
it('should handle edit', async () => {
- const config = mockAzureDefinition();
+ const config = mockAzureBindingDefinition();
const wrapper = shallowRender({ definitions: [config] });
wrapper.instance().handleEdit(config.key);
await waitAndUpdate(wrapper);
it('should create config', async () => {
const onUpdateDefinitions = jest.fn();
const createConfiguration = jest.fn(() => Promise.resolve());
- const config = mockAzureDefinition();
+ const config = mockAzureBindingDefinition();
const wrapper = shallowRender({ createConfiguration, onUpdateDefinitions });
wrapper.instance().handleCreate();
it('should update config', async () => {
const onUpdateDefinitions = jest.fn();
const updateConfiguration = jest.fn(() => Promise.resolve());
- const config = mockAzureDefinition();
+ const config = mockAzureBindingDefinition();
const wrapper = shallowRender({ onUpdateDefinitions, updateConfiguration });
wrapper.setState({ editedDefinition: config });
alm={AlmKeys.Azure}
createConfiguration={jest.fn()}
defaultBinding={DEFAULT_BINDING}
- definitions={[mockAzureDefinition()]}
+ definitions={[mockAzureBindingDefinition()]}
form={jest.fn()}
loading={false}
multipleAlmEnabled={true}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import { AlmKeys, GithubBindingDefinition } from '../../../../../types/alm-settings';
import AlmTabRenderer, { AlmTabRendererProps } from '../AlmTabRenderer';
it('should render correctly for multi-ALM binding', () => {
expect(shallowRender({ loading: true })).toMatchSnapshot('loading');
expect(shallowRender()).toMatchSnapshot('loaded');
- expect(shallowRender({ editedDefinition: mockGithubDefinition() })).toMatchSnapshot(
+ expect(shallowRender({ editedDefinition: mockGithubBindingDefinition() })).toMatchSnapshot(
'editing a definition'
);
expect(
expect(shallowRender({ loading: true, multipleAlmEnabled: false })).toMatchSnapshot();
expect(shallowRender({ multipleAlmEnabled: false })).toMatchSnapshot();
expect(
- shallowRender({ definitions: [mockGithubDefinition()], multipleAlmEnabled: false })
+ shallowRender({ definitions: [mockGithubBindingDefinition()], multipleAlmEnabled: false })
).toMatchSnapshot();
});
additionalColumnsHeaders={['url', 'app_id']}
additionalColumnsKeys={['url', 'appId']}
alm={AlmKeys.GitHub}
- defaultBinding={mockGithubDefinition()}
- definitions={[mockGithubDefinition()]}
+ defaultBinding={mockGithubBindingDefinition()}
+ definitions={[mockGithubBindingDefinition()]}
form={jest.fn()}
loading={false}
multipleAlmEnabled={true}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockAzureDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockAzureBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import AzureForm, { AzureFormProps } from '../AzureForm';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ formData: mockAzureDefinition() })).toMatchSnapshot();
+ expect(shallowRender({ formData: mockAzureBindingDefinition() })).toMatchSnapshot();
});
function shallowRender(props: Partial<AzureFormProps> = {}) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockAzureDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockAzureBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import AzureTab, { AzureTabProps } from '../AzureTab';
it('should render correctly', () => {
function shallowRender(props: Partial<AzureTabProps> = {}) {
return shallow(
<AzureTab
- definitions={[mockAzureDefinition()]}
+ definitions={[mockAzureBindingDefinition()]}
loading={false}
multipleAlmEnabled={true}
onDelete={jest.fn()}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockBitbucketDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockBitbucketBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import BitbucketForm, { BitbucketFormProps } from '../BitbucketForm';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ formData: mockBitbucketDefinition() })).toMatchSnapshot();
+ expect(shallowRender({ formData: mockBitbucketBindingDefinition() })).toMatchSnapshot();
});
function shallowRender(props: Partial<BitbucketFormProps> = {}) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockBitbucketDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockBitbucketBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import BitbucketTab, { BitbucketTabProps } from '../BitbucketTab';
it('should render correctly', () => {
function shallowRender(props: Partial<BitbucketTabProps> = {}) {
return shallow(
<BitbucketTab
- definitions={[mockBitbucketDefinition()]}
+ definitions={[mockBitbucketBindingDefinition()]}
loading={false}
multipleAlmEnabled={true}
onDelete={jest.fn()}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import GithubForm, { GithubFormProps } from '../GithubForm';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ formData: mockGithubDefinition() })).toMatchSnapshot();
+ expect(shallowRender({ formData: mockGithubBindingDefinition() })).toMatchSnapshot();
});
function shallowRender(props: Partial<GithubFormProps> = {}) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGithubDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGithubBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import GithubTab, { GithubTabProps } from '../GithubTab';
it('should render correctly', () => {
return shallow(
<GithubTab
branchesEnabled={true}
- definitions={[mockGithubDefinition()]}
+ definitions={[mockGithubBindingDefinition()]}
loading={false}
multipleAlmEnabled={true}
onDelete={jest.fn()}
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGitlabDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGitlabBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import GitlabForm, { GitlabFormProps } from '../GitlabForm';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
- expect(shallowRender({ formData: mockGitlabDefinition() })).toMatchSnapshot();
+ expect(shallowRender({ formData: mockGitlabBindingDefinition() })).toMatchSnapshot();
});
function shallowRender(props: Partial<GitlabFormProps> = {}) {
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { mockGitlabDefinition } from '../../../../../helpers/mocks/alm-settings';
+import { mockGitlabBindingDefinition } from '../../../../../helpers/mocks/alm-settings';
import GitlabTab, { GitlabTabProps } from '../GitlabTab';
it('should render correctly', () => {
return shallow(
<GitlabTab
branchesEnabled={true}
- definitions={[mockGitlabDefinition()]}
+ definitions={[mockGitlabBindingDefinition()]}
loading={false}
multipleAlmEnabled={true}
onDelete={jest.fn()}
setProjectGitlabBinding
} from '../../../../api/alm-settings';
import throwGlobalError from '../../../../app/utils/throwGlobalError';
-import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings';
+import {
+ AlmKeys,
+ AlmSettingsInstance,
+ ProjectAlmBindingResponse
+} from '../../../../types/alm-settings';
import PRDecorationBindingRenderer from './PRDecorationBindingRenderer';
+type FormData = T.Omit<ProjectAlmBindingResponse, 'alm'>;
+
interface Props {
component: T.Component;
}
interface State {
- formData: ProjectAlmBinding;
+ formData: FormData;
instances: AlmSettingsInstance[];
isChanged: boolean;
isConfigured: boolean;
isValid: boolean;
loading: boolean;
- orignalData?: ProjectAlmBinding;
+ orignalData?: FormData;
saving: boolean;
success: boolean;
}
const REQUIRED_FIELDS_BY_ALM: {
- [almKey in AlmKeys]: Array<keyof T.Omit<ProjectAlmBinding, 'key'>>;
+ [almKey in AlmKeys]: Array<keyof T.Omit<FormData, 'key'>>;
} = {
[AlmKeys.Azure]: [],
[AlmKeys.Bitbucket]: ['repository', 'slug'],
});
};
- getProjectBinding(project: string): Promise<ProjectAlmBinding | undefined> {
+ getProjectBinding(project: string): Promise<ProjectAlmBindingResponse | undefined> {
return getProjectAlmBinding(project).catch((response: Response) => {
if (response && response.status === 404) {
return undefined;
submitProjectAlmBinding(
alm: AlmKeys,
key: string,
- almSpecificFields?: T.Omit<ProjectAlmBinding, 'key'>
+ almSpecificFields?: T.Omit<FormData, 'key'>
): Promise<void> {
const almSetting = key;
const project = this.props.component.key;
};
isDataSame(
- { key, repository = '', slug = '', summaryCommentEnabled = false }: ProjectAlmBinding,
+ { key, repository = '', slug = '', summaryCommentEnabled = false }: FormData,
{
key: oKey = '',
repository: oRepository = '',
slug: oSlug = '',
summaryCommentEnabled: osummaryCommentEnabled = false
- }: ProjectAlmBinding
+ }: FormData
) {
return (
key === oKey &&
);
}
- handleFieldChange = (id: keyof ProjectAlmBinding, value: string | boolean) => {
+ handleFieldChange = (id: keyof ProjectAlmBindingResponse, value: string | boolean) => {
this.setState(({ formData, orignalData }) => {
const newFormData = {
...formData,
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { AlmKeys, AlmSettingsInstance, ProjectAlmBinding } from '../../../../types/alm-settings';
+import {
+ AlmKeys,
+ AlmSettingsInstance,
+ ProjectAlmBindingResponse
+} from '../../../../types/alm-settings';
import InputForBoolean from '../inputs/InputForBoolean';
export interface PRDecorationBindingRendererProps {
- formData: ProjectAlmBinding;
+ formData: T.Omit<ProjectAlmBindingResponse, 'alm'>;
instances: AlmSettingsInstance[];
isChanged: boolean;
isConfigured: boolean;
isValid: boolean;
loading: boolean;
- onFieldChange: (id: keyof ProjectAlmBinding, value: string | boolean) => void;
+ onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
onReset: () => void;
onSubmit: () => void;
saving: boolean;
}
interface CommonFieldProps extends LabelProps {
- onFieldChange: (id: keyof ProjectAlmBinding, value: string | boolean) => void;
- propKey: keyof ProjectAlmBinding;
+ onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
+ propKey: keyof ProjectAlmBindingResponse;
}
function optionRenderer(instance: AlmSettingsInstance) {
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 { getUniqueTokenName } from '../utils';
-
-const initialTokenName = 'Analyze "lightsaber"';
-
-it('should return the given name when the user has no token', () => {
- const userTokens: T.UserToken[] = [];
-
- expect(getUniqueTokenName(userTokens, initialTokenName)).toBe(initialTokenName);
-});
-
-it('should generate a token with the given name', () => {
- const userTokens = [{ name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' }];
-
- expect(getUniqueTokenName(userTokens, 'Analyze "project"')).toBe('Analyze "project"');
-});
-
-it('should generate a unique token when the name already exists', () => {
- const userTokens = [
- { name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' },
- { name: `${initialTokenName} 1`, createdAt: '2019-06-14T09:45:52+0200' }
- ];
-
- expect(getUniqueTokenName(userTokens, initialTokenName)).toBe('Analyze "lightsaber" 2');
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import InstanceMessage from '../../../components/common/InstanceMessage';
-import { isVSTS } from '../../../helpers/almIntegrations';
-import ProjectAnalysisStep from '../components/ProjectAnalysisStep';
-import TokenStep from '../components/TokenStep';
-import '../styles.css';
-
-export enum Steps {
- ANALYSIS,
- TOKEN
-}
-
-interface Props {
- component: T.Component;
- currentUser: T.LoggedInUser;
-}
-
-interface State {
- step: Steps;
- token?: string;
-}
-
-export default class AnalyzeTutorial extends React.PureComponent<Props, State> {
- state: State = { step: Steps.TOKEN };
-
- handleTokenDone = (token: string) => {
- this.setState({ step: Steps.ANALYSIS, token });
- };
-
- handleTokenOpen = () => {
- this.setState({ step: Steps.TOKEN });
- };
-
- render() {
- const { component, currentUser } = this.props;
- const { step, token } = this.state;
-
- const almKey = (component.alm && component.alm.key) || currentUser.externalProvider;
- return (
- <>
- <div className="page-header big-spacer-bottom">
- <h1 className="page-title">{translate('onboarding.project_analysis.header')}</h1>
- <p className="page-description">
- <InstanceMessage message={translate('onboarding.project_analysis.description')} />
- </p>
- </div>
-
- {!isVSTS(almKey) && (
- <>
- <TokenStep
- currentUser={currentUser}
- finished={Boolean(this.state.token)}
- initialTokenName={`Analyze "${component.name}"`}
- onContinue={this.handleTokenDone}
- onOpen={this.handleTokenOpen}
- open={step === Steps.TOKEN}
- stepNumber={1}
- />
-
- <ProjectAnalysisStep
- component={component}
- displayRowLayout={true}
- open={step === Steps.ANALYSIS}
- stepNumber={2}
- token={token}
- />
- </>
- )}
- </>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 AnalyzeTutorial from '../AnalyzeTutorial';
-
-Date.now = jest.fn().mockReturnValue(1540457859031);
-
-const component = {
- key: 'foo',
- analysisDate: '2016-01-01',
- breadcrumbs: [],
- name: 'Foo',
- organization: 'org',
- qualifier: 'TRK',
- version: '0.0.1'
-};
-
-const loggedInUser: T.LoggedInUser = {
- groups: [],
- isLoggedIn: true,
- login: 'luke',
- name: 'Skywalker',
- scmAccounts: []
-};
-
-it('renders correctly', () => {
- expect(getWrapper()).toMatchSnapshot();
-});
-
-function getWrapper(props = {}) {
- return shallow(<AnalyzeTutorial component={component} currentUser={loggedInUser} {...props} />);
-}
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<Fragment>
- <div
- className="page-header big-spacer-bottom"
- >
- <h1
- className="page-title"
- >
- onboarding.project_analysis.header
- </h1>
- <p
- className="page-description"
- >
- <InstanceMessage
- message="onboarding.project_analysis.description"
- />
- </p>
- </div>
- <TokenStep
- currentUser={
- Object {
- "groups": Array [],
- "isLoggedIn": true,
- "login": "luke",
- "name": "Skywalker",
- "scmAccounts": Array [],
- }
- }
- finished={false}
- initialTokenName="Analyze \\"Foo\\""
- onContinue={[Function]}
- onOpen={[Function]}
- open={true}
- stepNumber={1}
- />
- <ProjectAnalysisStep
- component={
- Object {
- "analysisDate": "2016-01-01",
- "breadcrumbs": Array [],
- "key": "foo",
- "name": "Foo",
- "organization": "org",
- "qualifier": "TRK",
- "version": "0.0.1",
- }
- }
- displayRowLayout={true}
- open={false}
- stepNumber={2}
- />
-</Fragment>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { isLanguageConfigured, LanguageConfig } from '../utils';
-import { RenderOptions } from './RenderOptions';
-
-interface Props {
- component: T.Component;
- config?: LanguageConfig;
- onDone: (config: LanguageConfig) => void;
- onReset: VoidFunction;
- organization?: string;
-}
-
-type State = LanguageConfig;
-
-export interface RenderOSProps {
- os: string | undefined;
- setOS: (os: string) => void;
-}
-
-export function RenderOS(props: RenderOSProps) {
- return (
- <RenderOptions
- checked={props.os}
- name="os"
- onCheck={props.setOS}
- optionLabelKey="onboarding.language.os"
- options={['linux', 'win', 'mac']}
- titleLabelKey="onboarding.language.os"
- />
- );
-}
-
-export default class LanguageForm extends React.PureComponent<Props, State> {
- constructor(props: Props) {
- super(props);
- this.state = {
- ...(this.props.config || {}),
- projectKey: props.component ? props.component.key : undefined
- };
- }
-
- handleChange = () => {
- if (isLanguageConfigured(this.state)) {
- this.props.onDone(this.state);
- } else {
- this.props.onReset();
- }
- };
-
- handleLanguageChange = (language: string) => {
- this.setState({ language }, this.handleChange);
- };
-
- handleJavaBuildChange = (javaBuild: string) => {
- this.setState({ javaBuild }, this.handleChange);
- };
-
- handleOSChange = (os: string) => {
- this.setState({ os }, this.handleChange);
- };
-
- renderJavaBuild = () => (
- <RenderOptions
- checked={this.state.javaBuild}
- name="java-build"
- onCheck={this.handleJavaBuildChange}
- optionLabelKey="onboarding.language.java.build_technology"
- options={['maven', 'gradle']}
- titleLabelKey="onboarding.language.java.build_technology"
- />
- );
-
- render() {
- const { language } = this.state;
- const languages = ['java', 'dotnet', 'other'];
-
- return (
- <>
- <div>
- <h4 className="spacer-bottom">{translate('onboarding.language')}</h4>
- <RadioToggle
- name="language"
- onCheck={this.handleLanguageChange}
- options={languages.map(language => ({
- label: translate('onboarding.language', language),
- value: language
- }))}
- value={language}
- />
- </div>
- {language === 'java' && this.renderJavaBuild()}
- {language === 'other' && <RenderOS os={this.state.os} setOS={this.handleOSChange} />}
- </>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { LanguageConfig } from '../utils';
-import AnalysisCommand from './commands/AnalysisCommand';
-import LanguageForm from './LanguageForm';
-import Step from './Step';
-
-interface Props {
- component: T.Component;
- displayRowLayout?: boolean;
- onFinish?: (projectKey?: string) => void;
- onReset?: VoidFunction;
- open: boolean;
- organization?: string;
- stepNumber: number;
- token?: string;
-}
-
-interface State {
- config?: LanguageConfig;
-}
-
-export function getProjectKey(config?: LanguageConfig, component?: T.Component) {
- return (component && component.key) || (config && config.projectKey);
-}
-
-export default class ProjectAnalysisStep extends React.PureComponent<Props, State> {
- state: State = {};
-
- handleLanguageSelect = (config: LanguageConfig) => {
- this.setState({ config });
- if (this.props.onFinish) {
- const projectKey = config.language !== 'java' ? getProjectKey(config) : undefined;
- this.props.onFinish(projectKey);
- }
- };
-
- handleLanguageReset = () => {
- this.setState({ config: undefined });
- if (this.props.onReset) {
- this.props.onReset();
- }
- };
-
- renderForm = () => {
- const languageComponent = (
- <LanguageForm
- component={this.props.component}
- onDone={this.handleLanguageSelect}
- onReset={this.handleLanguageReset}
- organization={this.props.organization}
- />
- );
- const analysisComponent = this.state.config && (
- <AnalysisCommand
- component={this.props.component}
- languageConfig={this.state.config}
- organization={this.props.organization}
- small={true}
- token={this.props.token}
- />
- );
-
- if (this.props.displayRowLayout) {
- return (
- <div className="boxed-group-inner">
- <div className="display-flex-column">
- {languageComponent}
- {analysisComponent && <div className="huge-spacer-top">{analysisComponent}</div>}
- </div>
- </div>
- );
- }
-
- return (
- <div className="boxed-group-inner">
- <div className="flex-columns">
- <div className="flex-column flex-column-half bordered-right">{languageComponent}</div>
- <div className="flex-column flex-column-half">{analysisComponent}</div>
- </div>
- </div>
- );
- };
-
- renderResult = () => null;
-
- render() {
- return (
- <Step
- finished={false}
- onOpen={() => {}}
- open={this.props.open}
- renderForm={this.renderForm}
- renderResult={this.renderResult}
- stepNumber={this.props.stepNumber}
- stepTitle={translate('onboarding.analysis.header')}
- />
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-
-interface RenderOptionsProps {
- checked: string | undefined;
- name: string;
- onCheck: (checked: string) => void;
- optionLabelKey: string;
- options: string[];
- titleLabelKey?: string;
-}
-
-export function RenderOptions({
- checked,
- onCheck,
- optionLabelKey,
- options,
- titleLabelKey
-}: RenderOptionsProps) {
- return (
- <div className="big-spacer-top">
- {titleLabelKey && <h4 className="spacer-bottom">{translate(titleLabelKey)}</h4>}
-
- <RadioToggle
- name={name}
- onCheck={onCheck}
- options={options.map(build => ({
- label: translate(optionLabelKey, build),
- value: build
- }))}
- value={checked}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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.
- */
-/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/no-noninteractive-tabindex */
-import * as classNames from 'classnames';
-import * as React from 'react';
-
-interface Props {
- finished?: boolean;
- onOpen: VoidFunction;
- open: boolean;
- renderForm: () => React.ReactNode;
- renderResult: () => React.ReactNode;
- stepNumber: number;
- stepTitle: React.ReactNode;
-}
-
-export default function Step(props: Props) {
- const className = classNames('boxed-group', 'onboarding-step', {
- 'is-open': props.open,
- 'is-finished': props.finished
- });
-
- const clickable = !props.open && props.finished;
-
- const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
- event.preventDefault();
- props.onOpen();
- };
-
- return (
- <div
- className={className}
- onClick={clickable ? handleClick : undefined}
- role={clickable ? 'button' : undefined}
- tabIndex={clickable ? 0 : undefined}>
- <div className="onboarding-step-number">{props.stepNumber}</div>
- {!props.open && props.renderResult()}
- <div className="boxed-group-header">
- <h2>{props.stepTitle}</h2>
- </div>
- {!props.open && <div className="boxed-group-inner" />}
- <div className={classNames({ hidden: !props.open })}>{props.renderForm()}</div>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { Link } from 'react-router';
-import { Button, DeleteButton, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
-import Radio from 'sonar-ui-common/components/controls/Radio';
-import AlertErrorIcon from 'sonar-ui-common/components/icons/AlertErrorIcon';
-import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import { generateToken, getTokens, revokeToken } from '../../../api/user-tokens';
-import { getUniqueTokenName } from '../utils';
-import Step from './Step';
-
-interface Props {
- currentUser: Pick<T.LoggedInUser, 'login'>;
- finished: boolean;
- initialTokenName?: string;
- open: boolean;
- onContinue: (token: string) => void;
- onOpen: VoidFunction;
- stepNumber: number;
-}
-
-interface State {
- existingToken: string;
- loading: boolean;
- selection: string;
- tokenName?: string;
- token?: string;
- tokens?: T.UserToken[];
-}
-
-export default class TokenStep extends React.PureComponent<Props, State> {
- mounted = false;
-
- constructor(props: Props) {
- super(props);
- this.state = {
- existingToken: '',
- loading: false,
- selection: 'generate',
- tokenName: props.initialTokenName
- };
- }
-
- componentDidMount() {
- this.mounted = true;
- getTokens(this.props.currentUser.login).then(
- tokens => {
- if (this.mounted) {
- this.setState({ tokens });
- if (
- this.props.initialTokenName !== undefined &&
- this.props.initialTokenName === this.state.tokenName
- ) {
- this.setState({ tokenName: getUniqueTokenName(tokens) });
- }
- }
- },
- () => {}
- );
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- getToken = () =>
- this.state.selection === 'generate' ? this.state.token : this.state.existingToken;
-
- canContinue = () => {
- const { existingToken, selection, token } = this.state;
- const validExistingToken = existingToken.match(/^[a-z0-9]+$/) != null;
- return (
- (selection === 'generate' && token != null) ||
- (selection === 'use-existing' && existingToken && validExistingToken)
- );
- };
-
- handleTokenNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ tokenName: event.target.value });
- };
-
- handleTokenGenerate = (event: React.FormEvent<HTMLFormElement>) => {
- event.preventDefault();
- const { tokenName } = this.state;
- if (tokenName) {
- this.setState({ loading: true });
- generateToken({ name: tokenName }).then(({ token }) => {
- if (this.mounted) {
- this.setState({ loading: false, token });
- }
- }, this.stopLoading);
- }
- };
-
- handleTokenRevoke = () => {
- const { tokenName } = this.state;
- if (tokenName) {
- this.setState({ loading: true });
- revokeToken({ name: tokenName }).then(() => {
- if (this.mounted) {
- this.setState({ loading: false, token: undefined, tokenName: undefined });
- }
- }, this.stopLoading);
- }
- };
-
- handleContinueClick = () => {
- const token = this.getToken();
- if (token) {
- this.props.onContinue(token);
- }
- };
-
- handleGenerateClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- this.setState({ selection: 'generate' });
- };
-
- handleUseExistingClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
- event.preventDefault();
- this.setState({ selection: 'use-existing' });
- };
-
- handleModeChange = (mode: string) => {
- this.setState({ selection: mode });
- };
-
- handleExisingTokenChange = (event: React.ChangeEvent<HTMLInputElement>) => {
- this.setState({ existingToken: event.currentTarget.value });
- };
-
- stopLoading = () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- };
-
- renderGenerateOption = () => (
- <div>
- {this.state.tokens !== undefined && this.state.tokens.length > 0 ? (
- <Radio
- checked={this.state.selection === 'generate'}
- onCheck={this.handleModeChange}
- value="generate">
- {translate('onboarding.token.generate_token')}
- </Radio>
- ) : (
- translate('onboarding.token.generate_token')
- )}
- {this.state.selection === 'generate' && (
- <div className="big-spacer-top">
- <form onSubmit={this.handleTokenGenerate}>
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- onChange={this.handleTokenNameChange}
- placeholder={translate('onboarding.token.generate_token.placeholder')}
- required={true}
- type="text"
- value={this.state.tokenName || ''}
- />
- {this.state.loading ? (
- <i className="spinner text-middle" />
- ) : (
- <SubmitButton className="text-middle" disabled={!this.state.tokenName}>
- {translate('onboarding.token.generate')}
- </SubmitButton>
- )}
- </form>
- </div>
- )}
- </div>
- );
-
- renderUseExistingOption = () => {
- const { existingToken } = this.state;
- const validInput = !existingToken || existingToken.match(/^[a-z0-9]+$/) != null;
-
- return (
- <div className="big-spacer-top">
- <Radio
- checked={this.state.selection === 'use-existing'}
- onCheck={this.handleModeChange}
- value="use-existing">
- {translate('onboarding.token.use_existing_token')}
- </Radio>
- {this.state.selection === 'use-existing' && (
- <div className="big-spacer-top">
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- onChange={this.handleExisingTokenChange}
- placeholder={translate('onboarding.token.use_existing_token.placeholder')}
- required={true}
- type="text"
- value={this.state.existingToken}
- />
- {!validInput && (
- <span className="text-danger">
- <AlertErrorIcon className="little-spacer-right text-text-top" />
- {translate('onboarding.token.invalid_format')}
- </span>
- )}
- </div>
- )}
- </div>
- );
- };
-
- renderForm = () => {
- const { loading, token, tokenName, tokens } = this.state;
- const canUseExisting = tokens !== undefined && tokens.length > 0;
-
- return (
- <div className="boxed-group-inner">
- {token != null ? (
- <form onSubmit={this.handleTokenRevoke}>
- <span className="text-middle">
- {tokenName}
- {': '}
- </span>
- <strong className="spacer-right text-middle">{token}</strong>
- {loading ? (
- <i className="spinner text-middle" />
- ) : (
- <DeleteButton className="button-small text-middle" onClick={this.handleTokenRevoke} />
- )}
- </form>
- ) : (
- <div>
- {this.renderGenerateOption()}
- {canUseExisting && this.renderUseExistingOption()}
- </div>
- )}
-
- <div className="note big-spacer-top width-50">
- <FormattedMessage
- defaultMessage={translate('onboarding.token.text')}
- id="onboarding.token.text"
- values={{
- link: (
- <Link target="_blank" to="/account/security">
- {translate('onboarding.token.text.user_account')}
- </Link>
- )
- }}
- />
- </div>
-
- {this.canContinue() && (
- <div className="big-spacer-top">
- <Button className="js-continue" onClick={this.handleContinueClick}>
- {translate('continue')}
- </Button>
- </div>
- )}
- </div>
- );
- };
-
- renderResult = () => {
- const { selection, tokenName } = this.state;
- const token = this.getToken();
-
- if (!token) {
- return null;
- }
-
- return (
- <div className="boxed-group-actions display-flex-center">
- <AlertSuccessIcon className="spacer-right" />
- {selection === 'generate' && tokenName && `${tokenName}: `}
- <strong>{token}</strong>
- </div>
- );
- };
-
- render() {
- return (
- <Step
- finished={this.props.finished}
- onOpen={this.props.onOpen}
- open={this.props.open}
- renderForm={this.renderForm}
- renderResult={this.renderResult}
- stepNumber={this.props.stepNumber}
- stepTitle={translate('onboarding.token.header')}
- />
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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/testMocks';
-import LanguageForm from '../LanguageForm';
-
-it('selects java', () => {
- const onDone = jest.fn();
- const wrapper = shallow(
- <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
- );
-
- (wrapper.find('RadioToggle').prop('onCheck') as Function)('java');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('selects c#', () => {
- const onDone = jest.fn();
- const wrapper = shallow(
- <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
- );
-
- (wrapper.find('RadioToggle').prop('onCheck') as Function)('dotnet');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('selects other', () => {
- const onDone = jest.fn();
- const wrapper = shallow(
- <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
- );
-
- (wrapper.find('RadioToggle').prop('onCheck') as Function)('other');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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/testMocks';
-import ProjectAnalysisStep from '../ProjectAnalysisStep';
-
-it('should render correctly', () => {
- expect(shallowRender()).toMatchSnapshot();
-});
-
-function shallowRender() {
- return shallow(<ProjectAnalysisStep component={mockComponent()} open={true} stepNumber={1} />);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 { click } from 'sonar-ui-common/helpers/testUtils';
-import Step from '../Step';
-
-it('renders', () => {
- const wrapper = shallow(
- <Step
- finished={true}
- onOpen={jest.fn()}
- open={true}
- renderForm={() => <div>form</div>}
- renderResult={() => <div>result</div>}
- stepNumber={1}
- stepTitle="First Step"
- />
- );
- expect(wrapper).toMatchSnapshot();
- wrapper.setProps({ open: false });
- expect(wrapper).toMatchSnapshot();
-});
-
-it('re-opens', () => {
- const onOpen = jest.fn();
- const wrapper = shallow(
- <Step
- finished={true}
- onOpen={onOpen}
- open={false}
- renderForm={() => <div>form</div>}
- renderResult={() => <div>result</div>}
- stepNumber={1}
- stepTitle="First Step"
- />
- );
- click(wrapper);
- expect(onOpen).toBeCalled();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 { change, click, submit, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
-import TokenStep from '../TokenStep';
-
-jest.mock('../../../../api/user-tokens', () => ({
- getTokens: () => Promise.resolve([{ name: 'foo' }]),
- generateToken: () => Promise.resolve({ token: 'abcd1234' }),
- revokeToken: () => Promise.resolve()
-}));
-
-const currentUser: Pick<T.LoggedInUser, 'login'> = { login: 'user' };
-
-it('generates token', async () => {
- const wrapper = shallow(
- <TokenStep
- currentUser={currentUser}
- finished={false}
- onContinue={jest.fn()}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- 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 = shallow(
- <TokenStep
- currentUser={currentUser}
- finished={false}
- onContinue={jest.fn()}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- 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 = shallow(
- <TokenStep
- currentUser={currentUser}
- finished={false}
- onContinue={onContinue}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- await new Promise(setImmediate);
- wrapper.setState({ token: 'abcd1234', tokenName: 'my token' });
- click(wrapper.dive().find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('abcd1234');
-});
-
-it('uses existing token', async () => {
- const onContinue = jest.fn();
- const wrapper = shallow(
- <TokenStep
- currentUser={currentUser}
- finished={false}
- onContinue={onContinue}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- await new Promise(setImmediate);
- wrapper.setState({ existingToken: 'abcd1234', selection: 'use-existing' });
- click(wrapper.dive().find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('abcd1234');
-});
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`selects c# 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.language
- </h4>
- <RadioToggle
- disabled={false}
- name="language"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java",
- "value": "java",
- },
- Object {
- "label": "onboarding.language.dotnet",
- "value": "dotnet",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="dotnet"
- />
- </div>
-</Fragment>
-`;
-
-exports[`selects java 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.language
- </h4>
- <RadioToggle
- disabled={false}
- name="language"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java",
- "value": "java",
- },
- Object {
- "label": "onboarding.language.dotnet",
- "value": "dotnet",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="java"
- />
- </div>
- <RenderOptions
- name="java-build"
- onCheck={[Function]}
- optionLabelKey="onboarding.language.java.build_technology"
- options={
- Array [
- "maven",
- "gradle",
- ]
- }
- titleLabelKey="onboarding.language.java.build_technology"
- />
-</Fragment>
-`;
-
-exports[`selects other 1`] = `
-<Fragment>
- <div>
- <h4
- className="spacer-bottom"
- >
- onboarding.language
- </h4>
- <RadioToggle
- disabled={false}
- name="language"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java",
- "value": "java",
- },
- Object {
- "label": "onboarding.language.dotnet",
- "value": "dotnet",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="other"
- />
- </div>
- <RenderOS
- setOS={[Function]}
- />
-</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={1}
- stepTitle="onboarding.analysis.header"
-/>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div
- className="boxed-group onboarding-step is-open is-finished"
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- First Step
- </h2>
- </div>
- <div
- className=""
- >
- <div>
- form
- </div>
- </div>
-</div>
-`;
-
-exports[`renders 2`] = `
-<div
- className="boxed-group onboarding-step is-finished"
- onClick={[Function]}
- role="button"
- tabIndex={0}
->
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div>
- result
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- First Step
- </h2>
- </div>
- <div
- className="boxed-group-inner"
- />
- <div
- className="hidden"
- >
- <div>
- form
- </div>
- </div>
-</div>
-`;
+++ /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
- className=""
- >
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate_token
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboarding.token.generate_token.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- onboarding.token.generate
- </SubmitButton>
- </form>
- </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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </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
- className=""
- >
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate_token
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboarding.token.generate_token.placeholder"
- required={true}
- type="text"
- value="my token"
- />
- <i
- className="spinner text-middle"
- />
- </form>
- </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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </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
- className=""
- >
- <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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </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
- className=""
- >
- <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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </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
- className=""
- >
- <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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </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
- className=""
- >
- <div
- className="boxed-group-inner"
- >
- <div>
- <div>
- <Radio
- checked={true}
- onCheck={[Function]}
- value="generate"
- >
- onboarding.token.generate_token
- </Radio>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboarding.token.generate_token.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- onboarding.token.generate
- </SubmitButton>
- </form>
- </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={
- Object {
- "link": <Link
- onlyActiveOnIndex={false}
- style={Object {}}
- target="_blank"
- to="/account/security"
- >
- onboarding.token.text.user_account
- </Link>,
- }
- }
- />
- </div>
- </div>
- </div>
-</div>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { getHostUrl } from 'sonar-ui-common/helpers/urls';
-import { LanguageConfig } from '../../utils';
-import { getProjectKey } from '../ProjectAnalysisStep';
-import DotNet from './DotNet';
-import JavaGradle from './JavaGradle';
-import JavaMaven from './JavaMaven';
-import Other from './Other';
-
-interface Props {
- component?: T.Component;
- organization?: string;
- languageConfig: LanguageConfig;
- small?: boolean;
- token?: string;
-}
-
-export default class AnalysisCommand extends React.PureComponent<Props> {
- renderCommandForMaven = () => {
- const { component, token } = this.props;
- if (!token) {
- return null;
- }
- return (
- <JavaMaven
- host={getHostUrl()}
- organization={this.props.organization}
- projectKey={component && component.key}
- token={token}
- />
- );
- };
-
- renderCommandForGradle = () => {
- const { component, token } = this.props;
- if (!token) {
- return null;
- }
- return (
- <JavaGradle
- host={getHostUrl()}
- organization={this.props.organization}
- projectKey={component && component.key}
- token={token}
- />
- );
- };
-
- renderCommandForDotNet = () => {
- const { component, languageConfig, small, token } = this.props;
- const projectKey = getProjectKey(languageConfig, component);
- if (!projectKey || !token) {
- return null;
- }
- return (
- <DotNet
- host={getHostUrl()}
- organization={this.props.organization}
- projectKey={projectKey}
- small={small}
- token={token}
- />
- );
- };
-
- renderCommandForOther = () => {
- const { component, languageConfig, token } = this.props;
- const projectKey = getProjectKey(languageConfig, component);
- if (!languageConfig || !projectKey || !languageConfig.os || !token) {
- return null;
- }
- return (
- <Other
- host={getHostUrl()}
- organization={this.props.organization}
- os={languageConfig.os}
- projectKey={projectKey}
- token={token}
- />
- );
- };
-
- render() {
- const { languageConfig } = this.props;
-
- if (languageConfig.language === 'java') {
- return languageConfig.javaBuild === 'maven'
- ? this.renderCommandForMaven()
- : this.renderCommandForGradle();
- } else if (languageConfig.language === 'dotnet') {
- return this.renderCommandForDotNet();
- } else {
- return this.renderCommandForOther();
- }
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import MSBuildScanner from './MSBuildScanner';
-
-export interface Props {
- host: string;
- organization?: string;
- projectKey: string;
- small?: boolean;
- token: string;
-}
-
-export default function DotNet(props: Props) {
- const command1 = [
- 'SonarScanner.MSBuild.exe begin',
- `/k:"${props.projectKey}"`,
- props.organization && `/d:sonar.organization="${props.organization}"`,
- `/d:sonar.host.url="${props.host}"`,
- `/d:sonar.login="${props.token}"`
- ];
-
- const command2 = 'MsBuild.exe /t:Rebuild';
-
- const command3 = ['SonarScanner.MSBuild.exe end', `/d:sonar.login="${props.token}"`];
-
- return (
- <div>
- <MSBuildScanner />
-
- <h4 className="huge-spacer-top spacer-bottom">
- {translate('onboarding.analysis.msbuild.execute')}
- </h4>
- <InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}>
- {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
- </InstanceMessage>
- <CodeSnippet isOneLine={true} snippet={command1} />
- <CodeSnippet isOneLine={false} snippet={command2} />
- <CodeSnippet isOneLine={props.small} snippet={command3} />
- <p className="big-spacer-top markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.docs')}
- id="onboarding.analysis.docs"
- values={{
- link: (
- <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('onboarding.analysis.msbuild.docs_link')}
- </a>
- )
- }}
- />
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-
-export interface Props {
- host: string;
- organization?: string;
- projectKey?: string;
- token: string;
-}
-
-export default function JavaGradle(props: Props) {
- const config = 'plugins {\n id "org.sonarqube" version "2.7"\n}';
-
- const command = [
- './gradlew sonarqube',
- props.projectKey && `-Dsonar.projectKey=${props.projectKey}`,
- props.organization && `-Dsonar.organization=${props.organization}`,
- `-Dsonar.host.url=${props.host}`,
- `-Dsonar.login=${props.token}`
- ];
-
- return (
- <div>
- <h4 className="spacer-bottom">{translate('onboarding.analysis.java.gradle.header')}</h4>
- <InstanceMessage message={translate('onboarding.analysis.java.gradle.text.1')}>
- {transformedMessage => (
- <p className="spacer-bottom markdown">
- <FormattedMessage
- defaultMessage={transformedMessage}
- id="onboarding.analysis.java.gradle.text.1"
- values={{
- plugin_code: <code>org.sonarqube</code>,
- filename: <code>build.gradle</code>
- }}
- />
- </p>
- )}
- </InstanceMessage>
- <CodeSnippet snippet={config} />
- <p className="spacer-top spacer-bottom markdown">
- {translate('onboarding.analysis.java.gradle.text.2')}
- </p>
- <CodeSnippet snippet={command} />
- <p className="big-spacer-top markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.docs')}
- id="onboarding.analysis.docs"
- values={{
- link: (
- <a
- href="http://redirect.sonarsource.com/doc/gradle.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('onboarding.analysis.java.gradle.docs_link')}
- </a>
- )
- }}
- />
- </p>
- <p className="big-spacer-top markdown">
- {props.projectKey
- ? translate('onboarding.analysis.auto_refresh_after_analysis')
- : translate('onboarding.analysis.browse_url_after_analysis')}
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-
-export interface Props {
- host: string;
- organization?: string;
- projectKey?: string;
- token: string;
-}
-
-export default function JavaMaven(props: Props) {
- const command = [
- 'mvn sonar:sonar',
- props.projectKey && `-Dsonar.projectKey=${props.projectKey}`,
- props.organization && `-Dsonar.organization=${props.organization}`,
- `-Dsonar.host.url=${props.host}`,
- `-Dsonar.login=${props.token}`
- ];
-
- return (
- <div>
- <h4 className="spacer-bottom">{translate('onboarding.analysis.java.maven.header')}</h4>
- <p className="spacer-bottom markdown">
- <InstanceMessage message={translate('onboarding.analysis.java.maven.text')} />
- </p>
- <CodeSnippet snippet={command} />
- <p className="big-spacer-top markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.docs')}
- id="onboarding.analysis.docs"
- values={{
- link: (
- <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('onboarding.analysis.java.maven.docs_link')}
- </a>
- )
- }}
- />
- </p>
- <p className="big-spacer-top markdown">
- {props.projectKey
- ? translate('onboarding.analysis.auto_refresh_after_analysis')
- : translate('onboarding.analysis.browse_url_after_analysis')}
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-
-interface Props {
- className?: string;
-}
-
-export default function MSBuildScanner(props: Props) {
- return (
- <div className={props.className}>
- <h4 className="spacer-bottom">{translate('onboarding.analysis.msbuild.header')}</h4>
- <p className="spacer-bottom markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.msbuild.text')}
- id="onboarding.analysis.msbuild.text"
- values={{ code: <code>%PATH%</code> }}
- />
- </p>
- <p>
- <a
- className="button"
- href="https://sonarcloud.io/documentation/analysis/scan/sonarscanner-for-msbuild/"
- rel="noopener noreferrer"
- target="_blank">
- {translate('download_verb')}
- </a>
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { quote } from '../../utils';
-import SQScanner from './SQScanner';
-
-export interface Props {
- host: string;
- organization?: string;
- os: string;
- projectKey: string;
- token: string;
-}
-
-export default function Other(props: Props) {
- const q = quote(props.os);
- const command = [
- props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
- '-D' + q(`sonar.projectKey=${props.projectKey}`),
- props.organization && '-D' + q(`sonar.organization=${props.organization}`),
- '-D' + q('sonar.sources=.'),
- '-D' + q(`sonar.host.url=${props.host}`),
- '-D' + q(`sonar.login=${props.token}`)
- ];
-
- return (
- <div>
- <SQScanner os={props.os} />
-
- <h4 className="huge-spacer-top spacer-bottom">
- {translate('onboarding.analysis.sq_scanner.execute')}
- </h4>
- <InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}>
- {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
- </InstanceMessage>
- <CodeSnippet isOneLine={props.os === 'win'} snippet={command} />
- <p className="big-spacer-top markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.sq_scanner.docs')}
- id="onboarding.analysis.sq_scanner.docs"
- values={{
- link: (
- <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('onboarding.analysis.sq_scanner.docs_link')}
- </a>
- )
- }}
- />
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 * as React from 'react';
-import { FormattedMessage } from 'react-intl';
-import { translate } from 'sonar-ui-common/helpers/l10n';
-
-interface Props {
- className?: string;
- os: string;
-}
-
-export default function SQScanner(props: Props) {
- return (
- <div className={props.className}>
- <h4 className="spacer-bottom">
- {translate('onboarding.analysis.sq_scanner.header', props.os)}
- </h4>
- <p className="spacer-bottom markdown">
- <FormattedMessage
- defaultMessage={translate('onboarding.analysis.sq_scanner.text')}
- id="onboarding.analysis.sq_scanner.text"
- values={{
- dir: <code>bin</code>,
- env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code>
- }}
- />
- </p>
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank">
- {translate('download_verb')}
- </a>
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 AnalysisCommand from '../AnalysisCommand';
-
-jest.mock('sonar-ui-common/helpers/urls', () => ({
- getHostUrl: () => 'HOST'
-}));
-
-it('display java command', () => {
- expect(
- getWrapper({ languageConfig: { language: 'java', javaBuild: 'gradle' } })
- ).toMatchSnapshot();
- expect(
- getWrapper({ languageConfig: { language: 'java', javaBuild: 'maven' } })
- ).toMatchSnapshot();
-});
-
-it('display c# command', () => {
- expect(
- getWrapper({ languageConfig: { language: 'dotnet', projectKey: 'project-foo' } })
- ).toMatchSnapshot();
-});
-
-it('display others command', () => {
- expect(
- getWrapper({
- languageConfig: { language: 'other', os: 'window', projectKey: 'project-foo' }
- })
- ).toMatchSnapshot();
-});
-
-function getWrapper(props = {}) {
- return shallow(<AnalysisCommand languageConfig={{}} token="myToken" {...props} />);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 DotNet, { Props } from '../DotNet';
-
-it('DotNet renders correctly', () => {
- expect(shallowRender).toMatchSnapshot();
-
- expect(
- shallowRender({
- organization: 'organization',
- small: true
- })
- ).toMatchSnapshot();
-});
-
-function shallowRender(props: Partial<Props> = {}) {
- return shallow(<DotNet host="host" projectKey="projectKey" token="token" {...props} />);
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 JavaGradle from '../JavaGradle';
-
-it('renders correctly', () => {
- expect(shallow(<JavaGradle host="host" token="token" />)).toMatchSnapshot();
- expect(
- shallow(<JavaGradle host="host" organization="organization" token="token" />)
- ).toMatchSnapshot();
-});
-
-it('renders with projectKey', () => {
- expect(
- shallow(<JavaGradle host="host" organization="organization" projectKey="foo" token="token" />)
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 JavaMaven from '../JavaMaven';
-
-it('renders correctly', () => {
- expect(shallow(<JavaMaven host="host" token="token" />)).toMatchSnapshot();
- expect(
- shallow(<JavaMaven host="host" organization="organization" token="token" />)
- ).toMatchSnapshot();
-});
-
-it('renders with projectKey', () => {
- expect(
- shallow(<JavaMaven host="host" organization="organization" projectKey="foo" token="token" />)
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 MSBuildScanner from '../MSBuildScanner';
-
-it('renders correctly', () => {
- expect(shallow(<MSBuildScanner />)).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 Other from '../Other';
-
-it('renders correctly', () => {
- expect(
- shallow(<Other host="host" os="win" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-
- expect(
- shallow(<Other host="host" os="linux" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-
- expect(
- shallow(<Other host="host" os="linux" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 SQScanner from '../SQScanner';
-
-it('renders correctly', () => {
- expect(shallow(<SQScanner os="win" />)).toMatchSnapshot();
- expect(shallow(<SQScanner os="linux" />)).toMatchSnapshot();
- expect(shallow(<SQScanner os="mac" />)).toMatchSnapshot();
-});
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`display c# command 1`] = `
-<DotNet
- host="HOST"
- projectKey="project-foo"
- token="myToken"
-/>
-`;
-
-exports[`display java command 1`] = `
-<JavaGradle
- host="HOST"
- token="myToken"
-/>
-`;
-
-exports[`display java command 2`] = `
-<JavaMaven
- host="HOST"
- token="myToken"
-/>
-`;
-
-exports[`display others command 1`] = `
-<Other
- host="HOST"
- os="window"
- projectKey="project-foo"
- token="myToken"
-/>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`DotNet renders correctly 1`] = `[Function]`;
-
-exports[`DotNet renders correctly 2`] = `
-<div>
- <MSBuildScanner />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.msbuild.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.msbuild.execute.text"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarScanner.MSBuild.exe begin",
- "/k:\\"projectKey\\"",
- "/d:sonar.organization=\\"organization\\"",
- "/d:sonar.host.url=\\"host\\"",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <CodeSnippet
- isOneLine={false}
- snippet="MsBuild.exe /t:Rebuild"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarScanner.MSBuild.exe end",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.msbuild.docs_link
- </a>,
- }
- }
- />
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.gradle.header
- </h4>
- <InstanceMessage
- message="onboarding.analysis.java.gradle.text.1"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- snippet="plugins {
- id \\"org.sonarqube\\" version \\"2.7\\"
-}"
- />
- <p
- className="spacer-top spacer-bottom markdown"
- >
- onboarding.analysis.java.gradle.text.2
- </p>
- <CodeSnippet
- snippet={
- Array [
- "./gradlew sonarqube",
- undefined,
- undefined,
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/gradle.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.gradle.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.browse_url_after_analysis
- </p>
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.gradle.header
- </h4>
- <InstanceMessage
- message="onboarding.analysis.java.gradle.text.1"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- snippet="plugins {
- id \\"org.sonarqube\\" version \\"2.7\\"
-}"
- />
- <p
- className="spacer-top spacer-bottom markdown"
- >
- onboarding.analysis.java.gradle.text.2
- </p>
- <CodeSnippet
- snippet={
- Array [
- "./gradlew sonarqube",
- undefined,
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/gradle.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.gradle.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.browse_url_after_analysis
- </p>
-</div>
-`;
-
-exports[`renders with projectKey 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.gradle.header
- </h4>
- <InstanceMessage
- message="onboarding.analysis.java.gradle.text.1"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- snippet="plugins {
- id \\"org.sonarqube\\" version \\"2.7\\"
-}"
- />
- <p
- className="spacer-top spacer-bottom markdown"
- >
- onboarding.analysis.java.gradle.text.2
- </p>
- <CodeSnippet
- snippet={
- Array [
- "./gradlew sonarqube",
- "-Dsonar.projectKey=foo",
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/gradle.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.gradle.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.maven.header
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <InstanceMessage
- message="onboarding.analysis.java.maven.text"
- />
- </p>
- <CodeSnippet
- snippet={
- Array [
- "mvn sonar:sonar",
- undefined,
- undefined,
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.maven.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.browse_url_after_analysis
- </p>
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.maven.header
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <InstanceMessage
- message="onboarding.analysis.java.maven.text"
- />
- </p>
- <CodeSnippet
- snippet={
- Array [
- "mvn sonar:sonar",
- undefined,
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.maven.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.browse_url_after_analysis
- </p>
-</div>
-`;
-
-exports[`renders with projectKey 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.maven.header
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <InstanceMessage
- message="onboarding.analysis.java.maven.text"
- />
- </p>
- <CodeSnippet
- snippet={
- Array [
- "mvn sonar:sonar",
- "-Dsonar.projectKey=foo",
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.docs"
- id="onboarding.analysis.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.java.maven.docs_link
- </a>,
- }
- }
- />
- </p>
- <p
- className="big-spacer-top markdown"
- >
- onboarding.analysis.auto_refresh_after_analysis
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.msbuild.header
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.msbuild.text"
- id="onboarding.analysis.msbuild.text"
- values={
- Object {
- "code": <code>
- %PATH%
- </code>,
- }
- }
- />
- </p>
- <p>
- <a
- className="button"
- href="https://sonarcloud.io/documentation/analysis/scan/sonarscanner-for-msbuild/"
- rel="noopener noreferrer"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <SQScanner
- os="win"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "sonar-scanner.bat",
- "-D\\"sonar.projectKey=projectKey\\"",
- undefined,
- "-D\\"sonar.sources=.\\"",
- "-D\\"sonar.host.url=host\\"",
- "-D\\"sonar.login=token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.docs"
- id="onboarding.analysis.sq_scanner.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.sq_scanner.docs_link
- </a>,
- }
- }
- />
- </p>
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <SQScanner
- os="linux"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- isOneLine={false}
- snippet={
- Array [
- "sonar-scanner",
- "-Dsonar.projectKey=projectKey",
- undefined,
- "-Dsonar.sources=.",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.docs"
- id="onboarding.analysis.sq_scanner.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.sq_scanner.docs_link
- </a>,
- }
- }
- />
- </p>
-</div>
-`;
-
-exports[`renders correctly 3`] = `
-<div>
- <SQScanner
- os="linux"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- >
- <Component />
- </InstanceMessage>
- <CodeSnippet
- isOneLine={false}
- snippet={
- Array [
- "sonar-scanner",
- "-Dsonar.projectKey=projectKey",
- undefined,
- "-Dsonar.sources=.",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.docs"
- id="onboarding.analysis.sq_scanner.docs"
- values={
- Object {
- "link": <a
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- onboarding.analysis.sq_scanner.docs_link
- </a>,
- }
- }
- />
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.sq_scanner.header.win
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.text"
- id="onboarding.analysis.sq_scanner.text"
- values={
- Object {
- "dir": <code>
- bin
- </code>,
- "env_var": <code>
- %PATH%
- </code>,
- }
- }
- />
- </p>
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.sq_scanner.header.linux
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.text"
- id="onboarding.analysis.sq_scanner.text"
- values={
- Object {
- "dir": <code>
- bin
- </code>,
- "env_var": <code>
- PATH
- </code>,
- }
- }
- />
- </p>
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
-
-exports[`renders correctly 3`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.sq_scanner.header.mac
- </h4>
- <p
- className="spacer-bottom markdown"
- >
- <FormattedMessage
- defaultMessage="onboarding.analysis.sq_scanner.text"
- id="onboarding.analysis.sq_scanner.text"
- values={
- Object {
- "dir": <code>
- bin
- </code>,
- "env_var": <code>
- PATH
- </code>,
- }
- }
- />
- </p>
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- rel="noopener noreferrer"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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.
- */
-.onboarding-step {
- position: relative;
- padding-left: 34px;
-}
-
-.onboarding-step:not(.is-open):not(.is-finished) {
- opacity: 0.4;
-}
-
-.onboarding-step .boxed-group-actions {
- height: var(--controlHeight);
- line-height: var(--controlHeight);
-}
-
-.onboarding-step hr {
- margin-left: -54px;
-}
-
-.onboarding-step-number {
- position: absolute;
- top: 15px;
- left: 15px;
- width: 24px;
- height: 24px;
- line-height: 24px;
- border-radius: 24px;
- background-color: #b9b9b9;
- color: #fff;
- font-size: var(--mediumFontSize);
- text-align: center;
-}
-
-.onboarding-step.is-open .onboarding-step-number {
- background-color: var(--darkBlue);
-}
-
-.onboarding-step.is-finished {
- cursor: pointer;
- outline: none;
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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.
- */
-export interface LanguageConfig {
- language?: string;
- javaBuild?: string;
- cFamilyCompiler?: string;
- os?: string;
- projectKey?: string;
-}
-
-export function isLanguageConfigured(config?: LanguageConfig) {
- if (!config) {
- return false;
- }
- const { language, javaBuild, cFamilyCompiler, os, projectKey } = config;
- const isJavaConfigured = language === 'java' && javaBuild != null;
- const isDotNetConfigured = language === 'dotnet' && projectKey != null;
- const isCFamilyConfigured =
- language === 'c-family' && (cFamilyCompiler === 'msvc' || os != null) && projectKey != null;
- const isOtherConfigured = language === 'other' && projectKey != null;
-
- return isJavaConfigured || isDotNetConfigured || isCFamilyConfigured || isOtherConfigured;
-}
-
-export function quote(os: string): (s: string) => string {
- return os === 'win' ? (s: string) => `"${s}"` : (s: string) => s;
-}
-
-export function getUniqueTokenName(tokens: T.UserToken[], initialTokenName = '') {
- const hasToken = (name: string) => tokens.find(token => token.name === name) !== undefined;
-
- if (!hasToken(initialTokenName)) {
- return initialTokenName;
- }
-
- let i = 1;
- while (hasToken(`${initialTokenName} ${i}`)) {
- i++;
- }
- return `${initialTokenName} ${i}`;
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { getUniqueTokenName } from '../utils';
+
+const initialTokenName = 'Analyze "lightsaber"';
+
+it('should return the given name when the user has no token', () => {
+ const userTokens: T.UserToken[] = [];
+
+ expect(getUniqueTokenName(userTokens, initialTokenName)).toBe(initialTokenName);
+});
+
+it('should generate a token with the given name', () => {
+ const userTokens = [{ name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' }];
+
+ expect(getUniqueTokenName(userTokens, 'Analyze "project"')).toBe('Analyze "project"');
+});
+
+it('should generate a unique token when the name already exists', () => {
+ const userTokens = [
+ { name: initialTokenName, createdAt: '2019-06-14T09:45:52+0200' },
+ { name: `${initialTokenName} 1`, createdAt: '2019-06-14T09:45:52+0200' }
+ ];
+
+ expect(getUniqueTokenName(userTokens, initialTokenName)).toBe('Analyze "lightsaber" 2');
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+export interface RenderOptionsProps {
+ checked: string | undefined;
+ name: string;
+ onCheck: (checked: string) => void;
+ optionLabelKey: string;
+ options: string[];
+ titleLabelKey?: string;
+}
+
+export default function RenderOptions({
+ checked,
+ onCheck,
+ optionLabelKey,
+ options,
+ titleLabelKey
+}: RenderOptionsProps) {
+ return (
+ <div className="big-spacer-top">
+ {titleLabelKey && <h4 className="spacer-bottom">{translate(titleLabelKey)}</h4>}
+
+ <RadioToggle
+ name={name}
+ onCheck={onCheck}
+ options={options.map(build => ({
+ label: translate(optionLabelKey, build),
+ value: build
+ }))}
+ value={checked}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.
+ */
+.onboarding-step {
+ position: relative;
+ padding-left: 34px;
+}
+
+.onboarding-step:not(.is-open):not(.is-finished) {
+ opacity: 0.4;
+}
+
+.onboarding-step .boxed-group-actions {
+ height: var(--controlHeight);
+ line-height: var(--controlHeight);
+}
+
+.onboarding-step hr {
+ margin-left: -54px;
+}
+
+.onboarding-step-number {
+ position: absolute;
+ top: 15px;
+ left: 15px;
+ width: 24px;
+ height: 24px;
+ line-height: 24px;
+ border-radius: 24px;
+ background-color: #b9b9b9;
+ color: #fff;
+ font-size: var(--mediumFontSize);
+ text-align: center;
+}
+
+.onboarding-step.is-open .onboarding-step-number {
+ background-color: var(--darkBlue);
+}
+
+.onboarding-step.is-finished {
+ cursor: pointer;
+ outline: none;
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.
+ */
+/* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/no-noninteractive-tabindex */
+import * as classNames from 'classnames';
+import * as React from 'react';
+import './Step.css';
+
+interface Props {
+ finished?: boolean;
+ onOpen: VoidFunction;
+ open: boolean;
+ renderForm: () => React.ReactNode;
+ renderResult: () => React.ReactNode;
+ stepNumber: number;
+ stepTitle: React.ReactNode;
+}
+
+export default function Step(props: Props) {
+ const className = classNames('boxed-group', 'onboarding-step', {
+ 'is-open': props.open,
+ 'is-finished': props.finished
+ });
+
+ const clickable = !props.open && props.finished;
+
+ const handleClick = (event: React.MouseEvent<HTMLDivElement>) => {
+ event.preventDefault();
+ props.onOpen();
+ };
+
+ return (
+ <div
+ className={className}
+ onClick={clickable ? handleClick : undefined}
+ role={clickable ? 'button' : undefined}
+ tabIndex={clickable ? 0 : undefined}>
+ <div className="onboarding-step-number">{props.stepNumber}</div>
+ {!props.open && props.renderResult()}
+ <div className="boxed-group-header">
+ <h2>{props.stepTitle}</h2>
+ </div>
+ {!props.open && <div className="boxed-group-inner" />}
+ <div className={classNames({ hidden: !props.open })}>{props.renderForm()}</div>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 RenderOptions, { RenderOptionsProps } from '../RenderOptions';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ checked: 'baz' })).toMatchSnapshot('option checked');
+ expect(shallowRender({ titleLabelKey: 'title.key' })).toMatchSnapshot('with title');
+});
+
+function shallowRender(props: Partial<RenderOptionsProps> = {}) {
+ return shallow<RenderOptionsProps>(
+ <RenderOptions
+ checked={undefined}
+ name="bar"
+ onCheck={jest.fn()}
+ optionLabelKey="foo.bar"
+ options={['foo', 'baz']}
+ {...props}
+ />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { click } from 'sonar-ui-common/helpers/testUtils';
+import Step from '../Step';
+
+it('renders', () => {
+ const wrapper = shallow(
+ <Step
+ finished={true}
+ onOpen={jest.fn()}
+ open={true}
+ renderForm={() => <div>form</div>}
+ renderResult={() => <div>result</div>}
+ stepNumber={1}
+ stepTitle="First Step"
+ />
+ );
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setProps({ open: false });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('re-opens', () => {
+ const onOpen = jest.fn();
+ const wrapper = shallow(
+ <Step
+ finished={true}
+ onOpen={onOpen}
+ open={false}
+ renderForm={() => <div>form</div>}
+ renderResult={() => <div>result</div>}
+ stepNumber={1}
+ stepTitle="First Step"
+ />
+ );
+ click(wrapper);
+ expect(onOpen).toBeCalled();
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly: default 1`] = `
+<div
+ className="big-spacer-top"
+>
+ <RadioToggle
+ disabled={false}
+ name=""
+ onCheck={[MockFunction]}
+ options={
+ Array [
+ Object {
+ "label": "foo.bar.foo",
+ "value": "foo",
+ },
+ Object {
+ "label": "foo.bar.baz",
+ "value": "baz",
+ },
+ ]
+ }
+ value={null}
+ />
+</div>
+`;
+
+exports[`should render correctly: option checked 1`] = `
+<div
+ className="big-spacer-top"
+>
+ <RadioToggle
+ disabled={false}
+ name=""
+ onCheck={[MockFunction]}
+ options={
+ Array [
+ Object {
+ "label": "foo.bar.foo",
+ "value": "foo",
+ },
+ Object {
+ "label": "foo.bar.baz",
+ "value": "baz",
+ },
+ ]
+ }
+ value="baz"
+ />
+</div>
+`;
+
+exports[`should render correctly: with title 1`] = `
+<div
+ className="big-spacer-top"
+>
+ <h4
+ className="spacer-bottom"
+ >
+ title.key
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name=""
+ onCheck={[MockFunction]}
+ options={
+ Array [
+ Object {
+ "label": "foo.bar.foo",
+ "value": "foo",
+ },
+ Object {
+ "label": "foo.bar.baz",
+ "value": "baz",
+ },
+ ]
+ }
+ value={null}
+ />
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<div
+ className="boxed-group onboarding-step is-open is-finished"
+>
+ <div
+ className="onboarding-step-number"
+ >
+ 1
+ </div>
+ <div
+ className="boxed-group-header"
+ >
+ <h2>
+ First Step
+ </h2>
+ </div>
+ <div
+ className=""
+ >
+ <div>
+ form
+ </div>
+ </div>
+</div>
+`;
+
+exports[`renders 2`] = `
+<div
+ className="boxed-group onboarding-step is-finished"
+ onClick={[Function]}
+ role="button"
+ tabIndex={0}
+>
+ <div
+ className="onboarding-step-number"
+ >
+ 1
+ </div>
+ <div>
+ result
+ </div>
+ <div
+ className="boxed-group-header"
+ >
+ <h2>
+ First Step
+ </h2>
+ </div>
+ <div
+ className="boxed-group-inner"
+ />
+ <div
+ className="hidden"
+ >
+ <div>
+ form
+ </div>
+ </div>
+</div>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import RadioToggle from 'sonar-ui-common/components/controls/RadioToggle';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import RenderOptions from '../components/RenderOptions';
+import { LanguageConfig } from '../types';
+import { isLanguageConfigured } from '../utils';
+
+interface Props {
+ component: T.Component;
+ config?: LanguageConfig;
+ onDone: (config: LanguageConfig) => void;
+ onReset: VoidFunction;
+ organization?: string;
+}
+
+type State = LanguageConfig;
+
+export interface RenderOSProps {
+ os: string | undefined;
+ setOS: (os: string) => void;
+}
+
+export function RenderOS(props: RenderOSProps) {
+ return (
+ <RenderOptions
+ checked={props.os}
+ name="os"
+ onCheck={props.setOS}
+ optionLabelKey="onboarding.language.os"
+ options={['linux', 'win', 'mac']}
+ titleLabelKey="onboarding.language.os"
+ />
+ );
+}
+
+export default class LanguageForm extends React.PureComponent<Props, State> {
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ ...(this.props.config || {}),
+ projectKey: props.component ? props.component.key : undefined
+ };
+ }
+
+ handleChange = () => {
+ if (isLanguageConfigured(this.state)) {
+ this.props.onDone(this.state);
+ } else {
+ this.props.onReset();
+ }
+ };
+
+ handleLanguageChange = (language: string) => {
+ this.setState({ language }, this.handleChange);
+ };
+
+ handleJavaBuildChange = (javaBuild: string) => {
+ this.setState({ javaBuild }, this.handleChange);
+ };
+
+ handleOSChange = (os: string) => {
+ this.setState({ os }, this.handleChange);
+ };
+
+ renderJavaBuild = () => (
+ <RenderOptions
+ checked={this.state.javaBuild}
+ name="java-build"
+ onCheck={this.handleJavaBuildChange}
+ optionLabelKey="onboarding.language.java.build_technology"
+ options={['maven', 'gradle']}
+ titleLabelKey="onboarding.language.java.build_technology"
+ />
+ );
+
+ render() {
+ const { language } = this.state;
+ const languages = ['java', 'dotnet', 'other'];
+
+ return (
+ <>
+ <div>
+ <h4 className="spacer-bottom">{translate('onboarding.language')}</h4>
+ <RadioToggle
+ name="language"
+ onCheck={this.handleLanguageChange}
+ options={languages.map(language => ({
+ label: translate('onboarding.language', language),
+ value: language
+ }))}
+ value={language}
+ />
+ </div>
+ {language === 'java' && this.renderJavaBuild()}
+ {language === 'other' && <RenderOS os={this.state.os} setOS={this.handleOSChange} />}
+ </>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
+import BackIcon from 'sonar-ui-common/components/icons/BackIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { isVSTS } from '../../../helpers/almIntegrations';
+import InstanceMessage from '../../common/InstanceMessage';
+import ProjectAnalysisStep from './ProjectAnalysisStep';
+import TokenStep from './TokenStep';
+
+export enum Steps {
+ ANALYSIS,
+ TOKEN
+}
+
+interface Props {
+ component: T.Component;
+ currentUser: T.LoggedInUser;
+ onBack?: () => void;
+}
+
+interface State {
+ step: Steps;
+ token?: string;
+}
+
+export default class ManualTutorial extends React.PureComponent<Props, State> {
+ state: State = { step: Steps.TOKEN };
+
+ handleTokenDone = (token: string) => {
+ this.setState({ step: Steps.ANALYSIS, token });
+ };
+
+ handleTokenOpen = () => {
+ this.setState({ step: Steps.TOKEN });
+ };
+
+ render() {
+ const { component, currentUser } = this.props;
+ const { step, token } = this.state;
+
+ const almKey = (component.alm && component.alm.key) || currentUser.externalProvider;
+ return (
+ <>
+ <div className="page-header big-spacer-bottom">
+ <h1 className="page-title">
+ {this.props.onBack !== undefined && (
+ <Tooltip overlay={translate('onboarding.tutorial.return_to_list')}>
+ <a
+ aria-label={translate('onboarding.tutorial.return_to_list')}
+ className="link-no-underline big-spacer-right"
+ onClick={this.props.onBack}>
+ <BackIcon />
+ </a>
+ </Tooltip>
+ )}
+ {translate('onboarding.project_analysis.header')}
+ </h1>
+ <p className="page-description">
+ <InstanceMessage message={translate('onboarding.project_analysis.description')} />
+ </p>
+ </div>
+
+ {!isVSTS(almKey) && (
+ <>
+ <TokenStep
+ currentUser={currentUser}
+ finished={Boolean(this.state.token)}
+ initialTokenName={`Analyze "${component.name}"`}
+ onContinue={this.handleTokenDone}
+ onOpen={this.handleTokenOpen}
+ open={step === Steps.TOKEN}
+ stepNumber={1}
+ />
+
+ <ProjectAnalysisStep
+ component={component}
+ displayRowLayout={true}
+ open={step === Steps.ANALYSIS}
+ stepNumber={2}
+ token={token}
+ />
+ </>
+ )}
+ </>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import Step from '../components/Step';
+import { LanguageConfig } from '../types';
+import AnalysisCommand from './commands/AnalysisCommand';
+import LanguageForm from './LanguageForm';
+
+interface Props {
+ component: T.Component;
+ displayRowLayout?: boolean;
+ onFinish?: (projectKey?: string) => void;
+ onReset?: VoidFunction;
+ open: boolean;
+ organization?: string;
+ stepNumber: number;
+ token?: string;
+}
+
+interface State {
+ config?: LanguageConfig;
+}
+
+export function getProjectKey(config?: LanguageConfig, component?: T.Component) {
+ return (component && component.key) || (config && config.projectKey);
+}
+
+export default class ProjectAnalysisStep extends React.PureComponent<Props, State> {
+ state: State = {};
+
+ handleLanguageSelect = (config: LanguageConfig) => {
+ this.setState({ config });
+ if (this.props.onFinish) {
+ const projectKey = config.language !== 'java' ? getProjectKey(config) : undefined;
+ this.props.onFinish(projectKey);
+ }
+ };
+
+ handleLanguageReset = () => {
+ this.setState({ config: undefined });
+ if (this.props.onReset) {
+ this.props.onReset();
+ }
+ };
+
+ renderForm = () => {
+ const languageComponent = (
+ <LanguageForm
+ component={this.props.component}
+ onDone={this.handleLanguageSelect}
+ onReset={this.handleLanguageReset}
+ organization={this.props.organization}
+ />
+ );
+ const analysisComponent = this.state.config && (
+ <AnalysisCommand
+ component={this.props.component}
+ languageConfig={this.state.config}
+ organization={this.props.organization}
+ small={true}
+ token={this.props.token}
+ />
+ );
+
+ if (this.props.displayRowLayout) {
+ return (
+ <div className="boxed-group-inner">
+ <div className="display-flex-column">
+ {languageComponent}
+ {analysisComponent && <div className="huge-spacer-top">{analysisComponent}</div>}
+ </div>
+ </div>
+ );
+ }
+
+ return (
+ <div className="boxed-group-inner">
+ <div className="flex-columns">
+ <div className="flex-column flex-column-half bordered-right">{languageComponent}</div>
+ <div className="flex-column flex-column-half">{analysisComponent}</div>
+ </div>
+ </div>
+ );
+ };
+
+ renderResult = () => null;
+
+ render() {
+ return (
+ <Step
+ finished={false}
+ onOpen={() => {}}
+ open={this.props.open}
+ renderForm={this.renderForm}
+ renderResult={this.renderResult}
+ stepNumber={this.props.stepNumber}
+ stepTitle={translate('onboarding.analysis.header')}
+ />
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { Link } from 'react-router';
+import { Button, DeleteButton, SubmitButton } from 'sonar-ui-common/components/controls/buttons';
+import Radio from 'sonar-ui-common/components/controls/Radio';
+import AlertErrorIcon from 'sonar-ui-common/components/icons/AlertErrorIcon';
+import AlertSuccessIcon from 'sonar-ui-common/components/icons/AlertSuccessIcon';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { generateToken, getTokens, revokeToken } from '../../../api/user-tokens';
+import Step from '../components/Step';
+import { getUniqueTokenName } from '../utils';
+
+interface Props {
+ currentUser: Pick<T.LoggedInUser, 'login'>;
+ finished: boolean;
+ initialTokenName?: string;
+ open: boolean;
+ onContinue: (token: string) => void;
+ onOpen: VoidFunction;
+ stepNumber: number;
+}
+
+interface State {
+ existingToken: string;
+ loading: boolean;
+ selection: string;
+ tokenName?: string;
+ token?: string;
+ tokens?: T.UserToken[];
+}
+
+export default class TokenStep extends React.PureComponent<Props, State> {
+ mounted = false;
+
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ existingToken: '',
+ loading: false,
+ selection: 'generate',
+ tokenName: props.initialTokenName
+ };
+ }
+
+ componentDidMount() {
+ this.mounted = true;
+ getTokens(this.props.currentUser.login).then(
+ tokens => {
+ if (this.mounted) {
+ this.setState({ tokens });
+ if (
+ this.props.initialTokenName !== undefined &&
+ this.props.initialTokenName === this.state.tokenName
+ ) {
+ this.setState({ tokenName: getUniqueTokenName(tokens) });
+ }
+ }
+ },
+ () => {}
+ );
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ getToken = () =>
+ this.state.selection === 'generate' ? this.state.token : this.state.existingToken;
+
+ canContinue = () => {
+ const { existingToken, selection, token } = this.state;
+ const validExistingToken = existingToken.match(/^[a-z0-9]+$/) != null;
+ return (
+ (selection === 'generate' && token != null) ||
+ (selection === 'use-existing' && existingToken && validExistingToken)
+ );
+ };
+
+ handleTokenNameChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ tokenName: event.target.value });
+ };
+
+ handleTokenGenerate = (event: React.FormEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ const { tokenName } = this.state;
+ if (tokenName) {
+ this.setState({ loading: true });
+ generateToken({ name: tokenName }).then(({ token }) => {
+ if (this.mounted) {
+ this.setState({ loading: false, token });
+ }
+ }, this.stopLoading);
+ }
+ };
+
+ handleTokenRevoke = () => {
+ const { tokenName } = this.state;
+ if (tokenName) {
+ this.setState({ loading: true });
+ revokeToken({ name: tokenName }).then(() => {
+ if (this.mounted) {
+ this.setState({ loading: false, token: undefined, tokenName: undefined });
+ }
+ }, this.stopLoading);
+ }
+ };
+
+ handleContinueClick = () => {
+ const token = this.getToken();
+ if (token) {
+ this.props.onContinue(token);
+ }
+ };
+
+ handleGenerateClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ selection: 'generate' });
+ };
+
+ handleUseExistingClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ selection: 'use-existing' });
+ };
+
+ handleModeChange = (mode: string) => {
+ this.setState({ selection: mode });
+ };
+
+ handleExisingTokenChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ existingToken: event.currentTarget.value });
+ };
+
+ stopLoading = () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ };
+
+ renderGenerateOption = () => (
+ <div>
+ {this.state.tokens !== undefined && this.state.tokens.length > 0 ? (
+ <Radio
+ checked={this.state.selection === 'generate'}
+ onCheck={this.handleModeChange}
+ value="generate">
+ {translate('onboarding.token.generate_token')}
+ </Radio>
+ ) : (
+ translate('onboarding.token.generate_token')
+ )}
+ {this.state.selection === 'generate' && (
+ <div className="big-spacer-top">
+ <form onSubmit={this.handleTokenGenerate}>
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ onChange={this.handleTokenNameChange}
+ placeholder={translate('onboarding.token.generate_token.placeholder')}
+ required={true}
+ type="text"
+ value={this.state.tokenName || ''}
+ />
+ {this.state.loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <SubmitButton className="text-middle" disabled={!this.state.tokenName}>
+ {translate('onboarding.token.generate')}
+ </SubmitButton>
+ )}
+ </form>
+ </div>
+ )}
+ </div>
+ );
+
+ renderUseExistingOption = () => {
+ const { existingToken } = this.state;
+ const validInput = !existingToken || existingToken.match(/^[a-z0-9]+$/) != null;
+
+ return (
+ <div className="big-spacer-top">
+ <Radio
+ checked={this.state.selection === 'use-existing'}
+ onCheck={this.handleModeChange}
+ value="use-existing">
+ {translate('onboarding.token.use_existing_token')}
+ </Radio>
+ {this.state.selection === 'use-existing' && (
+ <div className="big-spacer-top">
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ onChange={this.handleExisingTokenChange}
+ placeholder={translate('onboarding.token.use_existing_token.placeholder')}
+ required={true}
+ type="text"
+ value={this.state.existingToken}
+ />
+ {!validInput && (
+ <span className="text-danger">
+ <AlertErrorIcon className="little-spacer-right text-text-top" />
+ {translate('onboarding.token.invalid_format')}
+ </span>
+ )}
+ </div>
+ )}
+ </div>
+ );
+ };
+
+ renderForm = () => {
+ const { loading, token, tokenName, tokens } = this.state;
+ const canUseExisting = tokens !== undefined && tokens.length > 0;
+
+ return (
+ <div className="boxed-group-inner">
+ {token != null ? (
+ <form onSubmit={this.handleTokenRevoke}>
+ <span className="text-middle">
+ {tokenName}
+ {': '}
+ </span>
+ <strong className="spacer-right text-middle">{token}</strong>
+ {loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <DeleteButton className="button-small text-middle" onClick={this.handleTokenRevoke} />
+ )}
+ </form>
+ ) : (
+ <div>
+ {this.renderGenerateOption()}
+ {canUseExisting && this.renderUseExistingOption()}
+ </div>
+ )}
+
+ <div className="note big-spacer-top width-50">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.token.text')}
+ id="onboarding.token.text"
+ values={{
+ link: (
+ <Link target="_blank" to="/account/security">
+ {translate('onboarding.token.text.user_account')}
+ </Link>
+ )
+ }}
+ />
+ </div>
+
+ {this.canContinue() && (
+ <div className="big-spacer-top">
+ <Button className="js-continue" onClick={this.handleContinueClick}>
+ {translate('continue')}
+ </Button>
+ </div>
+ )}
+ </div>
+ );
+ };
+
+ renderResult = () => {
+ const { selection, tokenName } = this.state;
+ const token = this.getToken();
+
+ if (!token) {
+ return null;
+ }
+
+ return (
+ <div className="boxed-group-actions display-flex-center">
+ <AlertSuccessIcon className="spacer-right" />
+ {selection === 'generate' && tokenName && `${tokenName}: `}
+ <strong>{token}</strong>
+ </div>
+ );
+ };
+
+ render() {
+ return (
+ <Step
+ finished={this.props.finished}
+ onOpen={this.props.onOpen}
+ open={this.props.open}
+ renderForm={this.renderForm}
+ renderResult={this.renderResult}
+ stepNumber={this.props.stepNumber}
+ stepTitle={translate('onboarding.token.header')}
+ />
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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/testMocks';
+import LanguageForm from '../LanguageForm';
+
+it('selects java', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(
+ <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
+ );
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('java');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('selects c#', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(
+ <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
+ );
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('dotnet');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('selects other', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(
+ <LanguageForm component={mockComponent()} onDone={onDone} onReset={jest.fn()} />
+ );
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('other');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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, mockLoggedInUser } from '../../../../helpers/testMocks';
+import ManualTutorial from '../ManualTutorial';
+import ProjectAnalysisStep from '../ProjectAnalysisStep';
+import TokenStep from '../TokenStep';
+
+it('renders correctly', () => {
+ expect(shallowRender()).toMatchSnapshot('default');
+ expect(shallowRender({ onBack: jest.fn() })).toMatchSnapshot('with back button');
+});
+
+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<ManualTutorial['props']> = {}) {
+ return shallow<ManualTutorial>(
+ <ManualTutorial component={mockComponent()} currentUser={mockLoggedInUser()} {...props} />
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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/testMocks';
+import ProjectAnalysisStep from '../ProjectAnalysisStep';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+});
+
+function shallowRender() {
+ return shallow(<ProjectAnalysisStep component={mockComponent()} open={true} stepNumber={1} />);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 { change, click, submit, waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import TokenStep from '../TokenStep';
+
+jest.mock('../../../../api/user-tokens', () => ({
+ getTokens: () => Promise.resolve([{ name: 'foo' }]),
+ generateToken: () => Promise.resolve({ token: 'abcd1234' }),
+ revokeToken: () => Promise.resolve()
+}));
+
+const currentUser: Pick<T.LoggedInUser, 'login'> = { login: 'user' };
+
+it('generates token', async () => {
+ const wrapper = shallow(
+ <TokenStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={jest.fn()}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ 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 = shallow(
+ <TokenStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={jest.fn()}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ 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 = shallow(
+ <TokenStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={onContinue}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ await new Promise(setImmediate);
+ wrapper.setState({ token: 'abcd1234', tokenName: 'my token' });
+ click(wrapper.dive().find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('abcd1234');
+});
+
+it('uses existing token', async () => {
+ const onContinue = jest.fn();
+ const wrapper = shallow(
+ <TokenStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={onContinue}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ await new Promise(setImmediate);
+ wrapper.setState({ existingToken: 'abcd1234', selection: 'use-existing' });
+ click(wrapper.dive().find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('abcd1234');
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`selects c# 1`] = `
+<Fragment>
+ <div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="language"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java",
+ "value": "java",
+ },
+ Object {
+ "label": "onboarding.language.dotnet",
+ "value": "dotnet",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="dotnet"
+ />
+ </div>
+</Fragment>
+`;
+
+exports[`selects java 1`] = `
+<Fragment>
+ <div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="language"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java",
+ "value": "java",
+ },
+ Object {
+ "label": "onboarding.language.dotnet",
+ "value": "dotnet",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="java"
+ />
+ </div>
+ <RenderOptions
+ name="java-build"
+ onCheck={[Function]}
+ optionLabelKey="onboarding.language.java.build_technology"
+ options={
+ Array [
+ "maven",
+ "gradle",
+ ]
+ }
+ titleLabelKey="onboarding.language.java.build_technology"
+ />
+</Fragment>
+`;
+
+exports[`selects other 1`] = `
+<Fragment>
+ <div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="language"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java",
+ "value": "java",
+ },
+ Object {
+ "label": "onboarding.language.dotnet",
+ "value": "dotnet",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="other"
+ />
+ </div>
+ <RenderOS
+ setOS={[Function]}
+ />
+</Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly: default 1`] = `
+<Fragment>
+ <div
+ className="page-header big-spacer-bottom"
+ >
+ <h1
+ className="page-title"
+ >
+ onboarding.project_analysis.header
+ </h1>
+ <p
+ className="page-description"
+ >
+ <InstanceMessage
+ message="onboarding.project_analysis.description"
+ />
+ </p>
+ </div>
+ <TokenStep
+ currentUser={
+ Object {
+ "groups": Array [],
+ "isLoggedIn": true,
+ "login": "luke",
+ "name": "Skywalker",
+ "scmAccounts": Array [],
+ }
+ }
+ finished={false}
+ initialTokenName="Analyze \\"MyProject\\""
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={true}
+ stepNumber={1}
+ />
+ <ProjectAnalysisStep
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "organization": "foo",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
+ displayRowLayout={true}
+ open={false}
+ stepNumber={2}
+ />
+</Fragment>
+`;
+
+exports[`renders correctly: with back button 1`] = `
+<Fragment>
+ <div
+ className="page-header big-spacer-bottom"
+ >
+ <h1
+ className="page-title"
+ >
+ <Tooltip
+ overlay="onboarding.tutorial.return_to_list"
+ >
+ <a
+ aria-label="onboarding.tutorial.return_to_list"
+ className="link-no-underline big-spacer-right"
+ onClick={[MockFunction]}
+ >
+ <BackIcon />
+ </a>
+ </Tooltip>
+ onboarding.project_analysis.header
+ </h1>
+ <p
+ className="page-description"
+ >
+ <InstanceMessage
+ message="onboarding.project_analysis.description"
+ />
+ </p>
+ </div>
+ <TokenStep
+ currentUser={
+ Object {
+ "groups": Array [],
+ "isLoggedIn": true,
+ "login": "luke",
+ "name": "Skywalker",
+ "scmAccounts": Array [],
+ }
+ }
+ finished={false}
+ initialTokenName="Analyze \\"MyProject\\""
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={true}
+ stepNumber={1}
+ />
+ <ProjectAnalysisStep
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "organization": "foo",
+ "qualifier": "TRK",
+ "qualityGate": Object {
+ "isDefault": true,
+ "key": "30",
+ "name": "Sonar way",
+ },
+ "qualityProfiles": Array [
+ Object {
+ "deleted": false,
+ "key": "my-qp",
+ "language": "ts",
+ "name": "Sonar way",
+ },
+ ],
+ "tags": Array [],
+ }
+ }
+ displayRowLayout={true}
+ 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={1}
+ 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
+ className=""
+ >
+ <div
+ className="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <Radio
+ checked={true}
+ onCheck={[Function]}
+ value="generate"
+ >
+ onboarding.token.generate_token
+ </Radio>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ onChange={[Function]}
+ placeholder="onboarding.token.generate_token.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ onboarding.token.generate
+ </SubmitButton>
+ </form>
+ </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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </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
+ className=""
+ >
+ <div
+ className="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <Radio
+ checked={true}
+ onCheck={[Function]}
+ value="generate"
+ >
+ onboarding.token.generate_token
+ </Radio>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ onChange={[Function]}
+ placeholder="onboarding.token.generate_token.placeholder"
+ required={true}
+ type="text"
+ value="my token"
+ />
+ <i
+ className="spinner text-middle"
+ />
+ </form>
+ </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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </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
+ className=""
+ >
+ <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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </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
+ className=""
+ >
+ <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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </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
+ className=""
+ >
+ <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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </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
+ className=""
+ >
+ <div
+ className="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <Radio
+ checked={true}
+ onCheck={[Function]}
+ value="generate"
+ >
+ onboarding.token.generate_token
+ </Radio>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ onChange={[Function]}
+ placeholder="onboarding.token.generate_token.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ onboarding.token.generate
+ </SubmitButton>
+ </form>
+ </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={
+ Object {
+ "link": <Link
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ target="_blank"
+ to="/account/security"
+ >
+ onboarding.token.text.user_account
+ </Link>,
+ }
+ }
+ />
+ </div>
+ </div>
+ </div>
+</div>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { getHostUrl } from 'sonar-ui-common/helpers/urls';
+import { LanguageConfig } from '../../types';
+import { getProjectKey } from '../ProjectAnalysisStep';
+import DotNet from './DotNet';
+import JavaGradle from './JavaGradle';
+import JavaMaven from './JavaMaven';
+import Other from './Other';
+
+interface Props {
+ component?: T.Component;
+ organization?: string;
+ languageConfig: LanguageConfig;
+ small?: boolean;
+ token?: string;
+}
+
+export default class AnalysisCommand extends React.PureComponent<Props> {
+ renderCommandForMaven = () => {
+ const { component, token } = this.props;
+ if (!token) {
+ return null;
+ }
+ return (
+ <JavaMaven
+ host={getHostUrl()}
+ organization={this.props.organization}
+ projectKey={component && component.key}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForGradle = () => {
+ const { component, token } = this.props;
+ if (!token) {
+ return null;
+ }
+ return (
+ <JavaGradle
+ host={getHostUrl()}
+ organization={this.props.organization}
+ projectKey={component && component.key}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForDotNet = () => {
+ const { component, languageConfig, small, token } = this.props;
+ const projectKey = getProjectKey(languageConfig, component);
+ if (!projectKey || !token) {
+ return null;
+ }
+ return (
+ <DotNet
+ host={getHostUrl()}
+ organization={this.props.organization}
+ projectKey={projectKey}
+ small={small}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForOther = () => {
+ const { component, languageConfig, token } = this.props;
+ const projectKey = getProjectKey(languageConfig, component);
+ if (!languageConfig || !projectKey || !languageConfig.os || !token) {
+ return null;
+ }
+ return (
+ <Other
+ host={getHostUrl()}
+ organization={this.props.organization}
+ os={languageConfig.os}
+ projectKey={projectKey}
+ token={token}
+ />
+ );
+ };
+
+ render() {
+ const { languageConfig } = this.props;
+
+ if (languageConfig.language === 'java') {
+ return languageConfig.javaBuild === 'maven'
+ ? this.renderCommandForMaven()
+ : this.renderCommandForGradle();
+ } else if (languageConfig.language === 'dotnet') {
+ return this.renderCommandForDotNet();
+ } else {
+ return this.renderCommandForOther();
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import CodeSnippet from '../../../common/CodeSnippet';
+import InstanceMessage from '../../../common/InstanceMessage';
+import MSBuildScanner from './MSBuildScanner';
+
+export interface Props {
+ host: string;
+ organization?: string;
+ projectKey: string;
+ small?: boolean;
+ token: string;
+}
+
+export default function DotNet(props: Props) {
+ const command1 = [
+ 'SonarScanner.MSBuild.exe begin',
+ `/k:"${props.projectKey}"`,
+ props.organization && `/d:sonar.organization="${props.organization}"`,
+ `/d:sonar.host.url="${props.host}"`,
+ `/d:sonar.login="${props.token}"`
+ ];
+
+ const command2 = 'MsBuild.exe /t:Rebuild';
+
+ const command3 = ['SonarScanner.MSBuild.exe end', `/d:sonar.login="${props.token}"`];
+
+ return (
+ <div>
+ <MSBuildScanner />
+
+ <h4 className="huge-spacer-top spacer-bottom">
+ {translate('onboarding.analysis.msbuild.execute')}
+ </h4>
+ <InstanceMessage message={translate('onboarding.analysis.msbuild.execute.text')}>
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={true} snippet={command1} />
+ <CodeSnippet isOneLine={false} snippet={command2} />
+ <CodeSnippet isOneLine={props.small} snippet={command3} />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.msbuild.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import CodeSnippet from '../../../common/CodeSnippet';
+import InstanceMessage from '../../../common/InstanceMessage';
+
+export interface Props {
+ host: string;
+ organization?: string;
+ projectKey?: string;
+ token: string;
+}
+
+export default function JavaGradle(props: Props) {
+ const config = 'plugins {\n id "org.sonarqube" version "2.7"\n}';
+
+ const command = [
+ './gradlew sonarqube',
+ props.projectKey && `-Dsonar.projectKey=${props.projectKey}`,
+ props.organization && `-Dsonar.organization=${props.organization}`,
+ `-Dsonar.host.url=${props.host}`,
+ `-Dsonar.login=${props.token}`
+ ];
+
+ return (
+ <div>
+ <h4 className="spacer-bottom">{translate('onboarding.analysis.java.gradle.header')}</h4>
+ <InstanceMessage message={translate('onboarding.analysis.java.gradle.text.1')}>
+ {transformedMessage => (
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={transformedMessage}
+ id="onboarding.analysis.java.gradle.text.1"
+ values={{
+ plugin_code: <code>org.sonarqube</code>,
+ filename: <code>build.gradle</code>
+ }}
+ />
+ </p>
+ )}
+ </InstanceMessage>
+ <CodeSnippet snippet={config} />
+ <p className="spacer-top spacer-bottom markdown">
+ {translate('onboarding.analysis.java.gradle.text.2')}
+ </p>
+ <CodeSnippet snippet={command} />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.java.gradle.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ <p className="big-spacer-top markdown">
+ {props.projectKey
+ ? translate('onboarding.analysis.auto_refresh_after_analysis')
+ : translate('onboarding.analysis.browse_url_after_analysis')}
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import CodeSnippet from '../../../common/CodeSnippet';
+import InstanceMessage from '../../../common/InstanceMessage';
+
+export interface Props {
+ host: string;
+ organization?: string;
+ projectKey?: string;
+ token: string;
+}
+
+export default function JavaMaven(props: Props) {
+ const command = [
+ 'mvn sonar:sonar',
+ props.projectKey && `-Dsonar.projectKey=${props.projectKey}`,
+ props.organization && `-Dsonar.organization=${props.organization}`,
+ `-Dsonar.host.url=${props.host}`,
+ `-Dsonar.login=${props.token}`
+ ];
+
+ return (
+ <div>
+ <h4 className="spacer-bottom">{translate('onboarding.analysis.java.maven.header')}</h4>
+ <p className="spacer-bottom markdown">
+ <InstanceMessage message={translate('onboarding.analysis.java.maven.text')} />
+ </p>
+ <CodeSnippet snippet={command} />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.docs')}
+ id="onboarding.analysis.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.java.maven.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ <p className="big-spacer-top markdown">
+ {props.projectKey
+ ? translate('onboarding.analysis.auto_refresh_after_analysis')
+ : translate('onboarding.analysis.browse_url_after_analysis')}
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+interface Props {
+ className?: string;
+}
+
+export default function MSBuildScanner(props: Props) {
+ return (
+ <div className={props.className}>
+ <h4 className="spacer-bottom">{translate('onboarding.analysis.msbuild.header')}</h4>
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.msbuild.text')}
+ id="onboarding.analysis.msbuild.text"
+ values={{ code: <code>%PATH%</code> }}
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="https://sonarcloud.io/documentation/analysis/scan/sonarscanner-for-msbuild/"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('download_verb')}
+ </a>
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import CodeSnippet from '../../../common/CodeSnippet';
+import InstanceMessage from '../../../common/InstanceMessage';
+import { quote } from '../../utils';
+import SQScanner from './SQScanner';
+
+export interface Props {
+ host: string;
+ organization?: string;
+ os: string;
+ projectKey: string;
+ token: string;
+}
+
+export default function Other(props: Props) {
+ const q = quote(props.os);
+ const command = [
+ props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
+ '-D' + q(`sonar.projectKey=${props.projectKey}`),
+ props.organization && '-D' + q(`sonar.organization=${props.organization}`),
+ '-D' + q('sonar.sources=.'),
+ '-D' + q(`sonar.host.url=${props.host}`),
+ '-D' + q(`sonar.login=${props.token}`)
+ ];
+
+ return (
+ <div>
+ <SQScanner os={props.os} />
+
+ <h4 className="huge-spacer-top spacer-bottom">
+ {translate('onboarding.analysis.sq_scanner.execute')}
+ </h4>
+ <InstanceMessage message={translate('onboarding.analysis.sq_scanner.execute.text')}>
+ {transformedMessage => <p className="spacer-bottom markdown">{transformedMessage}</p>}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={props.os === 'win'} snippet={command} />
+ <p className="big-spacer-top markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.sq_scanner.docs')}
+ id="onboarding.analysis.sq_scanner.docs"
+ values={{
+ link: (
+ <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('onboarding.analysis.sq_scanner.docs_link')}
+ </a>
+ )
+ }}
+ />
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 * as React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+
+interface Props {
+ className?: string;
+ os: string;
+}
+
+export default function SQScanner(props: Props) {
+ return (
+ <div className={props.className}>
+ <h4 className="spacer-bottom">
+ {translate('onboarding.analysis.sq_scanner.header', props.os)}
+ </h4>
+ <p className="spacer-bottom markdown">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.analysis.sq_scanner.text')}
+ id="onboarding.analysis.sq_scanner.text"
+ values={{
+ dir: <code>bin</code>,
+ env_var: <code>{props.os === 'win' ? '%PATH%' : 'PATH'}</code>
+ }}
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('download_verb')}
+ </a>
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 AnalysisCommand from '../AnalysisCommand';
+
+jest.mock('sonar-ui-common/helpers/urls', () => ({
+ getHostUrl: () => 'HOST'
+}));
+
+it('display java command', () => {
+ expect(
+ getWrapper({ languageConfig: { language: 'java', javaBuild: 'gradle' } })
+ ).toMatchSnapshot();
+ expect(
+ getWrapper({ languageConfig: { language: 'java', javaBuild: 'maven' } })
+ ).toMatchSnapshot();
+});
+
+it('display c# command', () => {
+ expect(
+ getWrapper({ languageConfig: { language: 'dotnet', projectKey: 'project-foo' } })
+ ).toMatchSnapshot();
+});
+
+it('display others command', () => {
+ expect(
+ getWrapper({
+ languageConfig: { language: 'other', os: 'window', projectKey: 'project-foo' }
+ })
+ ).toMatchSnapshot();
+});
+
+function getWrapper(props = {}) {
+ return shallow(<AnalysisCommand languageConfig={{}} token="myToken" {...props} />);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 DotNet, { Props } from '../DotNet';
+
+it('DotNet renders correctly', () => {
+ expect(shallowRender).toMatchSnapshot();
+
+ expect(
+ shallowRender({
+ organization: 'organization',
+ small: true
+ })
+ ).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<Props> = {}) {
+ return shallow(<DotNet host="host" projectKey="projectKey" token="token" {...props} />);
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 JavaGradle from '../JavaGradle';
+
+it('renders correctly', () => {
+ expect(shallow(<JavaGradle host="host" token="token" />)).toMatchSnapshot();
+ expect(
+ shallow(<JavaGradle host="host" organization="organization" token="token" />)
+ ).toMatchSnapshot();
+});
+
+it('renders with projectKey', () => {
+ expect(
+ shallow(<JavaGradle host="host" organization="organization" projectKey="foo" token="token" />)
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 JavaMaven from '../JavaMaven';
+
+it('renders correctly', () => {
+ expect(shallow(<JavaMaven host="host" token="token" />)).toMatchSnapshot();
+ expect(
+ shallow(<JavaMaven host="host" organization="organization" token="token" />)
+ ).toMatchSnapshot();
+});
+
+it('renders with projectKey', () => {
+ expect(
+ shallow(<JavaMaven host="host" organization="organization" projectKey="foo" token="token" />)
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 MSBuildScanner from '../MSBuildScanner';
+
+it('renders correctly', () => {
+ expect(shallow(<MSBuildScanner />)).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 Other from '../Other';
+
+it('renders correctly', () => {
+ expect(
+ shallow(<Other host="host" os="win" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+
+ expect(
+ shallow(<Other host="host" os="linux" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+
+ expect(
+ shallow(<Other host="host" os="linux" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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 SQScanner from '../SQScanner';
+
+it('renders correctly', () => {
+ expect(shallow(<SQScanner os="win" />)).toMatchSnapshot();
+ expect(shallow(<SQScanner os="linux" />)).toMatchSnapshot();
+ expect(shallow(<SQScanner os="mac" />)).toMatchSnapshot();
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`display c# command 1`] = `
+<DotNet
+ host="HOST"
+ projectKey="project-foo"
+ token="myToken"
+/>
+`;
+
+exports[`display java command 1`] = `
+<JavaGradle
+ host="HOST"
+ token="myToken"
+/>
+`;
+
+exports[`display java command 2`] = `
+<JavaMaven
+ host="HOST"
+ token="myToken"
+/>
+`;
+
+exports[`display others command 1`] = `
+<Other
+ host="HOST"
+ os="window"
+ projectKey="project-foo"
+ token="myToken"
+/>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DotNet renders correctly 1`] = `[Function]`;
+
+exports[`DotNet renders correctly 2`] = `
+<div>
+ <MSBuildScanner />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.msbuild.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.msbuild.execute.text"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarScanner.MSBuild.exe begin",
+ "/k:\\"projectKey\\"",
+ "/d:sonar.organization=\\"organization\\"",
+ "/d:sonar.host.url=\\"host\\"",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <CodeSnippet
+ isOneLine={false}
+ snippet="MsBuild.exe /t:Rebuild"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarScanner.MSBuild.exe end",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.msbuild.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.gradle.header
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.java.gradle.text.1"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ snippet="plugins {
+ id \\"org.sonarqube\\" version \\"2.7\\"
+}"
+ />
+ <p
+ className="spacer-top spacer-bottom markdown"
+ >
+ onboarding.analysis.java.gradle.text.2
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "./gradlew sonarqube",
+ undefined,
+ undefined,
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.gradle.header
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.java.gradle.text.1"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ snippet="plugins {
+ id \\"org.sonarqube\\" version \\"2.7\\"
+}"
+ />
+ <p
+ className="spacer-top spacer-bottom markdown"
+ >
+ onboarding.analysis.java.gradle.text.2
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "./gradlew sonarqube",
+ undefined,
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
+</div>
+`;
+
+exports[`renders with projectKey 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.gradle.header
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.java.gradle.text.1"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ snippet="plugins {
+ id \\"org.sonarqube\\" version \\"2.7\\"
+}"
+ />
+ <p
+ className="spacer-top spacer-bottom markdown"
+ >
+ onboarding.analysis.java.gradle.text.2
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "./gradlew sonarqube",
+ "-Dsonar.projectKey=foo",
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/gradle.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.gradle.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.auto_refresh_after_analysis
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.maven.header
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <InstanceMessage
+ message="onboarding.analysis.java.maven.text"
+ />
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "mvn sonar:sonar",
+ undefined,
+ undefined,
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.maven.header
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <InstanceMessage
+ message="onboarding.analysis.java.maven.text"
+ />
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "mvn sonar:sonar",
+ undefined,
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.browse_url_after_analysis
+ </p>
+</div>
+`;
+
+exports[`renders with projectKey 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.maven.header
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <InstanceMessage
+ message="onboarding.analysis.java.maven.text"
+ />
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "mvn sonar:sonar",
+ "-Dsonar.projectKey=foo",
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.docs"
+ id="onboarding.analysis.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.java.maven.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+ <p
+ className="big-spacer-top markdown"
+ >
+ onboarding.analysis.auto_refresh_after_analysis
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.msbuild.header
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.msbuild.text"
+ id="onboarding.analysis.msbuild.text"
+ values={
+ Object {
+ "code": <code>
+ %PATH%
+ </code>,
+ }
+ }
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="https://sonarcloud.io/documentation/analysis/scan/sonarscanner-for-msbuild/"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <SQScanner
+ os="win"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "sonar-scanner.bat",
+ "-D\\"sonar.projectKey=projectKey\\"",
+ undefined,
+ "-D\\"sonar.sources=.\\"",
+ "-D\\"sonar.host.url=host\\"",
+ "-D\\"sonar.login=token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <SQScanner
+ os="linux"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ isOneLine={false}
+ snippet={
+ Array [
+ "sonar-scanner",
+ "-Dsonar.projectKey=projectKey",
+ undefined,
+ "-Dsonar.sources=.",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+</div>
+`;
+
+exports[`renders correctly 3`] = `
+<div>
+ <SQScanner
+ os="linux"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ >
+ <Component />
+ </InstanceMessage>
+ <CodeSnippet
+ isOneLine={false}
+ snippet={
+ Array [
+ "sonar-scanner",
+ "-Dsonar.projectKey=projectKey",
+ undefined,
+ "-Dsonar.sources=.",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.docs"
+ id="onboarding.analysis.sq_scanner.docs"
+ values={
+ Object {
+ "link": <a
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ onboarding.analysis.sq_scanner.docs_link
+ </a>,
+ }
+ }
+ />
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.header.win
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ %PATH%
+ </code>,
+ }
+ }
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.header.linux
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ PATH
+ </code>,
+ }
+ }
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
+
+exports[`renders correctly 3`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.header.mac
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.analysis.sq_scanner.text"
+ id="onboarding.analysis.sq_scanner.text"
+ values={
+ Object {
+ "dir": <code>
+ bin
+ </code>,
+ "env_var": <code>
+ PATH
+ </code>,
+ }
+ }
+ />
+ </p>
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2020 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.
+ */
+export interface LanguageConfig {
+ language?: string;
+ javaBuild?: string;
+ cFamilyCompiler?: string;
+ os?: string;
+ projectKey?: string;
+}
+
+export function isLanguageConfigured(config?: LanguageConfig) {
+ if (!config) {
+ return false;
+ }
+ const { language, javaBuild, cFamilyCompiler, os, projectKey } = config;
+ const isJavaConfigured = language === 'java' && javaBuild != null;
+ const isDotNetConfigured = language === 'dotnet' && projectKey != null;
+ const isCFamilyConfigured =
+ language === 'c-family' && (cFamilyCompiler === 'msvc' || os != null) && projectKey != null;
+ const isOtherConfigured = language === 'other' && projectKey != null;
+
+ return isJavaConfigured || isDotNetConfigured || isCFamilyConfigured || isOtherConfigured;
+}
+
+export function quote(os: string): (s: string) => string {
+ return os === 'win' ? (s: string) => `"${s}"` : (s: string) => s;
+}
+
+export function getUniqueTokenName(tokens: T.UserToken[], initialTokenName = '') {
+ const hasToken = (name: string) => tokens.find(token => token.name === name) !== undefined;
+
+ if (!hasToken(initialTokenName)) {
+ return initialTokenName;
+ }
+
+ let i = 1;
+ while (hasToken(`${initialTokenName} ${i}`)) {
+ i++;
+ }
+ return `${initialTokenName} ${i}`;
+}
};
}
-export function mockAzureDefinition(
+export function mockAzureBindingDefinition(
overrides: Partial<AzureBindingDefinition> = {}
): AzureBindingDefinition {
return {
};
}
-export function mockBitbucketDefinition(
+export function mockBitbucketBindingDefinition(
overrides: Partial<BitbucketBindingDefinition> = {}
): BitbucketBindingDefinition {
return {
};
}
-export function mockGithubDefinition(
+export function mockGithubBindingDefinition(
overrides: Partial<GithubBindingDefinition> = {}
): GithubBindingDefinition {
return {
};
}
-export function mockGitlabDefinition(
+export function mockGitlabBindingDefinition(
overrides: Partial<GitlabBindingDefinition> = {}
): GitlabBindingDefinition {
return {
url?: string;
}
-export interface ProjectAlmBinding {
+export interface ProjectAlmBindingResponse {
+ alm: AlmKeys;
key: string;
repository?: string;
slug?: string;
summaryCommentEnabled?: boolean;
}
-export interface AzureProjectAlmBinding {
+export interface ProjectAlmBindingParams {
almSetting: string;
project: string;
}
-export interface BitbucketProjectAlmBinding {
- almSetting: string;
- project: string;
+export interface AzureProjectAlmBindingParams extends ProjectAlmBindingParams {}
+
+export interface BitbucketProjectAlmBindingParams extends ProjectAlmBindingParams {
repository: string;
slug: string;
}
-export interface GithubProjectAlmBinding {
- almSetting: string;
- project: string;
+export interface GithubProjectAlmBindingParams extends ProjectAlmBindingParams {
repository: string;
summaryCommentEnabled: boolean;
}
-export interface GitlabProjectAlmBinding {
- almSetting: string;
- project: string;
+export interface GitlabProjectAlmBindingParams extends ProjectAlmBindingParams {
repository?: string;
}
}
export interface AlmSettingsBindingDefinitions {
- azure: AzureBindingDefinition[];
- bitbucket: BitbucketBindingDefinition[];
- github: GithubBindingDefinition[];
- gitlab: GitlabBindingDefinition[];
+ [AlmKeys.Azure]: AzureBindingDefinition[];
+ [AlmKeys.Bitbucket]: BitbucketBindingDefinition[];
+ [AlmKeys.GitHub]: GithubBindingDefinition[];
+ [AlmKeys.GitLab]: GitlabBindingDefinition[];
}