From: Grégoire Aubert Date: Fri, 15 Jun 2018 13:04:21 +0000 (+0200) Subject: SONARCLOUD-64 New onboarding with 3 cases for SonarCloud (#383) X-Git-Tag: 7.5~954 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=4e91bd432aeef4a2e7ff680910907e62007ac801;p=sonarqube.git SONARCLOUD-64 New onboarding with 3 cases for SonarCloud (#383) * SONARCLOUD-64 Move Onboarding to ProjectOnboarding * SONARCLOUD-64 Migrate project onboarding to TS * SONARCLOUD-64 Update ProjectOnboarding style * SONARCLOUD-64 Add main onboarding page --- diff --git a/server/sonar-web/src/main/js/app/components/StartupModal.tsx b/server/sonar-web/src/main/js/app/components/StartupModal.tsx index 101279628d1..914adc7b3ea 100644 --- a/server/sonar-web/src/main/js/app/components/StartupModal.tsx +++ b/server/sonar-web/src/main/js/app/components/StartupModal.tsx @@ -20,16 +20,21 @@ 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; @@ -38,7 +43,7 @@ interface StateProps { } interface DispatchProps { - skipOnboarding: () => void; + skipOnboardingAction: () => void; } interface OwnProps { @@ -50,7 +55,10 @@ type Props = StateProps & DispatchProps & OwnProps; enum ModalKey { license, - onboarding + onboarding, + organizationOnboarding, + projectOnboarding, + teamOnboarding } interface State { @@ -61,14 +69,18 @@ interface State { const LICENSE_PROMPT = 'sonarqube.license.prompt'; export class StartupModal extends React.PureComponent { + 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() { @@ -77,8 +89,9 @@ export class StartupModal extends React.PureComponent { 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; @@ -94,10 +107,27 @@ export class StartupModal extends React.PureComponent { }); }; + closeOrganizationOnboarding = ({ key }: Pick) => { + 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'); @@ -124,7 +154,11 @@ export class StartupModal extends React.PureComponent { 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(); + } } }; @@ -135,7 +169,24 @@ export class StartupModal extends React.PureComponent { {this.props.children} {modal === ModalKey.license && } {modal === ModalKey.onboarding && ( - + + )} + {modal === ModalKey.projectOnboarding && ( + + )} + {modal === ModalKey.organizationOnboarding && ( + + )} + {modal === ModalKey.teamOnboarding && ( + )} ); @@ -148,7 +199,7 @@ const mapStateToProps = (state: any): StateProps => ({ currentUser: getCurrentUser(state) }); -const mapDispatchToProps: DispatchProps = { skipOnboarding }; +const mapDispatchToProps: DispatchProps = { skipOnboardingAction }; export default connect(mapStateToProps, mapDispatchToProps)( StartupModal diff --git a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx index d2d48ee7d51..7a1e2bf2d3d 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx +++ b/server/sonar-web/src/main/js/app/components/__tests__/StartupModal-test.tsx @@ -119,12 +119,12 @@ it('should render onboarding modal', async () => { 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) { @@ -139,9 +139,10 @@ function getWrapper(props = {}) { currentEdition={EditionKey.enterprise} currentUser={LOGGED_IN_USER} location={{ pathname: 'foo/bar' }} - skipOnboarding={jest.fn()} + skipOnboardingAction={jest.fn()} {...props}>
- + , + { context: { router: { push: jest.fn() } } } ); } diff --git a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx index 061a3af556b..5cb06388326 100644 --- a/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx +++ b/server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx @@ -36,13 +36,13 @@ interface Props { export default class EmbedDocsPopup extends React.PureComponent { static contextTypes = { - openOnboardingTutorial: PropTypes.func + openProjectOnboarding: PropTypes.func }; onAnalyzeProjectClick = (event: React.SyntheticEvent) => { event.preventDefault(); event.currentTarget.blur(); - this.context.openOnboardingTutorial(); + this.context.openProjectOnboarding(); }; renderTitle(text: string) { diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx index 6d3cdcece68..0f596735299 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx @@ -50,7 +50,7 @@ interface OwnProps { type Props = StateProps & OwnProps; class GlobalNav extends React.PureComponent { - static contextTypes = { openOnboardingTutorial: PropTypes.func }; + static contextTypes = { openProjectOnboarding: PropTypes.func }; render() { return ( @@ -69,7 +69,7 @@ class GlobalNav extends React.PureComponent { {isLoggedIn(this.props.currentUser) && isSonarCloud() && ( - + )} diff --git a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx index d58fb2379ac..412846db466 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/GlobalNavPlus.tsx @@ -25,7 +25,7 @@ import Dropdown from '../../../../components/controls/Dropdown'; import { translate } from '../../../../helpers/l10n'; interface Props { - openOnboardingTutorial: () => void; + openProjectOnboarding: () => void; } interface State { @@ -44,7 +44,7 @@ export default class GlobalNavPlus extends React.PureComponent { handleNewProjectClick = (event: React.SyntheticEvent) => { event.preventDefault(); - this.props.openOnboardingTutorial(); + this.props.openProjectOnboarding(); }; openCreateOrganizationForm = () => this.setState({ createOrganization: true }); diff --git a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx index 3e4110f5193..88aaf4f172d 100644 --- a/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/global/__tests__/GlobalNavPlus-test.tsx @@ -23,18 +23,18 @@ import GlobalNavPlus from '../GlobalNavPlus'; import { click } from '../../../../../helpers/testUtils'; it('render', () => { - const wrapper = shallow(); + const wrapper = shallow(); 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() + shallow() .find('Dropdown') .prop('overlay') ); click(wrapper.find('.js-new-project')); - expect(openOnboardingTutorial).toBeCalled(); + expect(openProjectOnboarding).toBeCalled(); }); diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.js b/server/sonar-web/src/main/js/app/utils/startReactApp.js index b4b79feec06..e092a6c13eb 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.js +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.js @@ -172,7 +172,7 @@ const startReactApp = () => { - import('../../apps/tutorials/onboarding/OnboardingPage') + import('../../apps/tutorials/projectOnboarding/ProjectOnboardingPage') )} /> diff --git a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx index 6c52d002bb1..4cd7b7d2164 100644 --- a/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx +++ b/server/sonar-web/src/main/js/apps/projects/components/NoFavoriteProjects.tsx @@ -36,13 +36,13 @@ interface StateProps { export class NoFavoriteProjects extends React.PureComponent { static contextTypes = { - openOnboardingTutorial: PropTypes.func + openProjectOnboarding: PropTypes.func }; onAnalyzeProjectClick = (event: React.SyntheticEvent) => { event.preventDefault(); event.currentTarget.blur(); - this.context.openOnboardingTutorial(); + this.context.openProjectOnboarding(); }; render() { diff --git a/server/sonar-web/src/main/js/apps/tutorials/Onboarding.tsx b/server/sonar-web/src/main/js/apps/tutorials/Onboarding.tsx new file mode 100644 index 00000000000..e6a6d887bd3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/Onboarding.tsx @@ -0,0 +1,102 @@ +/* + * 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 { + componentDidMount() { + if (!isLoggedIn(this.props.currentUser)) { + handleRequiredAuthentication(); + } + } + + render() { + if (!isLoggedIn(this.props.currentUser)) { + return null; + } + + const header = translate('onboarding.header'); + return ( + +
+

{header}

+
+
+

+ {translate('onboarding.header.description')} +

+
    +
  • +

    {translate('onboarding.analyze_public_code')}

    + +
  • +
  • +

    {translate('onboarding.analyze_private_code')}

    + +
  • +
  • +

    + {translate('onboarding.contribute_existing_project')} +

    + +
  • +
+
+
+ {translate('close')} +
+
+ ); + } +} + +const mapStateToProps = (state: any): StateProps => ({ currentUser: getCurrentUser(state) }); + +export default connect(mapStateToProps)(Onboarding); diff --git a/server/sonar-web/src/main/js/apps/tutorials/__tests__/Onboarding-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/__tests__/Onboarding-test.tsx new file mode 100644 index 00000000000..c9b3e77500e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/__tests__/Onboarding-test.tsx @@ -0,0 +1,61 @@ +/* + * 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( + + ) + ).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( + + ); + + click(wrapper.find('ResetButtonLink')); + expect(onFinish).toHaveBeenCalled(); + + wrapper.find('Button').forEach(button => click(button)); + expect(onOpenOrganizationOnboarding).toHaveBeenCalled(); + expect(onOpenProjectOnboarding).toHaveBeenCalled(); + expect(onOpenTeamOnboarding).toHaveBeenCalled(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/__tests__/__snapshots__/Onboarding-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/__tests__/__snapshots__/Onboarding-test.tsx.snap new file mode 100644 index 00000000000..e017f778601 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/__tests__/__snapshots__/Onboarding-test.tsx.snap @@ -0,0 +1,82 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` + +
+

+ onboarding.header +

+
+
+

+ onboarding.header.description +

+
    +
  • +

    + onboarding.analyze_public_code +

    + +
  • +
  • +

    + onboarding.analyze_private_code +

    + +
  • +
  • +

    + onboarding.contribute_existing_project +

    + +
  • +
+
+
+ + close + +
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/AnalysisStep.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/AnalysisStep.js deleted file mode 100644 index afaa359bfb7..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/AnalysisStep.js +++ /dev/null @@ -1,190 +0,0 @@ -/* - * 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 ( -
-
-
- -
-
{this.renderCommand()}
-
-
- ); - }; - - renderFormattedCommand = (...lines /*: Array */) => ( - // keep this "useless" concatentation for the readability reason - // eslint-disable-next-line no-useless-concat -
{lines.join(' ' + '\\' + '\n' + '  ')}
- ); - - 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 = () => ( - - ); - - renderCommandForGradle = () => ( - - ); - - renderCommandForDotNet = () => { - return ( - - ); - }; - - renderCommandForMSVC = () => { - return ( - - ); - }; - - renderCommandForClangGCC = () => ( - - ); - - renderCommandForOther = () => ( - - ); - - renderResult = () => null; - - render() { - return ( - {}} - open={this.props.open} - renderForm={this.renderForm} - renderResult={this.renderResult} - stepNumber={this.props.stepNumber} - stepTitle={translate('onboarding.analysis.header')} - /> - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/LanguageStep.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/LanguageStep.js deleted file mode 100644 index c9bd1c15e5a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/LanguageStep.js +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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 = () => ( -
-

{translate('onboarding.language.java.build_technology')}

- ({ - label: translate('onboarding.language.java.build_technology', build), - value: build - }))} - value={this.state.javaBuild} - /> -
- ); - - renderCFamilyCompiler = () => ( -
-

{translate('onboarding.language.c-family.compiler')}

- ({ - label: translate('onboarding.language.c-family.compiler', compiler), - value: compiler - }))} - value={this.state.cFamilyCompiler} - /> -
- ); - - renderOS = () => ( -
-

{translate('onboarding.language.os')}

- ({ - label: translate('onboarding.language.os', os), - value: os - }))} - value={this.state.os} - /> -
- ); - - renderProjectKey = () => ( - - ); - - 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 ( -
-
-

{translate('onboarding.language')}

- ({ - label: translate('onboarding.language', language), - value: language - }))} - value={this.state.language} - /> -
- {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()} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewOrganizationForm.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewOrganizationForm.js deleted file mode 100644 index 11be750a41b..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewOrganizationForm.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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 ? ( -
- {organization} - {loading ? ( - - ) : ( - - )} -
- ) : ( -
- - {loading ? ( - - ) : ( - - {translate('create')} - - )} - {!unique && ( - - - {translate('this_name_is_already_taken')} - - )} -
- {translate('onboarding.organization.key_requirement')} -
- - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewProjectForm.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewProjectForm.js deleted file mode 100644 index cde4629a0a8..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/NewProjectForm.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 ? ( -
- {projectKey} - {loading ? ( - - ) : ( - - )} -
- ) : ( -
- - {loading ? ( - - ) : ( - - {translate('Done')} - - )} -
- {translate('onboarding.project_key_requirement')} -
- - ); - - return ( -
-

{translate('onboarding.language.project_key')}

- {form} -
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js deleted file mode 100644 index afcf049e397..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js +++ /dev/null @@ -1,236 +0,0 @@ -/* - * 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 ( -
- - {transformedMessage => } - - -
-
-

- -

-
- - - {automatic ? translate('tutorials.skip') : translate('close')} - - - -

- {translate( - isSonarCloud() - ? 'tutorials.find_it_back_in_plus' - : 'tutorials.find_it_back_in_help' - )} -

-
-
- {translateWithParameters( - 'onboarding.header.description', - organizationsEnabled ? 3 : 2 - )} -
-
- - {organizationsEnabled && ( - - )} - - - - - - {this.state.finished && - !this.state.skipping && - (this.state.projectKey ? ( - - ) : ( - - ))} -
-
- ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js deleted file mode 100644 index cf27d5dd333..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingContainer.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.d.ts b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.d.ts deleted file mode 100644 index 4b70adcc600..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.d.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 {} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx deleted file mode 100644 index 188e5cc7927..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingModal.tsx +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 ( - - - - ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx deleted file mode 100644 index 971ae8bddff..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OnboardingPage.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 { - static contextTypes = { - router: PropTypes.object.isRequired - }; - - onSkipOnboardingTutorial = () => { - this.props.skipOnboarding(); - this.context.router.replace('/'); - }; - - render() { - return ; - } -} - -const mapDispatchToProps: DispatchProps = { skipOnboarding }; - -export default connect<{}, DispatchProps, {}>(null, mapDispatchToProps)(OnboardingPage); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OrganizationStep.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/OrganizationStep.js deleted file mode 100644 index e55c34a341a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/OrganizationStep.js +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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, - 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 = () => ( - - ); - - renderExistingOrganizationOption = () => ( -
- - - {translate('onboarding.organization.exising_organization')} - - {this.state.selection === 'existing' && ( -
- - {this.state.loading ? ( - - ) : ( - - {translate('onboarding.token.generate')} - - )} - -
- )} -
- ); - - renderUseExistingOption = () => { - const { existingToken } = this.state; - const validInput = !existingToken || existingToken.match(/^[a-z0-9]+$/) != null; - - return ( -
- - - {translate('onboarding.token.use_existing_token')} - - {this.state.selection === 'use-existing' && ( -
- - {!validInput && ( - - - {translate('onboarding.token.invalid_format')} - - )} -
- )} -
- ); - }; - - renderForm = () => { - const { canUseExisting, loading, token, tokenName } = this.state; - - return ( -
- {token != null ? ( -
- - {tokenName} - {': '} - - {token} - {loading ? ( - - ) : ( - - )} - - ) : ( -
- {this.renderGenerateOption()} - {canUseExisting && this.renderUseExistingOption()} -
- )} - -
{translate('onboarding.token.text')}
- - {this.canContinue() && ( -
- -
- )} -
- ); - }; - - renderResult = () => { - const { selection, tokenName } = this.state; - const token = this.getToken(); - - if (!token) { - return null; - } - - return ( -
- - {selection === 'generate' && tokenName && `${tokenName}: `} - {token} -
- ); - }; - - render() { - return ( - - ); - } -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/LanguageStep-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/LanguageStep-test.js deleted file mode 100644 index 2609b550dd5..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/LanguageStep-test.js +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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(); - - 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(); - - 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(); - - 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(); - - 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' }); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewOrganizationForm-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewOrganizationForm-test.js deleted file mode 100644 index fcfbf8d810c..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewOrganizationForm-test.js +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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(); - 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(); - 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(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewProjectForm-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewProjectForm-test.js deleted file mode 100644 index 2d290f10503..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/NewProjectForm-test.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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(); - 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(); - 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(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js deleted file mode 100644 index e3acb2a83f6..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Onboarding-test.js +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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( - - ); - 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( - - ); - 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( - - ); - click(wrapper.find('.js-skip')); - return doAsync(() => { - expect(onFinish).toBeCalled(); - }); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/OrganizationStep-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/OrganizationStep-test.js deleted file mode 100644 index 01a5b711a2a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/OrganizationStep-test.js +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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( - - ); - click(wrapper.find('.js-continue')); - expect(onContinue).toBeCalledWith('user'); -}); - -it('works with existing organization', async () => { - const onContinue = jest.fn(); - const wrapper = mount( - - ); - 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( - - ); - 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'); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/ProjectWatcher-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/ProjectWatcher-test.js deleted file mode 100644 index cc6699fdefa..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/ProjectWatcher-test.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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( - - ); - 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(); - expect(onFinish).not.toBeCalled(); - jest.runTimersToTime(5000); -}); - -it('timeouts', () => { - const onTimeout = jest.fn(); - mount(); - expect(onTimeout).not.toBeCalled(); - jest.runTimersToTime(10 * 60 * 1000); - expect(onTimeout).toBeCalled(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Step-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Step-test.js deleted file mode 100644 index 396c4fa769a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/Step-test.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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( -
form
} - renderResult={() =>
result
} - 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( -
form
} - renderResult={() =>
result
} - stepNumber={1} - stepTitle="First Step" - /> - ); - click(wrapper); - expect(onOpen).toBeCalled(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/TokenStep-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/TokenStep-test.js deleted file mode 100644 index 4f439b440b5..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/TokenStep-test.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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( - - ); - 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( - - ); - 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( - - ); - 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( - - ); - await new Promise(setImmediate); - wrapper.setState({ existingToken: 'abcd1234', selection: 'use-existing' }); - click(wrapper.find('[className="js-continue"]')); - expect(onContinue).toBeCalledWith('abcd1234'); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/LanguageStep-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/LanguageStep-test.js.snap deleted file mode 100644 index 8e82d384b3f..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/LanguageStep-test.js.snap +++ /dev/null @@ -1,687 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`selects c# 1`] = ` -
-
-

- onboarding.language -

- -
- -
-`; - -exports[`selects c-family 1`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.c-family.compiler -

- -
-
-`; - -exports[`selects c-family 2`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.c-family.compiler -

- -
- -
-`; - -exports[`selects c-family 3`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.c-family.compiler -

- -
-
-

- onboarding.language.os -

- -
-
-`; - -exports[`selects c-family 4`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.c-family.compiler -

- -
-
-

- onboarding.language.os -

- -
- -
-`; - -exports[`selects java 1`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.java.build_technology -

- -
-
-`; - -exports[`selects java 2`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.java.build_technology -

- -
-
-`; - -exports[`selects java 3`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.java.build_technology -

- -
-
-`; - -exports[`selects other 1`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.os -

- -
-
-`; - -exports[`selects other 2`] = ` -
-
-

- onboarding.language -

- -
-
-

- onboarding.language.os -

- -
- -
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewOrganizationForm-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewOrganizationForm-test.js.snap deleted file mode 100644 index eae8fcdb833..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewOrganizationForm-test.js.snap +++ /dev/null @@ -1,270 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`creates new organization 1`] = ` - -
- - - - - -
- onboarding.organization.key_requirement -
-
-
-`; - -exports[`creates new organization 2`] = ` - -
- - -
- onboarding.organization.key_requirement -
- -
-`; - -exports[`creates new organization 3`] = ` - -
- - foo - - - - - - - -
-
-`; - -exports[`deletes organization 1`] = ` - -
- - foo - - - - - - - -
-
-`; - -exports[`deletes organization 2`] = ` - -
- - foo - - -
-
-`; - -exports[`deletes organization 3`] = ` - -
- - - - - -
- onboarding.organization.key_requirement -
-
-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewProjectForm-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewProjectForm-test.js.snap deleted file mode 100644 index f6722a21bf6..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/NewProjectForm-test.js.snap +++ /dev/null @@ -1,321 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`creates new project 1`] = ` - -
-

- onboarding.language.project_key -

-
- - - - - -
- onboarding.project_key_requirement -
-
-
-
-`; - -exports[`creates new project 2`] = ` - -
-

- onboarding.language.project_key -

-
- - -
- onboarding.project_key_requirement -
- -
-
-`; - -exports[`creates new project 3`] = ` - -
-

- onboarding.language.project_key -

-
- - foo - - - - - - - -
-
-
-`; - -exports[`deletes project 1`] = ` - -
-

- onboarding.language.project_key -

-
- - foo - - - - - - - -
-
-
-`; - -exports[`deletes project 2`] = ` - -
-

- onboarding.language.project_key -

-
- - foo - - -
-
-
-`; - -exports[`deletes project 3`] = ` - -
-

- onboarding.language.project_key -

-
- - - - - -
- onboarding.project_key_requirement -
-
-
-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap deleted file mode 100644 index 1635dc70bd5..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap +++ /dev/null @@ -1,388 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`guides for on-premise 1`] = ` -
- -
-
-

- -

-
- - - close - - -

- tutorials.find_it_back_in_help -

-
-
- onboarding.header.description.2 -
-
- - -
-
-`; - -exports[`guides for on-premise 2`] = ` -
- -
-
-

- -

-
- - - close - - -

- tutorials.find_it_back_in_help -

-
-
- onboarding.header.description.2 -
-
- - -
-
-`; - -exports[`guides for sonarcloud 1`] = ` -
- -
-
-

- -

-
- - - close - - -

- tutorials.find_it_back_in_plus -

-
-
- onboarding.header.description.3 -
-
- - - -
-
-`; - -exports[`guides for sonarcloud 2`] = ` -
- -
-
-

- -

-
- - - close - - -

- tutorials.find_it_back_in_plus -

-
-
- onboarding.header.description.3 -
-
- - - -
-
-`; - -exports[`guides for sonarcloud 3`] = ` -
- -
-
-

- -

-
- - - close - - -

- tutorials.find_it_back_in_plus -

-
-
- onboarding.header.description.3 -
-
- - - -
-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap deleted file mode 100644 index 7e30dedc4a9..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap +++ /dev/null @@ -1,381 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`works with existing organization 1`] = ` - - - onboarding.organization.header - - - } - > -
-
- 1 -
-
-

- - onboarding.organization.header - - - -

- } - > -
- - -
- } - > - - -
- } - > - - - - - - - - - - - - - -
- - - - - -
-
- onboarding.organization.text -
-
- -
-
- - -`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/ProjectWatcher-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/ProjectWatcher-test.js.snap deleted file mode 100644 index 4ecd80c2ae3..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/ProjectWatcher-test.js.snap +++ /dev/null @@ -1,42 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders 1`] = ` -
- onboarding.project_watcher.not_started -
-`; - -exports[`renders 2`] = ` -
- - onboarding.project_watcher.in_progress -
-`; - -exports[`renders 3`] = ` -
- - onboarding.project_watcher.finished -
-`; - -exports[`renders 4`] = ` -
- - onboarding.project_watcher.in_progress -
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Step-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Step-test.js.snap deleted file mode 100644 index 4667ca7ae8a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Step-test.js.snap +++ /dev/null @@ -1,51 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders 1`] = ` -
-
- 1 -
-
-

- First Step -

-
-
- form -
-
-`; - -exports[`renders 2`] = ` -
-
- 1 -
-
- result -
-
-

- First Step -

-
-
-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/TokenStep-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/TokenStep-test.js.snap deleted file mode 100644 index 9b991a92305..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/TokenStep-test.js.snap +++ /dev/null @@ -1,649 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`generates token 1`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
-
-
- - - onboading.token.generate_token - -
-
- - - - - -
-
-
- -
-
- onboarding.token.text -
-
-
-
-
-`; - -exports[`generates token 2`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
- -
- onboarding.token.text -
-
-
-
-
-`; - -exports[`generates token 3`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
-
- - my token - : - - - abcd1234 - - - - - - - -
-
- onboarding.token.text -
-
- - -
-
-
-
-
-`; - -exports[`revokes token 1`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
-
- - my token - : - - - abcd1234 - - - - - - - -
-
- onboarding.token.text -
-
- - -
-
-
-
-
-`; - -exports[`revokes token 2`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
-
- - my token - : - - - abcd1234 - - - -
- onboarding.token.text -
-
- - -
-
-
-
-
-`; - -exports[`revokes token 3`] = ` - - -
-
- 1 -
-
-

- onboarding.token.header -

-
-
-
-
- - - onboading.token.generate_token - -
-
- - - - - -
-
-
- -
-
- onboarding.token.text -
-
-
-
-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/BuildWrapper.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/BuildWrapper.js deleted file mode 100644 index 47fe5202388..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/BuildWrapper.js +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 ( -
-

- {translate('onboarding.analysis.build_wrapper.header', props.os)} -

-

-

- - {translate('download_verb')} - -

-
- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/ClangGCC.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/ClangGCC.js deleted file mode 100644 index 0c1fdab16cf..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/ClangGCC.js +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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 ( -
- - - -

- {translate('onboarding.analysis.sq_scanner.execute')} -

- - {transformedMessage => ( -

- )} - - - -

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/DotNet.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/DotNet.js deleted file mode 100644 index a5bd3fd4285..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/DotNet.js +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 ( -
- - -

- {translate('onboarding.analysis.msbuild.execute')} -

- - {transformedMessage => ( -

- )} - - - - -

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js deleted file mode 100644 index d3cc1c847da..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 ( -
-

{translate('onboarding.analysis.java.gradle.header')}

- - {transformedMessage => ( -

- )} - - -

- {translate('onboarding.analysis.java.gradle.text.2')} -

- -

-

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js deleted file mode 100644 index 8a02fb75630..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 ( -
-

{translate('onboarding.analysis.java.maven.header')}

-

- -

- -

-

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/MSBuildScanner.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/MSBuildScanner.js deleted file mode 100644 index af0ade047c3..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/MSBuildScanner.js +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 ( -
-

{translate('onboarding.analysis.msbuild.header')}

-

-

- - {translate('download_verb')} - -

-
- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Msvc.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Msvc.js deleted file mode 100644 index 03f5fe3eb63..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Msvc.js +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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 ( -
- - - -

- {translate('onboarding.analysis.msbuild.execute')} -

- - {transformedMessage => ( -

- )} - - - - -

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Other.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Other.js deleted file mode 100644 index 5bb0d0dd649..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/Other.js +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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 ( -
- - -

- {translate('onboarding.analysis.sq_scanner.execute')} -

- - {transformedMessage => ( -

- )} - - -

-

- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/SQScanner.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/SQScanner.js deleted file mode 100644 index 3fd3e3e9711..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/SQScanner.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 ( -
-

- {translate('onboarding.analysis.sq_scanner.header', props.os)} -

-

-

- - {translate('download_verb')} - -

-
- ); -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/BuildWrapper-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/BuildWrapper-test.js deleted file mode 100644 index 4d3f979b3c8..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/BuildWrapper-test.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect(shallow()).toMatchSnapshot(); - expect(shallow()).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/ClangGCC-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/ClangGCC-test.js deleted file mode 100644 index 9f8f9243da5..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/ClangGCC-test.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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() - ).toMatchSnapshot(); - - expect( - shallow() - ).toMatchSnapshot(); - - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/DotNet-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/DotNet-test.js deleted file mode 100644 index b9dc347956a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/DotNet-test.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaGradle-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaGradle-test.js deleted file mode 100644 index bfddcc9c728..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaGradle-test.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect( - shallow() - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaMaven-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaMaven-test.js deleted file mode 100644 index 592e578b3bc..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/JavaMaven-test.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect( - shallow() - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/MSBuildScanner-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/MSBuildScanner-test.js deleted file mode 100644 index 5551fcead5c..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/MSBuildScanner-test.js +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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()).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Msvc-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Msvc-test.js deleted file mode 100644 index 62ccf801fb9..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Msvc-test.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect( - shallow() - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Other-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Other-test.js deleted file mode 100644 index b7175078c96..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/Other-test.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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() - ).toMatchSnapshot(); - - expect( - shallow() - ).toMatchSnapshot(); - - expect( - shallow( - - ) - ).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/SQScanner-test.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/SQScanner-test.js deleted file mode 100644 index 11a0ccb58ad..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/SQScanner-test.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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()).toMatchSnapshot(); - expect(shallow()).toMatchSnapshot(); - expect(shallow()).toMatchSnapshot(); -}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/BuildWrapper-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/BuildWrapper-test.js.snap deleted file mode 100644 index 07e8eb45f0a..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/BuildWrapper-test.js.snap +++ /dev/null @@ -1,85 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- onboarding.analysis.build_wrapper.header.win -

-

-

- - download_verb - -

-
-`; - -exports[`renders correctly 2`] = ` -
-

- onboarding.analysis.build_wrapper.header.linux -

-

-

- - download_verb - -

-
-`; - -exports[`renders correctly 3`] = ` -
-

- onboarding.analysis.build_wrapper.header.mac -

-

-

- - download_verb - -

-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/ClangGCC-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/ClangGCC-test.js.snap deleted file mode 100644 index cdffd4c2061..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/ClangGCC-test.js.snap +++ /dev/null @@ -1,139 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
- - -

- onboarding.analysis.sq_scanner.execute -

- - - -

-

-`; - -exports[`renders correctly 2`] = ` -
- - -

- onboarding.analysis.sq_scanner.execute -

- - - -

-

-`; - -exports[`renders correctly 3`] = ` -
- - -

- onboarding.analysis.sq_scanner.execute -

- - - -

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/DotNet-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/DotNet-test.js.snap deleted file mode 100644 index 89b57fa28b4..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/DotNet-test.js.snap +++ /dev/null @@ -1,95 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
- -

- onboarding.analysis.msbuild.execute -

- - - - -

-

-`; - -exports[`renders correctly 2`] = ` -
- -

- onboarding.analysis.msbuild.execute -

- - - - -

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap deleted file mode 100644 index 401137a9234..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap +++ /dev/null @@ -1,99 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- onboarding.analysis.java.gradle.header -

- - -

- onboarding.analysis.java.gradle.text.2 -

- -

-

-

-`; - -exports[`renders correctly 2`] = ` -
-

- onboarding.analysis.java.gradle.header -

- - -

- onboarding.analysis.java.gradle.text.2 -

- -

-

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap deleted file mode 100644 index d4462b957c6..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap +++ /dev/null @@ -1,87 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- onboarding.analysis.java.maven.header -

-

- -

- -

-

-

-`; - -exports[`renders correctly 2`] = ` -
-

- onboarding.analysis.java.maven.header -

-

- -

- -

-

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.js.snap deleted file mode 100644 index c7f156bc53f..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.js.snap +++ /dev/null @@ -1,28 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- onboarding.analysis.msbuild.header -

-

-

- - download_verb - -

-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Msvc-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Msvc-test.js.snap deleted file mode 100644 index 2240a13995c..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Msvc-test.js.snap +++ /dev/null @@ -1,105 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
- - -

- onboarding.analysis.msbuild.execute -

- - - - -

-

-`; - -exports[`renders correctly 2`] = ` -
- - -

- onboarding.analysis.msbuild.execute -

- - - - -

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Other-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Other-test.js.snap deleted file mode 100644 index 73aba357dca..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/Other-test.js.snap +++ /dev/null @@ -1,112 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
- -

- onboarding.analysis.sq_scanner.execute -

- - -

-

-`; - -exports[`renders correctly 2`] = ` -
- -

- onboarding.analysis.sq_scanner.execute -

- - -

-

-`; - -exports[`renders correctly 3`] = ` -
- -

- onboarding.analysis.sq_scanner.execute -

- - -

-

-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/SQScanner-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/SQScanner-test.js.snap deleted file mode 100644 index bcdac075ce4..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/SQScanner-test.js.snap +++ /dev/null @@ -1,82 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders correctly 1`] = ` -
-

- onboarding.analysis.sq_scanner.header.win -

-

-

- - download_verb - -

-
-`; - -exports[`renders correctly 2`] = ` -
-

- onboarding.analysis.sq_scanner.header.linux -

-

-

- - download_verb - -

-
-`; - -exports[`renders correctly 3`] = ` -
-

- onboarding.analysis.sq_scanner.header.mac -

-

-

- - download_verb - -

-
-`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/styles.css b/server/sonar-web/src/main/js/apps/tutorials/onboarding/styles.css deleted file mode 100644 index 9c8dfc093fc..00000000000 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/styles.css +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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; -} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/AnalysisStep.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/AnalysisStep.tsx new file mode 100644 index 00000000000..a91ff541119 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/AnalysisStep.tsx @@ -0,0 +1,201 @@ +/* + * 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 { + 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 ( +
+
+
+ +
+
{this.renderCommand()}
+
+
+ ); + }; + + renderFormattedCommand = (...lines: Array) => ( + // keep this "useless" concatentation for the readability reason + // eslint-disable-next-line no-useless-concat +
{lines.join(' ' + '\\' + '\n' + '  ')}
+ ); + + 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 ; + }; + + renderCommandForGradle = () => { + const { token } = this.props; + if (!token) { + return null; + } + return ; + }; + + renderCommandForDotNet = () => { + const { token } = this.props; + const { result } = this.state; + if (!result || !result.projectKey || !token) { + return null; + } + return ( + + ); + }; + + renderCommandForMSVC = () => { + const { token } = this.props; + const { result } = this.state; + if (!result || !result.projectKey || !token) { + return null; + } + return ( + + ); + }; + + renderCommandForClangGCC = () => { + const { token } = this.props; + const { result } = this.state; + if (!result || !result.projectKey || !result.os || !token) { + return null; + } + return ( + + ); + }; + + renderCommandForOther = () => { + const { token } = this.props; + const { result } = this.state; + if (!result || !result.projectKey || !result.os || !token) { + return null; + } + return ( + + ); + }; + + renderResult = () => null; + + render() { + return ( + {}} + open={this.props.open} + renderForm={this.renderForm} + renderResult={this.renderResult} + stepNumber={this.props.stepNumber} + stepTitle={translate('onboarding.analysis.header')} + /> + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/LanguageStep.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/LanguageStep.tsx new file mode 100644 index 00000000000..25b7544ddcc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/LanguageStep.tsx @@ -0,0 +1,178 @@ +/* + * 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 { + 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 = () => ( +
+

{translate('onboarding.language.java.build_technology')}

+ ({ + label: translate('onboarding.language.java.build_technology', build), + value: build + }))} + value={this.state.javaBuild} + /> +
+ ); + + renderCFamilyCompiler = () => ( +
+

{translate('onboarding.language.c-family.compiler')}

+ ({ + label: translate('onboarding.language.c-family.compiler', compiler), + value: compiler + }))} + value={this.state.cFamilyCompiler} + /> +
+ ); + + renderOS = () => ( +
+

{translate('onboarding.language.os')}

+ ({ + label: translate('onboarding.language.os', os), + value: os + }))} + value={this.state.os} + /> +
+ ); + + renderProjectKey = () => ( + + ); + + 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 ( +
+
+

{translate('onboarding.language')}

+ ({ + label: translate('onboarding.language', language), + value: language + }))} + value={this.state.language} + /> +
+ {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()} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewOrganizationForm.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewOrganizationForm.tsx new file mode 100644 index 00000000000..1a0e5500129 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewOrganizationForm.tsx @@ -0,0 +1,165 @@ +/* + * 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 { + 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) => { + const organization = this.sanitizeOrganization(event.target.value); + this.setState({ organization }); + this.validateOrganization(organization); + }; + + handleOrganizationCreate = (event: React.FormEvent) => { + 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 ? ( +
+ {organization} + {loading ? ( + + ) : ( + + )} +
+ ) : ( +
+ + {loading ? ( + + ) : ( + + {translate('create')} + + )} + {!unique && ( + + + {translate('this_name_is_already_taken')} + + )} +
+ {translate('onboarding.organization.key_requirement')} +
+ + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewProjectForm.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewProjectForm.tsx new file mode 100644 index 00000000000..f09b4d152bf --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/NewProjectForm.tsx @@ -0,0 +1,150 @@ +/* + * 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 { + 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) => { + this.setState({ projectKey: this.sanitizeProjectKey(event.target.value) }); + }; + + handleProjectCreate = (event: React.FormEvent) => { + 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 ? ( +
+ {projectKey} + {loading ? ( + + ) : ( + + )} +
+ ) : ( +
+ + {loading ? ( + + ) : ( + + {translate('Done')} + + )} +
+ {translate('onboarding.project_key_requirement')} +
+ + ); + + return ( +
+

{translate('onboarding.language.project_key')}

+ {form} +
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/OrganizationStep.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/OrganizationStep.tsx new file mode 100644 index 00000000000..0d155ef9eee --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/OrganizationStep.tsx @@ -0,0 +1,270 @@ +/* + * 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; + personalOrganization?: string; + selection: 'personal' | 'existing' | 'new'; +} + +export default class OrganizationStep extends React.PureComponent { + 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) => { + event.preventDefault(); + this.setState({ selection: 'personal' }); + }; + + handleExistingClick = (event: React.MouseEvent) => { + event.preventDefault(); + this.setState({ selection: 'existing' }); + }; + + handleNewClick = (event: React.MouseEvent) => { + 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 = () => ( + + ); + + renderExistingOrganizationOption = () => ( +
+ + + {translate('onboarding.organization.exising_organization')} + + {this.state.selection === 'existing' && ( +
+ + {this.state.loading ? ( + + ) : ( + + {translate('onboarding.token.generate')} + + )} + +
+ )} +
+ ); + + renderUseExistingOption = () => { + const { existingToken } = this.state; + const validInput = !existingToken || existingToken.match(/^[a-z0-9]+$/) != null; + + return ( +
+ + + {translate('onboarding.token.use_existing_token')} + + {this.state.selection === 'use-existing' && ( +
+ + {!validInput && ( + + + {translate('onboarding.token.invalid_format')} + + )} +
+ )} +
+ ); + }; + + renderForm = () => { + const { canUseExisting, loading, token, tokenName } = this.state; + + return ( +
+ {token != null ? ( +
+ + {tokenName} + {': '} + + {token} + {loading ? ( + + ) : ( + + )} + + ) : ( +
+ {this.renderGenerateOption()} + {canUseExisting && this.renderUseExistingOption()} +
+ )} + +
{translate('onboarding.token.text')}
+ + {this.canContinue() && ( +
+ +
+ )} +
+ ); + }; + + renderResult = () => { + const { selection, tokenName } = this.state; + const token = this.getToken(); + + if (!token) { + return null; + } + + return ( +
+ + {selection === 'generate' && tokenName && `${tokenName}: `} + {token} +
+ ); + }; + + render() { + return ( + + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/LanguageStep-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/LanguageStep-test.tsx new file mode 100644 index 00000000000..629044f2c4c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/LanguageStep-test.tsx @@ -0,0 +1,131 @@ +/* + * 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).mockImplementation(() => false); +}); + +it('selects java', () => { + const onDone = jest.fn(); + const wrapper = shallow(); + + (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(); + + (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).mockImplementation(() => true); + const onDone = jest.fn(); + const wrapper = shallow(); + + (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(); + + (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' }); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewOrganizationForm-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewOrganizationForm-test.tsx new file mode 100644 index 00000000000..bb16f901167 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewOrganizationForm-test.tsx @@ -0,0 +1,56 @@ +/* + * 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(); + 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(); + 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(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewProjectForm-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewProjectForm-test.tsx new file mode 100644 index 00000000000..2c8c18cace4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/NewProjectForm-test.tsx @@ -0,0 +1,55 @@ +/* + * 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(); + 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(); + 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(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/OrganizationStep-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/OrganizationStep-test.tsx new file mode 100644 index 00000000000..b2192a0bce7 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/OrganizationStep-test.tsx @@ -0,0 +1,102 @@ +/* + * 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).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( + + ); + click(wrapper.find('.js-continue')); + expect(onContinue).toBeCalledWith('user'); +}); + +it('works with existing organization', async () => { + const onContinue = jest.fn(); + const wrapper = mount( + + ); + 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( + + ); + 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'); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectOnboarding-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectOnboarding-test.tsx new file mode 100644 index 00000000000..078d6702aa6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectOnboarding-test.tsx @@ -0,0 +1,82 @@ +/* + * 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).mockImplementation(() => 'SonarQube'); + (isSonarCloud as jest.Mock).mockImplementation(() => false); + const wrapper = shallow( + + ); + expect(wrapper).toMatchSnapshot(); + + (wrapper.instance() as ProjectOnboarding).handleTokenDone('abcd1234'); + wrapper.update(); + expect(wrapper).toMatchSnapshot(); +}); + +it('guides for sonarcloud', () => { + (getInstance as jest.Mock).mockImplementation(() => 'SonarCloud'); + (isSonarCloud as jest.Mock).mockImplementation(() => true); + const wrapper = shallow( + + ); + 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).mockImplementation(() => 'SonarQube'); + (isSonarCloud as jest.Mock).mockImplementation(() => false); + const onFinish = jest.fn(); + const wrapper = mount( + + ); + click(wrapper.find('ResetButtonLink')); + return doAsync(() => { + expect(onFinish).toBeCalled(); + }); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectWatcher-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectWatcher-test.tsx new file mode 100644 index 00000000000..16215259325 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/ProjectWatcher-test.tsx @@ -0,0 +1,58 @@ +/* + * 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( + + ); + 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(); + expect(onFinish).not.toBeCalled(); + jest.runTimersToTime(5000); +}); + +it('timeouts', () => { + const onTimeout = jest.fn(); + mount(); + expect(onTimeout).not.toBeCalled(); + jest.runTimersToTime(10 * 60 * 1000); + expect(onTimeout).toBeCalled(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/Step-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/Step-test.tsx new file mode 100644 index 00000000000..8a9664f71c8 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/Step-test.tsx @@ -0,0 +1,57 @@ +/* + * 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( +
form
} + renderResult={() =>
result
} + 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( +
form
} + renderResult={() =>
result
} + stepNumber={1} + stepTitle="First Step" + /> + ); + click(wrapper); + expect(onOpen).toBeCalled(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/TokenStep-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/TokenStep-test.tsx new file mode 100644 index 00000000000..25b5f0c7462 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/TokenStep-test.tsx @@ -0,0 +1,110 @@ +/* + * 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( + + ); + 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( + + ); + 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( + + ); + 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( + + ); + await new Promise(setImmediate); + wrapper.setState({ existingToken: 'abcd1234', selection: 'use-existing' }); + click(wrapper.find('[className="js-continue"]')); + expect(onContinue).toBeCalledWith('abcd1234'); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/LanguageStep-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/LanguageStep-test.tsx.snap new file mode 100644 index 00000000000..8e82d384b3f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/LanguageStep-test.tsx.snap @@ -0,0 +1,687 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`selects c# 1`] = ` +
+
+

+ onboarding.language +

+ +
+ +
+`; + +exports[`selects c-family 1`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.c-family.compiler +

+ +
+
+`; + +exports[`selects c-family 2`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.c-family.compiler +

+ +
+ +
+`; + +exports[`selects c-family 3`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.c-family.compiler +

+ +
+
+

+ onboarding.language.os +

+ +
+
+`; + +exports[`selects c-family 4`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.c-family.compiler +

+ +
+
+

+ onboarding.language.os +

+ +
+ +
+`; + +exports[`selects java 1`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.java.build_technology +

+ +
+
+`; + +exports[`selects java 2`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.java.build_technology +

+ +
+
+`; + +exports[`selects java 3`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.java.build_technology +

+ +
+
+`; + +exports[`selects other 1`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.os +

+ +
+
+`; + +exports[`selects other 2`] = ` +
+
+

+ onboarding.language +

+ +
+
+

+ onboarding.language.os +

+ +
+ +
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewOrganizationForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewOrganizationForm-test.tsx.snap new file mode 100644 index 00000000000..eae8fcdb833 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewOrganizationForm-test.tsx.snap @@ -0,0 +1,270 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`creates new organization 1`] = ` + +
+ + + + + +
+ onboarding.organization.key_requirement +
+
+
+`; + +exports[`creates new organization 2`] = ` + +
+ + +
+ onboarding.organization.key_requirement +
+ +
+`; + +exports[`creates new organization 3`] = ` + +
+ + foo + + + + + + + +
+
+`; + +exports[`deletes organization 1`] = ` + +
+ + foo + + + + + + + +
+
+`; + +exports[`deletes organization 2`] = ` + +
+ + foo + + +
+
+`; + +exports[`deletes organization 3`] = ` + +
+ + + + + +
+ onboarding.organization.key_requirement +
+
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewProjectForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewProjectForm-test.tsx.snap new file mode 100644 index 00000000000..f6722a21bf6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/NewProjectForm-test.tsx.snap @@ -0,0 +1,321 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`creates new project 1`] = ` + +
+

+ onboarding.language.project_key +

+
+ + + + + +
+ onboarding.project_key_requirement +
+
+
+
+`; + +exports[`creates new project 2`] = ` + +
+

+ onboarding.language.project_key +

+
+ + +
+ onboarding.project_key_requirement +
+ +
+
+`; + +exports[`creates new project 3`] = ` + +
+

+ onboarding.language.project_key +

+
+ + foo + + + + + + + +
+
+
+`; + +exports[`deletes project 1`] = ` + +
+

+ onboarding.language.project_key +

+
+ + foo + + + + + + + +
+
+
+`; + +exports[`deletes project 2`] = ` + +
+

+ onboarding.language.project_key +

+
+ + foo + + +
+
+
+`; + +exports[`deletes project 3`] = ` + +
+

+ onboarding.language.project_key +

+
+ + + + + +
+ onboarding.project_key_requirement +
+
+
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/OrganizationStep-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/OrganizationStep-test.tsx.snap new file mode 100644 index 00000000000..7e30dedc4a9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/OrganizationStep-test.tsx.snap @@ -0,0 +1,381 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`works with existing organization 1`] = ` + + + onboarding.organization.header + + + } + > +
+
+ 1 +
+
+

+ + onboarding.organization.header + + + +

+ } + > +
+ + +
+ } + > + + +
+ } + > + + + + + + + + + + + + + +
+ + + + + +
+
+ onboarding.organization.text +
+
+ +
+
+ + +`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectOnboarding-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectOnboarding-test.tsx.snap new file mode 100644 index 00000000000..0c5b93e108a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectOnboarding-test.tsx.snap @@ -0,0 +1,349 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`guides for on-premise 1`] = ` + + +
+

+ onboarding.project.header +

+
+
+

+ onboarding.project.header.description.2 +

+ + +
+
+ + close + + + tutorials.find_tutorial_back_in_help + +
+
+`; + +exports[`guides for on-premise 2`] = ` + + +
+

+ onboarding.project.header +

+
+
+

+ onboarding.project.header.description.2 +

+ + +
+
+ + close + + + tutorials.find_tutorial_back_in_help + +
+
+`; + +exports[`guides for sonarcloud 1`] = ` + + +
+

+ onboarding.project.header +

+
+
+

+ onboarding.project.header.description.3 +

+ + + +
+
+ + close + + + tutorials.find_tutorial_back_in_plus + +
+
+`; + +exports[`guides for sonarcloud 2`] = ` + + +
+

+ onboarding.project.header +

+
+
+

+ onboarding.project.header.description.3 +

+ + + +
+
+ + close + + + tutorials.find_tutorial_back_in_plus + +
+
+`; + +exports[`guides for sonarcloud 3`] = ` + + +
+

+ onboarding.project.header +

+
+
+

+ onboarding.project.header.description.3 +

+ + + +
+
+ + close + + + tutorials.find_tutorial_back_in_plus + +
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectWatcher-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectWatcher-test.tsx.snap new file mode 100644 index 00000000000..1cc4d9991f6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/ProjectWatcher-test.tsx.snap @@ -0,0 +1,42 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` +
+ onboarding.project_watcher.not_started +
+`; + +exports[`renders 2`] = ` +
+ + onboarding.project_watcher.in_progress +
+`; + +exports[`renders 3`] = ` +
+ + onboarding.project_watcher.finished +
+`; + +exports[`renders 4`] = ` +
+ + onboarding.project_watcher.in_progress +
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/Step-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/Step-test.tsx.snap new file mode 100644 index 00000000000..4667ca7ae8a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/Step-test.tsx.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders 1`] = ` +
+
+ 1 +
+
+

+ First Step +

+
+
+ form +
+
+`; + +exports[`renders 2`] = ` +
+
+ 1 +
+
+ result +
+
+

+ First Step +

+
+
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/TokenStep-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/TokenStep-test.tsx.snap new file mode 100644 index 00000000000..54847972e8c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/__tests__/__snapshots__/TokenStep-test.tsx.snap @@ -0,0 +1,649 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generates token 1`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+
+
+ + + onboarding.token.generate_token + +
+
+ + + + + +
+
+
+ +
+
+ onboarding.token.text +
+
+
+
+
+`; + +exports[`generates token 2`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+ +
+ onboarding.token.text +
+
+
+
+
+`; + +exports[`generates token 3`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+
+ + my token + : + + + abcd1234 + + + + + + + +
+
+ onboarding.token.text +
+
+ + +
+
+
+
+
+`; + +exports[`revokes token 1`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+
+ + my token + : + + + abcd1234 + + + + + + + +
+
+ onboarding.token.text +
+
+ + +
+
+
+
+
+`; + +exports[`revokes token 2`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+
+ + my token + : + + + abcd1234 + + + +
+ onboarding.token.text +
+
+ + +
+
+
+
+
+`; + +exports[`revokes token 3`] = ` + + +
+
+ 1 +
+
+

+ onboarding.token.header +

+
+
+
+
+ + + onboarding.token.generate_token + +
+
+ + + + + +
+
+
+ +
+
+ onboarding.token.text +
+
+
+
+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/BuildWrapper.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/BuildWrapper.tsx new file mode 100644 index 00000000000..ed03adbf911 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/BuildWrapper.tsx @@ -0,0 +1,58 @@ +/* + * 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 ( +
+

+ {translate('onboarding.analysis.build_wrapper.header', props.os)} +

+

+

+ + {translate('download_verb')} + +

+
+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/ClangGCC.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/ClangGCC.tsx new file mode 100644 index 00000000000..6ebe42a3ca9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/ClangGCC.tsx @@ -0,0 +1,78 @@ +/* + * 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 ( +
+ + + +

+ {translate('onboarding.analysis.sq_scanner.execute')} +

+ + {transformedMessage => ( +

+ )} + + + +

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/DotNet.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/DotNet.tsx new file mode 100644 index 00000000000..347ea01b7ac --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/DotNet.tsx @@ -0,0 +1,70 @@ +/* + * 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 ( +
+ + +

+ {translate('onboarding.analysis.msbuild.execute')} +

+ + {transformedMessage => ( +

+ )} + + + + +

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaGradle.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaGradle.tsx new file mode 100644 index 00000000000..02da9fd1a2a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaGradle.tsx @@ -0,0 +1,69 @@ +/* + * 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 ( +
+

{translate('onboarding.analysis.java.gradle.header')}

+ + {transformedMessage => ( +

+ )} + + +

+ {translate('onboarding.analysis.java.gradle.text.2')} +

+ +

+

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaMaven.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaMaven.tsx new file mode 100644 index 00000000000..5663b1f2911 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/JavaMaven.tsx @@ -0,0 +1,58 @@ +/* + * 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 ( +
+

{translate('onboarding.analysis.java.maven.header')}

+

+ +

+ +

+

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/MSBuildScanner.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/MSBuildScanner.tsx new file mode 100644 index 00000000000..65c4005af86 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/MSBuildScanner.tsx @@ -0,0 +1,47 @@ +/* + * 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 ( +
+

{translate('onboarding.analysis.msbuild.header')}

+

+

+ + {translate('download_verb')} + +

+
+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Msvc.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Msvc.tsx new file mode 100644 index 00000000000..cf6120a3b31 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Msvc.tsx @@ -0,0 +1,73 @@ +/* + * 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 ( +
+ + + +

+ {translate('onboarding.analysis.msbuild.execute')} +

+ + {transformedMessage => ( +

+ )} + + + + +

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Other.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Other.tsx new file mode 100644 index 00000000000..3d0b3b2a718 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/Other.tsx @@ -0,0 +1,66 @@ +/* + * 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 ( +
+ + +

+ {translate('onboarding.analysis.sq_scanner.execute')} +

+ + {transformedMessage => ( +

+ )} + + +

+

+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/SQScanner.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/SQScanner.tsx new file mode 100644 index 00000000000..78b90f851bc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/SQScanner.tsx @@ -0,0 +1,52 @@ +/* + * 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 ( +
+

+ {translate('onboarding.analysis.sq_scanner.header', props.os)} +

+

+

+ + {translate('download_verb')} + +

+
+ ); +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/BuildWrapper-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/BuildWrapper-test.tsx new file mode 100644 index 00000000000..b19e334793b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/BuildWrapper-test.tsx @@ -0,0 +1,28 @@ +/* + * 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()).toMatchSnapshot(); + expect(shallow()).toMatchSnapshot(); + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/ClangGCC-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/ClangGCC-test.tsx new file mode 100644 index 00000000000..a6f7c4f550a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/ClangGCC-test.tsx @@ -0,0 +1,45 @@ +/* + * 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() + ).toMatchSnapshot(); + + expect( + shallow() + ).toMatchSnapshot(); + + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/DotNet-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/DotNet-test.tsx new file mode 100644 index 00000000000..91ecab828b2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/DotNet-test.tsx @@ -0,0 +1,32 @@ +/* + * 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()).toMatchSnapshot(); + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaGradle-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaGradle-test.tsx new file mode 100644 index 00000000000..f0d130a248d --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaGradle-test.tsx @@ -0,0 +1,30 @@ +/* + * 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()).toMatchSnapshot(); + expect( + shallow() + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaMaven-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaMaven-test.tsx new file mode 100644 index 00000000000..dbda16ca13e --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/JavaMaven-test.tsx @@ -0,0 +1,30 @@ +/* + * 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()).toMatchSnapshot(); + expect( + shallow() + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/MSBuildScanner-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/MSBuildScanner-test.tsx new file mode 100644 index 00000000000..e5411341d10 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/MSBuildScanner-test.tsx @@ -0,0 +1,27 @@ +/* + * 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()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Msvc-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Msvc-test.tsx new file mode 100644 index 00000000000..78470bbd2e6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Msvc-test.tsx @@ -0,0 +1,30 @@ +/* + * 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()).toMatchSnapshot(); + expect( + shallow() + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Other-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Other-test.tsx new file mode 100644 index 00000000000..16cc44ae69f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/Other-test.tsx @@ -0,0 +1,45 @@ +/* + * 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() + ).toMatchSnapshot(); + + expect( + shallow() + ).toMatchSnapshot(); + + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/SQScanner-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/SQScanner-test.tsx new file mode 100644 index 00000000000..2be4e546bb3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/SQScanner-test.tsx @@ -0,0 +1,29 @@ +/* + * 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()).toMatchSnapshot(); + expect(shallow()).toMatchSnapshot(); + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/BuildWrapper-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/BuildWrapper-test.tsx.snap new file mode 100644 index 00000000000..07e8eb45f0a --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/BuildWrapper-test.tsx.snap @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+

+ onboarding.analysis.build_wrapper.header.win +

+

+

+ + download_verb + +

+
+`; + +exports[`renders correctly 2`] = ` +
+

+ onboarding.analysis.build_wrapper.header.linux +

+

+

+ + download_verb + +

+
+`; + +exports[`renders correctly 3`] = ` +
+

+ onboarding.analysis.build_wrapper.header.mac +

+

+

+ + download_verb + +

+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap new file mode 100644 index 00000000000..cdffd4c2061 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/ClangGCC-test.tsx.snap @@ -0,0 +1,139 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+ + +

+ onboarding.analysis.sq_scanner.execute +

+ + + +

+

+`; + +exports[`renders correctly 2`] = ` +
+ + +

+ onboarding.analysis.sq_scanner.execute +

+ + + +

+

+`; + +exports[`renders correctly 3`] = ` +
+ + +

+ onboarding.analysis.sq_scanner.execute +

+ + + +

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/DotNet-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/DotNet-test.tsx.snap new file mode 100644 index 00000000000..89b57fa28b4 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/DotNet-test.tsx.snap @@ -0,0 +1,95 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+ +

+ onboarding.analysis.msbuild.execute +

+ + + + +

+

+`; + +exports[`renders correctly 2`] = ` +
+ +

+ onboarding.analysis.msbuild.execute +

+ + + + +

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap new file mode 100644 index 00000000000..401137a9234 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaGradle-test.tsx.snap @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+

+ onboarding.analysis.java.gradle.header +

+ + +

+ onboarding.analysis.java.gradle.text.2 +

+ +

+

+

+`; + +exports[`renders correctly 2`] = ` +
+

+ onboarding.analysis.java.gradle.header +

+ + +

+ onboarding.analysis.java.gradle.text.2 +

+ +

+

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap new file mode 100644 index 00000000000..d4462b957c6 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/JavaMaven-test.tsx.snap @@ -0,0 +1,87 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+

+ onboarding.analysis.java.maven.header +

+

+ +

+ +

+

+

+`; + +exports[`renders correctly 2`] = ` +
+

+ onboarding.analysis.java.maven.header +

+

+ +

+ +

+

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.tsx.snap new file mode 100644 index 00000000000..740e26ed12b --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/MSBuildScanner-test.tsx.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+

+ onboarding.analysis.msbuild.header +

+

+

+ + download_verb + +

+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Msvc-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Msvc-test.tsx.snap new file mode 100644 index 00000000000..2240a13995c --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Msvc-test.tsx.snap @@ -0,0 +1,105 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+ + +

+ onboarding.analysis.msbuild.execute +

+ + + + +

+

+`; + +exports[`renders correctly 2`] = ` +
+ + +

+ onboarding.analysis.msbuild.execute +

+ + + + +

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Other-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Other-test.tsx.snap new file mode 100644 index 00000000000..73aba357dca --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/Other-test.tsx.snap @@ -0,0 +1,112 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+ +

+ onboarding.analysis.sq_scanner.execute +

+ + +

+

+`; + +exports[`renders correctly 2`] = ` +
+ +

+ onboarding.analysis.sq_scanner.execute +

+ + +

+

+`; + +exports[`renders correctly 3`] = ` +
+ +

+ onboarding.analysis.sq_scanner.execute +

+ + +

+

+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/SQScanner-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/SQScanner-test.tsx.snap new file mode 100644 index 00000000000..cf6a8de4ce3 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/projectOnboarding/commands/__tests__/__snapshots__/SQScanner-test.tsx.snap @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` +
+

+ onboarding.analysis.sq_scanner.header.win +

+

+

+ + download_verb + +

+
+`; + +exports[`renders correctly 2`] = ` +
+

+ onboarding.analysis.sq_scanner.header.linux +

+

+

+ + download_verb + +

+
+`; + +exports[`renders correctly 3`] = ` +
+

+ onboarding.analysis.sq_scanner.header.mac +

+

+

+ + download_verb + +

+
+`; diff --git a/server/sonar-web/src/main/js/apps/tutorials/styles.css b/server/sonar-web/src/main/js/apps/tutorials/styles.css new file mode 100644 index 00000000000..f73428e0f40 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/styles.css @@ -0,0 +1,62 @@ +/* + * 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; +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/TeamOnboardingModal.tsx b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/TeamOnboardingModal.tsx new file mode 100644 index 00000000000..0763e82b9ab --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/TeamOnboardingModal.tsx @@ -0,0 +1,68 @@ +/* + * 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 { + render() { + const header = translate('onboarding.team.header'); + return ( + +
+

{header}

+
+
+
+ {translate('onboarding.team.work_in_progress')} +
+

{translate('onboarding.team.first_step')}

+

+ + {translate('as_explained_here')} + + ) + }} + /> +

+
+
+ {translate('close')} +
+
+ ); + } +} diff --git a/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/TeamOnboardingModal-test.tsx b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/TeamOnboardingModal-test.tsx new file mode 100644 index 00000000000..0bd903f80f2 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/TeamOnboardingModal-test.tsx @@ -0,0 +1,26 @@ +/* + * 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()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/__snapshots__/TeamOnboardingModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/__snapshots__/TeamOnboardingModal-test.tsx.snap new file mode 100644 index 00000000000..a510b0e0eb9 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/tutorials/teamOnboarding/__tests__/__snapshots__/TeamOnboardingModal-test.tsx.snap @@ -0,0 +1,61 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders correctly 1`] = ` + +
+

+ onboarding.team.header +

+
+
+
+ onboarding.team.work_in_progress +
+

+ onboarding.team.first_step +

+

+ + as_explained_here + , + } + } + /> +

+
+ +
+`; diff --git a/server/sonar-web/src/main/js/helpers/testUtils.ts b/server/sonar-web/src/main/js/helpers/testUtils.ts index d650182b932..f3f96a9506a 100644 --- a/server/sonar-web/src/main/js/helpers/testUtils.ts +++ b/server/sonar-web/src/main/js/helpers/testUtils.ts @@ -44,13 +44,13 @@ export function clickOutside(event = {}): void { 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 }, diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index ac5f5a477ce..0027ae95882 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -202,6 +202,7 @@ no=No 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 @@ -921,8 +922,8 @@ shortcuts.section.rules.deactivate=deactivate selected rule 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 #------------------------------------------------------------------------------ @@ -2589,15 +2590,30 @@ footer.web_api=Web API # 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.