@@ -0,0 +1 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg" width="27" height="27"><g fill="none" fill-rule="evenodd" transform="rotate(-90 13.5 18.5)"><path fill="#236A97" fill-rule="nonzero" d="M23.755102 18.5408163L19.7526885 14.5v3.0306122H12v2.0204082h7.7526885v3.0306123z"/><path d="M0 0h36v36H0z"/><circle cx="18.5" cy="18.5" r="12" stroke="#236A97" stroke-width="3"/></g></svg> |
@@ -0,0 +1 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28"><g fill="none" fill-rule="evenodd" transform="translate(-4 -4)"><path d="M0 0h36v36H0z"/><path fill="#236A97" fill-rule="nonzero" d="M31.3333333 15.2148148H21.28821l4.0595336-4.1777778c-4.0447178-3.99999996-10.5933086-4.14814811-14.6380264-.1481481-4.04471779 4.0148148-4.04471779 10.4888889 0 14.5037037 4.0447178 4.0148148 10.5933086 4.0148148 14.6380264 0 2.014951-1.9851852 3.0224265-4.3111111 3.0224265-7.2444445h2.9631632c0 2.9333334-1.3037918 6.7407408-3.9113754 9.3185186-5.2003515 5.1555555-13.6453667 5.1555555-18.84571821 0-5.18553566-5.1407408-5.2299831-13.4962963-.02963163-18.63703707 5.20035144-5.14074074 13.54165594-5.14074074 18.74200744 0l4.0447178-4.16296296V15.2148148zm-12.5934437-3.1407407v6.2962963l5.1855356 3.0814815-1.0667387 1.7925925-6.3411693-3.7629629v-7.4074074h2.2223724z"/></g></svg> |
@@ -34,7 +34,11 @@ import { | |||
} from '../types/alm-settings'; | |||
export function getAlmDefinitions(): Promise<AlmSettingsBindingDefinitions> { | |||
return getJSON('/api/alm_settings/list_definitions').catch(throwGlobalError); | |||
return getAlmDefinitionsNoCatch().catch(throwGlobalError); | |||
} | |||
export function getAlmDefinitionsNoCatch(): Promise<AlmSettingsBindingDefinitions> { | |||
return getJSON('/api/alm_settings/list_definitions'); | |||
} | |||
export function getAlmSettings(project?: string): Promise<AlmSettingsInstance[]> { |
@@ -22,7 +22,7 @@ import { FormattedMessage } from 'react-intl'; | |||
import { connect } from 'react-redux'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import AnalyzeTutorial from '../../../components/tutorials/manual/AnalyzeTutorial'; | |||
import TutorialSelection from '../../../components/tutorials/TutorialSelection'; | |||
import { getBranchLikeDisplayName, isBranch, isMainBranch } from '../../../helpers/branch-like'; | |||
import { isLoggedIn } from '../../../helpers/users'; | |||
import { getCurrentUser, Store } from '../../../store/rootReducer'; | |||
@@ -87,7 +87,7 @@ export function EmptyOverview(props: Props) { | |||
{isLoggedIn(currentUser) ? ( | |||
<> | |||
{showWarning && <Alert variant="warning">{warning}</Alert>} | |||
{showTutorial && <AnalyzeTutorial component={component} currentUser={currentUser} />} | |||
{showTutorial && <TutorialSelection component={component} currentUser={currentUser} />} | |||
</> | |||
) : ( | |||
<Alert variant="warning">{warning}</Alert> |
@@ -4,7 +4,7 @@ exports[`renders correctly 1`] = ` | |||
<div | |||
className="page page-limited" | |||
> | |||
<AnalyzeTutorial | |||
<withRouter(TutorialSelection) | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], |
@@ -40,6 +40,7 @@ | |||
font-size: 11px; | |||
font-weight: normal; | |||
user-select: none; | |||
background: var(--gray40); | |||
} | |||
.code-snippet > button:hover, |
@@ -0,0 +1,109 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { WithRouterProps } from 'react-router'; | |||
import { getAlmDefinitionsNoCatch, getProjectAlmBinding } from '../../api/alm-settings'; | |||
import { AlmBindingDefinition, AlmKeys, ProjectAlmBindingResponse } from '../../types/alm-settings'; | |||
import { withRouter } from '../hoc/withRouter'; | |||
import './styles.css'; | |||
import TutorialSelectionRenderer from './TutorialSelectionRenderer'; | |||
import { TutorialModes } from './types'; | |||
interface Props extends Pick<WithRouterProps, 'router' | 'location'> { | |||
component: T.Component; | |||
currentUser: T.LoggedInUser; | |||
} | |||
interface State { | |||
almBinding?: AlmBindingDefinition; | |||
forceManual: boolean; | |||
loading: boolean; | |||
projectBinding?: ProjectAlmBindingResponse; | |||
} | |||
export class TutorialSelection extends React.PureComponent<Props, State> { | |||
mounted = false; | |||
state: State = { | |||
forceManual: true, | |||
loading: true | |||
}; | |||
componentDidMount() { | |||
this.mounted = true; | |||
this.fetchAlmBindings(); | |||
} | |||
fetchAlmBindings = async () => { | |||
const { component } = this.props; | |||
const [almDefinitions, projectBinding] = await Promise.all([ | |||
getAlmDefinitionsNoCatch().catch(() => undefined), | |||
getProjectAlmBinding(component.key).catch(() => undefined) | |||
]); | |||
if (this.mounted) { | |||
// We only support Bitbucket for now. | |||
if (projectBinding === undefined || projectBinding.alm !== AlmKeys.Bitbucket) { | |||
this.setState({ loading: false, forceManual: true }); | |||
} else { | |||
let almBinding; | |||
if (almDefinitions !== undefined) { | |||
almBinding = almDefinitions[projectBinding.alm].find(d => d.key === projectBinding.key); | |||
} | |||
this.setState({ almBinding, forceManual: false, projectBinding, loading: false }); | |||
} | |||
} | |||
}; | |||
handleSelectTutorial = (selectedTutorial: TutorialModes) => { | |||
const { | |||
router, | |||
location: { pathname, query } | |||
} = this.props; | |||
router.push({ | |||
pathname, | |||
query: { ...query, selectedTutorial } | |||
}); | |||
}; | |||
render() { | |||
const { component, currentUser, location } = this.props; | |||
const { almBinding, forceManual, loading, projectBinding } = this.state; | |||
const selectedTutorial: TutorialModes | undefined = forceManual | |||
? TutorialModes.Manual | |||
: location.query?.selectedTutorial; | |||
return ( | |||
<TutorialSelectionRenderer | |||
almBinding={almBinding} | |||
component={component} | |||
currentUser={currentUser} | |||
loading={loading} | |||
onSelectTutorial={this.handleSelectTutorial} | |||
projectBinding={projectBinding} | |||
selectedTutorial={selectedTutorial} | |||
/> | |||
); | |||
} | |||
} | |||
export default withRouter(TutorialSelection); |
@@ -0,0 +1,101 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import { AlmBindingDefinition, ProjectAlmBindingResponse } from '../../types/alm-settings'; | |||
import JenkinsTutorial from './jenkins/JenkinsTutorial'; | |||
import ManualTutorial from './manual/ManualTutorial'; | |||
import { TutorialModes } from './types'; | |||
export interface TutorialSelectionRendererProps { | |||
almBinding?: AlmBindingDefinition; | |||
component: T.Component; | |||
currentUser: T.LoggedInUser; | |||
loading: boolean; | |||
onSelectTutorial: (mode: TutorialModes) => void; | |||
projectBinding?: ProjectAlmBindingResponse; | |||
selectedTutorial?: TutorialModes; | |||
} | |||
export default function TutorialSelectionRenderer(props: TutorialSelectionRendererProps) { | |||
const { almBinding, component, currentUser, loading, projectBinding, selectedTutorial } = props; | |||
if (loading) { | |||
return <i className="spinner" />; | |||
} | |||
return ( | |||
<> | |||
{selectedTutorial === undefined && ( | |||
<div className="tutorial-selection"> | |||
<header className="spacer-top spacer-bottom padded"> | |||
<h1 className="text-center big-spacer-bottom"> | |||
{translate('onboarding.tutorial.choose_method')} | |||
</h1> | |||
</header> | |||
<div className="display-flex-space-around"> | |||
<button | |||
className="button button-huge display-flex-column tutorial-mode-jenkins" | |||
onClick={() => props.onSelectTutorial(TutorialModes.Jenkins)} | |||
type="button"> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
height={80} | |||
src={`${getBaseUrl()}/images/tutorials/jenkins.svg`} | |||
/> | |||
<div className="medium big-spacer-top"> | |||
{translate('onboarding.tutorial.choose_method.jenkins')} | |||
</div> | |||
</button> | |||
<button | |||
className="button button-huge display-flex-column tutorial-mode-manual" | |||
onClick={() => props.onSelectTutorial(TutorialModes.Manual)} | |||
type="button"> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
height={80} | |||
src={`${getBaseUrl()}/images/sonarcloud/analysis/manual.svg`} | |||
/> | |||
<div className="medium big-spacer-top"> | |||
{translate('onboarding.tutorial.choose_method.manual')} | |||
</div> | |||
</button> | |||
</div> | |||
</div> | |||
)} | |||
{selectedTutorial === TutorialModes.Manual && ( | |||
<ManualTutorial component={component} currentUser={currentUser} /> | |||
)} | |||
{selectedTutorial === TutorialModes.Jenkins && projectBinding !== undefined && ( | |||
<JenkinsTutorial | |||
almBinding={almBinding} | |||
component={component} | |||
projectBinding={projectBinding} | |||
/> | |||
)} | |||
</> | |||
); | |||
} |
@@ -0,0 +1,109 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils'; | |||
import { getAlmDefinitionsNoCatch, getProjectAlmBinding } from '../../../api/alm-settings'; | |||
import { mockBitbucketBindingDefinition } from '../../../helpers/mocks/alm-settings'; | |||
import { | |||
mockComponent, | |||
mockLocation, | |||
mockLoggedInUser, | |||
mockRouter | |||
} from '../../../helpers/testMocks'; | |||
import { AlmKeys } from '../../../types/alm-settings'; | |||
import { TutorialSelection } from '../TutorialSelection'; | |||
import { TutorialModes } from '../types'; | |||
jest.mock('../../../api/alm-settings', () => ({ | |||
getProjectAlmBinding: jest.fn().mockRejectedValue(null), | |||
getAlmDefinitionsNoCatch: jest.fn().mockRejectedValue(null) | |||
})); | |||
beforeEach(jest.clearAllMocks); | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
it('should select manual if project is not bound', async () => { | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().forceManual).toBe(true); | |||
}); | |||
it('should not select anything if project is bound to Bitbucket', async () => { | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.Bitbucket }); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().forceManual).toBe(false); | |||
}); | |||
it('should select manual if project is bound to any other ALM', async () => { | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.GitLab }); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().forceManual).toBe(true); | |||
}); | |||
it('should correctly find the global ALM binding definition', async () => { | |||
const key = 'foo'; | |||
const almBinding = mockBitbucketBindingDefinition({ key }); | |||
(getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.Bitbucket, key }); | |||
(getAlmDefinitionsNoCatch as jest.Mock).mockResolvedValueOnce({ | |||
[AlmKeys.Bitbucket]: [almBinding] | |||
}); | |||
const wrapper = shallowRender(); | |||
await waitAndUpdate(wrapper); | |||
expect(wrapper.state().almBinding).toBe(almBinding); | |||
}); | |||
it('should handle selection', () => { | |||
const push = jest.fn(); | |||
const wrapper = shallowRender({ router: mockRouter({ push }) }); | |||
const instance = wrapper.instance(); | |||
instance.handleSelectTutorial(TutorialModes.Manual); | |||
expect(push).toHaveBeenLastCalledWith( | |||
expect.objectContaining({ | |||
query: { selectedTutorial: TutorialModes.Manual } | |||
}) | |||
); | |||
instance.handleSelectTutorial(TutorialModes.Jenkins); | |||
expect(push).toHaveBeenLastCalledWith( | |||
expect.objectContaining({ | |||
query: { selectedTutorial: TutorialModes.Jenkins } | |||
}) | |||
); | |||
}); | |||
function shallowRender(props: Partial<TutorialSelection['props']> = {}) { | |||
return shallow<TutorialSelection>( | |||
<TutorialSelection | |||
component={mockComponent()} | |||
currentUser={mockLoggedInUser()} | |||
location={mockLocation()} | |||
router={mockRouter()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,70 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { click } from 'sonar-ui-common/helpers/testUtils'; | |||
import { | |||
mockBitbucketBindingDefinition, | |||
mockProjectBitbucketBindingGet | |||
} from '../../../helpers/mocks/alm-settings'; | |||
import { mockComponent, mockLoggedInUser } from '../../../helpers/testMocks'; | |||
import TutorialSelectionRenderer, { | |||
TutorialSelectionRendererProps | |||
} from '../TutorialSelectionRenderer'; | |||
import { TutorialModes } from '../types'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('selection'); | |||
expect(shallowRender({ loading: true })).toMatchSnapshot('loading'); | |||
expect(shallowRender({ selectedTutorial: TutorialModes.Manual })).toMatchSnapshot( | |||
'manual tutorial' | |||
); | |||
expect( | |||
shallowRender({ | |||
selectedTutorial: TutorialModes.Jenkins, | |||
projectBinding: mockProjectBitbucketBindingGet() | |||
}) | |||
).toMatchSnapshot('jenkins tutorial'); | |||
}); | |||
it('should allow mode selection', () => { | |||
const onSelectTutorial = jest.fn(); | |||
const wrapper = shallowRender({ onSelectTutorial }); | |||
click(wrapper.find('button.tutorial-mode-jenkins')); | |||
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Jenkins); | |||
click(wrapper.find('button.tutorial-mode-manual')); | |||
expect(onSelectTutorial).toHaveBeenLastCalledWith(TutorialModes.Manual); | |||
}); | |||
function shallowRender(props: Partial<TutorialSelectionRendererProps> = {}) { | |||
return shallow<TutorialSelectionRendererProps>( | |||
<TutorialSelectionRenderer | |||
almBinding={mockBitbucketBindingDefinition()} | |||
component={mockComponent()} | |||
currentUser={mockLoggedInUser()} | |||
loading={false} | |||
onSelectTutorial={jest.fn()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,41 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<TutorialSelectionRenderer | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
currentUser={ | |||
Object { | |||
"groups": Array [], | |||
"isLoggedIn": true, | |||
"login": "luke", | |||
"name": "Skywalker", | |||
"scmAccounts": Array [], | |||
} | |||
} | |||
loading={true} | |||
onSelectTutorial={[Function]} | |||
selectedTutorial="manual" | |||
/> | |||
`; |
@@ -0,0 +1,145 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: jenkins tutorial 1`] = ` | |||
<Fragment> | |||
<JenkinsTutorial | |||
almBinding={ | |||
Object { | |||
"key": "key", | |||
"personalAccessToken": "asdf1234", | |||
"url": "http://bbs.enterprise.com", | |||
} | |||
} | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
projectBinding={ | |||
Object { | |||
"alm": "bitbucket", | |||
"key": "foo", | |||
"repository": "PROJECT_KEY", | |||
"slug": "repo-slug", | |||
} | |||
} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: loading 1`] = ` | |||
<i | |||
className="spinner" | |||
/> | |||
`; | |||
exports[`should render correctly: manual tutorial 1`] = ` | |||
<Fragment> | |||
<ManualTutorial | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
currentUser={ | |||
Object { | |||
"groups": Array [], | |||
"isLoggedIn": true, | |||
"login": "luke", | |||
"name": "Skywalker", | |||
"scmAccounts": Array [], | |||
} | |||
} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: selection 1`] = ` | |||
<Fragment> | |||
<div | |||
className="tutorial-selection" | |||
> | |||
<header | |||
className="spacer-top spacer-bottom padded" | |||
> | |||
<h1 | |||
className="text-center big-spacer-bottom" | |||
> | |||
onboarding.tutorial.choose_method | |||
</h1> | |||
</header> | |||
<div | |||
className="display-flex-space-around" | |||
> | |||
<button | |||
className="button button-huge display-flex-column tutorial-mode-jenkins" | |||
onClick={[Function]} | |||
type="button" | |||
> | |||
<img | |||
alt="" | |||
height={80} | |||
src="/images/tutorials/jenkins.svg" | |||
/> | |||
<div | |||
className="medium big-spacer-top" | |||
> | |||
onboarding.tutorial.choose_method.jenkins | |||
</div> | |||
</button> | |||
<button | |||
className="button button-huge display-flex-column tutorial-mode-manual" | |||
onClick={[Function]} | |||
type="button" | |||
> | |||
<img | |||
alt="" | |||
height={80} | |||
src="/images/sonarcloud/analysis/manual.svg" | |||
/> | |||
<div | |||
className="medium big-spacer-top" | |||
> | |||
onboarding.tutorial.choose_method.manual | |||
</div> | |||
</button> | |||
</div> | |||
</div> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export interface LabelActionPairProps { | |||
translationKey: string; | |||
} | |||
export default function LabelActionPair({ translationKey }: LabelActionPairProps) { | |||
return ( | |||
<> | |||
<strong>{translate(translationKey, 'label')}:</strong> {translate(translationKey, 'action')} | |||
</> | |||
); | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { ClipboardIconButton } from 'sonar-ui-common/components/controls/clipboard'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export interface LabelValuePairProps { | |||
translationKey: string; | |||
value: string; | |||
} | |||
export default function LabelValuePair({ translationKey, value }: LabelValuePairProps) { | |||
return ( | |||
<div className="display-flex-center"> | |||
<strong className="little-spacer-right">{translate(translationKey, 'label')}:</strong> {value} | |||
<ClipboardIconButton className="little-spacer-left" copyValue={value} /> | |||
</div> | |||
); | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export interface SentenceWithFilenameProps { | |||
filename: string; | |||
translationKey: string; | |||
} | |||
export default function SentenceWithFilename({ | |||
filename, | |||
translationKey | |||
}: SentenceWithFilenameProps) { | |||
return ( | |||
<span className="markdown"> | |||
<FormattedMessage | |||
defaultMessage={translate(translationKey, 'sentence')} | |||
id={`${translationKey}.sentence`} | |||
values={{ | |||
file: <code>{filename}</code> | |||
}} | |||
/> | |||
</span> | |||
); | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
export interface SentenceWithHighlightsProps { | |||
highlightKeys: string[]; | |||
translationKey: string; | |||
} | |||
export default function SentenceWithHighlights({ | |||
highlightKeys, | |||
translationKey | |||
}: SentenceWithHighlightsProps) { | |||
const values: T.Dict<JSX.Element> = {}; | |||
highlightKeys.forEach(key => { | |||
values[key] = <strong>{translate(translationKey, 'sentence', key)}</strong>; | |||
}); | |||
return ( | |||
<FormattedMessage | |||
defaultMessage={translate(translationKey, 'sentence')} | |||
id={`${translationKey}.sentence`} | |||
values={values} | |||
/> | |||
); | |||
} |
@@ -20,6 +20,11 @@ | |||
.onboarding-step { | |||
position: relative; | |||
padding-left: 34px; | |||
margin-bottom: var(--gridSize); | |||
} | |||
.onboarding-step.no-step-number { | |||
padding-left: 0; | |||
} | |||
.onboarding-step:not(.is-open):not(.is-finished) { | |||
@@ -57,3 +62,40 @@ | |||
cursor: pointer; | |||
outline: none; | |||
} | |||
.onboarding-step ol.list-styled { | |||
list-style: none; | |||
padding-left: 0; | |||
counter-reset: step-counter; | |||
} | |||
.onboarding-step .markdown { | |||
line-height: inherit; | |||
} | |||
.onboarding-step ul.list-styled li { | |||
margin-top: var(--gridSize); | |||
margin-bottom: var(--gridSize); | |||
} | |||
.onboarding-step ol.list-styled > li { | |||
position: relative; | |||
counter-increment: step-counter; | |||
margin-bottom: calc(2 * var(--gridSize)); | |||
padding-left: calc(4 * var(--gridSize)); | |||
} | |||
.onboarding-step ol.list-styled > li::before { | |||
content: counter(step-counter); | |||
color: white; | |||
background-color: var(--blue); | |||
display: inline-flex; | |||
border-radius: 50%; | |||
width: 16px; | |||
position: absolute; | |||
left: 0; | |||
font-size: 10px; | |||
height: 16px; | |||
justify-content: center; | |||
align-items: center; | |||
} |
@@ -24,25 +24,29 @@ import './Step.css'; | |||
interface Props { | |||
finished?: boolean; | |||
onOpen: VoidFunction; | |||
onOpen?: VoidFunction; | |||
open: boolean; | |||
renderForm: () => React.ReactNode; | |||
renderResult: () => React.ReactNode; | |||
stepNumber: number; | |||
renderResult?: () => React.ReactNode; | |||
stepNumber?: number; | |||
stepTitle: React.ReactNode; | |||
} | |||
export default function Step(props: Props) { | |||
const { finished, open, stepNumber, stepTitle } = props; | |||
const className = classNames('boxed-group', 'onboarding-step', { | |||
'is-open': props.open, | |||
'is-finished': props.finished | |||
'is-open': open, | |||
'is-finished': finished, | |||
'no-step-number': stepNumber === undefined | |||
}); | |||
const clickable = !props.open && props.finished; | |||
const clickable = !open && finished && props.onOpen !== undefined; | |||
const handleClick = (event: React.MouseEvent<HTMLDivElement>) => { | |||
event.preventDefault(); | |||
props.onOpen(); | |||
if (props.onOpen !== undefined) { | |||
props.onOpen(); | |||
} | |||
}; | |||
return ( | |||
@@ -51,13 +55,13 @@ export default function Step(props: Props) { | |||
onClick={clickable ? handleClick : undefined} | |||
role={clickable ? 'button' : undefined} | |||
tabIndex={clickable ? 0 : undefined}> | |||
<div className="onboarding-step-number">{props.stepNumber}</div> | |||
{!props.open && props.renderResult()} | |||
{stepNumber !== undefined && <div className="onboarding-step-number">{stepNumber}</div>} | |||
{!open && props.renderResult && props.renderResult()} | |||
<div className="boxed-group-header"> | |||
<h2>{props.stepTitle}</h2> | |||
<h2>{stepTitle}</h2> | |||
</div> | |||
{!props.open && <div className="boxed-group-inner" />} | |||
<div className={classNames({ hidden: !props.open })}>{props.renderForm()}</div> | |||
{!open && <div className="boxed-group-inner" />} | |||
<div className={classNames({ hidden: !open })}>{props.renderForm()}</div> | |||
</div> | |||
); | |||
} |
@@ -0,0 +1,31 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import LabelActionPair, { LabelActionPairProps } from '../LabelActionPair'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<LabelActionPairProps> = {}) { | |||
return shallow<LabelActionPairProps>(<LabelActionPair translationKey="foo" {...props} />); | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import LabelValuePair, { LabelValuePairProps } from '../LabelValuePair'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<LabelValuePairProps> = {}) { | |||
return shallow<LabelValuePairProps>( | |||
<LabelValuePair translationKey="foo" value="bar" {...props} /> | |||
); | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import SentenceWithFilename, { SentenceWithFilenameProps } from '../SentenceWithFilename'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<SentenceWithFilenameProps> = {}) { | |||
return shallow<SentenceWithFilenameProps>( | |||
<SentenceWithFilename filename="foo.txt" translationKey="bar" {...props} /> | |||
); | |||
} |
@@ -0,0 +1,33 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import SentenceWithHighlights, { SentenceWithHighlightsProps } from '../SentenceWithHighlights'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<SentenceWithHighlightsProps> = {}) { | |||
return shallow<SentenceWithHighlightsProps>( | |||
<SentenceWithHighlights highlightKeys={['hello', 'world']} translationKey="foo" {...props} /> | |||
); | |||
} |
@@ -0,0 +1,12 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<strong> | |||
foo.label | |||
: | |||
</strong> | |||
foo.action | |||
</Fragment> | |||
`; |
@@ -0,0 +1,20 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<div | |||
className="display-flex-center" | |||
> | |||
<strong | |||
className="little-spacer-right" | |||
> | |||
foo.label | |||
: | |||
</strong> | |||
bar | |||
<ClipboardIconButton | |||
className="little-spacer-left" | |||
copyValue="bar" | |||
/> | |||
</div> | |||
`; |
@@ -0,0 +1,19 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<span | |||
className="markdown" | |||
> | |||
<FormattedMessage | |||
defaultMessage="bar.sentence" | |||
id="bar.sentence" | |||
values={ | |||
Object { | |||
"file": <code> | |||
foo.txt | |||
</code>, | |||
} | |||
} | |||
/> | |||
</span> | |||
`; |
@@ -0,0 +1,18 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<FormattedMessage | |||
defaultMessage="foo.sentence" | |||
id="foo.sentence" | |||
values={ | |||
Object { | |||
"hello": <strong> | |||
foo.sentence.hello | |||
</strong>, | |||
"world": <strong> | |||
foo.sentence.world | |||
</strong>, | |||
} | |||
} | |||
/> | |||
`; |
@@ -0,0 +1,143 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Button, ButtonLink } from 'sonar-ui-common/components/controls/buttons'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
BitbucketBindingDefinition, | |||
ProjectBitbucketBindingResponse | |||
} from '../../../types/alm-settings'; | |||
import CodeSnippet from '../../common/CodeSnippet'; | |||
import LabelActionPair from '../components/LabelActionPair'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
import Step from '../components/Step'; | |||
export interface BitbucketWebhookStepProps { | |||
almBinding?: BitbucketBindingDefinition; | |||
finished: boolean; | |||
onDone: () => void; | |||
onOpen: () => void; | |||
open: boolean; | |||
projectBinding: ProjectBitbucketBindingResponse; | |||
} | |||
export default function BitbucketWebhookStep(props: BitbucketWebhookStepProps) { | |||
const { almBinding, finished, open, projectBinding } = props; | |||
return ( | |||
<Step | |||
finished={finished} | |||
onOpen={props.onOpen} | |||
open={open} | |||
renderForm={() => ( | |||
<div className="boxed-group-inner"> | |||
<p className="big-spacer-bottom"> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence' | |||
)} | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence" | |||
values={{ | |||
link: ( | |||
<ButtonLink onClick={props.onDone}> | |||
{translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link')} | |||
</ButtonLink> | |||
) | |||
}} | |||
/> | |||
</p> | |||
<ol className="list-styled"> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence' | |||
)} | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence" | |||
values={{ | |||
link: | |||
almBinding !== undefined ? ( | |||
<a | |||
href={`${almBinding.url.replace( | |||
/\/$/, | |||
'' | |||
)}/plugins/servlet/webhooks/projects/${projectBinding.repository}/repos/${ | |||
projectBinding.slug | |||
}/create`} | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
{translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link')} | |||
</a> | |||
) : ( | |||
translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link') | |||
) | |||
}} | |||
/> | |||
<ul className="list-styled"> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name" /> | |||
</li> | |||
<li className="abs-width-600"> | |||
<p> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url" /> | |||
</p> | |||
<CodeSnippet | |||
isOneLine={true} | |||
snippet={`***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=${ | |||
almBinding !== undefined ? almBinding.url : '***BITBUCKET_URL***' | |||
}`} | |||
/> | |||
<Alert variant="info"> | |||
{translate( | |||
'onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning' | |||
)} | |||
</Alert> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['events']} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2" | |||
/> | |||
<ul className="list-styled"> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo" /> | |||
</li> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr" /> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['create']} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3" | |||
/> | |||
</li> | |||
</ol> | |||
<Button onClick={props.onDone}>{translate('continue')}</Button> | |||
</div> | |||
)} | |||
stepNumber={2} | |||
stepTitle={translate('onboarding.tutorial.with.jenkins.bitbucket_webhook.title')} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,89 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { | |||
isBitbucketBindingDefinition, | |||
isProjectBitbucketBindingResponse | |||
} from '../../../helpers/alm-settings'; | |||
import { AlmBindingDefinition, ProjectAlmBindingResponse } from '../../../types/alm-settings'; | |||
import BitbucketWebhookStep from './BitbucketWebhookStep'; | |||
import JenkinsfileStep from './JenkinsfileStep'; | |||
import MultiBranchPipelineStep from './MultiBranchPipelineStep'; | |||
import PreRequisitesStep from './PreRequisitesStep'; | |||
export interface JenkinsTutorialProps { | |||
almBinding?: AlmBindingDefinition; | |||
component: T.Component; | |||
projectBinding: ProjectAlmBindingResponse; | |||
} | |||
enum Steps { | |||
PreRequisites = 0, | |||
MultiBranchPipeline = 1, | |||
BitbucketWebhook = 2, | |||
Jenkinsfile = 3 | |||
} | |||
export default function JenkinsTutorial(props: JenkinsTutorialProps) { | |||
const { almBinding, component, projectBinding } = props; | |||
const [step, setStep] = React.useState(Steps.PreRequisites); | |||
// Failsafe; should never happen. | |||
if (!isProjectBitbucketBindingResponse(projectBinding)) { | |||
return ( | |||
<Alert variant="error">{translate('onboarding.tutorial.with.jenkins.only_bitbucket')}</Alert> | |||
); | |||
} | |||
return ( | |||
<> | |||
<div className="page-header big-spacer-bottom"> | |||
<h1 className="page-title">{translate('onboarding.tutorial.with.jenkins.title')}</h1> | |||
</div> | |||
<PreRequisitesStep | |||
onDone={() => setStep(Steps.MultiBranchPipeline)} | |||
onOpen={() => setStep(Steps.PreRequisites)} | |||
open={step === Steps.PreRequisites} | |||
/> | |||
<MultiBranchPipelineStep | |||
finished={step > Steps.MultiBranchPipeline} | |||
onDone={() => setStep(Steps.BitbucketWebhook)} | |||
onOpen={() => setStep(Steps.MultiBranchPipeline)} | |||
open={step === Steps.MultiBranchPipeline} | |||
projectBinding={projectBinding} | |||
/> | |||
<BitbucketWebhookStep | |||
almBinding={almBinding && isBitbucketBindingDefinition(almBinding) ? almBinding : undefined} | |||
finished={step > Steps.BitbucketWebhook} | |||
onDone={() => setStep(Steps.Jenkinsfile)} | |||
onOpen={() => setStep(Steps.BitbucketWebhook)} | |||
open={step === Steps.BitbucketWebhook} | |||
projectBinding={projectBinding} | |||
/> | |||
<JenkinsfileStep component={component} open={step === Steps.Jenkinsfile} /> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,126 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { getBaseUrl } from 'sonar-ui-common/helpers/urls'; | |||
import RenderOptions from '../components/RenderOptions'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
import Step from '../components/Step'; | |||
import Gradle from './buildtool-steps/Gradle'; | |||
import Maven from './buildtool-steps/Maven'; | |||
import MSBuild from './buildtool-steps/MSBuild'; | |||
import Other from './buildtool-steps/Other'; | |||
export interface JenkinsfileStepProps { | |||
component: T.Component; | |||
open: boolean; | |||
} | |||
export enum BuildTools { | |||
Maven = 'maven', | |||
Gradle = 'gradle', | |||
MSBuild = 'msbuild', | |||
Other = 'other' | |||
} | |||
const BUILDTOOL_COMPONENT_MAP: { | |||
[x in BuildTools]: React.ComponentType<{ component: T.Component }>; | |||
} = { | |||
[BuildTools.Maven]: Maven, | |||
[BuildTools.Gradle]: Gradle, | |||
[BuildTools.MSBuild]: MSBuild, | |||
[BuildTools.Other]: Other | |||
}; | |||
export default function JenkinsfileStep(props: JenkinsfileStepProps) { | |||
const { component, open } = props; | |||
const [buildTool, setBuildTool] = React.useState<BuildTools | undefined>(undefined); | |||
return ( | |||
<Step | |||
finished={false} | |||
open={open} | |||
renderForm={() => ( | |||
<div className="boxed-group-inner"> | |||
<ol className="list-styled"> | |||
<li> | |||
{translate('onboarding.build')} | |||
<RenderOptions | |||
checked={buildTool} | |||
name="buildtool" | |||
onCheck={value => setBuildTool(value as BuildTools)} | |||
optionLabelKey="onboarding.build" | |||
options={Object.values(BuildTools)} | |||
/> | |||
</li> | |||
{buildTool !== undefined && | |||
React.createElement(BUILDTOOL_COMPONENT_MAP[buildTool], { component })} | |||
</ol> | |||
{buildTool !== undefined && ( | |||
<> | |||
<hr className="huge-spacer-top huge-spacer-bottom" /> | |||
<div className="abs-width-600"> | |||
<p className="big-spacer-bottom"> | |||
<SentenceWithHighlights | |||
highlightKeys={['all_set']} | |||
translationKey="onboarding.tutorial.with.jenkins.all_set" | |||
/> | |||
</p> | |||
<div className="display-flex-row big-spacer-bottom"> | |||
<div> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
className="big-spacer-right" | |||
width={30} | |||
src={`${getBaseUrl()}/images/tutorials/commit.svg`} | |||
/> | |||
</div> | |||
<div> | |||
<p className="little-spacer-bottom"> | |||
<strong>{translate('onboarding.tutorial.with.jenkins.commit')}</strong> | |||
</p> | |||
<p>{translate('onboarding.tutorial.with.jenkins.commit.why')}</p> | |||
</div> | |||
</div> | |||
<div className="display-flex-row huge-spacer-bottom"> | |||
<div> | |||
<img | |||
alt="" // Should be ignored by screen readers | |||
className="big-spacer-right" | |||
width={30} | |||
src={`${getBaseUrl()}/images/tutorials/refresh.svg`} | |||
/> | |||
</div> | |||
<div> | |||
<p className="little-spacer-bottom"> | |||
<strong>{translate('onboarding.tutorial.with.jenkins.refresh')}</strong> | |||
</p> | |||
<p>{translate('onboarding.tutorial.with.jenkins.refresh.why')}</p> | |||
</div> | |||
</div> | |||
</div> | |||
</> | |||
)} | |||
</div> | |||
)} | |||
stepNumber={3} | |||
stepTitle={translate('onboarding.tutorial.with.jenkins.jenkinsfile.title')} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,113 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { ProjectBitbucketBindingResponse } from '../../../types/alm-settings'; | |||
import LabelActionPair from '../components/LabelActionPair'; | |||
import LabelValuePair from '../components/LabelValuePair'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
import Step from '../components/Step'; | |||
export interface MultiBranchPipelineStepProps { | |||
finished: boolean; | |||
onDone: () => void; | |||
onOpen: () => void; | |||
open: boolean; | |||
projectBinding: ProjectBitbucketBindingResponse; | |||
} | |||
export default function MultiBranchPipelineStep(props: MultiBranchPipelineStepProps) { | |||
const { finished, open, projectBinding } = props; | |||
return ( | |||
<Step | |||
finished={finished} | |||
onOpen={props.onOpen} | |||
open={open} | |||
renderForm={() => ( | |||
<div className="boxed-group-inner"> | |||
<p className="big-spacer-bottom"> | |||
{translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro')} | |||
</p> | |||
<ol className="list-styled"> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['new_item', 'type']} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1" | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['tab']} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2" | |||
/> | |||
<ul className="list-styled"> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server" /> | |||
</li> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds" /> | |||
</li> | |||
<li> | |||
<LabelValuePair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner" | |||
value={projectBinding.repository} | |||
/> | |||
</li> | |||
<li> | |||
<LabelValuePair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo" | |||
value={projectBinding.slug} | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour" /> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['tab']} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3" | |||
/> | |||
<ul className="list-styled"> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode" /> | |||
</li> | |||
<li> | |||
<LabelActionPair translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path" /> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={['save']} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4" | |||
/> | |||
</li> | |||
</ol> | |||
<Button onClick={props.onDone}>{translate('continue')}</Button> | |||
</div> | |||
)} | |||
stepNumber={1} | |||
stepTitle={translate('onboarding.tutorial.with.jenkins.multi_branch_pipeline.title')} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { Link } from 'react-router'; | |||
import { Button } from 'sonar-ui-common/components/controls/buttons'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import SentenceWithHighlights from '../components/SentenceWithHighlights'; | |||
import Step from '../components/Step'; | |||
export interface PreRequisitesStepProps { | |||
onDone: () => void; | |||
onOpen: () => void; | |||
open: boolean; | |||
} | |||
export default function PreRequisitesStep(props: PreRequisitesStepProps) { | |||
const { open } = props; | |||
return ( | |||
<Step | |||
finished={!open} | |||
onOpen={props.onOpen} | |||
open={open} | |||
renderForm={() => ( | |||
<div className="boxed-group-inner"> | |||
<p className="big-spacer-bottom"> | |||
<SentenceWithHighlights | |||
highlightKeys={['must_have']} | |||
translationKey="onboarding.tutorial.with.jenkins.prereqs.intro" | |||
/> | |||
</p> | |||
<ul className="list-styled big-spacer-bottom"> | |||
<li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source')}</li> | |||
<li>{translate('onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner')}</li> | |||
</ul> | |||
<p className="big-spacer-bottom"> | |||
<FormattedMessage | |||
defaultMessage={translate( | |||
'onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide' | |||
)} | |||
id="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" | |||
values={{ | |||
link: ( | |||
<Link target="_blank" to="/documentation/analysis/jenkins/"> | |||
{translate('onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link')} | |||
</Link> | |||
) | |||
}} | |||
/> | |||
</p> | |||
<p className="big-spacer-bottom"> | |||
{translate('onboarding.tutorial.with.jenkins.prereqs.following_are_recommendations')} | |||
</p> | |||
<Button onClick={props.onDone}> | |||
{translate('onboarding.tutorial.with.jenkins.prereqs.done')} | |||
</Button> | |||
</div> | |||
)} | |||
stepTitle={translate('onboarding.tutorial.with.jenkins.prereqs.title')} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,51 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { | |||
mockBitbucketBindingDefinition, | |||
mockProjectBitbucketBindingGet | |||
} from '../../../../helpers/mocks/alm-settings'; | |||
import BitbucketWebhookStep, { BitbucketWebhookStepProps } from '../BitbucketWebhookStep'; | |||
import { renderStepContent } from '../test-utils'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('Step wrapper'); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot('content'); | |||
expect(renderStepContent(wrapper.setProps({ almBinding: undefined }))).toMatchSnapshot( | |||
'no alm binding' | |||
); | |||
}); | |||
function shallowRender(props: Partial<BitbucketWebhookStepProps> = {}) { | |||
return shallow<BitbucketWebhookStepProps>( | |||
<BitbucketWebhookStep | |||
almBinding={mockBitbucketBindingDefinition()} | |||
finished={false} | |||
onDone={jest.fn()} | |||
onOpen={jest.fn()} | |||
open={true} | |||
projectBinding={mockProjectBitbucketBindingGet()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,91 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { | |||
mockProjectAlmBindingResponse, | |||
mockProjectBitbucketBindingGet | |||
} from '../../../../helpers/mocks/alm-settings'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import BitbucketWebhookStep from '../BitbucketWebhookStep'; | |||
import JenkinsfileStep from '../JenkinsfileStep'; | |||
import JenkinsTutorial, { JenkinsTutorialProps } from '../JenkinsTutorial'; | |||
import MultiBranchPipelineStep from '../MultiBranchPipelineStep'; | |||
import PreRequisitesStep from '../PreRequisitesStep'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ projectBinding: mockProjectAlmBindingResponse() })).toMatchSnapshot( | |||
'not Bitbucket binding' | |||
); | |||
}); | |||
it('should correctly navigate between steps', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(true); | |||
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false); | |||
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false); | |||
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false); | |||
// Pre-reqs done. | |||
wrapper.find(PreRequisitesStep).prop('onDone')(); | |||
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false); | |||
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(true); | |||
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false); | |||
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false); | |||
// Multibranch done. | |||
wrapper.find(MultiBranchPipelineStep).prop('onDone')(); | |||
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false); | |||
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false); | |||
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(true); | |||
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(false); | |||
// Webhook done. | |||
wrapper.find(BitbucketWebhookStep).prop('onDone')(); | |||
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(false); | |||
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(false); | |||
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(false); | |||
expect(wrapper.find(JenkinsfileStep).prop('open')).toBe(true); | |||
// Open Pre-reqs. | |||
wrapper.find(PreRequisitesStep).prop('onOpen')(); | |||
expect(wrapper.find(PreRequisitesStep).prop('open')).toBe(true); | |||
// Open Multibranch. | |||
wrapper.find(MultiBranchPipelineStep).prop('onOpen')(); | |||
expect(wrapper.find(MultiBranchPipelineStep).prop('open')).toBe(true); | |||
// Open Webhook. | |||
wrapper.find(BitbucketWebhookStep).prop('onOpen')(); | |||
expect(wrapper.find(BitbucketWebhookStep).prop('open')).toBe(true); | |||
}); | |||
function shallowRender(props: Partial<JenkinsTutorialProps> = {}) { | |||
return shallow<JenkinsTutorialProps>( | |||
<JenkinsTutorial | |||
component={mockComponent()} | |||
projectBinding={mockProjectBitbucketBindingGet()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,73 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow, ShallowWrapper } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../helpers/testMocks'; | |||
import RenderOptions from '../../components/RenderOptions'; | |||
import Step from '../../components/Step'; | |||
import JenkinsfileStep, { BuildTools, JenkinsfileStepProps } from '../JenkinsfileStep'; | |||
import { renderStepContent } from '../test-utils'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('Step wrapper'); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot('initial content'); | |||
}); | |||
it('should render correctly for Maven', () => { | |||
const wrapper = shallowRender(); | |||
selectBuildTool(wrapper, BuildTools.Maven); | |||
expect( | |||
wrapper | |||
.find(Step) | |||
.props() | |||
.renderForm() | |||
).toMatchSnapshot(); | |||
}); | |||
it('should render correctly for Gradle', () => { | |||
const wrapper = shallowRender(); | |||
selectBuildTool(wrapper, BuildTools.Gradle); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot(); | |||
}); | |||
it('should render correctly for MSBuild', () => { | |||
const wrapper = shallowRender(); | |||
selectBuildTool(wrapper, BuildTools.MSBuild); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot(); | |||
}); | |||
it('should render correctly for Other', () => { | |||
const wrapper = shallowRender(); | |||
selectBuildTool(wrapper, BuildTools.Other); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot(); | |||
}); | |||
function selectBuildTool(wrapper: ShallowWrapper<JenkinsfileStepProps>, tool: BuildTools) { | |||
const content = new ShallowWrapper(renderStepContent(wrapper) as JSX.Element); | |||
content.find(RenderOptions).prop('onCheck')(tool); | |||
} | |||
function shallowRender(props: Partial<JenkinsfileStepProps> = {}) { | |||
return shallow<JenkinsfileStepProps>( | |||
<JenkinsfileStep component={mockComponent()} open={true} {...props} /> | |||
); | |||
} |
@@ -0,0 +1,44 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockProjectBitbucketBindingGet } from '../../../../helpers/mocks/alm-settings'; | |||
import MultiBranchPipelineStep, { MultiBranchPipelineStepProps } from '../MultiBranchPipelineStep'; | |||
import { renderStepContent } from '../test-utils'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('Step wrapper'); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot('content'); | |||
}); | |||
function shallowRender(props: Partial<MultiBranchPipelineStepProps> = {}) { | |||
return shallow<MultiBranchPipelineStepProps>( | |||
<MultiBranchPipelineStep | |||
finished={false} | |||
onDone={jest.fn()} | |||
onOpen={jest.fn()} | |||
open={true} | |||
projectBinding={mockProjectBitbucketBindingGet()} | |||
{...props} | |||
/> | |||
); | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import PreRequisitesStep, { PreRequisitesStepProps } from '../PreRequisitesStep'; | |||
import { renderStepContent } from '../test-utils'; | |||
it('should render correctly', () => { | |||
const wrapper = shallowRender(); | |||
expect(wrapper).toMatchSnapshot('Step wrapper'); | |||
expect(renderStepContent(wrapper)).toMatchSnapshot('content'); | |||
}); | |||
function shallowRender(props: Partial<PreRequisitesStepProps> = {}) { | |||
return shallow<PreRequisitesStepProps>( | |||
<PreRequisitesStep onDone={jest.fn()} onOpen={jest.fn()} open={false} {...props} /> | |||
); | |||
} |
@@ -0,0 +1,228 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: Step wrapper 1`] = ` | |||
<Step | |||
finished={false} | |||
onOpen={[MockFunction]} | |||
open={true} | |||
renderForm={[Function]} | |||
stepNumber={2} | |||
stepTitle="onboarding.tutorial.with.jenkins.bitbucket_webhook.title" | |||
/> | |||
`; | |||
exports[`should render correctly: content 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence" | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence" | |||
values={ | |||
Object { | |||
"link": <ButtonLink | |||
onClick={[MockFunction]} | |||
> | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link | |||
</ButtonLink>, | |||
} | |||
} | |||
/> | |||
</p> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence" | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="http://bbs.enterprise.com/plugins/servlet/webhooks/projects/PROJECT_KEY/repos/repo-slug/create" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link | |||
</a>, | |||
} | |||
} | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name" | |||
/> | |||
</li> | |||
<li | |||
className="abs-width-600" | |||
> | |||
<p> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url" | |||
/> | |||
</p> | |||
<CodeSnippet | |||
isOneLine={true} | |||
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=http://bbs.enterprise.com" | |||
/> | |||
<Alert | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning | |||
</Alert> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"events", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2" | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo" | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr" | |||
/> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"create", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3" | |||
/> | |||
</li> | |||
</ol> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
continue | |||
</Button> | |||
</div> | |||
`; | |||
exports[`should render correctly: no alm binding 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence" | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence" | |||
values={ | |||
Object { | |||
"link": <ButtonLink | |||
onClick={[MockFunction]} | |||
> | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link | |||
</ButtonLink>, | |||
} | |||
} | |||
/> | |||
</p> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence" | |||
id="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence" | |||
values={ | |||
Object { | |||
"link": "onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link", | |||
} | |||
} | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name" | |||
/> | |||
</li> | |||
<li | |||
className="abs-width-600" | |||
> | |||
<p> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url" | |||
/> | |||
</p> | |||
<CodeSnippet | |||
isOneLine={true} | |||
snippet="***JENKINS_URL***/bitbucket-scmsource-hook/notify?server_url=***BITBUCKET_URL***" | |||
/> | |||
<Alert | |||
variant="info" | |||
> | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning | |||
</Alert> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"events", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2" | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo" | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr" | |||
/> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"create", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.bitbucket_webhook.step3" | |||
/> | |||
</li> | |||
</ol> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
continue | |||
</Button> | |||
</div> | |||
`; |
@@ -0,0 +1,82 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: default 1`] = ` | |||
<Fragment> | |||
<div | |||
className="page-header big-spacer-bottom" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
onboarding.tutorial.with.jenkins.title | |||
</h1> | |||
</div> | |||
<PreRequisitesStep | |||
onDone={[Function]} | |||
onOpen={[Function]} | |||
open={true} | |||
/> | |||
<MultiBranchPipelineStep | |||
finished={false} | |||
onDone={[Function]} | |||
onOpen={[Function]} | |||
open={false} | |||
projectBinding={ | |||
Object { | |||
"alm": "bitbucket", | |||
"key": "foo", | |||
"repository": "PROJECT_KEY", | |||
"slug": "repo-slug", | |||
} | |||
} | |||
/> | |||
<BitbucketWebhookStep | |||
finished={false} | |||
onDone={[Function]} | |||
onOpen={[Function]} | |||
open={false} | |||
projectBinding={ | |||
Object { | |||
"alm": "bitbucket", | |||
"key": "foo", | |||
"repository": "PROJECT_KEY", | |||
"slug": "repo-slug", | |||
} | |||
} | |||
/> | |||
<JenkinsfileStep | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
open={false} | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly: not Bitbucket binding 1`] = ` | |||
<Alert | |||
variant="error" | |||
> | |||
onboarding.tutorial.with.jenkins.only_bitbucket | |||
</Alert> | |||
`; |
@@ -0,0 +1,526 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly for Gradle 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
onboarding.build | |||
<RenderOptions | |||
checked="gradle" | |||
name="buildtool" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"maven", | |||
"gradle", | |||
"msbuild", | |||
"other", | |||
] | |||
} | |||
/> | |||
</li> | |||
<Gradle | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
</ol> | |||
<React.Fragment> | |||
<hr | |||
className="huge-spacer-top huge-spacer-bottom" | |||
/> | |||
<div | |||
className="abs-width-600" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"all_set", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.all_set" | |||
/> | |||
</p> | |||
<div | |||
className="display-flex-row big-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/commit.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.commit | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.commit.why | |||
</p> | |||
</div> | |||
</div> | |||
<div | |||
className="display-flex-row huge-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/refresh.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.refresh | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.refresh.why | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</React.Fragment> | |||
</div> | |||
`; | |||
exports[`should render correctly for MSBuild 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
onboarding.build | |||
<RenderOptions | |||
checked="msbuild" | |||
name="buildtool" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"maven", | |||
"gradle", | |||
"msbuild", | |||
"other", | |||
] | |||
} | |||
/> | |||
</li> | |||
<MSBuild | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
</ol> | |||
<React.Fragment> | |||
<hr | |||
className="huge-spacer-top huge-spacer-bottom" | |||
/> | |||
<div | |||
className="abs-width-600" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"all_set", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.all_set" | |||
/> | |||
</p> | |||
<div | |||
className="display-flex-row big-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/commit.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.commit | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.commit.why | |||
</p> | |||
</div> | |||
</div> | |||
<div | |||
className="display-flex-row huge-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/refresh.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.refresh | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.refresh.why | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</React.Fragment> | |||
</div> | |||
`; | |||
exports[`should render correctly for Maven 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
onboarding.build | |||
<RenderOptions | |||
checked="maven" | |||
name="buildtool" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"maven", | |||
"gradle", | |||
"msbuild", | |||
"other", | |||
] | |||
} | |||
/> | |||
</li> | |||
<Maven | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
</ol> | |||
<React.Fragment> | |||
<hr | |||
className="huge-spacer-top huge-spacer-bottom" | |||
/> | |||
<div | |||
className="abs-width-600" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"all_set", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.all_set" | |||
/> | |||
</p> | |||
<div | |||
className="display-flex-row big-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/commit.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.commit | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.commit.why | |||
</p> | |||
</div> | |||
</div> | |||
<div | |||
className="display-flex-row huge-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/refresh.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.refresh | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.refresh.why | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</React.Fragment> | |||
</div> | |||
`; | |||
exports[`should render correctly for Other 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
onboarding.build | |||
<RenderOptions | |||
checked="other" | |||
name="buildtool" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"maven", | |||
"gradle", | |||
"msbuild", | |||
"other", | |||
] | |||
} | |||
/> | |||
</li> | |||
<Other | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
/> | |||
</ol> | |||
<React.Fragment> | |||
<hr | |||
className="huge-spacer-top huge-spacer-bottom" | |||
/> | |||
<div | |||
className="abs-width-600" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"all_set", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.all_set" | |||
/> | |||
</p> | |||
<div | |||
className="display-flex-row big-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/commit.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.commit | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.commit.why | |||
</p> | |||
</div> | |||
</div> | |||
<div | |||
className="display-flex-row huge-spacer-bottom" | |||
> | |||
<div> | |||
<img | |||
alt="" | |||
className="big-spacer-right" | |||
src="/images/tutorials/refresh.svg" | |||
width={30} | |||
/> | |||
</div> | |||
<div> | |||
<p | |||
className="little-spacer-bottom" | |||
> | |||
<strong> | |||
onboarding.tutorial.with.jenkins.refresh | |||
</strong> | |||
</p> | |||
<p> | |||
onboarding.tutorial.with.jenkins.refresh.why | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</React.Fragment> | |||
</div> | |||
`; | |||
exports[`should render correctly: Step wrapper 1`] = ` | |||
<Step | |||
finished={false} | |||
open={true} | |||
renderForm={[Function]} | |||
stepNumber={3} | |||
stepTitle="onboarding.tutorial.with.jenkins.jenkinsfile.title" | |||
/> | |||
`; | |||
exports[`should render correctly: initial content 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
onboarding.build | |||
<RenderOptions | |||
name="buildtool" | |||
onCheck={[Function]} | |||
optionLabelKey="onboarding.build" | |||
options={ | |||
Array [ | |||
"maven", | |||
"gradle", | |||
"msbuild", | |||
"other", | |||
] | |||
} | |||
/> | |||
</li> | |||
</ol> | |||
</div> | |||
`; |
@@ -0,0 +1,119 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: Step wrapper 1`] = ` | |||
<Step | |||
finished={false} | |||
onOpen={[MockFunction]} | |||
open={true} | |||
renderForm={[Function]} | |||
stepNumber={1} | |||
stepTitle="onboarding.tutorial.with.jenkins.multi_branch_pipeline.title" | |||
/> | |||
`; | |||
exports[`should render correctly: content 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro | |||
</p> | |||
<ol | |||
className="list-styled" | |||
> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"new_item", | |||
"type", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1" | |||
/> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2" | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server" | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds" | |||
/> | |||
</li> | |||
<li> | |||
<LabelValuePair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner" | |||
value="PROJECT_KEY" | |||
/> | |||
</li> | |||
<li> | |||
<LabelValuePair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo" | |||
value="repo-slug" | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour" | |||
/> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"tab", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3" | |||
/> | |||
<ul | |||
className="list-styled" | |||
> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode" | |||
/> | |||
</li> | |||
<li> | |||
<LabelActionPair | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path" | |||
/> | |||
</li> | |||
</ul> | |||
</li> | |||
<li> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"save", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4" | |||
/> | |||
</li> | |||
</ol> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
continue | |||
</Button> | |||
</div> | |||
`; |
@@ -0,0 +1,70 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: Step wrapper 1`] = ` | |||
<Step | |||
finished={true} | |||
onOpen={[MockFunction]} | |||
open={false} | |||
renderForm={[Function]} | |||
stepTitle="onboarding.tutorial.with.jenkins.prereqs.title" | |||
/> | |||
`; | |||
exports[`should render correctly: content 1`] = ` | |||
<div | |||
className="boxed-group-inner" | |||
> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"must_have", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.prereqs.intro" | |||
/> | |||
</p> | |||
<ul | |||
className="list-styled big-spacer-bottom" | |||
> | |||
<li> | |||
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source | |||
</li> | |||
<li> | |||
onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner | |||
</li> | |||
</ul> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
<FormattedMessage | |||
defaultMessage="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" | |||
id="onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide" | |||
values={ | |||
Object { | |||
"link": <Link | |||
onlyActiveOnIndex={false} | |||
style={Object {}} | |||
target="_blank" | |||
to="/documentation/analysis/jenkins/" | |||
> | |||
onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link | |||
</Link>, | |||
} | |||
} | |||
/> | |||
</p> | |||
<p | |||
className="big-spacer-bottom" | |||
> | |||
onboarding.tutorial.with.jenkins.prereqs.following_are_recommendations | |||
</p> | |||
<Button | |||
onClick={[MockFunction]} | |||
> | |||
onboarding.tutorial.with.jenkins.prereqs.done | |||
</Button> | |||
</div> | |||
`; |
@@ -0,0 +1,73 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import SentenceWithHighlights from '../../components/SentenceWithHighlights'; | |||
export interface CreateJenkinsfileBulletPointProps { | |||
snippet: string; | |||
alertTranslationKeyPart?: string; | |||
} | |||
export default function CreateJenkinsfileBulletPoint(props: CreateJenkinsfileBulletPointProps) { | |||
const { snippet, alertTranslationKeyPart } = props; | |||
return ( | |||
<li className="abs-width-600"> | |||
<SentenceWithFilename | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
{alertTranslationKeyPart !== undefined && ( | |||
<Alert className="spacer-top" variant="info"> | |||
<p className="text-middle"> | |||
<SentenceWithHighlights | |||
highlightKeys={['default', 'in_jenkins']} | |||
translationKey={`${alertTranslationKeyPart}.replace`} | |||
/> | |||
<HelpTooltip | |||
className="little-spacer-left" | |||
overlay={ | |||
<> | |||
<p className="spacer-bottom"> | |||
<SentenceWithHighlights | |||
highlightKeys={['path']} | |||
translationKey={`${alertTranslationKeyPart}.help1`} | |||
/> | |||
</p> | |||
<p> | |||
<SentenceWithHighlights | |||
highlightKeys={['path', 'name']} | |||
translationKey={`${alertTranslationKeyPart}.help2`} | |||
/> | |||
</p> | |||
</> | |||
} | |||
/> | |||
</p> | |||
</Alert> | |||
)} | |||
<CodeSnippet snippet={snippet} /> | |||
</li> | |||
); | |||
} |
@@ -0,0 +1,64 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface GradleProps { | |||
component: T.Component; | |||
} | |||
const buildGradleSnippet = (key: string) => `plugins { | |||
id "org.sonarqube" version "2.7" | |||
} | |||
sonarqube { | |||
properties { | |||
property "sonar.projectKey", "${key}" | |||
} | |||
}`; | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
withSonarQubeEnv() { | |||
sh "./gradlew sonarqube" | |||
} | |||
} | |||
}`; | |||
export default function Gradle({ component }: GradleProps) { | |||
return ( | |||
<> | |||
<li className="abs-width-600"> | |||
<SentenceWithFilename | |||
filename="build.gradle" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2" | |||
/> | |||
<CodeSnippet snippet={buildGradleSnippet(component.key)} /> | |||
</li> | |||
<CreateJenkinsfileBulletPoint snippet={JENKINSFILE_SNIPPET} /> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,90 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip'; | |||
import { Alert } from 'sonar-ui-common/components/ui/Alert'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import SentenceWithHighlights from '../../components/SentenceWithHighlights'; | |||
export interface MSBuildProps { | |||
component: T.Component; | |||
} | |||
const jenkinsfileSnippet = (key: string) => `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def msbuildHome = tool 'Default MSBuild' | |||
def scannerHome = tool 'SonarScanner for MSBuild' | |||
withSonarQubeEnv() { | |||
bat "\\"\${scannerHome}\\\\SonarScanner.MSBuild.exe\\" begin /k:\\"${key}\\"" | |||
bat "\\"\${msbuildHome}\\\\MSBuild.exe\\" /t:Rebuild" | |||
bat "\\"\${scannerHome}\\\\SonarScanner.MSBuild.exe\\" end" | |||
} | |||
} | |||
} | |||
`; | |||
export default function MSBuild({ component }: MSBuildProps) { | |||
return ( | |||
<li className="abs-width-600"> | |||
<SentenceWithFilename | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
<Alert className="spacer-top" variant="info"> | |||
<p className="text-middle"> | |||
<SentenceWithHighlights | |||
highlightKeys={['default_msbuild', 'default_scanner', 'in_jenkins']} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace" | |||
/> | |||
<HelpTooltip | |||
className="little-spacer-left" | |||
overlay={ | |||
<> | |||
<p className="spacer-bottom"> | |||
<SentenceWithHighlights | |||
highlightKeys={['path']} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help1" | |||
/> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<SentenceWithHighlights | |||
highlightKeys={['path', 'name']} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help2" | |||
/> | |||
</p> | |||
<p> | |||
<SentenceWithHighlights | |||
highlightKeys={['path', 'name']} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help3" | |||
/> | |||
</p> | |||
</> | |||
} | |||
/> | |||
</p> | |||
</Alert> | |||
<CodeSnippet snippet={jenkinsfileSnippet(component.key)} /> | |||
</li> | |||
); | |||
} |
@@ -0,0 +1,62 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface MavenProps { | |||
component: T.Component; | |||
} | |||
const pomSnippet = (key: string) => `<properties> | |||
<sonar.projectKey>${key}</sonar.projectKey> | |||
</properties>`; | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def mvn = tool 'Default Maven'; | |||
withSonarQubeEnv() { | |||
sh "\${mvn}/bin/mvn sonar:sonar" | |||
} | |||
} | |||
}`; | |||
export default function Maven({ component }: MavenProps) { | |||
return ( | |||
<> | |||
<li className="abs-width-600"> | |||
<SentenceWithFilename | |||
filename="pom.xml" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step2" | |||
/> | |||
<CodeSnippet snippet={pomSnippet(component.key)} /> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3" | |||
snippet={JENKINSFILE_SNIPPET} | |||
/> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,60 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import CodeSnippet from '../../../common/CodeSnippet'; | |||
import SentenceWithFilename from '../../components/SentenceWithFilename'; | |||
import CreateJenkinsfileBulletPoint from './CreateJenkinsfileBulletPoint'; | |||
export interface OtherProps { | |||
component: T.Component; | |||
} | |||
const sonarProjectSnippet = (key: string) => `sonar.projectKey=${key}`; | |||
const JENKINSFILE_SNIPPET = `node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh "\${scannerHome}/bin/sonar-scanner" | |||
} | |||
} | |||
}`; | |||
export default function Other({ component }: OtherProps) { | |||
return ( | |||
<> | |||
<li className="abs-width-600"> | |||
<SentenceWithFilename | |||
filename="sonar-project.properties" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.other.step2" | |||
/> | |||
<CodeSnippet snippet={sonarProjectSnippet(component.key)} /> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet={JENKINSFILE_SNIPPET} | |||
/> | |||
</> | |||
); | |||
} |
@@ -0,0 +1,36 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import CreateJenkinsfileBulletPoint, { | |||
CreateJenkinsfileBulletPointProps | |||
} from '../CreateJenkinsfileBulletPoint'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ alertTranslationKeyPart: 'baz' })).toMatchSnapshot('with alert'); | |||
}); | |||
function shallowRender(props: Partial<CreateJenkinsfileBulletPointProps> = {}) { | |||
return shallow<CreateJenkinsfileBulletPointProps>( | |||
<CreateJenkinsfileBulletPoint snippet="foo { bar() }" {...props} /> | |||
); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Gradle, { GradleProps } from '../Gradle'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<GradleProps> = {}) { | |||
return shallow<GradleProps>(<Gradle component={mockComponent()} {...props} />); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import MSBuild, { MSBuildProps } from '../MSBuild'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<MSBuildProps> = {}) { | |||
return shallow<MSBuildProps>(<MSBuild component={mockComponent()} {...props} />); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Maven, { MavenProps } from '../Maven'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<MavenProps> = {}) { | |||
return shallow<MavenProps>(<Maven component={mockComponent()} {...props} />); | |||
} |
@@ -0,0 +1,32 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import { mockComponent } from '../../../../../helpers/testMocks'; | |||
import Other, { OtherProps } from '../Other'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<OtherProps> = {}) { | |||
return shallow<OtherProps>(<Other component={mockComponent()} {...props} />); | |||
} |
@@ -0,0 +1,77 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly: default 1`] = ` | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
<CodeSnippet | |||
snippet="foo { bar() }" | |||
/> | |||
</li> | |||
`; | |||
exports[`should render correctly: with alert 1`] = ` | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
<p | |||
className="text-middle" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"default", | |||
"in_jenkins", | |||
] | |||
} | |||
translationKey="baz.replace" | |||
/> | |||
<HelpTooltip | |||
className="little-spacer-left" | |||
overlay={ | |||
<React.Fragment> | |||
<p | |||
className="spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"path", | |||
] | |||
} | |||
translationKey="baz.help1" | |||
/> | |||
</p> | |||
<p> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"path", | |||
"name", | |||
] | |||
} | |||
translationKey="baz.help2" | |||
/> | |||
</p> | |||
</React.Fragment> | |||
} | |||
/> | |||
</p> | |||
</Alert> | |||
<CodeSnippet | |||
snippet="foo { bar() }" | |||
/> | |||
</li> | |||
`; |
@@ -0,0 +1,37 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="build.gradle" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2" | |||
/> | |||
<CodeSnippet | |||
snippet="plugins { | |||
id \\"org.sonarqube\\" version \\"2.7\\" | |||
} | |||
sonarqube { | |||
properties { | |||
property \\"sonar.projectKey\\", \\"my-project\\" | |||
} | |||
}" | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
withSonarQubeEnv() { | |||
sh \\"./gradlew sonarqube\\" | |||
} | |||
} | |||
}" | |||
/> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,91 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="Jenkinsfile" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step" | |||
/> | |||
<Alert | |||
className="spacer-top" | |||
variant="info" | |||
> | |||
<p | |||
className="text-middle" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"default_msbuild", | |||
"default_scanner", | |||
"in_jenkins", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace" | |||
/> | |||
<HelpTooltip | |||
className="little-spacer-left" | |||
overlay={ | |||
<React.Fragment> | |||
<p | |||
className="spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"path", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help1" | |||
/> | |||
</p> | |||
<p | |||
className="spacer-bottom" | |||
> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"path", | |||
"name", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help2" | |||
/> | |||
</p> | |||
<p> | |||
<SentenceWithHighlights | |||
highlightKeys={ | |||
Array [ | |||
"path", | |||
"name", | |||
] | |||
} | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help3" | |||
/> | |||
</p> | |||
</React.Fragment> | |||
} | |||
/> | |||
</p> | |||
</Alert> | |||
<CodeSnippet | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def msbuildHome = tool 'Default MSBuild' | |||
def scannerHome = tool 'SonarScanner for MSBuild' | |||
withSonarQubeEnv() { | |||
bat \\"\\\\\\"\${scannerHome}\\\\\\\\SonarScanner.MSBuild.exe\\\\\\" begin /k:\\\\\\"my-project\\\\\\"\\" | |||
bat \\"\\\\\\"\${msbuildHome}\\\\\\\\MSBuild.exe\\\\\\" /t:Rebuild\\" | |||
bat \\"\\\\\\"\${scannerHome}\\\\\\\\SonarScanner.MSBuild.exe\\\\\\" end\\" | |||
} | |||
} | |||
} | |||
" | |||
/> | |||
</li> | |||
`; |
@@ -0,0 +1,33 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="pom.xml" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step2" | |||
/> | |||
<CodeSnippet | |||
snippet="<properties> | |||
<sonar.projectKey>my-project</sonar.projectKey> | |||
</properties>" | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3" | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def mvn = tool 'Default Maven'; | |||
withSonarQubeEnv() { | |||
sh \\"\${mvn}/bin/mvn sonar:sonar\\" | |||
} | |||
} | |||
}" | |||
/> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,31 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`should render correctly 1`] = ` | |||
<Fragment> | |||
<li | |||
className="abs-width-600" | |||
> | |||
<SentenceWithFilename | |||
filename="sonar-project.properties" | |||
translationKey="onboarding.tutorial.with.jenkins.jenkinsfile.other.step2" | |||
/> | |||
<CodeSnippet | |||
snippet="sonar.projectKey=my-project" | |||
/> | |||
</li> | |||
<CreateJenkinsfileBulletPoint | |||
alertTranslationKeyPart="onboarding.tutorial.with.jenkins.jenkinsfile.other.step3" | |||
snippet="node { | |||
stage('SCM') { | |||
checkout scm | |||
} | |||
stage('SonarQube Analysis') { | |||
def scannerHome = tool 'SonarScanner'; | |||
withSonarQubeEnv() { | |||
sh \\"\${scannerHome}/bin/sonar-scanner\\" | |||
} | |||
} | |||
}" | |||
/> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,28 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { ShallowWrapper } from 'enzyme'; | |||
import Step from '../components/Step'; | |||
export function renderStepContent(wrapper: ShallowWrapper<React.ReactNode>) { | |||
return wrapper | |||
.find(Step) | |||
.props() | |||
.renderForm(); | |||
} |
@@ -18,8 +18,6 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import Tooltip from 'sonar-ui-common/components/controls/Tooltip'; | |||
import BackIcon from 'sonar-ui-common/components/icons/BackIcon'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import { isVSTS } from '../../../helpers/almIntegrations'; | |||
import InstanceMessage from '../../common/InstanceMessage'; | |||
@@ -34,7 +32,6 @@ export enum Steps { | |||
interface Props { | |||
component: T.Component; | |||
currentUser: T.LoggedInUser; | |||
onBack?: () => void; | |||
} | |||
interface State { | |||
@@ -61,19 +58,7 @@ export default class ManualTutorial extends React.PureComponent<Props, State> { | |||
return ( | |||
<> | |||
<div className="page-header big-spacer-bottom"> | |||
<h1 className="page-title"> | |||
{this.props.onBack !== undefined && ( | |||
<Tooltip overlay={translate('onboarding.tutorial.return_to_list')}> | |||
<a | |||
aria-label={translate('onboarding.tutorial.return_to_list')} | |||
className="link-no-underline big-spacer-right" | |||
onClick={this.props.onBack}> | |||
<BackIcon /> | |||
</a> | |||
</Tooltip> | |||
)} | |||
{translate('onboarding.project_analysis.header')} | |||
</h1> | |||
<h1 className="page-title">{translate('onboarding.project_analysis.header')}</h1> | |||
<p className="page-description"> | |||
<InstanceMessage message={translate('onboarding.project_analysis.description')} /> | |||
</p> |
@@ -26,7 +26,6 @@ import TokenStep from '../TokenStep'; | |||
it('renders correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ onBack: jest.fn() })).toMatchSnapshot('with back button'); | |||
}); | |||
it('allows to navigate between steps', () => { |
@@ -65,80 +65,3 @@ exports[`renders correctly: default 1`] = ` | |||
/> | |||
</Fragment> | |||
`; | |||
exports[`renders correctly: with back button 1`] = ` | |||
<Fragment> | |||
<div | |||
className="page-header big-spacer-bottom" | |||
> | |||
<h1 | |||
className="page-title" | |||
> | |||
<Tooltip | |||
overlay="onboarding.tutorial.return_to_list" | |||
> | |||
<a | |||
aria-label="onboarding.tutorial.return_to_list" | |||
className="link-no-underline big-spacer-right" | |||
onClick={[MockFunction]} | |||
> | |||
<BackIcon /> | |||
</a> | |||
</Tooltip> | |||
onboarding.project_analysis.header | |||
</h1> | |||
<p | |||
className="page-description" | |||
> | |||
<InstanceMessage | |||
message="onboarding.project_analysis.description" | |||
/> | |||
</p> | |||
</div> | |||
<TokenStep | |||
currentUser={ | |||
Object { | |||
"groups": Array [], | |||
"isLoggedIn": true, | |||
"login": "luke", | |||
"name": "Skywalker", | |||
"scmAccounts": Array [], | |||
} | |||
} | |||
finished={false} | |||
initialTokenName="Analyze \\"MyProject\\"" | |||
onContinue={[Function]} | |||
onOpen={[Function]} | |||
open={true} | |||
stepNumber={1} | |||
/> | |||
<ProjectAnalysisStep | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
displayRowLayout={true} | |||
open={false} | |||
stepNumber={2} | |||
/> | |||
</Fragment> | |||
`; |
@@ -0,0 +1,23 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
.tutorial-selection { | |||
margin: 0 auto; | |||
max-width: 500px; | |||
} |
@@ -0,0 +1,31 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
export enum TutorialModes { | |||
Manual = 'manual', | |||
Jenkins = 'jenkins' | |||
} | |||
export interface LanguageConfig { | |||
language?: string; | |||
javaBuild?: string; | |||
cFamilyCompiler?: string; | |||
os?: string; | |||
projectKey?: string; | |||
} |
@@ -17,13 +17,7 @@ | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
export interface LanguageConfig { | |||
language?: string; | |||
javaBuild?: string; | |||
cFamilyCompiler?: string; | |||
os?: string; | |||
projectKey?: string; | |||
} | |||
import { LanguageConfig } from './types'; | |||
export function isLanguageConfigured(config?: LanguageConfig) { | |||
if (!config) { |
@@ -0,0 +1,41 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { isBitbucketBindingDefinition, isProjectBitbucketBindingResponse } from '../alm-settings'; | |||
import { | |||
mockBitbucketBindingDefinition, | |||
mockGithubBindingDefinition, | |||
mockProjectAlmBindingResponse, | |||
mockProjectBitbucketBindingGet | |||
} from '../mocks/alm-settings'; | |||
describe('isProjectBitbucketBindingResponse', () => { | |||
it('works as expected', () => { | |||
expect(isProjectBitbucketBindingResponse(mockProjectAlmBindingResponse())).toBe(false); | |||
expect(isProjectBitbucketBindingResponse(mockProjectBitbucketBindingGet())).toBe(true); | |||
}); | |||
}); | |||
describe('isBitbucketBindingDefinition', () => { | |||
it('works as expected', () => { | |||
expect(isBitbucketBindingDefinition(mockGithubBindingDefinition())).toBe(false); | |||
expect(isBitbucketBindingDefinition(mockBitbucketBindingDefinition())).toBe(true); | |||
}); | |||
}); |
@@ -0,0 +1,38 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import { | |||
AlmBindingDefinition, | |||
AlmKeys, | |||
BitbucketBindingDefinition, | |||
ProjectAlmBindingResponse, | |||
ProjectBitbucketBindingResponse | |||
} from '../types/alm-settings'; | |||
export function isProjectBitbucketBindingResponse( | |||
binding: ProjectAlmBindingResponse | |||
): binding is ProjectBitbucketBindingResponse { | |||
return binding.alm === AlmKeys.Bitbucket; | |||
} | |||
export function isBitbucketBindingDefinition( | |||
binding: AlmBindingDefinition & { url?: string; personalAccessToken?: string } | |||
): binding is BitbucketBindingDefinition { | |||
return binding.url !== undefined && binding.personalAccessToken !== undefined; | |||
} |
@@ -23,7 +23,9 @@ import { | |||
AzureBindingDefinition, | |||
BitbucketBindingDefinition, | |||
GithubBindingDefinition, | |||
GitlabBindingDefinition | |||
GitlabBindingDefinition, | |||
ProjectAlmBindingResponse, | |||
ProjectBitbucketBindingResponse | |||
} from '../../types/alm-settings'; | |||
export function mockAlmSettingsInstance( | |||
@@ -78,3 +80,25 @@ export function mockGitlabBindingDefinition( | |||
...overrides | |||
}; | |||
} | |||
export function mockProjectAlmBindingResponse( | |||
overrides: Partial<ProjectAlmBindingResponse> = {} | |||
): ProjectAlmBindingResponse { | |||
return { | |||
alm: AlmKeys.GitHub, | |||
key: 'foo', | |||
...overrides | |||
}; | |||
} | |||
export function mockProjectBitbucketBindingGet( | |||
overrides: Partial<ProjectBitbucketBindingResponse> = {} | |||
): ProjectBitbucketBindingResponse { | |||
return { | |||
alm: AlmKeys.Bitbucket, | |||
key: 'foo', | |||
repository: 'PROJECT_KEY', | |||
slug: 'repo-slug', | |||
...overrides | |||
}; | |||
} |
@@ -56,6 +56,12 @@ export interface ProjectAlmBindingResponse { | |||
summaryCommentEnabled?: boolean; | |||
} | |||
export interface ProjectBitbucketBindingResponse extends ProjectAlmBindingResponse { | |||
alm: AlmKeys.Bitbucket; | |||
repository: string; | |||
slug: string; | |||
} | |||
export interface ProjectAlmBindingParams { | |||
almSetting: string; | |||
project: string; |
@@ -3180,6 +3180,7 @@ onboarding.build=What is your build technology? | |||
onboarding.build.maven=Maven | |||
onboarding.build.gradle=Gradle | |||
onboarding.build.make=Make | |||
onboarding.build.msbuild=MSBuild | |||
onboarding.build.other=Other (for JS, TS, Go, Python, PHP, ...) | |||
onboarding.language=What is your project's main language? | |||
@@ -3252,6 +3253,104 @@ onboarding.analysis.sqscanner.docs.gradle.example_project.title=live Gradle-base | |||
onboarding.tutorial.return_to_list=Choose another option | |||
onboarding.tutorial.choose_method=How do you want to analyze your repository? | |||
onboarding.tutorial.choose_method.manual=Manually | |||
onboarding.tutorial.choose_method.jenkins=With Jenkins | |||
onboarding.tutorial.with.jenkins.title=Analyze your project with Jenkins | |||
onboarding.tutorial.with.jenkins.only_bitbucket=This tutorial is only available for projects bound to Bitbucket Server. | |||
onboarding.tutorial.with.jenkins.prereqs.title=Prerequisites | |||
onboarding.tutorial.with.jenkins.prereqs.intro.sentence=To run your project analyses with Jenkins, the following plugins {must_have} | |||
onboarding.tutorial.with.jenkins.prereqs.intro.sentence.must_have=must be installed and configured: | |||
onboarding.tutorial.with.jenkins.prereqs.plugins.branch_source=Bitbucket Branch Source plugin for Jenkins - version 2.7 or later | |||
onboarding.tutorial.with.jenkins.prereqs.plugins.sonar_scanner=SonarQube Scanner plugin for Jenkins - version 2.11 or later | |||
onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide=For a step by step guide on installing and configuring those plugins in Jenkins, visit the {link} documentation page. | |||
onboarding.tutorial.with.jenkins.prereqs.step_by_step_guide.link=Analysis Prerequisites | |||
onboarding.tutorial.with.jenkins.prereqs.following_are_recommendations=We recommend using the configuration in the following steps for the best results, but you can customize it as needed. | |||
onboarding.tutorial.with.jenkins.prereqs.done=Configure Analysis | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.title=Create a Multibranch Pipeline Job | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.intro=Create a Multibranch Pipeline in order to automatically analyze all your branches and pull requests. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence=From Jenkins' dashboard, click {new_item} and create a {type}. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence.new_item=New Item | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step1.sentence.type=Multibranch Pipeline Job | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.sentence=Under {tab}, add a Bitbucket source and enter the following information: | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.sentence.tab=Branch Sources | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server.label=Server | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.server.action=select the instance hosting the repository you want to analyze. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds.label=Credentials | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.creds.action=select the Bitbucket Server credentials. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner.label=Owner | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.owner.action=enter your project key. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo.label=Repository | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.repo.action=select the repository you want to analyze. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour.label=Behavior | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step2.behaviour.action=select Exclude branches that are also filed as PRs. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.sentence=Jump to the {tab} section and set the following parameters: | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.sentence.tab=Build Configuration | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode.label=Mode | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.mode.action=by Jenkinsfile | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path.label=Script Path | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step3.script_path.action=Jenkinsfile | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4.sentence=Click {save}. | |||
onboarding.tutorial.with.jenkins.multi_branch_pipeline.step4.sentence.save=Save | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.title=Create a Bitbucket Server Webhook | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.sentence=Create a Webhook in your repository to trigger the Jenkins job on push. Already have a Webhook configured? {link} | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.intro.link=Skip this step. | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.sentence=Go to the {link} and enter the following information: | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.link=Bitbucket Server Webhook creation page for your repository | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name.label=Name | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.name.action=give a unique name. | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.label=URL | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.action=Enter the following URL, replacing the tokens as needed: | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step1.url.warning=The Bitbucket Server URL must be identical to the one in your Jenkins configuration. Watch out for any missing or extra "/" at the end. | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.sentence=Under {events}, make sure the following options are checked: | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.sentence.events=Events | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo.label=Repository | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.repo.action=Push | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr.label=Pull Request | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step2.pr.action=Opened | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step3.sentence=Click {create}. | |||
onboarding.tutorial.with.jenkins.bitbucket_webhook.step3.sentence.create=Create | |||
onboarding.tutorial.with.jenkins.jenkinsfile.title=Create a Jenkinsfile | |||
onboarding.tutorial.with.jenkins.jenkinsfile.jenkinsfile_step.sentence=Create a {file} file in your repository and paste the following code: | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step2.sentence=Add the following to your {file} file: | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.replace.sentence=Make sure to replace {default} with the name you gave to your Maven tool {in_jenkins}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.replace.sentence.default=Default Maven | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.replace.sentence.in_jenkins=in Jenkins | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.help1.sentence=To get the name of your Maven tool in Jenkins, navigate to {path}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.help1.sentence.path=Manage Jenkins > Global Tool Configuration | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.help2.sentence=The name is located under the {path} section, in the {name} field. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.help2.sentence.path=Maven > Maven installations | |||
onboarding.tutorial.with.jenkins.jenkinsfile.maven.step3.help2.sentence.name=Name | |||
onboarding.tutorial.with.jenkins.jenkinsfile.gradle.step2.sentence=Add the following to your {file} file: | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace.sentence=Make sure to replace {default_msbuild} and {default_scanner} with the names you gave to your MSBuild and SonarScanner for MSBuild tools {in_jenkins}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace.sentence.default_msbuild=Default MSBuild | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace.sentence.default_scanner=SonarScanner for MSBuild | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.replace.sentence.in_jenkins=in Jenkins | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help1.sentence=To get the name of these tools in Jenkins, navigate to {path}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help1.sentence.path=Manage Jenkins > Global Tool Configuration | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help2.sentence=For your MSBuild tool, the name is located under the {path} section, in the {name} field. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help2.sentence.path=MSBuild > MSBuild installations | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help2.sentence.name=Name | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help3.sentence=For your SonarScanner for MSBuild tool, the name is located under the {path} section, in the {name} field. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help3.sentence.path=SonarScanner for MSBuild > SonarScanner for MSBuild installations | |||
onboarding.tutorial.with.jenkins.jenkinsfile.msbuild.step2.help3.sentence.name=Name | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step2.sentence=Create a {file} file in your repository and paste the following code: | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.replace.sentence=Make sure to replace {default} with the name you gave to your SonarQube Scanner tool {in_jenkins}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.replace.sentence.default=SonarScanner | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.replace.sentence.in_jenkins=in Jenkins | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help1.sentence=To get the name of your SonarQube Scanner tool in Jenkins, navigate to {path}. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help1.sentence.path=Manage Jenkins > Global Tool Configuration | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence=The name is located under the {path} section, in the {name} field. | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence.path=SonarQube Scanner > SonarQube Scanner installations | |||
onboarding.tutorial.with.jenkins.jenkinsfile.other.step3.help2.sentence.name=Name | |||
onboarding.tutorial.with.jenkins.all_set.sentence={all_set} and ready to improve the quality and security of your code! | |||
onboarding.tutorial.with.jenkins.all_set.sentence.all_set=You're all set | |||
onboarding.tutorial.with.jenkins.commit=Commit and push your code to start the analysis. | |||
onboarding.tutorial.with.jenkins.commit.why=Each new push you make on your branches or pull requests will trigger a new analysis in SonarQube. | |||
onboarding.tutorial.with.jenkins.refresh=This page will then refresh with your analysis results. | |||
onboarding.tutorial.with.jenkins.refresh.why=If the page doesn't refresh after a while, please double-check the analysis configuration. | |||
#------------------------------------------------------------------------------ | |||
# | |||
# BRANCHES |