import * as React from 'react';
import * as PropTypes from 'prop-types';
import { connect } from 'react-redux';
-import OnboardingModal from '../../apps/tutorials/onboarding/OnboardingModal';
+import Onboarding from '../../apps/tutorials/Onboarding';
+import CreateOrganizationForm from '../../apps/account/organizations/CreateOrganizationForm';
import LicensePromptModal from '../../apps/marketplace/components/LicensePromptModal';
-import { CurrentUser, isLoggedIn } from '../types';
+import ProjectOnboardingModal from '../../apps/tutorials/projectOnboarding/ProjectOnboardingModal';
+import TeamOnboardingModal from '../../apps/tutorials/teamOnboarding/TeamOnboardingModal';
+import { CurrentUser, isLoggedIn, Organization } from '../types';
import { differenceInDays, parseDate, toShortNotSoISOString } from '../../helpers/dates';
import { EditionKey } from '../../apps/marketplace/utils';
import { getCurrentUser, getAppState } from '../../store/rootReducer';
-import { skipOnboarding } from '../../store/users/actions';
+import { skipOnboarding as skipOnboardingAction } from '../../store/users/actions';
import { showLicense } from '../../api/marketplace';
import { hasMessage } from '../../helpers/l10n';
import { save, get } from '../../helpers/storage';
+import { isSonarCloud } from '../../helpers/system';
+import { skipOnboarding } from '../../api/users';
interface StateProps {
canAdmin: boolean;
}
interface DispatchProps {
- skipOnboarding: () => void;
+ skipOnboardingAction: () => void;
}
interface OwnProps {
enum ModalKey {
license,
- onboarding
+ onboarding,
+ organizationOnboarding,
+ projectOnboarding,
+ teamOnboarding
}
interface State {
const LICENSE_PROMPT = 'sonarqube.license.prompt';
export class StartupModal extends React.PureComponent<Props, State> {
+ static contextTypes = {
+ router: PropTypes.object.isRequired
+ };
+
static childContextTypes = {
- openOnboardingTutorial: PropTypes.func
+ openProjectOnboarding: PropTypes.func
};
state: State = { automatic: false };
getChildContext() {
- return { openOnboardingTutorial: this.openOnboarding };
+ return { openProjectOnboarding: this.openProjectOnboarding };
}
componentDidMount() {
closeOnboarding = () => {
this.setState(state => {
- if (state.modal === ModalKey.onboarding) {
- this.props.skipOnboarding();
+ if (state.modal !== ModalKey.license) {
+ skipOnboarding();
+ this.props.skipOnboardingAction();
return { automatic: false, modal: undefined };
}
return undefined;
});
};
+ closeOrganizationOnboarding = ({ key }: Pick<Organization, 'key'>) => {
+ this.closeOnboarding();
+ this.context.router.push(`/organizations/${key}`);
+ };
+
openOnboarding = () => {
this.setState({ modal: ModalKey.onboarding });
};
+ openOrganizationOnboarding = () => {
+ this.setState({ modal: ModalKey.organizationOnboarding });
+ };
+
+ openProjectOnboarding = () => {
+ this.setState({ modal: ModalKey.projectOnboarding });
+ };
+
+ openTeamOnboarding = () => {
+ this.setState({ modal: ModalKey.teamOnboarding });
+ };
+
tryAutoOpenLicense = () => {
const { canAdmin, currentEdition, currentUser } = this.props;
const hasLicenseManager = hasMessage('license.prompt.title');
const { currentUser, location } = this.props;
if (currentUser.showOnboardingTutorial && !location.pathname.startsWith('documentation')) {
this.setState({ automatic: true });
- this.openOnboarding();
+ if (isSonarCloud()) {
+ this.openOnboarding();
+ } else {
+ this.openProjectOnboarding();
+ }
}
};
{this.props.children}
{modal === ModalKey.license && <LicensePromptModal onClose={this.closeLicense} />}
{modal === ModalKey.onboarding && (
- <OnboardingModal automatic={automatic} onFinish={this.closeOnboarding} />
+ <Onboarding
+ onFinish={this.closeOnboarding}
+ onOpenOrganizationOnboarding={this.openOrganizationOnboarding}
+ onOpenProjectOnboarding={this.openProjectOnboarding}
+ onOpenTeamOnboarding={this.openTeamOnboarding}
+ />
+ )}
+ {modal === ModalKey.projectOnboarding && (
+ <ProjectOnboardingModal automatic={automatic} onFinish={this.closeOnboarding} />
+ )}
+ {modal === ModalKey.organizationOnboarding && (
+ <CreateOrganizationForm
+ onClose={this.closeOnboarding}
+ onCreate={this.closeOrganizationOnboarding}
+ />
+ )}
+ {modal === ModalKey.teamOnboarding && (
+ <TeamOnboardingModal onFinish={this.closeOnboarding} />
)}
</>
);
currentUser: getCurrentUser(state)
});
-const mapDispatchToProps: DispatchProps = { skipOnboarding };
+const mapDispatchToProps: DispatchProps = { skipOnboardingAction };
export default connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(
StartupModal
async function shouldNotHaveModals(wrapper: ShallowWrapper) {
await waitAndUpdate(wrapper);
expect(wrapper.find('LicensePromptModal').exists()).toBeFalsy();
- expect(wrapper.find('OnboardingModal').exists()).toBeFalsy();
+ expect(wrapper.find('ProjectOnboardingModal').exists()).toBeFalsy();
}
async function shouldDisplayOnboarding(wrapper: ShallowWrapper) {
await waitAndUpdate(wrapper);
- expect(wrapper.find('OnboardingModal').exists()).toBeTruthy();
+ expect(wrapper.find('ProjectOnboardingModal').exists()).toBeTruthy();
}
async function shouldDisplayLicense(wrapper: ShallowWrapper) {
currentEdition={EditionKey.enterprise}
currentUser={LOGGED_IN_USER}
location={{ pathname: 'foo/bar' }}
- skipOnboarding={jest.fn()}
+ skipOnboardingAction={jest.fn()}
{...props}>
<div />
- </StartupModal>
+ </StartupModal>,
+ { context: { router: { push: jest.fn() } } }
);
}
export default class EmbedDocsPopup extends React.PureComponent<Props> {
static contextTypes = {
- openOnboardingTutorial: PropTypes.func
+ openProjectOnboarding: PropTypes.func
};
onAnalyzeProjectClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
event.preventDefault();
event.currentTarget.blur();
- this.context.openOnboardingTutorial();
+ this.context.openProjectOnboarding();
};
renderTitle(text: string) {
type Props = StateProps & OwnProps;
class GlobalNav extends React.PureComponent<Props> {
- static contextTypes = { openOnboardingTutorial: PropTypes.func };
+ static contextTypes = { openProjectOnboarding: PropTypes.func };
render() {
return (
<Search appState={this.props.appState} currentUser={this.props.currentUser} />
{isLoggedIn(this.props.currentUser) &&
isSonarCloud() && (
- <GlobalNavPlus openOnboardingTutorial={this.context.openOnboardingTutorial} />
+ <GlobalNavPlus openProjectOnboarding={this.context.openProjectOnboarding} />
)}
<GlobalNavUserContainer {...this.props} />
</ul>
import { translate } from '../../../../helpers/l10n';
interface Props {
- openOnboardingTutorial: () => void;
+ openProjectOnboarding: () => void;
}
interface State {
handleNewProjectClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
event.preventDefault();
- this.props.openOnboardingTutorial();
+ this.props.openProjectOnboarding();
};
openCreateOrganizationForm = () => this.setState({ createOrganization: true });
import { click } from '../../../../../helpers/testUtils';
it('render', () => {
- const wrapper = shallow(<GlobalNavPlus openOnboardingTutorial={jest.fn()} />);
+ const wrapper = shallow(<GlobalNavPlus openProjectOnboarding={jest.fn()} />);
expect(wrapper.is('Dropdown')).toBe(true);
expect(wrapper.find('Dropdown')).toMatchSnapshot();
});
it('opens onboarding', () => {
- const openOnboardingTutorial = jest.fn();
+ const openProjectOnboarding = jest.fn();
const wrapper = shallow(
- shallow(<GlobalNavPlus openOnboardingTutorial={openOnboardingTutorial} />)
+ shallow(<GlobalNavPlus openProjectOnboarding={openProjectOnboarding} />)
.find('Dropdown')
.prop('overlay')
);
click(wrapper.find('.js-new-project'));
- expect(openOnboardingTutorial).toBeCalled();
+ expect(openProjectOnboarding).toBeCalled();
});
<Route
path="onboarding"
component={lazyLoad(() =>
- import('../../apps/tutorials/onboarding/OnboardingPage')
+ import('../../apps/tutorials/projectOnboarding/ProjectOnboardingPage')
)}
/>
<Route path="organizations" childRoutes={organizationsRoutes} />
export class NoFavoriteProjects extends React.PureComponent<StateProps> {
static contextTypes = {
- openOnboardingTutorial: PropTypes.func
+ openProjectOnboarding: PropTypes.func
};
onAnalyzeProjectClick = (event: React.SyntheticEvent<HTMLAnchorElement>) => {
event.preventDefault();
event.currentTarget.blur();
- this.context.openOnboardingTutorial();
+ this.context.openProjectOnboarding();
};
render() {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { connect } from 'react-redux';
+import handleRequiredAuthentication from '../../app/utils/handleRequiredAuthentication';
+import Modal from '../../components/controls/Modal';
+import { ResetButtonLink, Button } from '../../components/ui/buttons';
+import { translate } from '../../helpers/l10n';
+import { CurrentUser, isLoggedIn } from '../../app/types';
+import { getCurrentUser } from '../../store/rootReducer';
+import './styles.css';
+
+interface OwnProps {
+ onFinish: () => void;
+ onOpenOrganizationOnboarding: () => void;
+ onOpenProjectOnboarding: () => void;
+ onOpenTeamOnboarding: () => void;
+}
+
+interface StateProps {
+ currentUser: CurrentUser;
+}
+
+type Props = OwnProps & StateProps;
+
+export class Onboarding extends React.PureComponent<Props> {
+ componentDidMount() {
+ if (!isLoggedIn(this.props.currentUser)) {
+ handleRequiredAuthentication();
+ }
+ }
+
+ render() {
+ if (!isLoggedIn(this.props.currentUser)) {
+ return null;
+ }
+
+ const header = translate('onboarding.header');
+ return (
+ <Modal
+ contentLabel={header}
+ medium={true}
+ onRequestClose={this.props.onFinish}
+ shouldCloseOnOverlayClick={false}>
+ <header className="modal-head">
+ <h2>{header}</h2>
+ </header>
+ <div className="modal-body">
+ <p className="spacer-top big-spacer-bottom">
+ {translate('onboarding.header.description')}
+ </p>
+ <ul className="onboarding-choices">
+ <li className="text-center">
+ <p className="big-spacer-bottom">{translate('onboarding.analyze_public_code')}</p>
+ <Button onClick={this.props.onOpenProjectOnboarding}>
+ {translate('onboarding.analyze_public_code.button')}
+ </Button>
+ </li>
+ <li className="text-center">
+ <p className="big-spacer-bottom">{translate('onboarding.analyze_private_code')}</p>
+ <Button onClick={this.props.onOpenOrganizationOnboarding}>
+ {translate('onboarding.analyze_private_code.button')}
+ </Button>
+ </li>
+ <li className="text-center">
+ <p className="big-spacer-bottom">
+ {translate('onboarding.contribute_existing_project')}
+ </p>
+ <Button onClick={this.props.onOpenTeamOnboarding}>
+ {translate('onboarding.contribute_existing_project.button')}
+ </Button>
+ </li>
+ </ul>
+ </div>
+ <footer className="modal-foot">
+ <ResetButtonLink onClick={this.props.onFinish}>{translate('close')}</ResetButtonLink>
+ </footer>
+ </Modal>
+ );
+ }
+}
+
+const mapStateToProps = (state: any): StateProps => ({ currentUser: getCurrentUser(state) });
+
+export default connect<StateProps, {}, OwnProps>(mapStateToProps)(Onboarding);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import { Onboarding } from '../Onboarding';
+import { click } from '../../../helpers/testUtils';
+
+it('renders correctly', () => {
+ expect(
+ shallow(
+ <Onboarding
+ currentUser={{ isLoggedIn: true }}
+ onFinish={jest.fn()}
+ onOpenOrganizationOnboarding={jest.fn()}
+ onOpenProjectOnboarding={jest.fn()}
+ onOpenTeamOnboarding={jest.fn()}
+ />
+ )
+ ).toMatchSnapshot();
+});
+
+it('should correctly open the different tutorials', () => {
+ const onFinish = jest.fn();
+ const onOpenOrganizationOnboarding = jest.fn();
+ const onOpenProjectOnboarding = jest.fn();
+ const onOpenTeamOnboarding = jest.fn();
+ const wrapper = shallow(
+ <Onboarding
+ currentUser={{ isLoggedIn: true }}
+ onFinish={onFinish}
+ onOpenOrganizationOnboarding={onOpenOrganizationOnboarding}
+ onOpenProjectOnboarding={onOpenProjectOnboarding}
+ onOpenTeamOnboarding={onOpenTeamOnboarding}
+ />
+ );
+
+ click(wrapper.find('ResetButtonLink'));
+ expect(onFinish).toHaveBeenCalled();
+
+ wrapper.find('Button').forEach(button => click(button));
+ expect(onOpenOrganizationOnboarding).toHaveBeenCalled();
+ expect(onOpenProjectOnboarding).toHaveBeenCalled();
+ expect(onOpenTeamOnboarding).toHaveBeenCalled();
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<Modal
+ contentLabel="onboarding.header"
+ medium={true}
+ onRequestClose={[MockFunction]}
+ shouldCloseOnOverlayClick={false}
+>
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.header
+ </h2>
+ </header>
+ <div
+ className="modal-body"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.header.description
+ </p>
+ <ul
+ className="onboarding-choices"
+ >
+ <li
+ className="text-center"
+ >
+ <p
+ className="big-spacer-bottom"
+ >
+ onboarding.analyze_public_code
+ </p>
+ <Button
+ onClick={[MockFunction]}
+ >
+ onboarding.analyze_public_code.button
+ </Button>
+ </li>
+ <li
+ className="text-center"
+ >
+ <p
+ className="big-spacer-bottom"
+ >
+ onboarding.analyze_private_code
+ </p>
+ <Button
+ onClick={[MockFunction]}
+ >
+ onboarding.analyze_private_code.button
+ </Button>
+ </li>
+ <li
+ className="text-center"
+ >
+ <p
+ className="big-spacer-bottom"
+ >
+ onboarding.contribute_existing_project
+ </p>
+ <Button
+ onClick={[MockFunction]}
+ >
+ onboarding.contribute_existing_project.button
+ </Button>
+ </li>
+ </ul>
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ onClick={[MockFunction]}
+ >
+ close
+ </ResetButtonLink>
+ </footer>
+</Modal>
+`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import Step from './Step';
-import LanguageStep from './LanguageStep';
-/*:: import type { Result } from './LanguageStep'; */
-import JavaMaven from './commands/JavaMaven';
-import JavaGradle from './commands/JavaGradle';
-import DotNet from './commands/DotNet';
-import Msvc from './commands/Msvc';
-import ClangGCC from './commands/ClangGCC';
-import Other from './commands/Other';
-import { translate } from '../../../helpers/l10n';
-import { getHostUrl } from '../../../helpers/urls';
-
-/*::
-type Props = {|
- onFinish: (projectKey?: string) => void,
- onReset: () => void,
- open: boolean,
- organization?: string,
- stepNumber: number,
- token: string
-|};
-*/
-
-/*::
-type State = {
- result?: Result
-};
-*/
-
-export default class AnalysisStep extends React.PureComponent {
- /*:: props: Props; */
- state /*: State */ = {};
-
- handleLanguageSelect = (result /*: Result | void */) => {
- this.setState({ result });
- const projectKey = result && result.language !== 'java' ? result.projectKey : undefined;
- this.props.onFinish(projectKey);
- };
-
- handleLanguageReset = () => {
- this.setState({ result: undefined });
- this.props.onReset();
- };
-
- renderForm = () => {
- return (
- <div className="boxed-group-inner">
- <div className="flex-columns">
- <div className="flex-column flex-column-half bordered-right">
- <LanguageStep
- onDone={this.handleLanguageSelect}
- onReset={this.handleLanguageReset}
- organization={this.props.organization}
- />
- </div>
- <div className="flex-column flex-column-half">{this.renderCommand()}</div>
- </div>
- </div>
- );
- };
-
- renderFormattedCommand = (...lines /*: Array<string> */) => (
- // keep this "useless" concatentation for the readability reason
- // eslint-disable-next-line no-useless-concat
- <pre>{lines.join(' ' + '\\' + '\n' + ' ')}</pre>
- );
-
- renderCommand = () => {
- const { result } = this.state;
-
- if (!result) {
- return null;
- }
-
- if (result.language === 'java') {
- return result.javaBuild === 'maven'
- ? this.renderCommandForMaven()
- : this.renderCommandForGradle();
- } else if (result.language === 'dotnet') {
- return this.renderCommandForDotNet();
- } else if (result.language === 'c-family') {
- return result.cFamilyCompiler === 'msvc'
- ? this.renderCommandForMSVC()
- : this.renderCommandForClangGCC();
- } else {
- return this.renderCommandForOther();
- }
- };
-
- renderCommandForMaven = () => (
- <JavaMaven
- host={getHostUrl()}
- organization={this.props.organization}
- token={this.props.token}
- />
- );
-
- renderCommandForGradle = () => (
- <JavaGradle
- host={getHostUrl()}
- organization={this.props.organization}
- token={this.props.token}
- />
- );
-
- renderCommandForDotNet = () => {
- return (
- <DotNet
- host={getHostUrl()}
- organization={this.props.organization}
- // $FlowFixMe
- projectKey={this.state.result.projectKey}
- token={this.props.token}
- />
- );
- };
-
- renderCommandForMSVC = () => {
- return (
- <Msvc
- host={getHostUrl()}
- organization={this.props.organization}
- // $FlowFixMe
- projectKey={this.state.result.projectKey}
- token={this.props.token}
- />
- );
- };
-
- renderCommandForClangGCC = () => (
- <ClangGCC
- host={getHostUrl()}
- organization={this.props.organization}
- // $FlowFixMe
- os={this.state.result.os}
- // $FlowFixMe
- projectKey={this.state.result.projectKey}
- token={this.props.token}
- />
- );
-
- renderCommandForOther = () => (
- <Other
- host={getHostUrl()}
- organization={this.props.organization}
- // $FlowFixMe
- os={this.state.result.os}
- // $FlowFixMe
- projectKey={this.state.result.projectKey}
- token={this.props.token}
- />
- );
-
- 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-2018 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.
- */
-// @flow
-import React from 'react';
-import NewProjectForm from './NewProjectForm';
-import RadioToggle from '../../../components/controls/RadioToggle';
-import { translate } from '../../../helpers/l10n';
-import { isSonarCloud } from '../../../helpers/system';
-
-/*::
-type Props = {|
- onDone: (result: Result) => void,
- onReset: () => void,
- organization?: string,
-|};
-*/
-
-/*::
-type State = {
- language?: string,
- javaBuild?: string,
- cFamilyCompiler?: string,
- os?: string,
- projectKey?: string
-};
-*/
-
-/*::
-export type Result = State; */
-
-export default class LanguageStep extends React.PureComponent {
- /*:: props: Props; */
-
- state /*: State */ = {};
-
- isConfigured = () => {
- const { language, javaBuild, cFamilyCompiler, os, projectKey } = this.state;
- 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;
- };
-
- handleChange = () => {
- if (this.isConfigured()) {
- 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);
- };
-
- handleCFamilyCompilerChange = (cFamilyCompiler /*: string */) => {
- this.setState({ cFamilyCompiler }, this.handleChange);
- };
-
- handleOSChange = (os /*: string */) => {
- this.setState({ os }, this.handleChange);
- };
-
- handleProjectKeyDone = (projectKey /*: string */) => {
- this.setState({ projectKey }, this.handleChange);
- };
-
- handleProjectKeyDelete = () => {
- this.setState({ projectKey: undefined }, this.handleChange);
- };
-
- renderJavaBuild = () => (
- <div className="big-spacer-top">
- <h4 className="spacer-bottom">{translate('onboarding.language.java.build_technology')}</h4>
- <RadioToggle
- name="java-build"
- onCheck={this.handleJavaBuildChange}
- options={['maven', 'gradle'].map(build => ({
- label: translate('onboarding.language.java.build_technology', build),
- value: build
- }))}
- value={this.state.javaBuild}
- />
- </div>
- );
-
- renderCFamilyCompiler = () => (
- <div className="big-spacer-top">
- <h4 className="spacer-bottom">{translate('onboarding.language.c-family.compiler')}</h4>
- <RadioToggle
- name="c-family-compiler"
- onCheck={this.handleCFamilyCompilerChange}
- options={['msvc', 'clang-gcc'].map(compiler => ({
- label: translate('onboarding.language.c-family.compiler', compiler),
- value: compiler
- }))}
- value={this.state.cFamilyCompiler}
- />
- </div>
- );
-
- renderOS = () => (
- <div className="big-spacer-top">
- <h4 className="spacer-bottom">{translate('onboarding.language.os')}</h4>
- <RadioToggle
- name="os"
- onCheck={this.handleOSChange}
- options={['linux', 'win', 'mac'].map(os => ({
- label: translate('onboarding.language.os', os),
- value: os
- }))}
- value={this.state.os}
- />
- </div>
- );
-
- renderProjectKey = () => (
- <NewProjectForm
- onDelete={this.handleProjectKeyDelete}
- onDone={this.handleProjectKeyDone}
- organization={this.props.organization}
- projectKey={this.state.projectKey}
- />
- );
-
- render() {
- const shouldAskProjectKey =
- this.state.language === 'dotnet' ||
- (this.state.language === 'c-family' &&
- (this.state.cFamilyCompiler === 'msvc' ||
- (this.state.cFamilyCompiler === 'clang-gcc' && this.state.os != null))) ||
- (this.state.language === 'other' && this.state.os !== undefined);
-
- const languages = isSonarCloud()
- ? ['java', 'dotnet', 'c-family', 'other']
- : ['java', 'dotnet', 'other'];
-
- return (
- <div>
- <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={this.state.language}
- />
- </div>
- {this.state.language === 'java' && this.renderJavaBuild()}
- {this.state.language === 'c-family' && this.renderCFamilyCompiler()}
- {((this.state.language === 'c-family' && this.state.cFamilyCompiler === 'clang-gcc') ||
- this.state.language === 'other') &&
- this.renderOS()}
- {shouldAskProjectKey && this.renderProjectKey()}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { debounce } from 'lodash';
-import {
- createOrganization,
- deleteOrganization,
- getOrganization
-} from '../../../api/organizations';
-import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
-import { DeleteButton, SubmitButton } from '../../../components/ui/buttons';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {|
- onDelete: () => void,
- onDone: (organization: string) => void,
- organization?: string
-|};
-*/
-
-/*::
-type State = {
- done: boolean,
- loading: boolean,
- organization: string,
- unique: boolean
-};
-*/
-
-export default class NewOrganizationForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- /*:: state: State; */
-
- constructor(props /*: Props */) {
- super(props);
- this.state = {
- done: props.organization != null,
- loading: false,
- organization: props.organization || '',
- unique: true
- };
- this.validateOrganization = debounce(this.validateOrganization, 500);
- }
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- stopLoading = () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- };
-
- validateOrganization = (organization /*: string */) => {
- getOrganization(organization).then(response => {
- if (this.mounted) {
- this.setState({ unique: response == null });
- }
- });
- };
-
- sanitizeOrganization = (organization /*: string */) =>
- organization
- .toLowerCase()
- .replace(/[^a-z0-9-]/, '')
- .replace(/^-/, '');
-
- handleOrganizationChange = (event /*: { target: HTMLInputElement } */) => {
- const organization = this.sanitizeOrganization(event.target.value);
- this.setState({ organization });
- this.validateOrganization(organization);
- };
-
- handleOrganizationCreate = (event /*: Event */) => {
- event.preventDefault();
- const { organization } = this.state;
- if (organization) {
- this.setState({ loading: true });
- createOrganization({ key: organization, name: organization }).then(() => {
- if (this.mounted) {
- this.setState({ done: true, loading: false });
- this.props.onDone(organization);
- }
- }, this.stopLoading);
- }
- };
-
- handleOrganizationDelete = () => {
- const { organization } = this.state;
- if (organization) {
- this.setState({ loading: true });
- deleteOrganization(organization).then(() => {
- if (this.mounted) {
- this.setState({ done: false, loading: false, organization: '' });
- this.props.onDelete();
- }
- }, this.stopLoading);
- }
- };
-
- render() {
- const { done, loading, organization, unique } = this.state;
-
- const valid = unique && organization.length >= 2;
-
- return done ? (
- <div>
- <span className="spacer-right text-middle">{organization}</span>
- {loading ? (
- <i className="spinner text-middle" />
- ) : (
- <DeleteButton className="button-small" onClick={this.handleOrganizationDelete} />
- )}
- </div>
- ) : (
- <form onSubmit={this.handleOrganizationCreate}>
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- maxLength={32}
- minLength={2}
- onChange={this.handleOrganizationChange}
- placeholder={translate('onboarding.organization.placeholder')}
- required={true}
- type="text"
- value={organization}
- />
- {loading ? (
- <i className="spinner text-middle" />
- ) : (
- <SubmitButton className="text-middle" disabled={!valid}>
- {translate('create')}
- </SubmitButton>
- )}
- {!unique && (
- <span className="big-spacer-left text-danger text-middle">
- <AlertErrorIcon className="little-spacer-right text-text-top" />
- {translate('this_name_is_already_taken')}
- </span>
- )}
- <div className="note spacer-top abs-width-300">
- {translate('onboarding.organization.key_requirement')}
- </div>
- </form>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { createProject, deleteProject } from '../../../api/components';
-import { DeleteButton, SubmitButton } from '../../../components/ui/buttons';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {|
- onDelete: () => void,
- onDone: (projectKey: string) => void,
- organization?: string,
- projectKey?: string
-|};
-*/
-
-/*::
-type State = {
- done: boolean,
- loading: boolean,
- projectKey: string
-};
-*/
-
-export default class NewProjectForm extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- /*:: state: State; */
-
- constructor(props /*: Props */) {
- super(props);
- this.state = {
- done: props.projectKey != null,
- loading: false,
- projectKey: props.projectKey || ''
- };
- }
-
- componentDidMount() {
- this.mounted = true;
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- stopLoading = () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- };
-
- sanitizeProjectKey = (projectKey /*: string */) => projectKey.replace(/[^-_a-zA-Z0-9.:]/, '');
-
- handleProjectKeyChange = (event /*: { target: HTMLInputElement } */) => {
- this.setState({ projectKey: this.sanitizeProjectKey(event.target.value) });
- };
-
- handleProjectCreate = (event /*: Event */) => {
- event.preventDefault();
- const { projectKey } = this.state;
- const data /*: { [string]: string } */ = {
- name: projectKey,
- project: projectKey
- };
- if (this.props.organization) {
- data.organization = this.props.organization;
- }
- this.setState({ loading: true });
- createProject(data).then(() => {
- if (this.mounted) {
- this.setState({ done: true, loading: false });
- this.props.onDone(projectKey);
- }
- }, this.stopLoading);
- };
-
- handleProjectDelete = () => {
- const { projectKey } = this.state;
- this.setState({ loading: true });
- deleteProject(projectKey).then(() => {
- if (this.mounted) {
- this.setState({ done: false, loading: false, projectKey: '' });
- this.props.onDelete();
- }
- }, this.stopLoading);
- };
-
- render() {
- const { done, loading, projectKey } = this.state;
-
- const valid = projectKey.length > 0;
-
- const form = done ? (
- <div>
- <span className="spacer-right text-middle">{projectKey}</span>
- {loading ? (
- <i className="spinner text-middle" />
- ) : (
- <DeleteButton className="button-small text-middle" onClick={this.handleProjectDelete} />
- )}
- </div>
- ) : (
- <form onSubmit={this.handleProjectCreate}>
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- maxLength={400}
- minLength={1}
- onChange={this.handleProjectKeyChange}
- required={true}
- type="text"
- value={projectKey}
- />
- {loading ? (
- <i className="spinner text-middle" />
- ) : (
- <SubmitButton className="text-middle" disabled={!valid}>
- {translate('Done')}
- </SubmitButton>
- )}
- <div className="note spacer-top abs-width-300">
- {translate('onboarding.project_key_requirement')}
- </div>
- </form>
- );
-
- return (
- <div className="big-spacer-top">
- <h4 className="spacer-bottom">{translate('onboarding.language.project_key')}</h4>
- {form}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import PropTypes from 'prop-types';
-import Helmet from 'react-helmet';
-import TokenStep from './TokenStep';
-import OrganizationStep from './OrganizationStep';
-import AnalysisStep from './AnalysisStep';
-import ProjectWatcher from './ProjectWatcher';
-import DeferredSpinner from '../../../components/common/DeferredSpinner';
-import InstanceMessage from '../../../components/common/InstanceMessage';
-import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
-import { skipOnboarding } from '../../../api/users';
-import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { getProjectUrl } from '../../../helpers/urls';
-import { isSonarCloud } from '../../../helpers/system';
-import './styles.css';
-
-/*::
-type Props = {|
- automatic?:boolean,
- className?: string,
- currentUser: { login: string, isLoggedIn: boolean },
- onFinish: () => void,
- organizationsEnabled: boolean
-|};
-*/
-
-/*::
-type State = {
- finished: boolean,
- organization?: string,
- projectKey?: string,
- skipping: boolean,
- step: string,
- token?: string
-};
-*/
-
-export default class Onboarding extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- /*:: state: State; */
-
- static contextTypes = {
- router: PropTypes.object
- };
-
- constructor(props /*: Props */) {
- super(props);
- this.state = {
- finished: false,
- skipping: false,
- step: props.organizationsEnabled ? 'organization' : 'token'
- };
- }
-
- componentDidMount() {
- this.mounted = true;
-
- // useCapture = true to receive the event before inputs
- window.addEventListener('keydown', this.onKeyDown, true);
-
- if (!this.props.currentUser.isLoggedIn) {
- handleRequiredAuthentication();
- }
- }
-
- componentWillUnmount() {
- window.removeEventListener('keydown', this.onKeyDown, true);
- this.mounted = false;
- }
-
- onKeyDown = (event /*: KeyboardEvent */) => {
- // ESC key
- if (event.keyCode === 27) {
- this.finishOnboarding();
- }
- };
-
- finishOnboarding = () => {
- this.setState({ skipping: true });
- skipOnboarding().then(
- () => {
- if (this.mounted) {
- this.props.onFinish();
-
- if (this.state.projectKey) {
- this.context.router.push(getProjectUrl(this.state.projectKey));
- }
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ skipping: false });
- }
- }
- );
- };
-
- handleTimeout = () => {
- // unset `projectKey` to display a generic "Finish this tutorial" button
- this.setState({ projectKey: undefined });
- };
-
- handleTokenDone = (token /*: string */) => {
- this.setState({ step: 'analysis', token });
- };
-
- handleOrganizationDone = (organization /*: string */) => {
- this.setState({ organization, step: 'token' });
- };
-
- handleTokenOpen = () => this.setState({ step: 'token' });
-
- handleOrganizationOpen = () => this.setState({ step: 'organization' });
-
- handleSkipClick = (event /*: Event */) => {
- event.preventDefault();
- this.finishOnboarding();
- };
-
- handleFinish = (projectKey /*: string | void */) => this.setState({ finished: true, projectKey });
-
- handleReset = () => this.setState({ finished: false, projectKey: undefined });
-
- render() {
- if (!this.props.currentUser.isLoggedIn) {
- return null;
- }
-
- const { automatic, organizationsEnabled } = this.props;
- const { step, token } = this.state;
- let stepNumber = 1;
-
- return (
- <div className={this.props.className}>
- <InstanceMessage message={translate('onboarding.header')}>
- {transformedMessage => <Helmet title={transformedMessage} titleTemplate="%s" />}
- </InstanceMessage>
-
- <div className="page page-limited onboarding">
- <header className="page-header">
- <h1 className="page-title">
- <InstanceMessage message={translate('onboarding.header')} />
- </h1>
- <div className="page-actions">
- <DeferredSpinner loading={this.state.skipping}>
- <a className="js-skip text-muted" href="#" onClick={this.handleSkipClick}>
- {automatic ? translate('tutorials.skip') : translate('close')}
- </a>
- </DeferredSpinner>
-
- <p className="note">
- {translate(
- isSonarCloud()
- ? 'tutorials.find_it_back_in_plus'
- : 'tutorials.find_it_back_in_help'
- )}
- </p>
- </div>
- <div className="page-description">
- {translateWithParameters(
- 'onboarding.header.description',
- organizationsEnabled ? 3 : 2
- )}
- </div>
- </header>
-
- {organizationsEnabled && (
- <OrganizationStep
- currentUser={this.props.currentUser}
- finished={this.state.organization != null}
- onContinue={this.handleOrganizationDone}
- onOpen={this.handleOrganizationOpen}
- open={step === 'organization'}
- stepNumber={stepNumber++}
- />
- )}
-
- <TokenStep
- currentUser={this.props.currentUser}
- finished={this.state.token != null}
- onContinue={this.handleTokenDone}
- onOpen={this.handleTokenOpen}
- open={step === 'token'}
- stepNumber={stepNumber++}
- />
-
- <AnalysisStep
- onFinish={this.handleFinish}
- onReset={this.handleReset}
- open={step === 'analysis'}
- organization={this.state.organization}
- stepNumber={stepNumber}
- token={token}
- />
-
- {this.state.finished &&
- !this.state.skipping &&
- (this.state.projectKey ? (
- <ProjectWatcher
- onFinish={this.finishOnboarding}
- onTimeout={this.handleTimeout}
- projectKey={this.state.projectKey}
- />
- ) : (
- <footer className="text-right">
- <a className="button" href="#" onClick={this.handleSkipClick}>
- {translate('tutorials.finish')}
- </a>
- </footer>
- ))}
- </div>
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import { connect } from 'react-redux';
-import Onboarding from './Onboarding';
-import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer';
-
-const mapStateToProps = state => {
- return {
- className: 'modal-container',
- currentUser: getCurrentUser(state),
- organizationsEnabled: areThereCustomOrganizations(state)
- };
-};
-
-export default connect(mapStateToProps)(Onboarding);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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';
-
-export interface Props {
- onFinish: () => void;
-}
-
-export default class OnboardingModal extends React.PureComponent<Props> {}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 Modal from '../../../components/controls/Modal';
-import { translate } from '../../../helpers/l10n';
-import { lazyLoad } from '../../../components/lazyLoad';
-
-interface Props {
- automatic?: boolean;
- onFinish: () => void;
-}
-
-const OnboardingContainer = lazyLoad(() => import('./OnboardingContainer'));
-
-export default function OnboardingModal(props: Props) {
- return (
- <Modal contentLabel={translate('tutorials.onboarding')} large={true}>
- <OnboardingContainer {...props} />
- </Modal>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 * as PropTypes from 'prop-types';
-import { connect } from 'react-redux';
-import OnboardingModal from './OnboardingModal';
-import { skipOnboarding } from '../../../store/users/actions';
-
-interface DispatchProps {
- skipOnboarding: () => void;
-}
-
-export class OnboardingPage extends React.PureComponent<DispatchProps> {
- static contextTypes = {
- router: PropTypes.object.isRequired
- };
-
- onSkipOnboardingTutorial = () => {
- this.props.skipOnboarding();
- this.context.router.replace('/');
- };
-
- render() {
- return <OnboardingModal onFinish={this.onSkipOnboardingTutorial} />;
- }
-}
-
-const mapDispatchToProps: DispatchProps = { skipOnboarding };
-
-export default connect<{}, DispatchProps, {}>(null, mapDispatchToProps)(OnboardingPage);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import classNames from 'classnames';
-import { sortBy } from 'lodash';
-import Step from './Step';
-import NewOrganizationForm from './NewOrganizationForm';
-import DocTooltip from '../../../components/docs/DocTooltip';
-import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
-import { getOrganizations } from '../../../api/organizations';
-import Select from '../../../components/controls/Select';
-import { translate } from '../../../helpers/l10n';
-import { Button } from '../../../components/ui/buttons';
-
-/*::
-type Props = {|
- currentUser: { login: string, isLoggedIn: boolean },
- finished: boolean,
- onOpen: () => void,
- onContinue: (organization: string) => void,
- open: boolean,
- stepNumber: number
-|};
-*/
-
-/*::
-type State = {
- loading: boolean,
- newOrganization?: string,
- existingOrganization?: string,
- existingOrganizations: Array<string>,
- personalOrganization?: string,
- selection: 'personal' | 'existing' | 'new'
-};
-*/
-
-export default class OrganizationStep extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
- loading: true,
- existingOrganizations: [],
- selection: 'personal'
- };
-
- componentDidMount() {
- this.mounted = true;
- this.fetchOrganizations();
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- fetchOrganizations = () => {
- getOrganizations({ member: true }).then(
- ({ organizations }) => {
- if (this.mounted) {
- const organizationKeys = organizations.filter(o => o.isAdmin).map(o => o.key);
- // best guess: if there is only one organization, then it is personal
- // otherwise, we can't guess, let's display them all as just "existing organizations"
- const personalOrganization =
- organizationKeys.length === 1 ? organizationKeys[0] : undefined;
- const existingOrganizations = organizationKeys.length > 1 ? sortBy(organizationKeys) : [];
- const selection = personalOrganization
- ? 'personal'
- : existingOrganizations.length > 0 ? 'existing' : 'new';
- this.setState({
- loading: false,
- existingOrganizations,
- personalOrganization,
- selection
- });
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- }
- );
- };
-
- getSelectedOrganization = () => {
- switch (this.state.selection) {
- case 'personal':
- return this.state.personalOrganization;
- case 'existing':
- return this.state.existingOrganization;
- case 'new':
- return this.state.newOrganization;
- default:
- return null;
- }
- };
-
- handlePersonalClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ selection: 'personal' });
- };
-
- handleExistingClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ selection: 'existing' });
- };
-
- handleNewClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ selection: 'new' });
- };
-
- handleOrganizationCreate = (newOrganization /*: string */) => {
- this.setState({ newOrganization });
- };
-
- handleOrganizationDelete = () => {
- this.setState({ newOrganization: undefined });
- };
-
- handleExistingOrganizationSelect = ({ value } /*: { value: string } */) => {
- this.setState({ existingOrganization: value });
- };
-
- handleContinueClick = () => {
- const organization = this.getSelectedOrganization();
- if (organization) {
- this.props.onContinue(organization);
- }
- };
-
- renderPersonalOrganizationOption = () => (
- <div>
- <a className="link-base-color link-no-underline" href="#" onClick={this.handlePersonalClick}>
- <i
- className={classNames('icon-radio', 'spacer-right', {
- 'is-checked': this.state.selection === 'personal'
- })}
- />
- {translate('onboarding.organization.my_personal_organization')}
- <span className="note spacer-left">{this.state.personalOrganization}</span>
- </a>
- </div>
- );
-
- renderExistingOrganizationOption = () => (
- <div className="big-spacer-top">
- <a
- className="js-existing link-base-color link-no-underline"
- href="#"
- onClick={this.handleExistingClick}>
- <i
- className={classNames('icon-radio', 'spacer-right', {
- 'is-checked': this.state.selection === 'existing'
- })}
- />
- {translate('onboarding.organization.exising_organization')}
- </a>
- {this.state.selection === 'existing' && (
- <div className="big-spacer-top">
- <Select
- className="input-super-large"
- clearable={false}
- onChange={this.handleExistingOrganizationSelect}
- options={this.state.existingOrganizations.map(organization => ({
- label: organization,
- value: organization
- }))}
- value={this.state.existingOrganization}
- />
- </div>
- )}
- </div>
- );
-
- renderNewOrganizationOption = () => (
- <div className="big-spacer-top">
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={this.handleNewClick}>
- <i
- className={classNames('icon-radio', 'spacer-right', {
- 'is-checked': this.state.selection === 'new'
- })}
- />
- {translate('onboarding.organization.create_another_organization')}
- </a>
- {this.state.selection === 'new' && (
- <div className="big-spacer-top">
- <NewOrganizationForm
- onDelete={this.handleOrganizationDelete}
- onDone={this.handleOrganizationCreate}
- organization={this.state.newOrganization}
- />
- </div>
- )}
- </div>
- );
-
- renderForm = () => {
- return (
- <div className="boxed-group-inner">
- <div className="big-spacer-bottom width-50">
- {translate('onboarding.organization.text')}
- </div>
-
- {this.state.loading ? (
- <i className="spinner" />
- ) : (
- <div>
- {this.state.personalOrganization && this.renderPersonalOrganizationOption()}
- {this.state.existingOrganizations.length > 0 && this.renderExistingOrganizationOption()}
- {this.renderNewOrganizationOption()}
- </div>
- )}
-
- {this.getSelectedOrganization() != null &&
- !this.state.loading && (
- <div className="big-spacer-top">
- <Button className="js-continue" onClick={this.handleContinueClick}>
- {translate('continue')}
- </Button>
- </div>
- )}
- </div>
- );
- };
-
- renderResult = () => {
- const result = this.getSelectedOrganization();
-
- return result != null ? (
- <div className="boxed-group-actions display-flex-center">
- <AlertSuccessIcon className="spacer-right" />
- <strong>{result}</strong>
- </div>
- ) : null;
- };
-
- 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={
- <span>
- {translate('onboarding.organization.header')}
- <DocTooltip className="little-spacer-left" doc="organizations/organization" />
- </span>
- }
- />
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
-import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
-import { getTasksForComponent } from '../../../api/ce';
-import { STATUSES } from '../../../apps/background-tasks/constants';
-import { translate } from '../../../helpers/l10n';
-
-const INTERVAL = 5000;
-const TIMEOUT = 10 * 60 * 1000; // 10 min
-
-/*::
-type Props = {
- onFinish: () => void,
- onTimeout: () => void,
- projectKey: string
-};
-*/
-
-/*::
-type State = {
- inQueue: boolean,
- status: ?string
-};
-*/
-
-export default class ProjectWatcher extends React.PureComponent {
- /*:: interval: number; */
- /*:: mounted: boolean; */
- /*:: props: Props; */
- /*:: timeout: number; */
- state /*: State */ = {
- inQueue: false,
- status: null
- };
-
- componentDidMount() {
- this.mounted = true;
- this.watch();
- this.timeout = setTimeout(this.props.onTimeout, TIMEOUT);
- }
-
- componentWillUnmount() {
- clearInterval(this.interval);
- clearInterval(this.timeout);
- this.mounted = false;
- }
-
- watch = () => (this.interval = setTimeout(this.checkProject, INTERVAL));
-
- checkProject = () => {
- const { projectKey } = this.props;
- getTasksForComponent(projectKey).then(
- response => {
- if (response.queue.length > 0) {
- this.setState({ inQueue: true });
- }
-
- if (response.current != null) {
- const { status } = response.current;
- this.setState({ status });
- if (status === STATUSES.SUCCESS) {
- this.props.onFinish();
- } else if (status === STATUSES.PENDING || status === STATUSES.IN_PROGRESS) {
- this.watch();
- }
- } else {
- this.watch();
- }
- },
- () => {}
- );
- };
-
- render() {
- const { inQueue, status } = this.state;
-
- if (status === STATUSES.SUCCESS) {
- return (
- <div className="big-spacer-top note text-center">
- <AlertSuccessIcon className="spacer-right" />
- {translate('onboarding.project_watcher.finished')}
- </div>
- );
- }
-
- if (inQueue || status === STATUSES.PENDING || status === STATUSES.IN_PROGRESS) {
- return (
- <div className="big-spacer-top note text-center">
- <i className="spinner spacer-right" />
- {translate('onboarding.project_watcher.in_progress')}
- </div>
- );
- }
-
- if (status != null) {
- return (
- <div className="big-spacer-top note text-center">
- <AlertErrorIcon className="spacer-right" />
- {translate('onboarding.project_watcher.failed')}
- </div>
- );
- }
-
- return (
- <div className="big-spacer-top note text-center">
- {translate('onboarding.project_watcher.not_started')}
- </div>
- );
- }
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import classNames from 'classnames';
-
-/*::
-type Props = {|
- finished: boolean,
- onOpen: () => void,
- open: boolean,
- renderForm: () => React.Element<*>,
- renderResult: () => ?React.Element<*>,
- stepNumber: number,
- stepTitle: React.Element<*> | string
-|};
-*/
-
-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 /*: Event */) => {
- 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 ? props.renderForm() : <div className="boxed-group-inner" />}
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import classNames from 'classnames';
-import Step from './Step';
-import { getTokens, generateToken, revokeToken } from '../../../api/user-tokens';
-import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
-import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
-import { DeleteButton, SubmitButton, Button } from '../../../components/ui/buttons';
-import { translate } from '../../../helpers/l10n';
-
-/*::
-type Props = {|
- currentUser: { login: string },
- finished: boolean,
- open: boolean,
- onContinue: (token: string) => void,
- onOpen: () => void,
- stepNumber: number
-|};
-*/
-
-/*::
-type State = {
- canUseExisting: boolean,
- existingToken: string,
- loading: boolean,
- selection: string,
- tokenName?: string,
- token?: string
-};
-*/
-
-export default class TokenStep extends React.PureComponent {
- /*:: mounted: boolean; */
- /*:: props: Props; */
- state /*: State */ = {
- canUseExisting: false,
- existingToken: '',
- loading: false,
- selection: 'generate'
- };
-
- componentDidMount() {
- this.mounted = true;
- getTokens(this.props.currentUser.login).then(
- tokens => {
- if (this.mounted) {
- this.setState({ canUseExisting: tokens.length > 0 });
- }
- },
- () => {}
- );
- }
-
- 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 /*: { target: HTMLInputElement } */) => {
- this.setState({ tokenName: event.target.value });
- };
-
- handleTokenGenerate = (event /*: Event */) => {
- 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 });
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- }
- );
- }
- };
-
- 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 });
- }
- },
- () => {
- if (this.mounted) {
- this.setState({ loading: false });
- }
- }
- );
- }
- };
-
- handleContinueClick = () => {
- const token = this.getToken();
- if (token) {
- this.props.onContinue(token);
- }
- };
-
- handleGenerateClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ selection: 'generate' });
- };
-
- handleUseExistingClick = (event /*: Event */) => {
- event.preventDefault();
- this.setState({ selection: 'use-existing' });
- };
-
- handleExisingTokenChange = (event /*: { currentTarget: HTMLInputElement } */) => {
- this.setState({ existingToken: event.currentTarget.value });
- };
-
- renderGenerateOption = () => (
- <div>
- {this.state.canUseExisting ? (
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={this.handleGenerateClick}>
- <i
- className={classNames('icon-radio', 'spacer-right', {
- 'is-checked': this.state.selection === 'generate'
- })}
- />
- {translate('onboading.token.generate_token')}
- </a>
- ) : (
- translate('onboading.token.generate_token')
- )}
- {this.state.selection === 'generate' && (
- <div className="big-spacer-top">
- <form onSubmit={this.handleTokenGenerate}>
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- onChange={this.handleTokenNameChange}
- placeholder={translate('onboading.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">
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={this.handleUseExistingClick}>
- <i
- className={classNames('icon-radio', 'spacer-right', {
- 'is-checked': this.state.selection === 'use-existing'
- })}
- />
- {translate('onboarding.token.use_existing_token')}
- </a>
- {this.state.selection === 'use-existing' && (
- <div className="big-spacer-top">
- <input
- autoFocus={true}
- className="input-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 { canUseExisting, loading, token, tokenName } = this.state;
-
- 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">{translate('onboarding.token.text')}</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-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import LanguageStep from '../LanguageStep';
-import { isSonarCloud } from '../../../../helpers/system';
-
-jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
-
-beforeEach(() => {
- isSonarCloud.mockImplementation(() => false);
-});
-
-it('selects java', () => {
- const onDone = jest.fn();
- const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
-
- wrapper.find('RadioToggle').prop('onCheck')('java');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper
- .find('RadioToggle')
- .at(1)
- .prop('onCheck')('maven');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
- expect(onDone).lastCalledWith({ language: 'java', javaBuild: 'maven' });
-
- wrapper
- .find('RadioToggle')
- .at(1)
- .prop('onCheck')('gradle');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
- expect(onDone).lastCalledWith({ language: 'java', javaBuild: 'gradle' });
-});
-
-it('selects c#', () => {
- const onDone = jest.fn();
- const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
-
- wrapper.find('RadioToggle').prop('onCheck')('dotnet');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('NewProjectForm').prop('onDone')('project-foo');
- expect(onDone).lastCalledWith({ language: 'dotnet', projectKey: 'project-foo' });
-});
-
-it('selects c-family', () => {
- isSonarCloud.mockImplementation(() => true);
- const onDone = jest.fn();
- const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
-
- wrapper.find('RadioToggle').prop('onCheck')('c-family');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper
- .find('RadioToggle')
- .at(1)
- .prop('onCheck')('msvc');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('NewProjectForm').prop('onDone')('project-foo');
- expect(onDone).lastCalledWith({
- language: 'c-family',
- cFamilyCompiler: 'msvc',
- projectKey: 'project-foo'
- });
-
- wrapper
- .find('RadioToggle')
- .at(1)
- .prop('onCheck')('clang-gcc');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper
- .find('RadioToggle')
- .at(2)
- .prop('onCheck')('linux');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('NewProjectForm').prop('onDone')('project-foo');
- expect(onDone).lastCalledWith({
- language: 'c-family',
- cFamilyCompiler: 'clang-gcc',
- os: 'linux',
- projectKey: 'project-foo'
- });
-});
-
-it('selects other', () => {
- const onDone = jest.fn();
- const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
-
- wrapper.find('RadioToggle').prop('onCheck')('other');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper
- .find('RadioToggle')
- .at(1)
- .prop('onCheck')('mac');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- wrapper.find('NewProjectForm').prop('onDone')('project-foo');
- expect(onDone).lastCalledWith({ language: 'other', os: 'mac', projectKey: 'project-foo' });
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { mount } from 'enzyme';
-import NewOrganizationForm from '../NewOrganizationForm';
-import { change, submit, waitAndUpdate } from '../../../../helpers/testUtils';
-
-jest.mock('../../../../api/organizations', () => ({
- createOrganization: () => Promise.resolve(),
- deleteOrganization: () => Promise.resolve(),
- getOrganization: () => Promise.resolve(null)
-}));
-
-jest.mock('../../../../components/icons-components/ClearIcon');
-
-it('creates new organization', async () => {
- const onDone = jest.fn();
- const wrapper = mount(<NewOrganizationForm onDelete={jest.fn()} onDone={onDone} />);
- expect(wrapper).toMatchSnapshot();
- change(wrapper.find('input'), 'foo');
- submit(wrapper.find('form'));
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- expect(onDone).toBeCalledWith('foo');
-});
-
-it('deletes organization', async () => {
- const onDelete = jest.fn();
- const wrapper = mount(<NewOrganizationForm onDelete={onDelete} onDone={jest.fn()} />);
- wrapper.setState({ done: true, loading: false, organization: 'foo' });
- expect(wrapper).toMatchSnapshot();
- wrapper.find('DeleteButton').prop('onClick')();
- wrapper.update();
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- expect(onDelete).toBeCalled();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { mount } from 'enzyme';
-import NewProjectForm from '../NewProjectForm';
-import { change, submit, waitAndUpdate } from '../../../../helpers/testUtils';
-
-jest.mock('../../../../api/components', () => ({
- createProject: () => Promise.resolve(),
- deleteProject: () => Promise.resolve()
-}));
-
-jest.mock('../../../../components/icons-components/ClearIcon');
-
-it('creates new project', async () => {
- const onDone = jest.fn();
- const wrapper = mount(<NewProjectForm onDelete={jest.fn()} onDone={onDone} />);
- expect(wrapper).toMatchSnapshot();
- change(wrapper.find('input'), 'foo');
- submit(wrapper.find('form'));
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- expect(onDone).toBeCalledWith('foo');
-});
-
-it('deletes project', async () => {
- const onDelete = jest.fn();
- const wrapper = mount(<NewProjectForm onDelete={onDelete} onDone={jest.fn()} />);
- wrapper.setState({ done: true, loading: false, projectKey: 'foo' });
- expect(wrapper).toMatchSnapshot();
- wrapper.find('DeleteButton').prop('onClick')();
- wrapper.update();
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- expect(onDelete).toBeCalled();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-import Onboarding from '../Onboarding';
-import { click, doAsync } from '../../../../helpers/testUtils';
-import { getInstance, isSonarCloud } from '../../../../helpers/system';
-
-jest.mock('../../../../api/users', () => ({
- skipOnboarding: () => Promise.resolve()
-}));
-
-jest.mock('../../../../helpers/system', () => ({
- getInstance: jest.fn(),
- isSonarCloud: jest.fn()
-}));
-
-const currentUser = { login: 'admin', isLoggedIn: true };
-
-it('guides for on-premise', () => {
- getInstance.mockImplementation(() => 'SonarQube');
- isSonarCloud.mockImplementation(() => false);
- const wrapper = shallow(
- <Onboarding
- className="modal-container"
- currentUser={currentUser}
- onFinish={jest.fn()}
- organizationsEnabled={false}
- />
- );
- expect(wrapper).toMatchSnapshot();
-
- // $FlowFixMe
- wrapper.instance().handleTokenDone('abcd1234');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('guides for sonarcloud', () => {
- getInstance.mockImplementation(() => 'SonarCloud');
- isSonarCloud.mockImplementation(() => true);
- const wrapper = shallow(
- <Onboarding currentUser={currentUser} onFinish={jest.fn()} organizationsEnabled={true} />
- );
- expect(wrapper).toMatchSnapshot();
-
- // $FlowFixMe
- wrapper.instance().handleOrganizationDone('my-org');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-
- // $FlowFixMe
- wrapper.instance().handleTokenDone('abcd1234');
- wrapper.update();
- expect(wrapper).toMatchSnapshot();
-});
-
-it('finishes', () => {
- getInstance.mockImplementation(() => 'SonarQube');
- isSonarCloud.mockImplementation(() => false);
- const onFinish = jest.fn();
- const wrapper = mount(
- <Onboarding currentUser={currentUser} onFinish={onFinish} organizationsEnabled={false} />
- );
- click(wrapper.find('.js-skip'));
- return doAsync(() => {
- expect(onFinish).toBeCalled();
- });
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { mount } from 'enzyme';
-import OrganizationStep from '../OrganizationStep';
-import { click, waitAndUpdate } from '../../../../helpers/testUtils';
-import { getOrganizations } from '../../../../api/organizations';
-
-jest.mock('../../../../api/organizations', () => ({
- getOrganizations: jest.fn(() =>
- Promise.resolve({
- organizations: [{ isAdmin: true, key: 'user' }, { isAdmin: true, key: 'another' }]
- })
- )
-}));
-
-const currentUser = { isLoggedIn: true, login: 'user' };
-
-beforeEach(() => {
- getOrganizations.mockClear();
-});
-
-// FIXME
-// - if `mount` is used, then it's not possible to correctly set the state,
-// because the mocked api call is used
-// - if `shallow` is used, then the continue button is not rendered
-it.skip('works with personal organization', () => {
- const onContinue = jest.fn();
- const wrapper = mount(
- <OrganizationStep
- currentUser={currentUser}
- finished={false}
- onContinue={onContinue}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- click(wrapper.find('.js-continue'));
- expect(onContinue).toBeCalledWith('user');
-});
-
-it('works with existing organization', async () => {
- const onContinue = jest.fn();
- const wrapper = mount(
- <OrganizationStep
- currentUser={currentUser}
- finished={false}
- onContinue={onContinue}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- await waitAndUpdate(wrapper);
- click(wrapper.find('.js-existing'));
- expect(wrapper).toMatchSnapshot();
- wrapper
- .find('Select')
- .first()
- .prop('onChange')({ value: 'another' });
- wrapper.update();
- click(wrapper.find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('another');
-});
-
-it('works with new organization', async () => {
- const onContinue = jest.fn();
- const wrapper = mount(
- <OrganizationStep
- currentUser={currentUser}
- finished={false}
- onContinue={onContinue}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- await waitAndUpdate(wrapper);
- click(wrapper.find('.js-new'));
- wrapper.find('NewOrganizationForm').prop('onDone')('new');
- wrapper.update();
- click(wrapper.find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('new');
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-import ProjectWatcher from '../ProjectWatcher';
-
-jest.mock('../../../../api/ce', () => ({
- getTasksForComponent: () => Promise.resolve({ current: { status: 'SUCCESS' }, queue: [] })
-}));
-
-jest.useFakeTimers();
-
-it('renders', () => {
- const wrapper = shallow(
- <ProjectWatcher onFinish={jest.fn()} onTimeout={jest.fn()} projectKey="foo" />
- );
- expect(wrapper).toMatchSnapshot();
- wrapper.setState({ inQueue: true });
- expect(wrapper).toMatchSnapshot();
- wrapper.setState({ status: 'SUCCESS' });
- expect(wrapper).toMatchSnapshot();
- wrapper.setState({ status: 'FAILED' });
- expect(wrapper).toMatchSnapshot();
-});
-
-it('finishes', done => {
- // checking `expect(onFinish).toBeCalled();` is not working, because it's called asynchronously
- // instead let's finish the test as soon as `onFinish` callback is called
- const onFinish = jest.fn(done);
- mount(<ProjectWatcher onFinish={onFinish} onTimeout={jest.fn()} projectKey="foo" />);
- expect(onFinish).not.toBeCalled();
- jest.runTimersToTime(5000);
-});
-
-it('timeouts', () => {
- const onTimeout = jest.fn();
- mount(<ProjectWatcher onFinish={jest.fn()} onTimeout={onTimeout} projectKey="foo" />);
- expect(onTimeout).not.toBeCalled();
- jest.runTimersToTime(10 * 60 * 1000);
- expect(onTimeout).toBeCalled();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import Step from '../Step';
-import { click } from '../../../../helpers/testUtils';
-
-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-2018 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.
- */
-// @flow
-import React from 'react';
-import { mount } from 'enzyme';
-import TokenStep from '../TokenStep';
-import { change, click, submit, waitAndUpdate } from '../../../../helpers/testUtils';
-
-jest.mock('../../../../api/user-tokens', () => ({
- getTokens: () => Promise.resolve([{ name: 'foo' }]),
- generateToken: () => Promise.resolve({ token: 'abcd1234' }),
- revokeToken: () => Promise.resolve()
-}));
-
-jest.mock('../../../../components/icons-components/ClearIcon');
-
-const currentUser = { login: 'user' };
-
-it('generates token', async () => {
- const wrapper = mount(
- <TokenStep
- currentUser={currentUser}
- finished={false}
- onContinue={jest.fn()}
- onOpen={jest.fn()}
- open={true}
- stepNumber={1}
- />
- );
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
- change(wrapper.find('input'), 'my token');
- submit(wrapper.find('form'));
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
-});
-
-it('revokes token', async () => {
- const wrapper = mount(
- <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).toMatchSnapshot();
- wrapper.find('DeleteButton').prop('onClick')();
- wrapper.update();
- expect(wrapper).toMatchSnapshot(); // spinner
- await waitAndUpdate(wrapper);
- expect(wrapper).toMatchSnapshot();
-});
-
-it('continues', async () => {
- const onContinue = jest.fn();
- const wrapper = mount(
- <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.find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('abcd1234');
-});
-
-it('uses existing token', async () => {
- const onContinue = jest.fn();
- const wrapper = mount(
- <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.find('[className="js-continue"]'));
- expect(onContinue).toBeCalledWith('abcd1234');
-});
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`selects c# 1`] = `
-<div>
- <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>
- <NewProjectForm
- onDelete={[Function]}
- onDone={[Function]}
- />
-</div>
-`;
-
-exports[`selects c-family 1`] = `
-<div>
- <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.c-family",
- "value": "c-family",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="c-family"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.c-family.compiler
- </h4>
- <RadioToggle
- disabled={false}
- name="c-family-compiler"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.c-family.compiler.msvc",
- "value": "msvc",
- },
- Object {
- "label": "onboarding.language.c-family.compiler.clang-gcc",
- "value": "clang-gcc",
- },
- ]
- }
- value={null}
- />
- </div>
-</div>
-`;
-
-exports[`selects c-family 2`] = `
-<div>
- <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.c-family",
- "value": "c-family",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="c-family"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.c-family.compiler
- </h4>
- <RadioToggle
- disabled={false}
- name="c-family-compiler"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.c-family.compiler.msvc",
- "value": "msvc",
- },
- Object {
- "label": "onboarding.language.c-family.compiler.clang-gcc",
- "value": "clang-gcc",
- },
- ]
- }
- value="msvc"
- />
- </div>
- <NewProjectForm
- onDelete={[Function]}
- onDone={[Function]}
- />
-</div>
-`;
-
-exports[`selects c-family 3`] = `
-<div>
- <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.c-family",
- "value": "c-family",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="c-family"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.c-family.compiler
- </h4>
- <RadioToggle
- disabled={false}
- name="c-family-compiler"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.c-family.compiler.msvc",
- "value": "msvc",
- },
- Object {
- "label": "onboarding.language.c-family.compiler.clang-gcc",
- "value": "clang-gcc",
- },
- ]
- }
- value="clang-gcc"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.os
- </h4>
- <RadioToggle
- disabled={false}
- name="os"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.os.linux",
- "value": "linux",
- },
- Object {
- "label": "onboarding.language.os.win",
- "value": "win",
- },
- Object {
- "label": "onboarding.language.os.mac",
- "value": "mac",
- },
- ]
- }
- value={null}
- />
- </div>
-</div>
-`;
-
-exports[`selects c-family 4`] = `
-<div>
- <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.c-family",
- "value": "c-family",
- },
- Object {
- "label": "onboarding.language.other",
- "value": "other",
- },
- ]
- }
- value="c-family"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.c-family.compiler
- </h4>
- <RadioToggle
- disabled={false}
- name="c-family-compiler"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.c-family.compiler.msvc",
- "value": "msvc",
- },
- Object {
- "label": "onboarding.language.c-family.compiler.clang-gcc",
- "value": "clang-gcc",
- },
- ]
- }
- value="clang-gcc"
- />
- </div>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.os
- </h4>
- <RadioToggle
- disabled={false}
- name="os"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.os.linux",
- "value": "linux",
- },
- Object {
- "label": "onboarding.language.os.win",
- "value": "win",
- },
- Object {
- "label": "onboarding.language.os.mac",
- "value": "mac",
- },
- ]
- }
- value="linux"
- />
- </div>
- <NewProjectForm
- onDelete={[Function]}
- onDone={[Function]}
- projectKey="project-foo"
- />
-</div>
-`;
-
-exports[`selects java 1`] = `
-<div>
- <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>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.java.build_technology
- </h4>
- <RadioToggle
- disabled={false}
- name="java-build"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java.build_technology.maven",
- "value": "maven",
- },
- Object {
- "label": "onboarding.language.java.build_technology.gradle",
- "value": "gradle",
- },
- ]
- }
- value={null}
- />
- </div>
-</div>
-`;
-
-exports[`selects java 2`] = `
-<div>
- <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>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.java.build_technology
- </h4>
- <RadioToggle
- disabled={false}
- name="java-build"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java.build_technology.maven",
- "value": "maven",
- },
- Object {
- "label": "onboarding.language.java.build_technology.gradle",
- "value": "gradle",
- },
- ]
- }
- value="maven"
- />
- </div>
-</div>
-`;
-
-exports[`selects java 3`] = `
-<div>
- <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>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.java.build_technology
- </h4>
- <RadioToggle
- disabled={false}
- name="java-build"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.java.build_technology.maven",
- "value": "maven",
- },
- Object {
- "label": "onboarding.language.java.build_technology.gradle",
- "value": "gradle",
- },
- ]
- }
- value="gradle"
- />
- </div>
-</div>
-`;
-
-exports[`selects other 1`] = `
-<div>
- <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>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.os
- </h4>
- <RadioToggle
- disabled={false}
- name="os"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.os.linux",
- "value": "linux",
- },
- Object {
- "label": "onboarding.language.os.win",
- "value": "win",
- },
- Object {
- "label": "onboarding.language.os.mac",
- "value": "mac",
- },
- ]
- }
- value={null}
- />
- </div>
-</div>
-`;
-
-exports[`selects other 2`] = `
-<div>
- <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>
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.os
- </h4>
- <RadioToggle
- disabled={false}
- name="os"
- onCheck={[Function]}
- options={
- Array [
- Object {
- "label": "onboarding.language.os.linux",
- "value": "linux",
- },
- Object {
- "label": "onboarding.language.os.win",
- "value": "win",
- },
- Object {
- "label": "onboarding.language.os.mac",
- "value": "mac",
- },
- ]
- }
- value="mac"
- />
- </div>
- <NewProjectForm
- onDelete={[Function]}
- onDone={[Function]}
- />
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`creates new organization 1`] = `
-<NewOrganizationForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- maxLength={32}
- minLength={2}
- onChange={[Function]}
- placeholder="onboarding.organization.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- create
- </button>
- </Button>
- </SubmitButton>
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.organization.key_requirement
- </div>
- </form>
-</NewOrganizationForm>
-`;
-
-exports[`creates new organization 2`] = `
-<NewOrganizationForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- maxLength={32}
- minLength={2}
- onChange={[Function]}
- placeholder="onboarding.organization.placeholder"
- required={true}
- type="text"
- value="foo"
- />
- <i
- className="spinner text-middle"
- />
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.organization.key_requirement
- </div>
- </form>
-</NewOrganizationForm>
-`;
-
-exports[`creates new organization 3`] = `
-<NewOrganizationForm
- onDelete={[MockFunction]}
- onDone={
- [MockFunction] {
- "calls": Array [
- Array [
- "foo",
- ],
- ],
- "results": Array [
- Object {
- "isThrow": false,
- "value": undefined,
- },
- ],
- }
- }
->
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <DeleteButton
- className="button-small"
- onClick={[Function]}
- >
- <ButtonIcon
- className="button-small"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </div>
-</NewOrganizationForm>
-`;
-
-exports[`deletes organization 1`] = `
-<NewOrganizationForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <DeleteButton
- className="button-small"
- onClick={[Function]}
- >
- <ButtonIcon
- className="button-small"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </div>
-</NewOrganizationForm>
-`;
-
-exports[`deletes organization 2`] = `
-<NewOrganizationForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <i
- className="spinner text-middle"
- />
- </div>
-</NewOrganizationForm>
-`;
-
-exports[`deletes organization 3`] = `
-<NewOrganizationForm
- onDelete={
- [MockFunction] {
- "calls": Array [
- Array [],
- ],
- "results": Array [
- Object {
- "isThrow": false,
- "value": undefined,
- },
- ],
- }
- }
- onDone={[MockFunction]}
->
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-super-large spacer-right text-middle"
- maxLength={32}
- minLength={2}
- onChange={[Function]}
- placeholder="onboarding.organization.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- create
- </button>
- </Button>
- </SubmitButton>
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.organization.key_requirement
- </div>
- </form>
-</NewOrganizationForm>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`creates new project 1`] = `
-<NewProjectForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- maxLength={400}
- minLength={1}
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- Done
- </button>
- </Button>
- </SubmitButton>
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.project_key_requirement
- </div>
- </form>
- </div>
-</NewProjectForm>
-`;
-
-exports[`creates new project 2`] = `
-<NewProjectForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- maxLength={400}
- minLength={1}
- onChange={[Function]}
- required={true}
- type="text"
- value="foo"
- />
- <i
- className="spinner text-middle"
- />
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.project_key_requirement
- </div>
- </form>
- </div>
-</NewProjectForm>
-`;
-
-exports[`creates new project 3`] = `
-<NewProjectForm
- onDelete={[MockFunction]}
- onDone={
- [MockFunction] {
- "calls": Array [
- Array [
- "foo",
- ],
- ],
- "results": Array [
- Object {
- "isThrow": false,
- "value": undefined,
- },
- ],
- }
- }
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <DeleteButton
- className="button-small text-middle"
- onClick={[Function]}
- >
- <ButtonIcon
- className="button-small text-middle"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small text-middle button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small text-middle button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </div>
- </div>
-</NewProjectForm>
-`;
-
-exports[`deletes project 1`] = `
-<NewProjectForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <DeleteButton
- className="button-small text-middle"
- onClick={[Function]}
- >
- <ButtonIcon
- className="button-small text-middle"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small text-middle button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small text-middle button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </div>
- </div>
-</NewProjectForm>
-`;
-
-exports[`deletes project 2`] = `
-<NewProjectForm
- onDelete={[MockFunction]}
- onDone={[MockFunction]}
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <div>
- <span
- className="spacer-right text-middle"
- >
- foo
- </span>
- <i
- className="spinner text-middle"
- />
- </div>
- </div>
-</NewProjectForm>
-`;
-
-exports[`deletes project 3`] = `
-<NewProjectForm
- onDelete={
- [MockFunction] {
- "calls": Array [
- Array [],
- ],
- "results": Array [
- Object {
- "isThrow": false,
- "value": undefined,
- },
- ],
- }
- }
- onDone={[MockFunction]}
->
- <div
- className="big-spacer-top"
- >
- <h4
- className="spacer-bottom"
- >
- onboarding.language.project_key
- </h4>
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- maxLength={400}
- minLength={1}
- onChange={[Function]}
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- Done
- </button>
- </Button>
- </SubmitButton>
- <div
- className="note spacer-top abs-width-300"
- >
- onboarding.project_key_requirement
- </div>
- </form>
- </div>
-</NewProjectForm>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`guides for on-premise 1`] = `
-<div
- className="modal-container"
->
- <InstanceMessage
- message="onboarding.header"
- />
- <div
- className="page page-limited onboarding"
- >
- <header
- className="page-header"
- >
- <h1
- className="page-title"
- >
- <InstanceMessage
- message="onboarding.header"
- />
- </h1>
- <div
- className="page-actions"
- >
- <DeferredSpinner
- loading={false}
- timeout={100}
- >
- <a
- className="js-skip text-muted"
- href="#"
- onClick={[Function]}
- >
- close
- </a>
- </DeferredSpinner>
- <p
- className="note"
- >
- tutorials.find_it_back_in_help
- </p>
- </div>
- <div
- className="page-description"
- >
- onboarding.header.description.2
- </div>
- </header>
- <TokenStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={false}
- onContinue={[Function]}
- onOpen={[Function]}
- open={true}
- stepNumber={1}
- />
- <AnalysisStep
- onFinish={[Function]}
- onReset={[Function]}
- open={false}
- stepNumber={2}
- />
- </div>
-</div>
-`;
-
-exports[`guides for on-premise 2`] = `
-<div
- className="modal-container"
->
- <InstanceMessage
- message="onboarding.header"
- />
- <div
- className="page page-limited onboarding"
- >
- <header
- className="page-header"
- >
- <h1
- className="page-title"
- >
- <InstanceMessage
- message="onboarding.header"
- />
- </h1>
- <div
- className="page-actions"
- >
- <DeferredSpinner
- loading={false}
- timeout={100}
- >
- <a
- className="js-skip text-muted"
- href="#"
- onClick={[Function]}
- >
- close
- </a>
- </DeferredSpinner>
- <p
- className="note"
- >
- tutorials.find_it_back_in_help
- </p>
- </div>
- <div
- className="page-description"
- >
- onboarding.header.description.2
- </div>
- </header>
- <TokenStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={true}
- onContinue={[Function]}
- onOpen={[Function]}
- open={false}
- stepNumber={1}
- />
- <AnalysisStep
- onFinish={[Function]}
- onReset={[Function]}
- open={true}
- stepNumber={2}
- token="abcd1234"
- />
- </div>
-</div>
-`;
-
-exports[`guides for sonarcloud 1`] = `
-<div>
- <InstanceMessage
- message="onboarding.header"
- />
- <div
- className="page page-limited onboarding"
- >
- <header
- className="page-header"
- >
- <h1
- className="page-title"
- >
- <InstanceMessage
- message="onboarding.header"
- />
- </h1>
- <div
- className="page-actions"
- >
- <DeferredSpinner
- loading={false}
- timeout={100}
- >
- <a
- className="js-skip text-muted"
- href="#"
- onClick={[Function]}
- >
- close
- </a>
- </DeferredSpinner>
- <p
- className="note"
- >
- tutorials.find_it_back_in_plus
- </p>
- </div>
- <div
- className="page-description"
- >
- onboarding.header.description.3
- </div>
- </header>
- <OrganizationStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={false}
- onContinue={[Function]}
- onOpen={[Function]}
- open={true}
- stepNumber={1}
- />
- <TokenStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={false}
- onContinue={[Function]}
- onOpen={[Function]}
- open={false}
- stepNumber={2}
- />
- <AnalysisStep
- onFinish={[Function]}
- onReset={[Function]}
- open={false}
- stepNumber={3}
- />
- </div>
-</div>
-`;
-
-exports[`guides for sonarcloud 2`] = `
-<div>
- <InstanceMessage
- message="onboarding.header"
- />
- <div
- className="page page-limited onboarding"
- >
- <header
- className="page-header"
- >
- <h1
- className="page-title"
- >
- <InstanceMessage
- message="onboarding.header"
- />
- </h1>
- <div
- className="page-actions"
- >
- <DeferredSpinner
- loading={false}
- timeout={100}
- >
- <a
- className="js-skip text-muted"
- href="#"
- onClick={[Function]}
- >
- close
- </a>
- </DeferredSpinner>
- <p
- className="note"
- >
- tutorials.find_it_back_in_plus
- </p>
- </div>
- <div
- className="page-description"
- >
- onboarding.header.description.3
- </div>
- </header>
- <OrganizationStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={true}
- onContinue={[Function]}
- onOpen={[Function]}
- open={false}
- stepNumber={1}
- />
- <TokenStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={false}
- onContinue={[Function]}
- onOpen={[Function]}
- open={true}
- stepNumber={2}
- />
- <AnalysisStep
- onFinish={[Function]}
- onReset={[Function]}
- open={false}
- organization="my-org"
- stepNumber={3}
- />
- </div>
-</div>
-`;
-
-exports[`guides for sonarcloud 3`] = `
-<div>
- <InstanceMessage
- message="onboarding.header"
- />
- <div
- className="page page-limited onboarding"
- >
- <header
- className="page-header"
- >
- <h1
- className="page-title"
- >
- <InstanceMessage
- message="onboarding.header"
- />
- </h1>
- <div
- className="page-actions"
- >
- <DeferredSpinner
- loading={false}
- timeout={100}
- >
- <a
- className="js-skip text-muted"
- href="#"
- onClick={[Function]}
- >
- close
- </a>
- </DeferredSpinner>
- <p
- className="note"
- >
- tutorials.find_it_back_in_plus
- </p>
- </div>
- <div
- className="page-description"
- >
- onboarding.header.description.3
- </div>
- </header>
- <OrganizationStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={true}
- onContinue={[Function]}
- onOpen={[Function]}
- open={false}
- stepNumber={1}
- />
- <TokenStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "admin",
- }
- }
- finished={true}
- onContinue={[Function]}
- onOpen={[Function]}
- open={false}
- stepNumber={2}
- />
- <AnalysisStep
- onFinish={[Function]}
- onReset={[Function]}
- open={true}
- organization="my-org"
- stepNumber={3}
- token="abcd1234"
- />
- </div>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`works with existing organization 1`] = `
-<OrganizationStep
- currentUser={
- Object {
- "isLoggedIn": true,
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle={
- <span>
- onboarding.organization.header
- <DocTooltip
- className="little-spacer-left"
- doc="organizations/organization"
- />
- </span>
- }
- >
- <div
- className="boxed-group onboarding-step is-open"
- >
- <div
- className="onboarding-step-number"
- >
- 1
- </div>
- <div
- className="boxed-group-header"
- >
- <h2>
- <span>
- onboarding.organization.header
- <DocTooltip
- className="little-spacer-left"
- doc="organizations/organization"
- >
- <HelpTooltip
- className="little-spacer-left"
- onShow={[Function]}
- overlay={
- <div
- className="abs-width-300"
- >
- <LazyLoader
- className="cut-margins"
- isTooltip={true}
- />
- </div>
- }
- >
- <div
- className="help-tooltip little-spacer-left"
- >
- <Tooltip
- mouseLeaveDelay={0.25}
- onShow={[Function]}
- overlay={
- <div
- className="abs-width-300"
- >
- <LazyLoader
- className="cut-margins"
- isTooltip={true}
- />
- </div>
- }
- >
- <TooltipInner
- mouseEnterDelay={0.1}
- mouseLeaveDelay={0.25}
- onShow={[Function]}
- overlay={
- <div
- className="abs-width-300"
- >
- <LazyLoader
- className="cut-margins"
- isTooltip={true}
- />
- </div>
- }
- >
- <span
- className="display-inline-flex-center"
- onMouseEnter={[Function]}
- onMouseLeave={[Function]}
- >
- <HelpIcon
- fill="#b4b4b4"
- size={12}
- >
- <Icon
- size={12}
- >
- <svg
- height={12}
- style={
- Object {
- "clipRule": "evenodd",
- "fillRule": "evenodd",
- "strokeLinejoin": "round",
- "strokeMiterlimit": "1.41421",
- }
- }
- version="1.1"
- viewBox="0 0 16 16"
- width={12}
- xmlSpace="preserve"
- xmlnsXlink="http://www.w3.org/1999/xlink"
- >
- <g
- transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)"
- >
- <path
- d="M224,344L224,296C224,293.667 223.25,291.75 221.75,290.25C220.25,288.75 218.333,288 216,288L168,288C165.667,288 163.75,288.75 162.25,290.25C160.75,291.75 160,293.667 160,296L160,344C160,346.333 160.75,348.25 162.25,349.75C163.75,351.25 165.667,352 168,352L216,352C218.333,352 220.25,351.25 221.75,349.75C223.25,348.25 224,346.333 224,344ZM288,176C288,161.333 283.375,147.75 274.125,135.25C264.875,122.75 253.333,113.083 239.5,106.25C225.667,99.417 211.5,96 197,96C156.5,96 125.583,113.75 104.25,149.25C101.75,153.25 102.417,156.75 106.25,159.75L139.25,184.75C140.417,185.75 142,186.25 144,186.25C146.667,186.25 148.75,185.25 150.25,183.25C159.083,171.917 166.25,164.25 171.75,160.25C177.417,156.25 184.583,154.25 193.25,154.25C201.25,154.25 208.375,156.417 214.625,160.75C220.875,165.083 224,170 224,175.5C224,181.833 222.333,186.917 219,190.75C215.667,194.583 210,198.333 202,202C191.5,206.667 181.875,213.875 173.125,223.625C164.375,233.375 160,243.833 160,255L160,264C160,266.333 160.75,268.25 162.25,269.75C163.75,271.25 165.667,272 168,272L216,272C218.333,272 220.25,271.25 221.75,269.75C223.25,268.25 224,266.333 224,264C224,260.833 225.792,256.708 229.375,251.625C232.958,246.542 237.5,242.417 243,239.25C248.333,236.25 252.417,233.875 255.25,232.125C258.083,230.375 261.917,227.458 266.75,223.375C271.583,219.292 275.292,215.292 277.875,211.375C280.458,207.458 282.792,202.417 284.875,196.25C286.958,190.083 288,183.333 288,176ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z"
- style={
- Object {
- "fill": "#b4b4b4",
- }
- }
- />
- </g>
- </svg>
- </Icon>
- </HelpIcon>
- </span>
- </TooltipInner>
- </Tooltip>
- </div>
- </HelpTooltip>
- </DocTooltip>
- </span>
- </h2>
- </div>
- <div
- className="boxed-group-inner"
- >
- <div
- className="big-spacer-bottom width-50"
- >
- onboarding.organization.text
- </div>
- <div>
- <div
- className="big-spacer-top"
- >
- <a
- className="js-existing link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right is-checked"
- />
- onboarding.organization.exising_organization
- </a>
- <div
- className="big-spacer-top"
- >
- <Select
- className="input-super-large"
- clearable={false}
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "another",
- "value": "another",
- },
- Object {
- "label": "user",
- "value": "user",
- },
- ]
- }
- >
- <LazyLoader
- className="input-super-large"
- clearRenderer={[Function]}
- clearable={false}
- onChange={[Function]}
- options={
- Array [
- Object {
- "label": "another",
- "value": "another",
- },
- Object {
- "label": "user",
- "value": "user",
- },
- ]
- }
- >
- <Select
- arrowRenderer={[Function]}
- autosize={true}
- backspaceRemoves={true}
- backspaceToRemoveMessage="Press backspace to remove {label}"
- className="input-super-large"
- clearAllText="Clear all"
- clearRenderer={[Function]}
- clearValueText="Clear value"
- clearable={false}
- closeOnSelect={true}
- deleteRemoves={true}
- delimiter=","
- disabled={false}
- escapeClearsValue={true}
- filterOptions={[Function]}
- ignoreAccents={true}
- ignoreCase={true}
- inputProps={Object {}}
- isLoading={false}
- joinValues={false}
- labelKey="label"
- matchPos="any"
- matchProp="any"
- menuBuffer={0}
- menuRenderer={[Function]}
- multi={false}
- noResultsText="No results found"
- onBlurResetsInput={true}
- onChange={[Function]}
- onCloseResetsInput={true}
- onSelectResetsInput={true}
- openOnClick={true}
- optionComponent={[Function]}
- options={
- Array [
- Object {
- "label": "another",
- "value": "another",
- },
- Object {
- "label": "user",
- "value": "user",
- },
- ]
- }
- pageSize={5}
- placeholder="Select..."
- removeSelected={true}
- required={false}
- rtl={false}
- scrollMenuIntoView={true}
- searchable={true}
- simpleValue={false}
- tabSelectsValue={true}
- trimFilter={true}
- valueComponent={[Function]}
- valueKey="value"
- >
- <div
- className="Select input-super-large is-searchable Select--single"
- >
- <div
- className="Select-control"
- onKeyDown={[Function]}
- onMouseDown={[Function]}
- onTouchEnd={[Function]}
- onTouchMove={[Function]}
- onTouchStart={[Function]}
- >
- <span
- className="Select-multi-value-wrapper"
- id="react-select-2--value"
- >
- <div
- className="Select-placeholder"
- >
- Select...
- </div>
- <AutosizeInput
- aria-activedescendant="react-select-2--value"
- aria-expanded="false"
- aria-haspopup="false"
- aria-owns=""
- className="Select-input"
- injectStyles={true}
- minWidth="5"
- onBlur={[Function]}
- onChange={[Function]}
- onFocus={[Function]}
- required={false}
- role="combobox"
- value=""
- >
- <div
- className="Select-input"
- style={
- Object {
- "display": "inline-block",
- }
- }
- >
- <input
- aria-activedescendant="react-select-2--value"
- aria-expanded="false"
- aria-haspopup="false"
- aria-owns=""
- onBlur={[Function]}
- onChange={[Function]}
- onFocus={[Function]}
- required={false}
- role="combobox"
- style={
- Object {
- "boxSizing": "content-box",
- "width": "5px",
- }
- }
- value=""
- />
- <div
- style={
- Object {
- "height": 0,
- "left": 0,
- "overflow": "scroll",
- "position": "absolute",
- "top": 0,
- "visibility": "hidden",
- "whiteSpace": "pre",
- }
- }
- />
- </div>
- </AutosizeInput>
- </span>
- <span
- className="Select-arrow-zone"
- onMouseDown={[Function]}
- >
- <span
- className="Select-arrow"
- onMouseDown={[Function]}
- />
- </span>
- </div>
- </div>
- </Select>
- </LazyLoader>
- </Select>
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right"
- />
- onboarding.organization.create_another_organization
- </a>
- </div>
- </div>
- </div>
- </div>
- </Step>
-</OrganizationStep>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders 1`] = `
-<div
- className="big-spacer-top note text-center"
->
- onboarding.project_watcher.not_started
-</div>
-`;
-
-exports[`renders 2`] = `
-<div
- className="big-spacer-top note text-center"
->
- <i
- className="spinner spacer-right"
- />
- onboarding.project_watcher.in_progress
-</div>
-`;
-
-exports[`renders 3`] = `
-<div
- className="big-spacer-top note text-center"
->
- <AlertSuccessIcon
- className="spacer-right"
- />
- onboarding.project_watcher.finished
-</div>
-`;
-
-exports[`renders 4`] = `
-<div
- className="big-spacer-top note text-center"
->
- <i
- className="spinner spacer-right"
- />
- onboarding.project_watcher.in_progress
-</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>
- form
- </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>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`generates token 1`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="boxed-group-inner"
- >
- <div>
- <div>
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right is-checked"
- />
- onboading.token.generate_token
- </a>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboading.token.generate_token.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- onboarding.token.generate
- </button>
- </Button>
- </SubmitButton>
- </form>
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right"
- />
- onboarding.token.use_existing_token
- </a>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- onboarding.token.text
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
-
-exports[`generates token 2`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="boxed-group-inner"
- >
- <div>
- <div>
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right is-checked"
- />
- onboading.token.generate_token
- </a>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboading.token.generate_token.placeholder"
- required={true}
- type="text"
- value="my token"
- />
- <i
- className="spinner text-middle"
- />
- </form>
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right"
- />
- onboarding.token.use_existing_token
- </a>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- onboarding.token.text
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
-
-exports[`generates token 3`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="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]}
- >
- <ButtonIcon
- className="button-small text-middle"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small text-middle button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small text-middle button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </form>
- <div
- className="note big-spacer-top width-50"
- >
- onboarding.token.text
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- <button
- className="button js-continue"
- onClick={[Function]}
- type="button"
- >
- continue
- </button>
- </Button>
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
-
-exports[`revokes token 1`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="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]}
- >
- <ButtonIcon
- className="button-small text-middle"
- color="#d4333f"
- onClick={[Function]}
- >
- <Button
- className="button-small text-middle button-icon"
- onClick={[Function]}
- stopPropagation={true}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- >
- <button
- className="button button-small text-middle button-icon"
- onClick={[Function]}
- style={
- Object {
- "color": "#d4333f",
- }
- }
- type="button"
- >
- <ClearIcon />
- </button>
- </Button>
- </ButtonIcon>
- </DeleteButton>
- </form>
- <div
- className="note big-spacer-top width-50"
- >
- onboarding.token.text
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- <button
- className="button js-continue"
- onClick={[Function]}
- type="button"
- >
- continue
- </button>
- </Button>
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
-
-exports[`revokes token 2`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="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"
- >
- onboarding.token.text
- </div>
- <div
- className="big-spacer-top"
- >
- <Button
- className="js-continue"
- onClick={[Function]}
- >
- <button
- className="button js-continue"
- onClick={[Function]}
- type="button"
- >
- continue
- </button>
- </Button>
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
-
-exports[`revokes token 3`] = `
-<TokenStep
- currentUser={
- Object {
- "login": "user",
- }
- }
- finished={false}
- onContinue={[MockFunction]}
- onOpen={[MockFunction]}
- open={true}
- stepNumber={1}
->
- <Step
- finished={false}
- onOpen={[MockFunction]}
- open={true}
- renderForm={[Function]}
- renderResult={[Function]}
- stepNumber={1}
- stepTitle="onboarding.token.header"
- >
- <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="boxed-group-inner"
- >
- <div>
- <div>
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right is-checked"
- />
- onboading.token.generate_token
- </a>
- <div
- className="big-spacer-top"
- >
- <form
- onSubmit={[Function]}
- >
- <input
- autoFocus={true}
- className="input-large spacer-right text-middle"
- onChange={[Function]}
- placeholder="onboading.token.generate_token.placeholder"
- required={true}
- type="text"
- value=""
- />
- <SubmitButton
- className="text-middle"
- disabled={true}
- >
- <Button
- className="text-middle"
- disabled={true}
- preventDefault={false}
- type="submit"
- >
- <button
- className="button text-middle"
- disabled={true}
- onClick={[Function]}
- type="submit"
- >
- onboarding.token.generate
- </button>
- </Button>
- </SubmitButton>
- </form>
- </div>
- </div>
- <div
- className="big-spacer-top"
- >
- <a
- className="js-new link-base-color link-no-underline"
- href="#"
- onClick={[Function]}
- >
- <i
- className="icon-radio spacer-right"
- />
- onboarding.token.use_existing_token
- </a>
- </div>
- </div>
- <div
- className="note big-spacer-top width-50"
- >
- onboarding.token.text
- </div>
- </div>
- </div>
- </Step>
-</TokenStep>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {
- className?: string,
- os: string
-};
-*/
-
-const filenames = {
- win: 'build-wrapper-win-x86.zip',
- linux: 'build-wrapper-linux-x86.zip',
- mac: 'build-wrapper-macosx-x86.zip'
-};
-
-export default function BuildWrapper(props /*: Props */) {
- return (
- <div className={props.className}>
- <h4 className="spacer-bottom">
- {translate('onboarding.analysis.build_wrapper.header', props.os)}
- </h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.build_wrapper.text', props.os)
- }}
- />
- <p>
- <a
- className="button"
- download={filenames[props.os]}
- href={window.baseUrl + '/static/cpp/' + filenames[props.os]}
- target="_blank">
- {translate('download_verb')}
- </a>
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import SQScanner from './SQScanner';
-import BuildWrapper from './BuildWrapper';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {
- host: string,
- os: string,
- organization?: string,
- projectKey: string,
- token: string
-};
-*/
-
-const executables = {
- linux: 'build-wrapper-linux-x86-64',
- win: 'build-wrapper-win-x86-64.exe',
- mac: 'build-wrapper-macosx-x86'
-};
-
-export default function ClangGCC(props /*: Props */) {
- const command1 = `${executables[props.os]} --out-dir bw-output make clean all`;
-
- const command2 = [
- props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
- `-Dsonar.projectKey=${props.projectKey}`,
- props.organization && `-Dsonar.organization=${props.organization}`,
- '-Dsonar.sources=.',
- '-Dsonar.cfamily.build-wrapper-output=bw-output',
- `-Dsonar.host.url=${props.host}`,
- `-Dsonar.login=${props.token}`
- ];
-
- return (
- <div>
- <SQScanner os={props.os} />
- <BuildWrapper className="huge-spacer-top" 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"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
- </InstanceMessage>
- <CodeSnippet isOneLine={true} snippet={command1} />
- <CodeSnippet isOneLine={props.os === 'win'} snippet={command2} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import MSBuildScanner from './MSBuildScanner';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {|
- host: string,
- organization?: string,
- projectKey: string,
- token: string
-|};
-*/
-
-export default function DotNet(props /*: Props */) {
- const command1 = [
- 'SonarQube.Scanner.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 = ['SonarQube.Scanner.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"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
- </InstanceMessage>
- <CodeSnippet isOneLine={true} snippet={command1} />
- <CodeSnippet isOneLine={true} snippet={command2} />
- <CodeSnippet isOneLine={true} snippet={command3} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {|
- host: string,
- organization?: string,
- token: string
-|};
-*/
-
-export default function JavaGradle(props /*: Props */) {
- const config = 'plugins {\n id "org.sonarqube" version "2.6"\n}';
-
- const command = [
- './gradlew sonarqube',
- 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"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
- </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"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.docs') }}
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.browse_url_after_analysis')
- }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {|
- host: string,
- organization?: string,
- token: string
-|};
-*/
-
-export default function JavaMaven(props /*: Props */) {
- const command = [
- 'mvn sonar:sonar',
- 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"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.maven.docs') }}
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.browse_url_after_analysis')
- }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type 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"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.text') }}
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
- target="_blank">
- {translate('download_verb')}
- </a>
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import MSBuildScanner from './MSBuildScanner';
-import BuildWrapper from './BuildWrapper';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {|
- host: string,
- organization?: string,
- projectKey: string,
- token: string
-|};
-*/
-
-export default function Msvc(props /*: Props */) {
- const command1 = [
- 'SonarQube.Scanner.MSBuild.exe begin',
- `/k:"${props.projectKey}"`,
- props.organization && `/d:sonar.organization="${props.organization}"`,
- '/d:sonar.cfamily.build-wrapper-output=bw-output',
- `/d:sonar.host.url="${props.host}"`,
- `/d:sonar.login="${props.token}"`
- ];
-
- const command2 = 'build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild';
-
- const command3 = ['SonarQube.Scanner.MSBuild.exe end', `/d:sonar.login="${props.token}"`];
-
- return (
- <div>
- <MSBuildScanner />
- <BuildWrapper className="huge-spacer-top" os="win" />
-
- <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"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
- </InstanceMessage>
- <CodeSnippet isOneLine={true} snippet={command1} />
- <CodeSnippet isOneLine={true} snippet={command2} />
- <CodeSnippet isOneLine={true} snippet={command3} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import SQScanner from './SQScanner';
-import CodeSnippet from '../../../../components/common/CodeSnippet';
-import InstanceMessage from '../../../../components/common/InstanceMessage';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type Props = {|
- host: string,
- organization?: string,
- os: string,
- projectKey: string,
- token: string
-|};
-*/
-
-export default function Other(props /*: Props */) {
- const command = [
- props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
- `-Dsonar.projectKey=${props.projectKey}`,
- props.organization && `-Dsonar.organization=${props.organization}`,
- '-Dsonar.sources=.',
- `-Dsonar.host.url=${props.host}`,
- `-Dsonar.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"
- dangerouslySetInnerHTML={{ __html: transformedMessage }}
- />
- )}
- </InstanceMessage>
- <CodeSnippet isOneLine={props.os === 'win'} snippet={command} />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
- />
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { translate } from '../../../../helpers/l10n';
-
-/*::
-type 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"
- dangerouslySetInnerHTML={{
- __html: translate('onboarding.analysis.sq_scanner.text', props.os)
- }}
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- target="_blank">
- {translate('download_verb')}
- </a>
- </p>
- </div>
- );
-}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import BuildWrapper from '../BuildWrapper';
-
-it('renders correctly', () => {
- expect(shallow(<BuildWrapper os="win" />)).toMatchSnapshot();
- expect(shallow(<BuildWrapper os="linux" />)).toMatchSnapshot();
- expect(shallow(<BuildWrapper os="mac" />)).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import ClangGCC from '../ClangGCC';
-
-it('renders correctly', () => {
- expect(
- shallow(<ClangGCC host="host" os="win" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-
- expect(
- shallow(<ClangGCC host="host" os="linux" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-
- expect(
- shallow(
- <ClangGCC
- host="host"
- os="linux"
- organization="organization"
- projectKey="projectKey"
- token="token"
- />
- )
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import DotNet from '../DotNet';
-
-it('renders correctly', () => {
- expect(shallow(<DotNet host="host" projectKey="projectKey" token="token" />)).toMatchSnapshot();
- expect(
- shallow(
- <DotNet host="host" organization="organization" projectKey="projectKey" token="token" />
- )
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-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();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-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();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import MSBuildScanner from '../MSBuildScanner';
-
-it('renders correctly', () => {
- expect(shallow(<MSBuildScanner />)).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-import Msvc from '../Msvc';
-
-it('renders correctly', () => {
- expect(shallow(<Msvc host="host" projectKey="projectKey" token="token" />)).toMatchSnapshot();
- expect(
- shallow(<Msvc host="host" organization="organization" projectKey="projectKey" token="token" />)
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-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"
- organization="organization"
- projectKey="projectKey"
- token="token"
- />
- )
- ).toMatchSnapshot();
-});
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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.
- */
-// @flow
-import React from 'react';
-import { shallow } from 'enzyme';
-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[`renders correctly 1`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.build_wrapper.header.win
- </h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.win",
- }
- }
- />
- <p>
- <a
- className="button"
- download="build-wrapper-win-x86.zip"
- href="/static/cpp/build-wrapper-win-x86.zip"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.build_wrapper.header.linux
- </h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.linux",
- }
- }
- />
- <p>
- <a
- className="button"
- download="build-wrapper-linux-x86.zip"
- href="/static/cpp/build-wrapper-linux-x86.zip"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
-
-exports[`renders correctly 3`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.build_wrapper.header.mac
- </h4>
- <p
- className="spacer-bottom markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.build_wrapper.text.mac",
- }
- }
- />
- <p>
- <a
- className="button"
- download="build-wrapper-macosx-x86.zip"
- href="/static/cpp/build-wrapper-macosx-x86.zip"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <SQScanner
- os="win"
- />
- <BuildWrapper
- className="huge-spacer-top"
- os="win"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet="build-wrapper-win-x86-64.exe --out-dir bw-output make clean all"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "sonar-scanner.bat",
- "-Dsonar.projectKey=projectKey",
- undefined,
- "-Dsonar.sources=.",
- "-Dsonar.cfamily.build-wrapper-output=bw-output",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <SQScanner
- os="linux"
- />
- <BuildWrapper
- className="huge-spacer-top"
- os="linux"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet="build-wrapper-linux-x86-64 --out-dir bw-output make clean all"
- />
- <CodeSnippet
- isOneLine={false}
- snippet={
- Array [
- "sonar-scanner",
- "-Dsonar.projectKey=projectKey",
- undefined,
- "-Dsonar.sources=.",
- "-Dsonar.cfamily.build-wrapper-output=bw-output",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</div>
-`;
-
-exports[`renders correctly 3`] = `
-<div>
- <SQScanner
- os="linux"
- />
- <BuildWrapper
- className="huge-spacer-top"
- os="linux"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.sq_scanner.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.sq_scanner.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet="build-wrapper-linux-x86-64 --out-dir bw-output make clean all"
- />
- <CodeSnippet
- isOneLine={false}
- snippet={
- Array [
- "sonar-scanner",
- "-Dsonar.projectKey=projectKey",
- "-Dsonar.organization=organization",
- "-Dsonar.sources=.",
- "-Dsonar.cfamily.build-wrapper-output=bw-output",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <MSBuildScanner />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.msbuild.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.msbuild.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe begin",
- "/k:\\"projectKey\\"",
- undefined,
- "/d:sonar.host.url=\\"host\\"",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <CodeSnippet
- isOneLine={true}
- snippet="MsBuild.exe /t:Rebuild"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe end",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
- }
- }
- />
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <MSBuildScanner />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.msbuild.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.msbuild.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe begin",
- "/k:\\"projectKey\\"",
- "/d:sonar.organization=\\"organization\\"",
- "/d:sonar.host.url=\\"host\\"",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <CodeSnippet
- isOneLine={true}
- snippet="MsBuild.exe /t:Rebuild"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe end",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
- }
- }
- />
-</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"
- />
- <CodeSnippet
- snippet="plugins {
- id \\"org.sonarqube\\" version \\"2.6\\"
-}"
- />
- <p
- className="spacer-top spacer-bottom markdown"
- >
- onboarding.analysis.java.gradle.text.2
- </p>
- <CodeSnippet
- snippet={
- Array [
- "./gradlew sonarqube",
- undefined,
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.gradle.docs",
- }
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <h4
- className="spacer-bottom"
- >
- onboarding.analysis.java.gradle.header
- </h4>
- <InstanceMessage
- message="onboarding.analysis.java.gradle.text.1"
- />
- <CodeSnippet
- snippet="plugins {
- id \\"org.sonarqube\\" version \\"2.6\\"
-}"
- />
- <p
- className="spacer-top spacer-bottom markdown"
- >
- onboarding.analysis.java.gradle.text.2
- </p>
- <CodeSnippet
- snippet={
- Array [
- "./gradlew sonarqube",
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.gradle.docs",
- }
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
-</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,
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.maven.docs",
- }
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
-</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",
- "-Dsonar.organization=organization",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.java.maven.docs",
- }
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.browse_url_after_analysis",
- }
- }
- />
-</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"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.text",
- }
- }
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
+++ /dev/null
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`renders correctly 1`] = `
-<div>
- <MSBuildScanner />
- <BuildWrapper
- className="huge-spacer-top"
- os="win"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.msbuild.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.msbuild.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe begin",
- "/k:\\"projectKey\\"",
- undefined,
- "/d:sonar.cfamily.build-wrapper-output=bw-output",
- "/d:sonar.host.url=\\"host\\"",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <CodeSnippet
- isOneLine={true}
- snippet="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe end",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
- }
- }
- />
-</div>
-`;
-
-exports[`renders correctly 2`] = `
-<div>
- <MSBuildScanner />
- <BuildWrapper
- className="huge-spacer-top"
- os="win"
- />
- <h4
- className="huge-spacer-top spacer-bottom"
- >
- onboarding.analysis.msbuild.execute
- </h4>
- <InstanceMessage
- message="onboarding.analysis.msbuild.execute.text"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe begin",
- "/k:\\"projectKey\\"",
- "/d:sonar.organization=\\"organization\\"",
- "/d:sonar.cfamily.build-wrapper-output=bw-output",
- "/d:sonar.host.url=\\"host\\"",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <CodeSnippet
- isOneLine={true}
- snippet="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "SonarQube.Scanner.MSBuild.exe end",
- "/d:sonar.login=\\"token\\"",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.msbuild.docs",
- }
- }
- />
-</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"
- />
- <CodeSnippet
- isOneLine={true}
- snippet={
- Array [
- "sonar-scanner.bat",
- "-Dsonar.projectKey=projectKey",
- undefined,
- "-Dsonar.sources=.",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</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"
- />
- <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"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</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"
- />
- <CodeSnippet
- isOneLine={false}
- snippet={
- Array [
- "sonar-scanner",
- "-Dsonar.projectKey=projectKey",
- "-Dsonar.organization=organization",
- "-Dsonar.sources=.",
- "-Dsonar.host.url=host",
- "-Dsonar.login=token",
- ]
- }
- />
- <p
- className="big-spacer-top markdown"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.docs",
- }
- }
- />
-</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"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.win",
- }
- }
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- 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"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.linux",
- }
- }
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- 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"
- dangerouslySetInnerHTML={
- Object {
- "__html": "onboarding.analysis.sq_scanner.text.mac",
- }
- }
- />
- <p>
- <a
- className="button"
- href="http://redirect.sonarsource.com/doc/install-configure-scanner.html"
- target="_blank"
- >
- download_verb
- </a>
- </p>
-</div>
-`;
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 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 {
- min-height: calc(70vh - 60px);
-}
-
-.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-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;
-}
-
-.onboarding .page-actions {
- text-align: right;
- margin-bottom: 0;
-}
-
-.onboarding .page-actions p {
- line-height: 16px;
- margin-top: 6px;
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 Step from './Step';
+import LanguageStep, { Result } from './LanguageStep';
+import JavaMaven from './commands/JavaMaven';
+import JavaGradle from './commands/JavaGradle';
+import DotNet from './commands/DotNet';
+import Msvc from './commands/Msvc';
+import ClangGCC from './commands/ClangGCC';
+import Other from './commands/Other';
+import { translate } from '../../../helpers/l10n';
+import { getHostUrl } from '../../../helpers/urls';
+
+interface Props {
+ onFinish: (projectKey?: string) => void;
+ onReset: () => void;
+ open: boolean;
+ organization?: string;
+ stepNumber: number;
+ token?: string;
+}
+
+interface State {
+ result?: Result;
+}
+
+export default class AnalysisStep extends React.PureComponent<Props, State> {
+ state: State = {};
+
+ handleLanguageSelect = (result?: Result) => {
+ this.setState({ result });
+ const projectKey = result && result.language !== 'java' ? result.projectKey : undefined;
+ this.props.onFinish(projectKey);
+ };
+
+ handleLanguageReset = () => {
+ this.setState({ result: undefined });
+ this.props.onReset();
+ };
+
+ renderForm = () => {
+ return (
+ <div className="boxed-group-inner">
+ <div className="flex-columns">
+ <div className="flex-column flex-column-half bordered-right">
+ <LanguageStep
+ onDone={this.handleLanguageSelect}
+ onReset={this.handleLanguageReset}
+ organization={this.props.organization}
+ />
+ </div>
+ <div className="flex-column flex-column-half">{this.renderCommand()}</div>
+ </div>
+ </div>
+ );
+ };
+
+ renderFormattedCommand = (...lines: Array<string>) => (
+ // keep this "useless" concatentation for the readability reason
+ // eslint-disable-next-line no-useless-concat
+ <pre>{lines.join(' ' + '\\' + '\n' + ' ')}</pre>
+ );
+
+ renderCommand = () => {
+ const { result } = this.state;
+
+ if (!result) {
+ return null;
+ }
+
+ if (result.language === 'java') {
+ return result.javaBuild === 'maven'
+ ? this.renderCommandForMaven()
+ : this.renderCommandForGradle();
+ } else if (result.language === 'dotnet') {
+ return this.renderCommandForDotNet();
+ } else if (result.language === 'c-family') {
+ return result.cFamilyCompiler === 'msvc'
+ ? this.renderCommandForMSVC()
+ : this.renderCommandForClangGCC();
+ } else {
+ return this.renderCommandForOther();
+ }
+ };
+
+ renderCommandForMaven = () => {
+ const { token } = this.props;
+ if (!token) {
+ return null;
+ }
+ return <JavaMaven host={getHostUrl()} organization={this.props.organization} token={token} />;
+ };
+
+ renderCommandForGradle = () => {
+ const { token } = this.props;
+ if (!token) {
+ return null;
+ }
+ return <JavaGradle host={getHostUrl()} organization={this.props.organization} token={token} />;
+ };
+
+ renderCommandForDotNet = () => {
+ const { token } = this.props;
+ const { result } = this.state;
+ if (!result || !result.projectKey || !token) {
+ return null;
+ }
+ return (
+ <DotNet
+ host={getHostUrl()}
+ organization={this.props.organization}
+ projectKey={result.projectKey}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForMSVC = () => {
+ const { token } = this.props;
+ const { result } = this.state;
+ if (!result || !result.projectKey || !token) {
+ return null;
+ }
+ return (
+ <Msvc
+ host={getHostUrl()}
+ organization={this.props.organization}
+ projectKey={result.projectKey}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForClangGCC = () => {
+ const { token } = this.props;
+ const { result } = this.state;
+ if (!result || !result.projectKey || !result.os || !token) {
+ return null;
+ }
+ return (
+ <ClangGCC
+ host={getHostUrl()}
+ organization={this.props.organization}
+ os={result.os}
+ projectKey={result.projectKey}
+ token={token}
+ />
+ );
+ };
+
+ renderCommandForOther = () => {
+ const { token } = this.props;
+ const { result } = this.state;
+ if (!result || !result.projectKey || !result.os || !token) {
+ return null;
+ }
+ return (
+ <Other
+ host={getHostUrl()}
+ organization={this.props.organization}
+ os={result.os}
+ projectKey={result.projectKey}
+ token={token}
+ />
+ );
+ };
+
+ 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-2018 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 NewProjectForm from './NewProjectForm';
+import RadioToggle from '../../../components/controls/RadioToggle';
+import { translate } from '../../../helpers/l10n';
+import { isSonarCloud } from '../../../helpers/system';
+
+export interface Result {
+ language?: string;
+ javaBuild?: string;
+ cFamilyCompiler?: string;
+ os?: string;
+ projectKey?: string;
+}
+
+interface Props {
+ onDone: (result: Result) => void;
+ onReset: () => void;
+ organization?: string;
+}
+
+type State = Result;
+
+export default class LanguageStep extends React.PureComponent<Props, State> {
+ state: State = {};
+
+ isConfigured = () => {
+ const { language, javaBuild, cFamilyCompiler, os, projectKey } = this.state;
+ 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;
+ };
+
+ handleChange = () => {
+ if (this.isConfigured()) {
+ 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);
+ };
+
+ handleCFamilyCompilerChange = (cFamilyCompiler: string) => {
+ this.setState({ cFamilyCompiler }, this.handleChange);
+ };
+
+ handleOSChange = (os: string) => {
+ this.setState({ os }, this.handleChange);
+ };
+
+ handleProjectKeyDone = (projectKey: string) => {
+ this.setState({ projectKey }, this.handleChange);
+ };
+
+ handleProjectKeyDelete = () => {
+ this.setState({ projectKey: undefined }, this.handleChange);
+ };
+
+ renderJavaBuild = () => (
+ <div className="big-spacer-top">
+ <h4 className="spacer-bottom">{translate('onboarding.language.java.build_technology')}</h4>
+ <RadioToggle
+ name="java-build"
+ onCheck={this.handleJavaBuildChange}
+ options={['maven', 'gradle'].map(build => ({
+ label: translate('onboarding.language.java.build_technology', build),
+ value: build
+ }))}
+ value={this.state.javaBuild}
+ />
+ </div>
+ );
+
+ renderCFamilyCompiler = () => (
+ <div className="big-spacer-top">
+ <h4 className="spacer-bottom">{translate('onboarding.language.c-family.compiler')}</h4>
+ <RadioToggle
+ name="c-family-compiler"
+ onCheck={this.handleCFamilyCompilerChange}
+ options={['msvc', 'clang-gcc'].map(compiler => ({
+ label: translate('onboarding.language.c-family.compiler', compiler),
+ value: compiler
+ }))}
+ value={this.state.cFamilyCompiler}
+ />
+ </div>
+ );
+
+ renderOS = () => (
+ <div className="big-spacer-top">
+ <h4 className="spacer-bottom">{translate('onboarding.language.os')}</h4>
+ <RadioToggle
+ name="os"
+ onCheck={this.handleOSChange}
+ options={['linux', 'win', 'mac'].map(os => ({
+ label: translate('onboarding.language.os', os),
+ value: os
+ }))}
+ value={this.state.os}
+ />
+ </div>
+ );
+
+ renderProjectKey = () => (
+ <NewProjectForm
+ onDelete={this.handleProjectKeyDelete}
+ onDone={this.handleProjectKeyDone}
+ organization={this.props.organization}
+ projectKey={this.state.projectKey}
+ />
+ );
+
+ render() {
+ const shouldAskProjectKey =
+ this.state.language === 'dotnet' ||
+ (this.state.language === 'c-family' &&
+ (this.state.cFamilyCompiler === 'msvc' ||
+ (this.state.cFamilyCompiler === 'clang-gcc' && this.state.os != null))) ||
+ (this.state.language === 'other' && this.state.os !== undefined);
+
+ const languages = isSonarCloud()
+ ? ['java', 'dotnet', 'c-family', 'other']
+ : ['java', 'dotnet', 'other'];
+
+ return (
+ <div>
+ <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={this.state.language}
+ />
+ </div>
+ {this.state.language === 'java' && this.renderJavaBuild()}
+ {this.state.language === 'c-family' && this.renderCFamilyCompiler()}
+ {((this.state.language === 'c-family' && this.state.cFamilyCompiler === 'clang-gcc') ||
+ this.state.language === 'other') &&
+ this.renderOS()}
+ {shouldAskProjectKey && this.renderProjectKey()}
+ </div>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { debounce } from 'lodash';
+import {
+ createOrganization,
+ deleteOrganization,
+ getOrganization
+} from '../../../api/organizations';
+import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
+import { DeleteButton, SubmitButton } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ onDelete: () => void;
+ onDone: (organization: string) => void;
+ organization?: string;
+}
+
+interface State {
+ done: boolean;
+ loading: boolean;
+ organization: string;
+ unique: boolean;
+}
+
+export default class NewOrganizationForm extends React.PureComponent<Props, State> {
+ mounted = false;
+
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ done: props.organization != null,
+ loading: false,
+ organization: props.organization || '',
+ unique: true
+ };
+ this.validateOrganization = debounce(this.validateOrganization, 500);
+ }
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ stopLoading = () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ };
+
+ validateOrganization = (organization: string) => {
+ getOrganization(organization).then(response => {
+ if (this.mounted) {
+ this.setState({ unique: response == null });
+ }
+ });
+ };
+
+ sanitizeOrganization = (organization: string) =>
+ organization
+ .toLowerCase()
+ .replace(/[^a-z0-9-]/, '')
+ .replace(/^-/, '');
+
+ handleOrganizationChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ const organization = this.sanitizeOrganization(event.target.value);
+ this.setState({ organization });
+ this.validateOrganization(organization);
+ };
+
+ handleOrganizationCreate = (event: React.FormEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ const { organization } = this.state;
+ if (organization) {
+ this.setState({ loading: true });
+ createOrganization({ key: organization, name: organization }).then(() => {
+ if (this.mounted) {
+ this.setState({ done: true, loading: false });
+ this.props.onDone(organization);
+ }
+ }, this.stopLoading);
+ }
+ };
+
+ handleOrganizationDelete = () => {
+ const { organization } = this.state;
+ if (organization) {
+ this.setState({ loading: true });
+ deleteOrganization(organization).then(() => {
+ if (this.mounted) {
+ this.setState({ done: false, loading: false, organization: '' });
+ this.props.onDelete();
+ }
+ }, this.stopLoading);
+ }
+ };
+
+ render() {
+ const { done, loading, organization, unique } = this.state;
+
+ const valid = unique && organization.length >= 2;
+
+ return done ? (
+ <div>
+ <span className="spacer-right text-middle">{organization}</span>
+ {loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <DeleteButton className="button-small" onClick={this.handleOrganizationDelete} />
+ )}
+ </div>
+ ) : (
+ <form onSubmit={this.handleOrganizationCreate}>
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ maxLength={32}
+ minLength={2}
+ onChange={this.handleOrganizationChange}
+ placeholder={translate('onboarding.organization.placeholder')}
+ required={true}
+ type="text"
+ value={organization}
+ />
+ {loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <SubmitButton className="text-middle" disabled={!valid}>
+ {translate('create')}
+ </SubmitButton>
+ )}
+ {!unique && (
+ <span className="big-spacer-left text-danger text-middle">
+ <AlertErrorIcon className="little-spacer-right text-text-top" />
+ {translate('this_name_is_already_taken')}
+ </span>
+ )}
+ <div className="note spacer-top abs-width-300">
+ {translate('onboarding.organization.key_requirement')}
+ </div>
+ </form>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { createProject, deleteProject } from '../../../api/components';
+import { DeleteButton, SubmitButton } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ onDelete: () => void;
+ onDone: (projectKey: string) => void;
+ organization?: string;
+ projectKey?: string;
+}
+
+interface State {
+ done: boolean;
+ loading: boolean;
+ projectKey: string;
+}
+
+export default class NewProjectForm extends React.PureComponent<Props, State> {
+ mounted = false;
+
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ done: props.projectKey != null,
+ loading: false,
+ projectKey: props.projectKey || ''
+ };
+ }
+
+ componentDidMount() {
+ this.mounted = true;
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ stopLoading = () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ };
+
+ sanitizeProjectKey = (projectKey: string) => projectKey.replace(/[^-_a-zA-Z0-9.:]/, '');
+
+ handleProjectKeyChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ projectKey: this.sanitizeProjectKey(event.target.value) });
+ };
+
+ handleProjectCreate = (event: React.FormEvent<HTMLFormElement>) => {
+ event.preventDefault();
+ const { projectKey } = this.state;
+ const data: {
+ name: string;
+ project: string;
+ organization?: string;
+ } = {
+ name: projectKey,
+ project: projectKey
+ };
+ if (this.props.organization) {
+ data.organization = this.props.organization;
+ }
+ this.setState({ loading: true });
+ createProject(data).then(() => {
+ if (this.mounted) {
+ this.setState({ done: true, loading: false });
+ this.props.onDone(projectKey);
+ }
+ }, this.stopLoading);
+ };
+
+ handleProjectDelete = () => {
+ const { projectKey } = this.state;
+ this.setState({ loading: true });
+ deleteProject(projectKey).then(() => {
+ if (this.mounted) {
+ this.setState({ done: false, loading: false, projectKey: '' });
+ this.props.onDelete();
+ }
+ }, this.stopLoading);
+ };
+
+ render() {
+ const { done, loading, projectKey } = this.state;
+
+ const valid = projectKey.length > 0;
+
+ const form = done ? (
+ <div>
+ <span className="spacer-right text-middle">{projectKey}</span>
+ {loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <DeleteButton className="button-small text-middle" onClick={this.handleProjectDelete} />
+ )}
+ </div>
+ ) : (
+ <form onSubmit={this.handleProjectCreate}>
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ maxLength={400}
+ minLength={1}
+ onChange={this.handleProjectKeyChange}
+ required={true}
+ type="text"
+ value={projectKey}
+ />
+ {loading ? (
+ <i className="spinner text-middle" />
+ ) : (
+ <SubmitButton className="text-middle" disabled={!valid}>
+ {translate('Done')}
+ </SubmitButton>
+ )}
+ <div className="note spacer-top abs-width-300">
+ {translate('onboarding.project_key_requirement')}
+ </div>
+ </form>
+ );
+
+ return (
+ <div className="big-spacer-top">
+ <h4 className="spacer-bottom">{translate('onboarding.language.project_key')}</h4>
+ {form}
+ </div>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as classNames from 'classnames';
+import { sortBy } from 'lodash';
+import Step from './Step';
+import NewOrganizationForm from './NewOrganizationForm';
+import DocTooltip from '../../../components/docs/DocTooltip';
+import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
+import { getOrganizations } from '../../../api/organizations';
+import Select from '../../../components/controls/Select';
+import { translate } from '../../../helpers/l10n';
+import { Button } from '../../../components/ui/buttons';
+
+interface Props {
+ currentUser: { login: string; isLoggedIn: boolean };
+ finished: boolean;
+ onOpen: () => void;
+ onContinue: (organization: string) => void;
+ open: boolean;
+ stepNumber: number;
+}
+
+interface State {
+ loading: boolean;
+ newOrganization?: string;
+ existingOrganization?: string;
+ existingOrganizations: Array<string>;
+ personalOrganization?: string;
+ selection: 'personal' | 'existing' | 'new';
+}
+
+export default class OrganizationStep extends React.PureComponent<Props, State> {
+ mounted = false;
+ state: State = {
+ loading: true,
+ existingOrganizations: [],
+ selection: 'personal'
+ };
+
+ componentDidMount() {
+ this.mounted = true;
+ this.fetchOrganizations();
+ }
+
+ componentWillUnmount() {
+ this.mounted = false;
+ }
+
+ fetchOrganizations = () => {
+ getOrganizations({ member: true }).then(
+ ({ organizations }) => {
+ if (this.mounted) {
+ const organizationKeys = organizations.filter(o => o.isAdmin).map(o => o.key);
+ // best guess: if there is only one organization, then it is personal
+ // otherwise, we can't guess, let's display them all as just "existing organizations"
+ const personalOrganization =
+ organizationKeys.length === 1 ? organizationKeys[0] : undefined;
+ const existingOrganizations = organizationKeys.length > 1 ? sortBy(organizationKeys) : [];
+ const selection = personalOrganization
+ ? 'personal'
+ : existingOrganizations.length > 0 ? 'existing' : 'new';
+ this.setState({
+ loading: false,
+ existingOrganizations,
+ personalOrganization,
+ selection
+ });
+ }
+ },
+ () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ }
+ );
+ };
+
+ getSelectedOrganization = () => {
+ switch (this.state.selection) {
+ case 'personal':
+ return this.state.personalOrganization;
+ case 'existing':
+ return this.state.existingOrganization;
+ case 'new':
+ return this.state.newOrganization;
+ default:
+ return null;
+ }
+ };
+
+ handlePersonalClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ selection: 'personal' });
+ };
+
+ handleExistingClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ selection: 'existing' });
+ };
+
+ handleNewClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
+ event.preventDefault();
+ this.setState({ selection: 'new' });
+ };
+
+ handleOrganizationCreate = (newOrganization: string) => {
+ this.setState({ newOrganization });
+ };
+
+ handleOrganizationDelete = () => {
+ this.setState({ newOrganization: undefined });
+ };
+
+ handleExistingOrganizationSelect = ({ value }: { value: string }) => {
+ this.setState({ existingOrganization: value });
+ };
+
+ handleContinueClick = () => {
+ const organization = this.getSelectedOrganization();
+ if (organization) {
+ this.props.onContinue(organization);
+ }
+ };
+
+ renderPersonalOrganizationOption = () => (
+ <div>
+ <a className="link-base-color link-no-underline" href="#" onClick={this.handlePersonalClick}>
+ <i
+ className={classNames('icon-radio', 'spacer-right', {
+ 'is-checked': this.state.selection === 'personal'
+ })}
+ />
+ {translate('onboarding.organization.my_personal_organization')}
+ <span className="note spacer-left">{this.state.personalOrganization}</span>
+ </a>
+ </div>
+ );
+
+ renderExistingOrganizationOption = () => (
+ <div className="big-spacer-top">
+ <a
+ className="js-existing link-base-color link-no-underline"
+ href="#"
+ onClick={this.handleExistingClick}>
+ <i
+ className={classNames('icon-radio', 'spacer-right', {
+ 'is-checked': this.state.selection === 'existing'
+ })}
+ />
+ {translate('onboarding.organization.exising_organization')}
+ </a>
+ {this.state.selection === 'existing' && (
+ <div className="big-spacer-top">
+ <Select
+ className="input-super-large"
+ clearable={false}
+ onChange={this.handleExistingOrganizationSelect}
+ options={this.state.existingOrganizations.map(organization => ({
+ label: organization,
+ value: organization
+ }))}
+ value={this.state.existingOrganization}
+ />
+ </div>
+ )}
+ </div>
+ );
+
+ renderNewOrganizationOption = () => (
+ <div className="big-spacer-top">
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={this.handleNewClick}>
+ <i
+ className={classNames('icon-radio', 'spacer-right', {
+ 'is-checked': this.state.selection === 'new'
+ })}
+ />
+ {translate('onboarding.organization.create_another_organization')}
+ </a>
+ {this.state.selection === 'new' && (
+ <div className="big-spacer-top">
+ <NewOrganizationForm
+ onDelete={this.handleOrganizationDelete}
+ onDone={this.handleOrganizationCreate}
+ organization={this.state.newOrganization}
+ />
+ </div>
+ )}
+ </div>
+ );
+
+ renderForm = () => {
+ return (
+ <div className="boxed-group-inner">
+ <div className="big-spacer-bottom width-50">
+ {translate('onboarding.organization.text')}
+ </div>
+
+ {this.state.loading ? (
+ <i className="spinner" />
+ ) : (
+ <div>
+ {this.state.personalOrganization && this.renderPersonalOrganizationOption()}
+ {this.state.existingOrganizations.length > 0 && this.renderExistingOrganizationOption()}
+ {this.renderNewOrganizationOption()}
+ </div>
+ )}
+
+ {this.getSelectedOrganization() != null &&
+ !this.state.loading && (
+ <div className="big-spacer-top">
+ <Button className="js-continue" onClick={this.handleContinueClick}>
+ {translate('continue')}
+ </Button>
+ </div>
+ )}
+ </div>
+ );
+ };
+
+ renderResult = () => {
+ const result = this.getSelectedOrganization();
+
+ return result != null ? (
+ <div className="boxed-group-actions display-flex-center">
+ <AlertSuccessIcon className="spacer-right" />
+ <strong>{result}</strong>
+ </div>
+ ) : null;
+ };
+
+ 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={
+ <span>
+ {translate('onboarding.organization.header')}
+ <DocTooltip className="little-spacer-left" doc="organizations/organization" />
+ </span>
+ }
+ />
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as PropTypes from 'prop-types';
+import Helmet from 'react-helmet';
+import { connect } from 'react-redux';
+import TokenStep from './TokenStep';
+import OrganizationStep from './OrganizationStep';
+import AnalysisStep from './AnalysisStep';
+import ProjectWatcher from './ProjectWatcher';
+import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication';
+import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer';
+import { CurrentUser, isLoggedIn } from '../../../app/types';
+import { ResetButtonLink } from '../../../components/ui/buttons';
+import { getProjectUrl } from '../../../helpers/urls';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { isSonarCloud } from '../../../helpers/system';
+import '../styles.css';
+
+interface OwnProps {
+ automatic?: boolean;
+ onFinish: () => void;
+}
+
+interface StateProps {
+ currentUser: CurrentUser;
+ organizationsEnabled: boolean;
+}
+
+type Props = OwnProps & StateProps;
+
+interface State {
+ finished: boolean;
+ organization?: string;
+ projectKey?: string;
+ step: string;
+ token?: string;
+}
+
+export class ProjectOnboarding extends React.PureComponent<Props, State> {
+ mounted = false;
+ static contextTypes = {
+ router: PropTypes.object
+ };
+
+ constructor(props: Props) {
+ super(props);
+ this.state = {
+ finished: false,
+ step: props.organizationsEnabled ? 'organization' : 'token'
+ };
+ }
+
+ componentDidMount() {
+ this.mounted = true;
+
+ // useCapture = true to receive the event before inputs
+ window.addEventListener('keydown', this.onKeyDown, true);
+
+ if (!isLoggedIn(this.props.currentUser)) {
+ handleRequiredAuthentication();
+ }
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('keydown', this.onKeyDown, true);
+ this.mounted = false;
+ }
+
+ onKeyDown = (event: KeyboardEvent) => {
+ if (event.key === 'Escape') {
+ this.finishOnboarding();
+ }
+ };
+
+ finishOnboarding = () => {
+ this.props.onFinish();
+ if (this.state.projectKey) {
+ this.context.router.push(getProjectUrl(this.state.projectKey));
+ }
+ };
+
+ handleTimeout = () => {
+ // unset `projectKey` to display a generic "Finish this tutorial" button
+ this.setState({ projectKey: undefined });
+ };
+
+ handleTokenDone = (token: string) => {
+ this.setState({ step: 'analysis', token });
+ };
+
+ handleOrganizationDone = (organization: string) => {
+ this.setState({ organization, step: 'token' });
+ };
+
+ handleTokenOpen = () => this.setState({ step: 'token' });
+
+ handleOrganizationOpen = () => this.setState({ step: 'organization' });
+
+ handleFinish = (projectKey?: string) => this.setState({ finished: true, projectKey });
+
+ handleReset = () => this.setState({ finished: false, projectKey: undefined });
+
+ render() {
+ const { automatic, currentUser, organizationsEnabled } = this.props;
+ if (!isLoggedIn(currentUser)) {
+ return null;
+ }
+
+ const { finished, projectKey, step, token } = this.state;
+ const header = translate('onboarding.project.header');
+ let stepNumber = 1;
+
+ return (
+ <>
+ <Helmet title={header} titleTemplate="%s" />
+ <header className="modal-head">
+ <h2>{header}</h2>
+ </header>
+ <div className="modal-body modal-container">
+ <p className="spacer-top big-spacer-bottom">
+ {translateWithParameters(
+ 'onboarding.project.header.description',
+ organizationsEnabled ? 3 : 2
+ )}
+ </p>
+ {organizationsEnabled && (
+ <OrganizationStep
+ currentUser={currentUser}
+ finished={this.state.organization != null}
+ onContinue={this.handleOrganizationDone}
+ onOpen={this.handleOrganizationOpen}
+ open={step === 'organization'}
+ stepNumber={stepNumber++}
+ />
+ )}
+
+ <TokenStep
+ currentUser={currentUser}
+ finished={this.state.token != null}
+ onContinue={this.handleTokenDone}
+ onOpen={this.handleTokenOpen}
+ open={step === 'token'}
+ stepNumber={stepNumber++}
+ />
+
+ <AnalysisStep
+ onFinish={this.handleFinish}
+ onReset={this.handleReset}
+ open={step === 'analysis'}
+ organization={this.state.organization}
+ stepNumber={stepNumber}
+ token={token}
+ />
+ </div>
+ <footer className="modal-foot">
+ <ResetButtonLink className="js-skip" onClick={this.finishOnboarding}>
+ {(finished && translate('tutorials.finish')) ||
+ (automatic ? translate('tutorials.skip') : translate('close'))}
+ </ResetButtonLink>
+ {finished && projectKey ? (
+ <ProjectWatcher
+ onFinish={this.finishOnboarding}
+ onTimeout={this.handleTimeout}
+ projectKey={projectKey}
+ />
+ ) : (
+ <span className="pull-left note">
+ {translate(
+ isSonarCloud()
+ ? 'tutorials.find_tutorial_back_in_plus'
+ : 'tutorials.find_tutorial_back_in_help'
+ )}
+ </span>
+ )}
+ </footer>
+ </>
+ );
+ }
+}
+
+const mapStateToProps = (state: any): StateProps => {
+ return {
+ currentUser: getCurrentUser(state),
+ organizationsEnabled: areThereCustomOrganizations(state)
+ };
+};
+
+export default connect<StateProps, {}, OwnProps>(mapStateToProps)(ProjectOnboarding);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 Modal from '../../../components/controls/Modal';
+import { translate } from '../../../helpers/l10n';
+import { lazyLoad } from '../../../components/lazyLoad';
+
+interface Props {
+ automatic?: boolean;
+ onFinish: () => void;
+}
+
+const ProjectOnboarding = lazyLoad(() => import('./ProjectOnboarding'));
+
+export default function ProjectOnboardingModal(props: Props) {
+ return (
+ <Modal contentLabel={translate('tutorials.onboarding')} large={true}>
+ <ProjectOnboarding {...props} />
+ </Modal>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import ProjectOnboardingModal from './ProjectOnboardingModal';
+import { skipOnboarding } from '../../../store/users/actions';
+
+interface DispatchProps {
+ skipOnboarding: () => void;
+}
+
+export class ProjectOnboardingPage extends React.PureComponent<DispatchProps> {
+ static contextTypes = {
+ router: PropTypes.object.isRequired
+ };
+
+ onSkipOnboardingTutorial = () => {
+ this.props.skipOnboarding();
+ this.context.router.replace('/');
+ };
+
+ render() {
+ return <ProjectOnboardingModal onFinish={this.onSkipOnboardingTutorial} />;
+ }
+}
+
+const mapDispatchToProps: DispatchProps = { skipOnboarding };
+
+export default connect<{}, DispatchProps>(null, mapDispatchToProps)(ProjectOnboardingPage);
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as classNames from 'classnames';
+import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
+import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
+import { getTasksForComponent } from '../../../api/ce';
+import { STATUSES } from '../../../apps/background-tasks/constants';
+import { translate } from '../../../helpers/l10n';
+
+const INTERVAL = 5000;
+const TIMEOUT = 10 * 60 * 1000; // 10 min
+
+interface Props {
+ onFinish: () => void;
+ onTimeout: () => void;
+ projectKey: string;
+}
+
+interface State {
+ inQueue: boolean;
+ status?: string;
+}
+
+export default class ProjectWatcher extends React.PureComponent<Props, State> {
+ interval?: number;
+ timeout?: number;
+ mounted = false;
+ state: State = { inQueue: false };
+
+ componentDidMount() {
+ this.mounted = true;
+ this.watch();
+ this.timeout = window.setTimeout(this.props.onTimeout, TIMEOUT);
+ }
+
+ componentWillUnmount() {
+ clearInterval(this.interval);
+ clearInterval(this.timeout);
+ this.mounted = false;
+ }
+
+ watch = () => (this.interval = window.setTimeout(this.checkProject, INTERVAL));
+
+ checkProject = () => {
+ const { projectKey } = this.props;
+ getTasksForComponent(projectKey).then(
+ response => {
+ if (response.queue.length > 0) {
+ this.setState({ inQueue: true });
+ }
+
+ if (response.current != null) {
+ const { status } = response.current;
+ this.setState({ status });
+ if (status === STATUSES.SUCCESS) {
+ this.props.onFinish();
+ } else if (status === STATUSES.PENDING || status === STATUSES.IN_PROGRESS) {
+ this.watch();
+ }
+ } else {
+ this.watch();
+ }
+ },
+ () => {}
+ );
+ };
+
+ render() {
+ const { inQueue, status } = this.state;
+ const className = 'pull-left note';
+
+ if (status === STATUSES.SUCCESS) {
+ return (
+ <div className={classNames(className, 'display-inline-flex-center')}>
+ <AlertSuccessIcon className="spacer-right" />
+ {translate('onboarding.project_watcher.finished')}
+ </div>
+ );
+ }
+
+ if (inQueue || status === STATUSES.PENDING || status === STATUSES.IN_PROGRESS) {
+ return (
+ <div className={className}>
+ <i className="spinner spacer-right" />
+ {translate('onboarding.project_watcher.in_progress')}
+ </div>
+ );
+ }
+
+ if (status != null) {
+ return (
+ <div className={classNames(className, 'display-inline-flex-center')}>
+ <AlertErrorIcon className="spacer-right" />
+ {translate('onboarding.project_watcher.failed')}
+ </div>
+ );
+ }
+
+ return <div className={className}>{translate('onboarding.project_watcher.not_started')}</div>;
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 React from 'react';
+import * as classNames from 'classnames';
+
+interface Props {
+ finished: boolean;
+ onOpen: () => void;
+ 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 ? props.renderForm() : <div className="boxed-group-inner" />}
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 * as classNames from 'classnames';
+import Step from './Step';
+import { getTokens, generateToken, revokeToken } from '../../../api/user-tokens';
+import AlertErrorIcon from '../../../components/icons-components/AlertErrorIcon';
+import AlertSuccessIcon from '../../../components/icons-components/AlertSuccessIcon';
+import { DeleteButton, SubmitButton, Button } from '../../../components/ui/buttons';
+import { translate } from '../../../helpers/l10n';
+
+interface Props {
+ currentUser: { login: string };
+ finished: boolean;
+ open: boolean;
+ onContinue: (token: string) => void;
+ onOpen: () => void;
+ stepNumber: number;
+}
+
+interface State {
+ canUseExisting: boolean;
+ existingToken: string;
+ loading: boolean;
+ selection: string;
+ tokenName?: string;
+ token?: string;
+}
+
+export default class TokenStep extends React.PureComponent<Props, State> {
+ mounted = false;
+
+ state: State = {
+ canUseExisting: false,
+ existingToken: '',
+ loading: false,
+ selection: 'generate'
+ };
+
+ componentDidMount() {
+ this.mounted = true;
+ getTokens(this.props.currentUser.login).then(
+ tokens => {
+ if (this.mounted) {
+ this.setState({ canUseExisting: tokens.length > 0 });
+ }
+ },
+ () => {}
+ );
+ }
+
+ 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' });
+ };
+
+ handleExisingTokenChange = (event: React.ChangeEvent<HTMLInputElement>) => {
+ this.setState({ existingToken: event.currentTarget.value });
+ };
+
+ stopLoading = () => {
+ if (this.mounted) {
+ this.setState({ loading: false });
+ }
+ };
+
+ renderGenerateOption = () => (
+ <div>
+ {this.state.canUseExisting ? (
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={this.handleGenerateClick}>
+ <i
+ className={classNames('icon-radio', 'spacer-right', {
+ 'is-checked': this.state.selection === 'generate'
+ })}
+ />
+ {translate('onboarding.token.generate_token')}
+ </a>
+ ) : (
+ translate('onboarding.token.generate_token')
+ )}
+ {this.state.selection === 'generate' && (
+ <div className="big-spacer-top">
+ <form onSubmit={this.handleTokenGenerate}>
+ <input
+ autoFocus={true}
+ className="input-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">
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={this.handleUseExistingClick}>
+ <i
+ className={classNames('icon-radio', 'spacer-right', {
+ 'is-checked': this.state.selection === 'use-existing'
+ })}
+ />
+ {translate('onboarding.token.use_existing_token')}
+ </a>
+ {this.state.selection === 'use-existing' && (
+ <div className="big-spacer-top">
+ <input
+ autoFocus={true}
+ className="input-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 { canUseExisting, loading, token, tokenName } = this.state;
+
+ 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">{translate('onboarding.token.text')}</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-2018 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 { shallow } from 'enzyme';
+import LanguageStep from '../LanguageStep';
+import { isSonarCloud } from '../../../../helpers/system';
+
+jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() }));
+
+beforeEach(() => {
+ (isSonarCloud as jest.Mock<any>).mockImplementation(() => false);
+});
+
+it('selects java', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('java');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper
+ .find('RadioToggle')
+ .at(1)
+ .prop('onCheck') as Function)('maven');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+ expect(onDone).lastCalledWith({ language: 'java', javaBuild: 'maven' });
+
+ (wrapper
+ .find('RadioToggle')
+ .at(1)
+ .prop('onCheck') as Function)('gradle');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+ expect(onDone).lastCalledWith({ language: 'java', javaBuild: 'gradle' });
+});
+
+it('selects c#', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('dotnet');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.find('NewProjectForm').prop('onDone') as Function)('project-foo');
+ expect(onDone).lastCalledWith({ language: 'dotnet', projectKey: 'project-foo' });
+});
+
+it('selects c-family', () => {
+ (isSonarCloud as jest.Mock<any>).mockImplementation(() => true);
+ const onDone = jest.fn();
+ const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('c-family');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper
+ .find('RadioToggle')
+ .at(1)
+ .prop('onCheck') as Function)('msvc');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.find('NewProjectForm').prop('onDone') as Function)('project-foo');
+ expect(onDone).lastCalledWith({
+ language: 'c-family',
+ cFamilyCompiler: 'msvc',
+ projectKey: 'project-foo'
+ });
+
+ (wrapper
+ .find('RadioToggle')
+ .at(1)
+ .prop('onCheck') as Function)('clang-gcc');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper
+ .find('RadioToggle')
+ .at(2)
+ .prop('onCheck') as Function)('linux');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.find('NewProjectForm').prop('onDone') as Function)('project-foo');
+ expect(onDone).lastCalledWith({
+ language: 'c-family',
+ cFamilyCompiler: 'clang-gcc',
+ os: 'linux',
+ projectKey: 'project-foo'
+ });
+});
+
+it('selects other', () => {
+ const onDone = jest.fn();
+ const wrapper = shallow(<LanguageStep onDone={onDone} onReset={jest.fn()} />);
+
+ (wrapper.find('RadioToggle').prop('onCheck') as Function)('other');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper
+ .find('RadioToggle')
+ .at(1)
+ .prop('onCheck') as Function)('mac');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.find('NewProjectForm').prop('onDone') as Function)('project-foo');
+ expect(onDone).lastCalledWith({ language: 'other', os: 'mac', projectKey: 'project-foo' });
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { mount } from 'enzyme';
+import NewOrganizationForm from '../NewOrganizationForm';
+import { change, submit, waitAndUpdate } from '../../../../helpers/testUtils';
+
+jest.mock('../../../../api/organizations', () => ({
+ createOrganization: () => Promise.resolve(),
+ deleteOrganization: () => Promise.resolve(),
+ getOrganization: () => Promise.resolve(null)
+}));
+
+jest.mock('../../../../components/icons-components/ClearIcon');
+
+it('creates new organization', async () => {
+ const onDone = jest.fn();
+ const wrapper = mount(<NewOrganizationForm onDelete={jest.fn()} onDone={onDone} />);
+ expect(wrapper).toMatchSnapshot();
+ change(wrapper.find('input'), 'foo');
+ submit(wrapper.find('form'));
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+ expect(onDone).toBeCalledWith('foo');
+});
+
+it('deletes organization', async () => {
+ const onDelete = jest.fn();
+ const wrapper = mount(<NewOrganizationForm onDelete={onDelete} onDone={jest.fn()} />);
+ wrapper.setState({ done: true, loading: false, organization: 'foo' });
+ expect(wrapper).toMatchSnapshot();
+ (wrapper.find('DeleteButton').prop('onClick') as Function)();
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+ expect(onDelete).toBeCalled();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { mount } from 'enzyme';
+import NewProjectForm from '../NewProjectForm';
+import { change, submit, waitAndUpdate } from '../../../../helpers/testUtils';
+
+jest.mock('../../../../api/components', () => ({
+ createProject: () => Promise.resolve(),
+ deleteProject: () => Promise.resolve()
+}));
+
+jest.mock('../../../../components/icons-components/ClearIcon');
+
+it('creates new project', async () => {
+ const onDone = jest.fn();
+ const wrapper = mount(<NewProjectForm onDelete={jest.fn()} onDone={onDone} />);
+ expect(wrapper).toMatchSnapshot();
+ change(wrapper.find('input'), 'foo');
+ submit(wrapper.find('form'));
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+ expect(onDone).toBeCalledWith('foo');
+});
+
+it('deletes project', async () => {
+ const onDelete = jest.fn();
+ const wrapper = mount(<NewProjectForm onDelete={onDelete} onDone={jest.fn()} />);
+ wrapper.setState({ done: true, loading: false, projectKey: 'foo' });
+ expect(wrapper).toMatchSnapshot();
+ (wrapper.find('DeleteButton').prop('onClick') as Function)();
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+ expect(onDelete).toBeCalled();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { mount } from 'enzyme';
+import OrganizationStep from '../OrganizationStep';
+import { click, waitAndUpdate } from '../../../../helpers/testUtils';
+import { getOrganizations } from '../../../../api/organizations';
+
+jest.mock('../../../../api/organizations', () => ({
+ getOrganizations: jest.fn(() =>
+ Promise.resolve({
+ organizations: [{ isAdmin: true, key: 'user' }, { isAdmin: true, key: 'another' }]
+ })
+ )
+}));
+
+const currentUser = { isLoggedIn: true, login: 'user' };
+
+beforeEach(() => {
+ (getOrganizations as jest.Mock<any>).mockClear();
+});
+
+// FIXME
+// - if `mount` is used, then it's not possible to correctly set the state,
+// because the mocked api call is used
+// - if `shallow` is used, then the continue button is not rendered
+it.skip('works with personal organization', () => {
+ const onContinue = jest.fn();
+ const wrapper = mount(
+ <OrganizationStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={onContinue}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ click(wrapper.find('.js-continue'));
+ expect(onContinue).toBeCalledWith('user');
+});
+
+it('works with existing organization', async () => {
+ const onContinue = jest.fn();
+ const wrapper = mount(
+ <OrganizationStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={onContinue}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ await waitAndUpdate(wrapper);
+ click(wrapper.find('.js-existing'));
+ expect(wrapper).toMatchSnapshot();
+ (wrapper
+ .find('Select')
+ .first()
+ .prop('onChange') as Function)({ value: 'another' });
+ wrapper.update();
+ click(wrapper.find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('another');
+});
+
+it('works with new organization', async () => {
+ const onContinue = jest.fn();
+ const wrapper = mount(
+ <OrganizationStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={onContinue}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ await waitAndUpdate(wrapper);
+ click(wrapper.find('.js-new'));
+ (wrapper.find('NewOrganizationForm').prop('onDone') as Function)('new');
+ wrapper.update();
+ click(wrapper.find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('new');
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow, mount } from 'enzyme';
+import { ProjectOnboarding } from '../ProjectOnboarding';
+import { click, doAsync } from '../../../../helpers/testUtils';
+import { getInstance, isSonarCloud } from '../../../../helpers/system';
+
+jest.mock('../../../../api/users', () => ({
+ skipOnboarding: () => Promise.resolve()
+}));
+
+jest.mock('../../../../helpers/system', () => ({
+ getInstance: jest.fn(),
+ isSonarCloud: jest.fn()
+}));
+
+const currentUser = { login: 'admin', isLoggedIn: true };
+
+it('guides for on-premise', () => {
+ (getInstance as jest.Mock<any>).mockImplementation(() => 'SonarQube');
+ (isSonarCloud as jest.Mock<any>).mockImplementation(() => false);
+ const wrapper = shallow(
+ <ProjectOnboarding
+ currentUser={currentUser}
+ onFinish={jest.fn()}
+ organizationsEnabled={false}
+ />
+ );
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.instance() as ProjectOnboarding).handleTokenDone('abcd1234');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('guides for sonarcloud', () => {
+ (getInstance as jest.Mock<any>).mockImplementation(() => 'SonarCloud');
+ (isSonarCloud as jest.Mock<any>).mockImplementation(() => true);
+ const wrapper = shallow(
+ <ProjectOnboarding currentUser={currentUser} onFinish={jest.fn()} organizationsEnabled={true} />
+ );
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.instance() as ProjectOnboarding).handleOrganizationDone('my-org');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+
+ (wrapper.instance() as ProjectOnboarding).handleTokenDone('abcd1234');
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('finishes', () => {
+ (getInstance as jest.Mock<any>).mockImplementation(() => 'SonarQube');
+ (isSonarCloud as jest.Mock<any>).mockImplementation(() => false);
+ const onFinish = jest.fn();
+ const wrapper = mount(
+ <ProjectOnboarding currentUser={currentUser} onFinish={onFinish} organizationsEnabled={false} />
+ );
+ click(wrapper.find('ResetButtonLink'));
+ return doAsync(() => {
+ expect(onFinish).toBeCalled();
+ });
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow, mount } from 'enzyme';
+import ProjectWatcher from '../ProjectWatcher';
+
+jest.mock('../../../../api/ce', () => ({
+ getTasksForComponent: () => Promise.resolve({ current: { status: 'SUCCESS' }, queue: [] })
+}));
+
+jest.useFakeTimers();
+
+it('renders', () => {
+ const wrapper = shallow(
+ <ProjectWatcher onFinish={jest.fn()} onTimeout={jest.fn()} projectKey="foo" />
+ );
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ inQueue: true });
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ status: 'SUCCESS' });
+ expect(wrapper).toMatchSnapshot();
+ wrapper.setState({ status: 'FAILED' });
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('finishes', done => {
+ // checking `expect(onFinish).toBeCalled();` is not working, because it's called asynchronously
+ // instead let's finish the test as soon as `onFinish` callback is called
+ const onFinish = jest.fn(done);
+ mount(<ProjectWatcher onFinish={onFinish} onTimeout={jest.fn()} projectKey="foo" />);
+ expect(onFinish).not.toBeCalled();
+ jest.runTimersToTime(5000);
+});
+
+it('timeouts', () => {
+ const onTimeout = jest.fn();
+ mount(<ProjectWatcher onFinish={jest.fn()} onTimeout={onTimeout} projectKey="foo" />);
+ expect(onTimeout).not.toBeCalled();
+ jest.runTimersToTime(10 * 60 * 1000);
+ expect(onTimeout).toBeCalled();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import Step from '../Step';
+import { click } from '../../../../helpers/testUtils';
+
+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-2018 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 { mount } from 'enzyme';
+import TokenStep from '../TokenStep';
+import { change, click, submit, waitAndUpdate } from '../../../../helpers/testUtils';
+
+jest.mock('../../../../api/user-tokens', () => ({
+ getTokens: () => Promise.resolve([{ name: 'foo' }]),
+ generateToken: () => Promise.resolve({ token: 'abcd1234' }),
+ revokeToken: () => Promise.resolve()
+}));
+
+jest.mock('../../../../components/icons-components/ClearIcon');
+
+const currentUser = { login: 'user' };
+
+it('generates token', async () => {
+ const wrapper = mount(
+ <TokenStep
+ currentUser={currentUser}
+ finished={false}
+ onContinue={jest.fn()}
+ onOpen={jest.fn()}
+ open={true}
+ stepNumber={1}
+ />
+ );
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+ change(wrapper.find('input'), 'my token');
+ submit(wrapper.find('form'));
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('revokes token', async () => {
+ const wrapper = mount(
+ <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).toMatchSnapshot();
+ (wrapper.find('DeleteButton').prop('onClick') as Function)();
+ wrapper.update();
+ expect(wrapper).toMatchSnapshot(); // spinner
+ await waitAndUpdate(wrapper);
+ expect(wrapper).toMatchSnapshot();
+});
+
+it('continues', async () => {
+ const onContinue = jest.fn();
+ const wrapper = mount(
+ <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.find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('abcd1234');
+});
+
+it('uses existing token', async () => {
+ const onContinue = jest.fn();
+ const wrapper = mount(
+ <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.find('[className="js-continue"]'));
+ expect(onContinue).toBeCalledWith('abcd1234');
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`selects c# 1`] = `
+<div>
+ <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>
+ <NewProjectForm
+ onDelete={[Function]}
+ onDone={[Function]}
+ />
+</div>
+`;
+
+exports[`selects c-family 1`] = `
+<div>
+ <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.c-family",
+ "value": "c-family",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="c-family"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.c-family.compiler
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="c-family-compiler"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.c-family.compiler.msvc",
+ "value": "msvc",
+ },
+ Object {
+ "label": "onboarding.language.c-family.compiler.clang-gcc",
+ "value": "clang-gcc",
+ },
+ ]
+ }
+ value={null}
+ />
+ </div>
+</div>
+`;
+
+exports[`selects c-family 2`] = `
+<div>
+ <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.c-family",
+ "value": "c-family",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="c-family"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.c-family.compiler
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="c-family-compiler"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.c-family.compiler.msvc",
+ "value": "msvc",
+ },
+ Object {
+ "label": "onboarding.language.c-family.compiler.clang-gcc",
+ "value": "clang-gcc",
+ },
+ ]
+ }
+ value="msvc"
+ />
+ </div>
+ <NewProjectForm
+ onDelete={[Function]}
+ onDone={[Function]}
+ />
+</div>
+`;
+
+exports[`selects c-family 3`] = `
+<div>
+ <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.c-family",
+ "value": "c-family",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="c-family"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.c-family.compiler
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="c-family-compiler"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.c-family.compiler.msvc",
+ "value": "msvc",
+ },
+ Object {
+ "label": "onboarding.language.c-family.compiler.clang-gcc",
+ "value": "clang-gcc",
+ },
+ ]
+ }
+ value="clang-gcc"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.os
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="os"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.os.linux",
+ "value": "linux",
+ },
+ Object {
+ "label": "onboarding.language.os.win",
+ "value": "win",
+ },
+ Object {
+ "label": "onboarding.language.os.mac",
+ "value": "mac",
+ },
+ ]
+ }
+ value={null}
+ />
+ </div>
+</div>
+`;
+
+exports[`selects c-family 4`] = `
+<div>
+ <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.c-family",
+ "value": "c-family",
+ },
+ Object {
+ "label": "onboarding.language.other",
+ "value": "other",
+ },
+ ]
+ }
+ value="c-family"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.c-family.compiler
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="c-family-compiler"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.c-family.compiler.msvc",
+ "value": "msvc",
+ },
+ Object {
+ "label": "onboarding.language.c-family.compiler.clang-gcc",
+ "value": "clang-gcc",
+ },
+ ]
+ }
+ value="clang-gcc"
+ />
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.os
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="os"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.os.linux",
+ "value": "linux",
+ },
+ Object {
+ "label": "onboarding.language.os.win",
+ "value": "win",
+ },
+ Object {
+ "label": "onboarding.language.os.mac",
+ "value": "mac",
+ },
+ ]
+ }
+ value="linux"
+ />
+ </div>
+ <NewProjectForm
+ onDelete={[Function]}
+ onDone={[Function]}
+ projectKey="project-foo"
+ />
+</div>
+`;
+
+exports[`selects java 1`] = `
+<div>
+ <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>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.java.build_technology
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="java-build"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java.build_technology.maven",
+ "value": "maven",
+ },
+ Object {
+ "label": "onboarding.language.java.build_technology.gradle",
+ "value": "gradle",
+ },
+ ]
+ }
+ value={null}
+ />
+ </div>
+</div>
+`;
+
+exports[`selects java 2`] = `
+<div>
+ <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>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.java.build_technology
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="java-build"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java.build_technology.maven",
+ "value": "maven",
+ },
+ Object {
+ "label": "onboarding.language.java.build_technology.gradle",
+ "value": "gradle",
+ },
+ ]
+ }
+ value="maven"
+ />
+ </div>
+</div>
+`;
+
+exports[`selects java 3`] = `
+<div>
+ <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>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.java.build_technology
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="java-build"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.java.build_technology.maven",
+ "value": "maven",
+ },
+ Object {
+ "label": "onboarding.language.java.build_technology.gradle",
+ "value": "gradle",
+ },
+ ]
+ }
+ value="gradle"
+ />
+ </div>
+</div>
+`;
+
+exports[`selects other 1`] = `
+<div>
+ <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>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.os
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="os"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.os.linux",
+ "value": "linux",
+ },
+ Object {
+ "label": "onboarding.language.os.win",
+ "value": "win",
+ },
+ Object {
+ "label": "onboarding.language.os.mac",
+ "value": "mac",
+ },
+ ]
+ }
+ value={null}
+ />
+ </div>
+</div>
+`;
+
+exports[`selects other 2`] = `
+<div>
+ <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>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.os
+ </h4>
+ <RadioToggle
+ disabled={false}
+ name="os"
+ onCheck={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "onboarding.language.os.linux",
+ "value": "linux",
+ },
+ Object {
+ "label": "onboarding.language.os.win",
+ "value": "win",
+ },
+ Object {
+ "label": "onboarding.language.os.mac",
+ "value": "mac",
+ },
+ ]
+ }
+ value="mac"
+ />
+ </div>
+ <NewProjectForm
+ onDelete={[Function]}
+ onDone={[Function]}
+ />
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`creates new organization 1`] = `
+<NewOrganizationForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ maxLength={32}
+ minLength={2}
+ onChange={[Function]}
+ placeholder="onboarding.organization.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ create
+ </button>
+ </Button>
+ </SubmitButton>
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.organization.key_requirement
+ </div>
+ </form>
+</NewOrganizationForm>
+`;
+
+exports[`creates new organization 2`] = `
+<NewOrganizationForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ maxLength={32}
+ minLength={2}
+ onChange={[Function]}
+ placeholder="onboarding.organization.placeholder"
+ required={true}
+ type="text"
+ value="foo"
+ />
+ <i
+ className="spinner text-middle"
+ />
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.organization.key_requirement
+ </div>
+ </form>
+</NewOrganizationForm>
+`;
+
+exports[`creates new organization 3`] = `
+<NewOrganizationForm
+ onDelete={[MockFunction]}
+ onDone={
+ [MockFunction] {
+ "calls": Array [
+ Array [
+ "foo",
+ ],
+ ],
+ "results": Array [
+ Object {
+ "isThrow": false,
+ "value": undefined,
+ },
+ ],
+ }
+ }
+>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <DeleteButton
+ className="button-small"
+ onClick={[Function]}
+ >
+ <ButtonIcon
+ className="button-small"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </div>
+</NewOrganizationForm>
+`;
+
+exports[`deletes organization 1`] = `
+<NewOrganizationForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <DeleteButton
+ className="button-small"
+ onClick={[Function]}
+ >
+ <ButtonIcon
+ className="button-small"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </div>
+</NewOrganizationForm>
+`;
+
+exports[`deletes organization 2`] = `
+<NewOrganizationForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <i
+ className="spinner text-middle"
+ />
+ </div>
+</NewOrganizationForm>
+`;
+
+exports[`deletes organization 3`] = `
+<NewOrganizationForm
+ onDelete={
+ [MockFunction] {
+ "calls": Array [
+ Array [],
+ ],
+ "results": Array [
+ Object {
+ "isThrow": false,
+ "value": undefined,
+ },
+ ],
+ }
+ }
+ onDone={[MockFunction]}
+>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-super-large spacer-right text-middle"
+ maxLength={32}
+ minLength={2}
+ onChange={[Function]}
+ placeholder="onboarding.organization.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ create
+ </button>
+ </Button>
+ </SubmitButton>
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.organization.key_requirement
+ </div>
+ </form>
+</NewOrganizationForm>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`creates new project 1`] = `
+<NewProjectForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ maxLength={400}
+ minLength={1}
+ onChange={[Function]}
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ Done
+ </button>
+ </Button>
+ </SubmitButton>
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.project_key_requirement
+ </div>
+ </form>
+ </div>
+</NewProjectForm>
+`;
+
+exports[`creates new project 2`] = `
+<NewProjectForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ maxLength={400}
+ minLength={1}
+ onChange={[Function]}
+ required={true}
+ type="text"
+ value="foo"
+ />
+ <i
+ className="spinner text-middle"
+ />
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.project_key_requirement
+ </div>
+ </form>
+ </div>
+</NewProjectForm>
+`;
+
+exports[`creates new project 3`] = `
+<NewProjectForm
+ onDelete={[MockFunction]}
+ onDone={
+ [MockFunction] {
+ "calls": Array [
+ Array [
+ "foo",
+ ],
+ ],
+ "results": Array [
+ Object {
+ "isThrow": false,
+ "value": undefined,
+ },
+ ],
+ }
+ }
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <DeleteButton
+ className="button-small text-middle"
+ onClick={[Function]}
+ >
+ <ButtonIcon
+ className="button-small text-middle"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small text-middle button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small text-middle button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </div>
+ </div>
+</NewProjectForm>
+`;
+
+exports[`deletes project 1`] = `
+<NewProjectForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <DeleteButton
+ className="button-small text-middle"
+ onClick={[Function]}
+ >
+ <ButtonIcon
+ className="button-small text-middle"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small text-middle button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small text-middle button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </div>
+ </div>
+</NewProjectForm>
+`;
+
+exports[`deletes project 2`] = `
+<NewProjectForm
+ onDelete={[MockFunction]}
+ onDone={[MockFunction]}
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <div>
+ <span
+ className="spacer-right text-middle"
+ >
+ foo
+ </span>
+ <i
+ className="spinner text-middle"
+ />
+ </div>
+ </div>
+</NewProjectForm>
+`;
+
+exports[`deletes project 3`] = `
+<NewProjectForm
+ onDelete={
+ [MockFunction] {
+ "calls": Array [
+ Array [],
+ ],
+ "results": Array [
+ Object {
+ "isThrow": false,
+ "value": undefined,
+ },
+ ],
+ }
+ }
+ onDone={[MockFunction]}
+>
+ <div
+ className="big-spacer-top"
+ >
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.language.project_key
+ </h4>
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ maxLength={400}
+ minLength={1}
+ onChange={[Function]}
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ Done
+ </button>
+ </Button>
+ </SubmitButton>
+ <div
+ className="note spacer-top abs-width-300"
+ >
+ onboarding.project_key_requirement
+ </div>
+ </form>
+ </div>
+</NewProjectForm>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`works with existing organization 1`] = `
+<OrganizationStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle={
+ <span>
+ onboarding.organization.header
+ <DocTooltip
+ className="little-spacer-left"
+ doc="organizations/organization"
+ />
+ </span>
+ }
+ >
+ <div
+ className="boxed-group onboarding-step is-open"
+ >
+ <div
+ className="onboarding-step-number"
+ >
+ 1
+ </div>
+ <div
+ className="boxed-group-header"
+ >
+ <h2>
+ <span>
+ onboarding.organization.header
+ <DocTooltip
+ className="little-spacer-left"
+ doc="organizations/organization"
+ >
+ <HelpTooltip
+ className="little-spacer-left"
+ onShow={[Function]}
+ overlay={
+ <div
+ className="abs-width-300"
+ >
+ <LazyLoader
+ className="cut-margins"
+ isTooltip={true}
+ />
+ </div>
+ }
+ >
+ <div
+ className="help-tooltip little-spacer-left"
+ >
+ <Tooltip
+ mouseLeaveDelay={0.25}
+ onShow={[Function]}
+ overlay={
+ <div
+ className="abs-width-300"
+ >
+ <LazyLoader
+ className="cut-margins"
+ isTooltip={true}
+ />
+ </div>
+ }
+ >
+ <TooltipInner
+ mouseEnterDelay={0.1}
+ mouseLeaveDelay={0.25}
+ onShow={[Function]}
+ overlay={
+ <div
+ className="abs-width-300"
+ >
+ <LazyLoader
+ className="cut-margins"
+ isTooltip={true}
+ />
+ </div>
+ }
+ >
+ <span
+ className="display-inline-flex-center"
+ onMouseEnter={[Function]}
+ onMouseLeave={[Function]}
+ >
+ <HelpIcon
+ fill="#b4b4b4"
+ size={12}
+ >
+ <Icon
+ size={12}
+ >
+ <svg
+ height={12}
+ style={
+ Object {
+ "clipRule": "evenodd",
+ "fillRule": "evenodd",
+ "strokeLinejoin": "round",
+ "strokeMiterlimit": "1.41421",
+ }
+ }
+ version="1.1"
+ viewBox="0 0 16 16"
+ width={12}
+ xmlSpace="preserve"
+ xmlnsXlink="http://www.w3.org/1999/xlink"
+ >
+ <g
+ transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)"
+ >
+ <path
+ d="M224,344L224,296C224,293.667 223.25,291.75 221.75,290.25C220.25,288.75 218.333,288 216,288L168,288C165.667,288 163.75,288.75 162.25,290.25C160.75,291.75 160,293.667 160,296L160,344C160,346.333 160.75,348.25 162.25,349.75C163.75,351.25 165.667,352 168,352L216,352C218.333,352 220.25,351.25 221.75,349.75C223.25,348.25 224,346.333 224,344ZM288,176C288,161.333 283.375,147.75 274.125,135.25C264.875,122.75 253.333,113.083 239.5,106.25C225.667,99.417 211.5,96 197,96C156.5,96 125.583,113.75 104.25,149.25C101.75,153.25 102.417,156.75 106.25,159.75L139.25,184.75C140.417,185.75 142,186.25 144,186.25C146.667,186.25 148.75,185.25 150.25,183.25C159.083,171.917 166.25,164.25 171.75,160.25C177.417,156.25 184.583,154.25 193.25,154.25C201.25,154.25 208.375,156.417 214.625,160.75C220.875,165.083 224,170 224,175.5C224,181.833 222.333,186.917 219,190.75C215.667,194.583 210,198.333 202,202C191.5,206.667 181.875,213.875 173.125,223.625C164.375,233.375 160,243.833 160,255L160,264C160,266.333 160.75,268.25 162.25,269.75C163.75,271.25 165.667,272 168,272L216,272C218.333,272 220.25,271.25 221.75,269.75C223.25,268.25 224,266.333 224,264C224,260.833 225.792,256.708 229.375,251.625C232.958,246.542 237.5,242.417 243,239.25C248.333,236.25 252.417,233.875 255.25,232.125C258.083,230.375 261.917,227.458 266.75,223.375C271.583,219.292 275.292,215.292 277.875,211.375C280.458,207.458 282.792,202.417 284.875,196.25C286.958,190.083 288,183.333 288,176ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z"
+ style={
+ Object {
+ "fill": "#b4b4b4",
+ }
+ }
+ />
+ </g>
+ </svg>
+ </Icon>
+ </HelpIcon>
+ </span>
+ </TooltipInner>
+ </Tooltip>
+ </div>
+ </HelpTooltip>
+ </DocTooltip>
+ </span>
+ </h2>
+ </div>
+ <div
+ className="boxed-group-inner"
+ >
+ <div
+ className="big-spacer-bottom width-50"
+ >
+ onboarding.organization.text
+ </div>
+ <div>
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="js-existing link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right is-checked"
+ />
+ onboarding.organization.exising_organization
+ </a>
+ <div
+ className="big-spacer-top"
+ >
+ <Select
+ className="input-super-large"
+ clearable={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "another",
+ "value": "another",
+ },
+ Object {
+ "label": "user",
+ "value": "user",
+ },
+ ]
+ }
+ >
+ <LazyLoader
+ className="input-super-large"
+ clearRenderer={[Function]}
+ clearable={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "another",
+ "value": "another",
+ },
+ Object {
+ "label": "user",
+ "value": "user",
+ },
+ ]
+ }
+ >
+ <Select
+ arrowRenderer={[Function]}
+ autosize={true}
+ backspaceRemoves={true}
+ backspaceToRemoveMessage="Press backspace to remove {label}"
+ className="input-super-large"
+ clearAllText="Clear all"
+ clearRenderer={[Function]}
+ clearValueText="Clear value"
+ clearable={false}
+ closeOnSelect={true}
+ deleteRemoves={true}
+ delimiter=","
+ disabled={false}
+ escapeClearsValue={true}
+ filterOptions={[Function]}
+ ignoreAccents={true}
+ ignoreCase={true}
+ inputProps={Object {}}
+ isLoading={false}
+ joinValues={false}
+ labelKey="label"
+ matchPos="any"
+ matchProp="any"
+ menuBuffer={0}
+ menuRenderer={[Function]}
+ multi={false}
+ noResultsText="No results found"
+ onBlurResetsInput={true}
+ onChange={[Function]}
+ onCloseResetsInput={true}
+ onSelectResetsInput={true}
+ openOnClick={true}
+ optionComponent={[Function]}
+ options={
+ Array [
+ Object {
+ "label": "another",
+ "value": "another",
+ },
+ Object {
+ "label": "user",
+ "value": "user",
+ },
+ ]
+ }
+ pageSize={5}
+ placeholder="Select..."
+ removeSelected={true}
+ required={false}
+ rtl={false}
+ scrollMenuIntoView={true}
+ searchable={true}
+ simpleValue={false}
+ tabSelectsValue={true}
+ trimFilter={true}
+ valueComponent={[Function]}
+ valueKey="value"
+ >
+ <div
+ className="Select input-super-large is-searchable Select--single"
+ >
+ <div
+ className="Select-control"
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onTouchEnd={[Function]}
+ onTouchMove={[Function]}
+ onTouchStart={[Function]}
+ >
+ <span
+ className="Select-multi-value-wrapper"
+ id="react-select-2--value"
+ >
+ <div
+ className="Select-placeholder"
+ >
+ Select...
+ </div>
+ <AutosizeInput
+ aria-activedescendant="react-select-2--value"
+ aria-expanded="false"
+ aria-haspopup="false"
+ aria-owns=""
+ className="Select-input"
+ injectStyles={true}
+ minWidth="5"
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ required={false}
+ role="combobox"
+ value=""
+ >
+ <div
+ className="Select-input"
+ style={
+ Object {
+ "display": "inline-block",
+ }
+ }
+ >
+ <input
+ aria-activedescendant="react-select-2--value"
+ aria-expanded="false"
+ aria-haspopup="false"
+ aria-owns=""
+ onBlur={[Function]}
+ onChange={[Function]}
+ onFocus={[Function]}
+ required={false}
+ role="combobox"
+ style={
+ Object {
+ "boxSizing": "content-box",
+ "width": "5px",
+ }
+ }
+ value=""
+ />
+ <div
+ style={
+ Object {
+ "height": 0,
+ "left": 0,
+ "overflow": "scroll",
+ "position": "absolute",
+ "top": 0,
+ "visibility": "hidden",
+ "whiteSpace": "pre",
+ }
+ }
+ />
+ </div>
+ </AutosizeInput>
+ </span>
+ <span
+ className="Select-arrow-zone"
+ onMouseDown={[Function]}
+ >
+ <span
+ className="Select-arrow"
+ onMouseDown={[Function]}
+ />
+ </span>
+ </div>
+ </div>
+ </Select>
+ </LazyLoader>
+ </Select>
+ </div>
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right"
+ />
+ onboarding.organization.create_another_organization
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ </Step>
+</OrganizationStep>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`guides for on-premise 1`] = `
+<React.Fragment>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="onboarding.project.header"
+ titleTemplate="%s"
+ />
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.project.header
+ </h2>
+ </header>
+ <div
+ className="modal-body modal-container"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.project.header.description.2
+ </p>
+ <TokenStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={false}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={true}
+ stepNumber={1}
+ />
+ <AnalysisStep
+ onFinish={[Function]}
+ onReset={[Function]}
+ open={false}
+ stepNumber={2}
+ />
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ className="js-skip"
+ onClick={[Function]}
+ >
+ close
+ </ResetButtonLink>
+ <span
+ className="pull-left note"
+ >
+ tutorials.find_tutorial_back_in_help
+ </span>
+ </footer>
+</React.Fragment>
+`;
+
+exports[`guides for on-premise 2`] = `
+<React.Fragment>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="onboarding.project.header"
+ titleTemplate="%s"
+ />
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.project.header
+ </h2>
+ </header>
+ <div
+ className="modal-body modal-container"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.project.header.description.2
+ </p>
+ <TokenStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={true}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={false}
+ stepNumber={1}
+ />
+ <AnalysisStep
+ onFinish={[Function]}
+ onReset={[Function]}
+ open={true}
+ stepNumber={2}
+ token="abcd1234"
+ />
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ className="js-skip"
+ onClick={[Function]}
+ >
+ close
+ </ResetButtonLink>
+ <span
+ className="pull-left note"
+ >
+ tutorials.find_tutorial_back_in_help
+ </span>
+ </footer>
+</React.Fragment>
+`;
+
+exports[`guides for sonarcloud 1`] = `
+<React.Fragment>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="onboarding.project.header"
+ titleTemplate="%s"
+ />
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.project.header
+ </h2>
+ </header>
+ <div
+ className="modal-body modal-container"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.project.header.description.3
+ </p>
+ <OrganizationStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={false}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={true}
+ stepNumber={1}
+ />
+ <TokenStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={false}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={false}
+ stepNumber={2}
+ />
+ <AnalysisStep
+ onFinish={[Function]}
+ onReset={[Function]}
+ open={false}
+ stepNumber={3}
+ />
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ className="js-skip"
+ onClick={[Function]}
+ >
+ close
+ </ResetButtonLink>
+ <span
+ className="pull-left note"
+ >
+ tutorials.find_tutorial_back_in_plus
+ </span>
+ </footer>
+</React.Fragment>
+`;
+
+exports[`guides for sonarcloud 2`] = `
+<React.Fragment>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="onboarding.project.header"
+ titleTemplate="%s"
+ />
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.project.header
+ </h2>
+ </header>
+ <div
+ className="modal-body modal-container"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.project.header.description.3
+ </p>
+ <OrganizationStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={true}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={false}
+ stepNumber={1}
+ />
+ <TokenStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={false}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={true}
+ stepNumber={2}
+ />
+ <AnalysisStep
+ onFinish={[Function]}
+ onReset={[Function]}
+ open={false}
+ organization="my-org"
+ stepNumber={3}
+ />
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ className="js-skip"
+ onClick={[Function]}
+ >
+ close
+ </ResetButtonLink>
+ <span
+ className="pull-left note"
+ >
+ tutorials.find_tutorial_back_in_plus
+ </span>
+ </footer>
+</React.Fragment>
+`;
+
+exports[`guides for sonarcloud 3`] = `
+<React.Fragment>
+ <HelmetWrapper
+ defer={true}
+ encodeSpecialCharacters={true}
+ title="onboarding.project.header"
+ titleTemplate="%s"
+ />
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.project.header
+ </h2>
+ </header>
+ <div
+ className="modal-body modal-container"
+ >
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.project.header.description.3
+ </p>
+ <OrganizationStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={true}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={false}
+ stepNumber={1}
+ />
+ <TokenStep
+ currentUser={
+ Object {
+ "isLoggedIn": true,
+ "login": "admin",
+ }
+ }
+ finished={true}
+ onContinue={[Function]}
+ onOpen={[Function]}
+ open={false}
+ stepNumber={2}
+ />
+ <AnalysisStep
+ onFinish={[Function]}
+ onReset={[Function]}
+ open={true}
+ organization="my-org"
+ stepNumber={3}
+ token="abcd1234"
+ />
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ className="js-skip"
+ onClick={[Function]}
+ >
+ close
+ </ResetButtonLink>
+ <span
+ className="pull-left note"
+ >
+ tutorials.find_tutorial_back_in_plus
+ </span>
+ </footer>
+</React.Fragment>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders 1`] = `
+<div
+ className="pull-left note"
+>
+ onboarding.project_watcher.not_started
+</div>
+`;
+
+exports[`renders 2`] = `
+<div
+ className="pull-left note"
+>
+ <i
+ className="spinner spacer-right"
+ />
+ onboarding.project_watcher.in_progress
+</div>
+`;
+
+exports[`renders 3`] = `
+<div
+ className="pull-left note display-inline-flex-center"
+>
+ <AlertSuccessIcon
+ className="spacer-right"
+ />
+ onboarding.project_watcher.finished
+</div>
+`;
+
+exports[`renders 4`] = `
+<div
+ className="pull-left note"
+>
+ <i
+ className="spinner spacer-right"
+ />
+ onboarding.project_watcher.in_progress
+</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>
+ form
+ </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>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`generates token 1`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right is-checked"
+ />
+ onboarding.token.generate_token
+ </a>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ onChange={[Function]}
+ placeholder="onboarding.token.generate_token.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ onboarding.token.generate
+ </button>
+ </Button>
+ </SubmitButton>
+ </form>
+ </div>
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right"
+ />
+ onboarding.token.use_existing_token
+ </a>
+ </div>
+ </div>
+ <div
+ className="note big-spacer-top width-50"
+ >
+ onboarding.token.text
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
+
+exports[`generates token 2`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right is-checked"
+ />
+ onboarding.token.generate_token
+ </a>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-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"
+ >
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right"
+ />
+ onboarding.token.use_existing_token
+ </a>
+ </div>
+ </div>
+ <div
+ className="note big-spacer-top width-50"
+ >
+ onboarding.token.text
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
+
+exports[`generates token 3`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="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]}
+ >
+ <ButtonIcon
+ className="button-small text-middle"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small text-middle button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small text-middle button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </form>
+ <div
+ className="note big-spacer-top width-50"
+ >
+ onboarding.token.text
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <Button
+ className="js-continue"
+ onClick={[Function]}
+ >
+ <button
+ className="button js-continue"
+ onClick={[Function]}
+ type="button"
+ >
+ continue
+ </button>
+ </Button>
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
+
+exports[`revokes token 1`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="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]}
+ >
+ <ButtonIcon
+ className="button-small text-middle"
+ color="#d4333f"
+ onClick={[Function]}
+ >
+ <Button
+ className="button-small text-middle button-icon"
+ onClick={[Function]}
+ stopPropagation={true}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ >
+ <button
+ className="button button-small text-middle button-icon"
+ onClick={[Function]}
+ style={
+ Object {
+ "color": "#d4333f",
+ }
+ }
+ type="button"
+ >
+ <ClearIcon />
+ </button>
+ </Button>
+ </ButtonIcon>
+ </DeleteButton>
+ </form>
+ <div
+ className="note big-spacer-top width-50"
+ >
+ onboarding.token.text
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <Button
+ className="js-continue"
+ onClick={[Function]}
+ >
+ <button
+ className="button js-continue"
+ onClick={[Function]}
+ type="button"
+ >
+ continue
+ </button>
+ </Button>
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
+
+exports[`revokes token 2`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="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"
+ >
+ onboarding.token.text
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <Button
+ className="js-continue"
+ onClick={[Function]}
+ >
+ <button
+ className="button js-continue"
+ onClick={[Function]}
+ type="button"
+ >
+ continue
+ </button>
+ </Button>
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
+
+exports[`revokes token 3`] = `
+<TokenStep
+ currentUser={
+ Object {
+ "login": "user",
+ }
+ }
+ finished={false}
+ onContinue={[MockFunction]}
+ onOpen={[MockFunction]}
+ open={true}
+ stepNumber={1}
+>
+ <Step
+ finished={false}
+ onOpen={[MockFunction]}
+ open={true}
+ renderForm={[Function]}
+ renderResult={[Function]}
+ stepNumber={1}
+ stepTitle="onboarding.token.header"
+ >
+ <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="boxed-group-inner"
+ >
+ <div>
+ <div>
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right is-checked"
+ />
+ onboarding.token.generate_token
+ </a>
+ <div
+ className="big-spacer-top"
+ >
+ <form
+ onSubmit={[Function]}
+ >
+ <input
+ autoFocus={true}
+ className="input-large spacer-right text-middle"
+ onChange={[Function]}
+ placeholder="onboarding.token.generate_token.placeholder"
+ required={true}
+ type="text"
+ value=""
+ />
+ <SubmitButton
+ className="text-middle"
+ disabled={true}
+ >
+ <Button
+ className="text-middle"
+ disabled={true}
+ preventDefault={false}
+ type="submit"
+ >
+ <button
+ className="button text-middle"
+ disabled={true}
+ onClick={[Function]}
+ type="submit"
+ >
+ onboarding.token.generate
+ </button>
+ </Button>
+ </SubmitButton>
+ </form>
+ </div>
+ </div>
+ <div
+ className="big-spacer-top"
+ >
+ <a
+ className="js-new link-base-color link-no-underline"
+ href="#"
+ onClick={[Function]}
+ >
+ <i
+ className="icon-radio spacer-right"
+ />
+ onboarding.token.use_existing_token
+ </a>
+ </div>
+ </div>
+ <div
+ className="note big-spacer-top width-50"
+ >
+ onboarding.token.text
+ </div>
+ </div>
+ </div>
+ </Step>
+</TokenStep>
+`;
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 '../../../../helpers/l10n';
+import { getBaseUrl } from '../../../../helpers/urls';
+
+interface Props {
+ className?: string;
+ os: string;
+}
+
+const filenames: { [key: string]: string } = {
+ win: 'build-wrapper-win-x86.zip',
+ linux: 'build-wrapper-linux-x86.zip',
+ mac: 'build-wrapper-macosx-x86.zip'
+};
+
+export default function BuildWrapper(props: Props) {
+ return (
+ <div className={props.className}>
+ <h4 className="spacer-bottom">
+ {translate('onboarding.analysis.build_wrapper.header', props.os)}
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ dangerouslySetInnerHTML={{
+ __html: translate('onboarding.analysis.build_wrapper.text', props.os)
+ }}
+ />
+ <p>
+ <a
+ className="button"
+ download={filenames[props.os]}
+ href={`${getBaseUrl()}/static/cpp/${filenames[props.os]}`}
+ target="_blank">
+ {translate('download_verb')}
+ </a>
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 SQScanner from './SQScanner';
+import BuildWrapper from './BuildWrapper';
+import CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ os: string;
+ organization?: string;
+ projectKey: string;
+ token: string;
+}
+
+const executables: { [key: string]: string } = {
+ linux: 'build-wrapper-linux-x86-64',
+ win: 'build-wrapper-win-x86-64.exe',
+ mac: 'build-wrapper-macosx-x86'
+};
+
+export default function ClangGCC(props: Props) {
+ const command1 = `${executables[props.os]} --out-dir bw-output make clean all`;
+
+ const command2 = [
+ props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
+ `-Dsonar.projectKey=${props.projectKey}`,
+ props.organization && `-Dsonar.organization=${props.organization}`,
+ '-Dsonar.sources=.',
+ '-Dsonar.cfamily.build-wrapper-output=bw-output',
+ `-Dsonar.host.url=${props.host}`,
+ `-Dsonar.login=${props.token}`
+ ];
+
+ return (
+ <div>
+ <SQScanner os={props.os} />
+ <BuildWrapper className="huge-spacer-top" 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"
+ dangerouslySetInnerHTML={{ __html: transformedMessage }}
+ />
+ )}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={true} snippet={command1} />
+ <CodeSnippet isOneLine={props.os === 'win'} snippet={command2} />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 MSBuildScanner from './MSBuildScanner';
+import CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ organization?: string;
+ projectKey: string;
+ token: string;
+}
+
+export default function DotNet(props: Props) {
+ const command1 = [
+ 'SonarQube.Scanner.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 = ['SonarQube.Scanner.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"
+ dangerouslySetInnerHTML={{ __html: transformedMessage }}
+ />
+ )}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={true} snippet={command1} />
+ <CodeSnippet isOneLine={true} snippet={command2} />
+ <CodeSnippet isOneLine={true} snippet={command3} />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ organization?: string;
+ token: string;
+}
+
+export default function JavaGradle(props: Props) {
+ const config = 'plugins {\n id "org.sonarqube" version "2.6"\n}';
+
+ const command = [
+ './gradlew sonarqube',
+ 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"
+ dangerouslySetInnerHTML={{ __html: transformedMessage }}
+ />
+ )}
+ </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"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.docs') }}
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{
+ __html: translate('onboarding.analysis.browse_url_after_analysis')
+ }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ organization?: string;
+ token: string;
+}
+
+export default function JavaMaven(props: Props) {
+ const command = [
+ 'mvn sonar:sonar',
+ 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"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.maven.docs') }}
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{
+ __html: translate('onboarding.analysis.browse_url_after_analysis')
+ }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 '../../../../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"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.text') }}
+ />
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('download_verb')}
+ </a>
+ </p>
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 MSBuildScanner from './MSBuildScanner';
+import BuildWrapper from './BuildWrapper';
+import CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ organization?: string;
+ projectKey: string;
+ token: string;
+}
+
+export default function Msvc(props: Props) {
+ const command1 = [
+ 'SonarQube.Scanner.MSBuild.exe begin',
+ `/k:"${props.projectKey}"`,
+ props.organization && `/d:sonar.organization="${props.organization}"`,
+ '/d:sonar.cfamily.build-wrapper-output=bw-output',
+ `/d:sonar.host.url="${props.host}"`,
+ `/d:sonar.login="${props.token}"`
+ ];
+
+ const command2 = 'build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild';
+
+ const command3 = ['SonarQube.Scanner.MSBuild.exe end', `/d:sonar.login="${props.token}"`];
+
+ return (
+ <div>
+ <MSBuildScanner />
+ <BuildWrapper className="huge-spacer-top" os="win" />
+
+ <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"
+ dangerouslySetInnerHTML={{ __html: transformedMessage }}
+ />
+ )}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={true} snippet={command1} />
+ <CodeSnippet isOneLine={true} snippet={command2} />
+ <CodeSnippet isOneLine={true} snippet={command3} />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.msbuild.docs') }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 SQScanner from './SQScanner';
+import CodeSnippet from '../../../../components/common/CodeSnippet';
+import InstanceMessage from '../../../../components/common/InstanceMessage';
+import { translate } from '../../../../helpers/l10n';
+
+interface Props {
+ host: string;
+ organization?: string;
+ os: string;
+ projectKey: string;
+ token: string;
+}
+
+export default function Other(props: Props) {
+ const command = [
+ props.os === 'win' ? 'sonar-scanner.bat' : 'sonar-scanner',
+ `-Dsonar.projectKey=${props.projectKey}`,
+ props.organization && `-Dsonar.organization=${props.organization}`,
+ '-Dsonar.sources=.',
+ `-Dsonar.host.url=${props.host}`,
+ `-Dsonar.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"
+ dangerouslySetInnerHTML={{ __html: transformedMessage }}
+ />
+ )}
+ </InstanceMessage>
+ <CodeSnippet isOneLine={props.os === 'win'} snippet={command} />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.sq_scanner.docs') }}
+ />
+ </div>
+ );
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 '../../../../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"
+ dangerouslySetInnerHTML={{
+ __html: translate('onboarding.analysis.sq_scanner.text', props.os)
+ }}
+ />
+ <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-2018 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 { shallow } from 'enzyme';
+import BuildWrapper from '../BuildWrapper';
+
+it('renders correctly', () => {
+ expect(shallow(<BuildWrapper os="win" />)).toMatchSnapshot();
+ expect(shallow(<BuildWrapper os="linux" />)).toMatchSnapshot();
+ expect(shallow(<BuildWrapper os="mac" />)).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import ClangGCC from '../ClangGCC';
+
+it('renders correctly', () => {
+ expect(
+ shallow(<ClangGCC host="host" os="win" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+
+ expect(
+ shallow(<ClangGCC host="host" os="linux" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+
+ expect(
+ shallow(
+ <ClangGCC
+ host="host"
+ organization="organization"
+ os="linux"
+ projectKey="projectKey"
+ token="token"
+ />
+ )
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import DotNet from '../DotNet';
+
+it('renders correctly', () => {
+ expect(shallow(<DotNet host="host" projectKey="projectKey" token="token" />)).toMatchSnapshot();
+ expect(
+ shallow(
+ <DotNet host="host" organization="organization" projectKey="projectKey" token="token" />
+ )
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+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();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+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();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import MSBuildScanner from '../MSBuildScanner';
+
+it('renders correctly', () => {
+ expect(shallow(<MSBuildScanner />)).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import Msvc from '../Msvc';
+
+it('renders correctly', () => {
+ expect(shallow(<Msvc host="host" projectKey="projectKey" token="token" />)).toMatchSnapshot();
+ expect(
+ shallow(<Msvc host="host" organization="organization" projectKey="projectKey" token="token" />)
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+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"
+ organization="organization"
+ os="linux"
+ projectKey="projectKey"
+ token="token"
+ />
+ )
+ ).toMatchSnapshot();
+});
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+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[`renders correctly 1`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.build_wrapper.header.win
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.build_wrapper.text.win",
+ }
+ }
+ />
+ <p>
+ <a
+ className="button"
+ download="build-wrapper-win-x86.zip"
+ href="/static/cpp/build-wrapper-win-x86.zip"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.build_wrapper.header.linux
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.build_wrapper.text.linux",
+ }
+ }
+ />
+ <p>
+ <a
+ className="button"
+ download="build-wrapper-linux-x86.zip"
+ href="/static/cpp/build-wrapper-linux-x86.zip"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
+
+exports[`renders correctly 3`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.build_wrapper.header.mac
+ </h4>
+ <p
+ className="spacer-bottom markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.build_wrapper.text.mac",
+ }
+ }
+ />
+ <p>
+ <a
+ className="button"
+ download="build-wrapper-macosx-x86.zip"
+ href="/static/cpp/build-wrapper-macosx-x86.zip"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <SQScanner
+ os="win"
+ />
+ <BuildWrapper
+ className="huge-spacer-top"
+ os="win"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="build-wrapper-win-x86-64.exe --out-dir bw-output make clean all"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "sonar-scanner.bat",
+ "-Dsonar.projectKey=projectKey",
+ undefined,
+ "-Dsonar.sources=.",
+ "-Dsonar.cfamily.build-wrapper-output=bw-output",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <SQScanner
+ os="linux"
+ />
+ <BuildWrapper
+ className="huge-spacer-top"
+ os="linux"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="build-wrapper-linux-x86-64 --out-dir bw-output make clean all"
+ />
+ <CodeSnippet
+ isOneLine={false}
+ snippet={
+ Array [
+ "sonar-scanner",
+ "-Dsonar.projectKey=projectKey",
+ undefined,
+ "-Dsonar.sources=.",
+ "-Dsonar.cfamily.build-wrapper-output=bw-output",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`renders correctly 3`] = `
+<div>
+ <SQScanner
+ os="linux"
+ />
+ <BuildWrapper
+ className="huge-spacer-top"
+ os="linux"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.sq_scanner.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.sq_scanner.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="build-wrapper-linux-x86-64 --out-dir bw-output make clean all"
+ />
+ <CodeSnippet
+ isOneLine={false}
+ snippet={
+ Array [
+ "sonar-scanner",
+ "-Dsonar.projectKey=projectKey",
+ "-Dsonar.organization=organization",
+ "-Dsonar.sources=.",
+ "-Dsonar.cfamily.build-wrapper-output=bw-output",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <MSBuildScanner />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.msbuild.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.msbuild.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe begin",
+ "/k:\\"projectKey\\"",
+ undefined,
+ "/d:sonar.host.url=\\"host\\"",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="MsBuild.exe /t:Rebuild"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe end",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.msbuild.docs",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <MSBuildScanner />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.msbuild.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.msbuild.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe begin",
+ "/k:\\"projectKey\\"",
+ "/d:sonar.organization=\\"organization\\"",
+ "/d:sonar.host.url=\\"host\\"",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="MsBuild.exe /t:Rebuild"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe end",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.msbuild.docs",
+ }
+ }
+ />
+</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"
+ />
+ <CodeSnippet
+ snippet="plugins {
+ id \\"org.sonarqube\\" version \\"2.6\\"
+}"
+ />
+ <p
+ className="spacer-top spacer-bottom markdown"
+ >
+ onboarding.analysis.java.gradle.text.2
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "./gradlew sonarqube",
+ undefined,
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.java.gradle.docs",
+ }
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.browse_url_after_analysis",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <h4
+ className="spacer-bottom"
+ >
+ onboarding.analysis.java.gradle.header
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.java.gradle.text.1"
+ />
+ <CodeSnippet
+ snippet="plugins {
+ id \\"org.sonarqube\\" version \\"2.6\\"
+}"
+ />
+ <p
+ className="spacer-top spacer-bottom markdown"
+ >
+ onboarding.analysis.java.gradle.text.2
+ </p>
+ <CodeSnippet
+ snippet={
+ Array [
+ "./gradlew sonarqube",
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.java.gradle.docs",
+ }
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.browse_url_after_analysis",
+ }
+ }
+ />
+</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,
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.java.maven.docs",
+ }
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.browse_url_after_analysis",
+ }
+ }
+ />
+</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",
+ "-Dsonar.organization=organization",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.java.maven.docs",
+ }
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.browse_url_after_analysis",
+ }
+ }
+ />
+</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"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.msbuild.text",
+ }
+ }
+ />
+ <p>
+ <a
+ className="button"
+ href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ download_verb
+ </a>
+ </p>
+</div>
+`;
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<div>
+ <MSBuildScanner />
+ <BuildWrapper
+ className="huge-spacer-top"
+ os="win"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.msbuild.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.msbuild.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe begin",
+ "/k:\\"projectKey\\"",
+ undefined,
+ "/d:sonar.cfamily.build-wrapper-output=bw-output",
+ "/d:sonar.host.url=\\"host\\"",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe end",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.msbuild.docs",
+ }
+ }
+ />
+</div>
+`;
+
+exports[`renders correctly 2`] = `
+<div>
+ <MSBuildScanner />
+ <BuildWrapper
+ className="huge-spacer-top"
+ os="win"
+ />
+ <h4
+ className="huge-spacer-top spacer-bottom"
+ >
+ onboarding.analysis.msbuild.execute
+ </h4>
+ <InstanceMessage
+ message="onboarding.analysis.msbuild.execute.text"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe begin",
+ "/k:\\"projectKey\\"",
+ "/d:sonar.organization=\\"organization\\"",
+ "/d:sonar.cfamily.build-wrapper-output=bw-output",
+ "/d:sonar.host.url=\\"host\\"",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet="build-wrapper-win-x86-64.exe --out-dir bw-output MsBuild.exe /t:Rebuild"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "SonarQube.Scanner.MSBuild.exe end",
+ "/d:sonar.login=\\"token\\"",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.msbuild.docs",
+ }
+ }
+ />
+</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"
+ />
+ <CodeSnippet
+ isOneLine={true}
+ snippet={
+ Array [
+ "sonar-scanner.bat",
+ "-Dsonar.projectKey=projectKey",
+ undefined,
+ "-Dsonar.sources=.",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</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"
+ />
+ <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"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</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"
+ />
+ <CodeSnippet
+ isOneLine={false}
+ snippet={
+ Array [
+ "sonar-scanner",
+ "-Dsonar.projectKey=projectKey",
+ "-Dsonar.organization=organization",
+ "-Dsonar.sources=.",
+ "-Dsonar.host.url=host",
+ "-Dsonar.login=token",
+ ]
+ }
+ />
+ <p
+ className="big-spacer-top markdown"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.docs",
+ }
+ }
+ />
+</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"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.text.win",
+ }
+ }
+ />
+ <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"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.text.linux",
+ }
+ }
+ />
+ <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"
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "onboarding.analysis.sq_scanner.text.mac",
+ }
+ }
+ />
+ <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-2018 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-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;
+}
+
+.onboarding-choices {
+ display: flex;
+ justify-content: space-around;
+ padding: 24px 0 44px;
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 Modal from '../../../components/controls/Modal';
+import { translate } from '../../../helpers/l10n';
+import { ResetButtonLink } from '../../../components/ui/buttons';
+
+interface Props {
+ onFinish: () => void;
+}
+
+export default class TeamOnboardingModal extends React.PureComponent<Props> {
+ render() {
+ const header = translate('onboarding.team.header');
+ return (
+ <Modal
+ contentLabel={header}
+ medium={true}
+ onRequestClose={this.props.onFinish}
+ shouldCloseOnOverlayClick={false}>
+ <header className="modal-head">
+ <h2>{header}</h2>
+ </header>
+ <div className="modal-body">
+ <div className="alert alert-info modal-alert">
+ {translate('onboarding.team.work_in_progress')}
+ </div>
+ <p className="spacer-top big-spacer-bottom">{translate('onboarding.team.first_step')}</p>
+ <p className="spacer-top big-spacer-bottom">
+ <FormattedMessage
+ defaultMessage={translate('onboarding.team.how_to_join')}
+ id="onboarding.team.how_to_join"
+ values={{
+ link: (
+ <Link onClick={this.props.onFinish} to="/documentation/organizations/manage-team">
+ {translate('as_explained_here')}
+ </Link>
+ )
+ }}
+ />
+ </p>
+ </div>
+ <footer className="modal-foot">
+ <ResetButtonLink onClick={this.props.onFinish}>{translate('close')}</ResetButtonLink>
+ </footer>
+ </Modal>
+ );
+ }
+}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 { shallow } from 'enzyme';
+import TeamOnboardingModal from '../TeamOnboardingModal';
+
+it('renders correctly', () => {
+ expect(shallow(<TeamOnboardingModal onFinish={jest.fn()} />)).toMatchSnapshot();
+});
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+<Modal
+ contentLabel="onboarding.team.header"
+ medium={true}
+ onRequestClose={[MockFunction]}
+ shouldCloseOnOverlayClick={false}
+>
+ <header
+ className="modal-head"
+ >
+ <h2>
+ onboarding.team.header
+ </h2>
+ </header>
+ <div
+ className="modal-body"
+ >
+ <div
+ className="alert alert-info modal-alert"
+ >
+ onboarding.team.work_in_progress
+ </div>
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ onboarding.team.first_step
+ </p>
+ <p
+ className="spacer-top big-spacer-bottom"
+ >
+ <FormattedMessage
+ defaultMessage="onboarding.team.how_to_join"
+ id="onboarding.team.how_to_join"
+ values={
+ Object {
+ "link": <Link
+ onClick={[MockFunction]}
+ onlyActiveOnIndex={false}
+ style={Object {}}
+ to="/documentation/organizations/manage-team"
+ >
+ as_explained_here
+ </Link>,
+ }
+ }
+ />
+ </p>
+ </div>
+ <footer
+ className="modal-foot"
+ >
+ <ResetButtonLink
+ onClick={[MockFunction]}
+ >
+ close
+ </ResetButtonLink>
+ </footer>
+</Modal>
+`;
window.dispatchEvent(dispatchedEvent);
}
-export function submit(element: ShallowWrapper): void {
+export function submit(element: ShallowWrapper | ReactWrapper): void {
element.simulate('submit', {
preventDefault() {}
});
}
-export function change(element: ShallowWrapper, value: string, event = {}): void {
+export function change(element: ShallowWrapper | ReactWrapper, value: string, event = {}): void {
element.simulate('change', {
target: { value },
currentTarget: { value },
and_worse=and worse
are_you_sure=Are you sure?
+as_explained_here=as explained here
assigned_to=Assigned to
bulk_change=Bulk Change
bulleted_point=Bulleted point
tutorials.onboarding=Analyze a new project
tutorials.skip=Skip this tutorial
tutorials.finish=Finish this tutorial
-tutorials.find_it_back_in_help=Find it back anytime in the Help section
-tutorials.find_it_back_in_plus=Find it back anytime in the "+" menu
+tutorials.find_tutorial_back_in_help=Find this tutorial back anytime in the Help section
+tutorials.find_tutorial_back_in_plus=Find this tutorial back anytime in the "+" menu
#------------------------------------------------------------------------------
# ONBOARDING
#
#------------------------------------------------------------------------------
-onboarding.header=Welcome to {instance}!
-onboarding.header.description=Want to quickly analyze a first project? Follow these {0} easy steps.
+onboarding.header=Welcome to SonarCloud!
+onboarding.header.description=Let us help you get started. What do you want to do?
+
+onboarding.project.header=Analyze a project
+onboarding.project.header.description=Want to quickly analyze a first project? Follow these {0} easy steps.
+
+onboarding.team.header=Join a team
+onboarding.team.first_step=Well congrats, the first step is done!
+onboarding.team.how_to_join=To join a team, the only thing you need to do is to be a user registered on Sonarcloud. The administrator of the Sonarcloud organization you wish to join has to add you to his organization's members {link}. Ask him to do so!
+onboarding.team.work_in_progress=We are currently working on a better way to join a team or invite people to yours.
+
+onboarding.analyze_public_code=I want to analyze public code
+onboarding.analyze_public_code.button=Analyze a project
+onboarding.analyze_private_code=I want to analyze private code
+onboarding.analyze_private_code.button=Setup a new organization
+onboarding.contribute_existing_project=I want to contribute to an existing project
+onboarding.contribute_existing_project.button=Join a team
onboarding.token.header=Provide a token
onboarding.token.text=The token is used to identify you when an analysis is performed. If it has been compromised, you can revoke it at any point of time in your user account.
onboarding.token.generate=Generate
onboarding.token.placeholder=Enter a name for your token
-onboading.token.generate_token=Generate a token
-onboading.token.generate_token.placeholder=Enter a name for your token
+onboarding.token.generate_token=Generate a token
+onboarding.token.generate_token.placeholder=Enter a name for your token
onboarding.token.use_existing_token=Use existing token
onboarding.token.use_existing_token.placeholder=Enter your existing token
onboarding.token.invalid_format=The token you have entered has invalid format.