import { CreateProjectModes } from './types';
interface Props extends Pick<WithRouterProps, 'router' | 'location'> {
- appState: Pick<T.AppState, 'branchesEnabled' | 'canAdmin'>;
+ appState: Pick<T.AppState, 'canAdmin'>;
currentUser: T.LoggedInUser;
}
};
componentDidMount() {
- const {
- appState: { branchesEnabled }
- } = this.props;
this.mounted = true;
- if (branchesEnabled) {
- this.fetchAlmBindings();
- }
+ this.fetchAlmBindings();
}
componentWillUnmount() {
}
render() {
- const {
- appState: { branchesEnabled },
- location
- } = this.props;
+ const { location } = this.props;
const mode: CreateProjectModes | undefined = location.query?.mode;
return (
<Helmet title={translate('my_account.create_new.TRK')} titleTemplate="%s" />
<A11ySkipTarget anchor="create_project_main" />
<div className="page page-limited huge-spacer-bottom position-relative" id="create-project">
- {this.renderForm(branchesEnabled ? mode : CreateProjectModes.Manual)}
+ {this.renderForm(mode)}
</div>
</>
);
expect(getAlmSettings).toBeCalled();
});
-it('should render correctly if no branch support', () => {
- expect(shallowRender({ appState: { branchesEnabled: false } })).toMatchSnapshot();
- expect(getAlmSettings).not.toBeCalled();
-});
-
it('should render correctly if the manual method is selected', () => {
expect(
shallowRender({
function shallowRender(props: Partial<CreateProjectPage['props']> = {}) {
return shallow<CreateProjectPage>(
<CreateProjectPage
- appState={{ branchesEnabled: true }}
+ appState={{}}
currentUser={mockLoggedInUser()}
location={mockLocation()}
router={mockRouter()}
</Fragment>
`;
-exports[`should render correctly if no branch support 1`] = `
-<Fragment>
- <Helmet
- defer={true}
- encodeSpecialCharacters={true}
- title="my_account.create_new.TRK"
- titleTemplate="%s"
- />
- <A11ySkipTarget
- anchor="create_project_main"
- />
- <div
- className="page page-limited huge-spacer-bottom position-relative"
- id="create-project"
- >
- <ManualProjectCreate
- onProjectCreate={[Function]}
- />
- </div>
-</Fragment>
-`;
-
exports[`should render correctly if the Azure method is selected 1`] = `
<Fragment>
<Helmet
import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon';
import { translate } from 'sonar-ui-common/helpers/l10n';
import { getAlmSettings } from '../../../api/alm-settings';
-import { withAppState } from '../../../components/hoc/withAppState';
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import { hasGlobalPermission } from '../../../helpers/users';
import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import ProjectCreationMenuItem from './ProjectCreationMenuItem';
interface Props {
- appState: Pick<T.AppState, 'branchesEnabled'>;
className?: string;
currentUser: T.LoggedInUser;
}
};
fetchAlmBindings = async () => {
- const {
- appState: { branchesEnabled },
- currentUser
- } = this.props;
+ const { currentUser } = this.props;
const canCreateProject = hasGlobalPermission(currentUser, PROJECT_CREATION_PERMISSION);
// getAlmSettings requires branchesEnabled
- if (!canCreateProject || !branchesEnabled) {
+ if (!canCreateProject) {
return;
}
- const almSettings = await getAlmSettings();
+ const almSettings: AlmSettingsInstance[] = await getAlmSettings().catch(() => []);
// Import is only available if exactly one binding is configured
const boundAlms = IMPORT_COMPATIBLE_ALMS.filter(key => {
}
}
-export default withAppState(withCurrentUser(ProjectCreationMenu));
+export default withCurrentUser(ProjectCreationMenu);
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { getAlmSettings } from '../../../../api/alm-settings';
-import { mockAppState, mockLoggedInUser } from '../../../../helpers/testMocks';
+import { mockLoggedInUser } from '../../../../helpers/testMocks';
import { AlmKeys } from '../../../../types/alm-settings';
import { ProjectCreationMenu } from '../ProjectCreationMenu';
expect(getAlmSettings).not.toBeCalled();
});
-it('should not fetch alm bindings if branches are not enabled', async () => {
- const wrapper = shallowRender({ appState: mockAppState({ branchesEnabled: false }) });
- await waitAndUpdate(wrapper);
- expect(getAlmSettings).not.toBeCalled();
-});
-
it('should filter alm bindings appropriately', async () => {
(getAlmSettings as jest.Mock).mockResolvedValueOnce([
{ alm: AlmKeys.Azure },
function shallowRender(overrides: Partial<ProjectCreationMenu['props']> = {}) {
return shallow<ProjectCreationMenu>(
<ProjectCreationMenu
- appState={mockAppState({ branchesEnabled: true })}
currentUser={mockLoggedInUser({ permissions: { global: ['provisioning'] } })}
{...overrides}
/>
<div
className="display-flex-center"
>
- <Connect(withAppState(Connect(withCurrentUser(ProjectCreationMenu))))
+ <Connect(withCurrentUser(ProjectCreationMenu))
className="little-spacer-right"
/>
<Connect(withAppState(Connect(withCurrentUser(withRouter(ApplicationCreation)))))
<div
className="display-flex-center"
>
- <Connect(withAppState(Connect(withCurrentUser(ProjectCreationMenu))))
+ <Connect(withCurrentUser(ProjectCreationMenu))
className="little-spacer-right"
/>
<Connect(withAppState(Connect(withCurrentUser(withRouter(ApplicationCreation)))))
<div
className="display-flex-center"
>
- <Connect(withAppState(Connect(withCurrentUser(ProjectCreationMenu))))
+ <Connect(withCurrentUser(ProjectCreationMenu))
className="little-spacer-right"
/>
<Connect(withAppState(Connect(withCurrentUser(withRouter(ApplicationCreation)))))
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
import { Button } from 'sonar-ui-common/components/controls/buttons';
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
import EditIcon from 'sonar-ui-common/components/icons/EditIcon';
import { Alert } from 'sonar-ui-common/components/ui/Alert';
import { translate } from 'sonar-ui-common/helpers/l10n';
+import { getEdition, getEditionUrl } from '../../../../helpers/editions';
import {
AlmBindingDefinition,
AlmKeys,
AlmSettingsBindingStatus,
AlmSettingsBindingStatusType
} from '../../../../types/alm-settings';
+import { EditionKey } from '../../../../types/editions';
export interface AlmBindingDefinitionBoxProps {
alm: AlmKeys;
+ branchesEnabled: boolean;
definition: AlmBindingDefinition;
multipleDefinitions: boolean;
onCheck: (definitionKey: string) => void;
[AlmSettingsBindingStatusType.Success]: <AlertSuccessIcon className="spacer-left" />
};
+function getPRDecorationFeatureStatus(
+ branchesEnabled: boolean,
+ type: AlmSettingsBindingStatusType.Success | AlmSettingsBindingStatusType.Failure
+) {
+ if (branchesEnabled) {
+ return STATUS_ICON[type];
+ }
+
+ return (
+ <div className="display-inline-flex-center">
+ <strong className="spacer-left">
+ {translate('settings.almintegration.feature.pr_decoration.disabled')}
+ </strong>
+ <HelpTooltip
+ className="little-spacer-left"
+ overlay={
+ <FormattedMessage
+ id="settings.almintegration.feature.pr_decoration.disabled.no_branches"
+ defaultMessage={translate(
+ 'settings.almintegration.feature.pr_decoration.disabled.no_branches'
+ )}
+ values={{
+ link: (
+ <a
+ href={getEditionUrl(getEdition(EditionKey.developer), {
+ sourceEdition: EditionKey.community
+ })}
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate(
+ 'settings.almintegration.feature.pr_decoration.disabled.no_branches.link'
+ )}
+ </a>
+ )
+ }}
+ />
+ }
+ />
+ </div>
+ );
+}
+
function getImportFeatureStatus(
definition: AlmBindingDefinition,
multipleDefinitions: boolean,
/>
</div>
);
- } else if (!definition.url) {
+ }
+
+ if (!definition.url) {
return (
<div className="display-inline-flex-center">
<strong className="spacer-left">
/>
</div>
);
- } else {
- return STATUS_ICON[type];
}
+
+ return STATUS_ICON[type];
}
export default function AlmBindingDefinitionBox(props: AlmBindingDefinitionBoxProps) {
- const { alm, definition, multipleDefinitions, status = DEFAULT_STATUS } = props;
+ const { alm, branchesEnabled, definition, multipleDefinitions, status = DEFAULT_STATUS } = props;
const importFeatureTitle =
alm === AlmKeys.GitLab
<>
{status.type !== AlmSettingsBindingStatusType.Warning && (
<div className="display-flex-row spacer-bottom">
- <Tooltip overlay={importFeatureDescription}>
- <div className="huge-spacer-right">
- {importFeatureTitle}
- {STATUS_ICON[status.type]}
- </div>
- </Tooltip>
+ <div className="huge-spacer-right">
+ <Tooltip overlay={importFeatureDescription}>
+ <span>{importFeatureTitle}</span>
+ </Tooltip>
+ {getPRDecorationFeatureStatus(branchesEnabled, status.type)}
+ </div>
<div>
<Tooltip
overlay={translate(
};
fetchPullRequestDecorationSetting = () => {
- const {
- appState: { branchesEnabled }
- } = this.props;
-
- if (!branchesEnabled) {
- return Promise.resolve();
- }
-
this.setState({ loadingAlmDefinitions: true });
return getAlmDefinitions()
.then(definitions => {
/>
GitHub
</>
- )
+ ),
+ requiresBranchesEnabled: false
},
{
key: AlmKeys.Bitbucket,
Bitbucket Server
</>
),
- requiresBranchesEnabled: true
+ requiresBranchesEnabled: false
},
{
key: AlmKeys.Azure,
Azure DevOps Server
</>
),
- requiresBranchesEnabled: true
+ requiresBranchesEnabled: false
},
{
key: AlmKeys.GitLab,
/>
GitLab
</>
- )
+ ),
+ requiresBranchesEnabled: false
}
];
{currentAlm === AlmKeys.Azure && (
<AzureTab
+ branchesEnabled={branchesEnabled}
definitions={definitions.azure}
definitionStatus={definitionStatus}
loadingAlmDefinitions={loadingAlmDefinitions}
)}
{currentAlm === AlmKeys.Bitbucket && (
<BitbucketTab
+ branchesEnabled={branchesEnabled}
definitions={definitions.bitbucket}
definitionStatus={definitionStatus}
loadingAlmDefinitions={loadingAlmDefinitions}
interface Props<B> {
alm: AlmKeys;
+ branchesEnabled: boolean;
createConfiguration: (data: B) => Promise<void>;
defaultBinding: B;
definitions: B[];
render() {
const {
alm,
+ branchesEnabled,
defaultBinding,
definitions,
definitionStatus,
return (
<AlmTabRenderer
alm={alm}
+ branchesEnabled={branchesEnabled}
defaultBinding={defaultBinding}
definitions={definitions}
definitionStatus={definitionStatus}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { FormattedMessage } from 'react-intl';
import { Button } from 'sonar-ui-common/components/controls/buttons';
-import Tooltip from 'sonar-ui-common/components/controls/Tooltip';
import DeferredSpinner from 'sonar-ui-common/components/ui/DeferredSpinner';
import { translate } from 'sonar-ui-common/helpers/l10n';
-import { getEdition, getEditionUrl } from '../../../../helpers/editions';
import {
AlmBindingDefinition,
AlmKeys,
AlmSettingsBindingStatus
} from '../../../../types/alm-settings';
-import { EditionKey } from '../../../../types/editions';
import AlmBindingDefinitionBox from './AlmBindingDefinitionBox';
import AlmBindingDefinitionForm, {
AlmBindingDefinitionFormChildrenProps
} from './AlmBindingDefinitionForm';
+import CreationTooltip from './CreationTooltip';
export interface AlmTabRendererProps<B> {
alm: AlmKeys;
+ branchesEnabled: boolean;
definitionStatus: T.Dict<AlmSettingsBindingStatus>;
editedDefinition?: B;
defaultBinding: B;
) {
const {
alm,
+ branchesEnabled,
definitions,
definitionStatus,
editedDefinition,
} = props;
const preventCreation = loadingProjectCount || (!multipleAlmEnabled && definitions.length > 0);
- const creationTooltip = preventCreation ? (
- <FormattedMessage
- id="settings.almintegration.create.tooltip"
- defaultMessage={translate('settings.almintegration.create.tooltip')}
- values={{
- link: (
- <a
- href={getEditionUrl(getEdition(EditionKey.enterprise), {
- sourceEdition: EditionKey.developer
- })}
- rel="noopener noreferrer"
- target="_blank">
- {translate('settings.almintegration.create.tooltip.link')}
- </a>
- ),
- alm: translate('alm', alm)
- }}
- />
- ) : null;
return (
<div className="big-padded">
)}
<div className={definitions.length > 0 ? 'spacer-bottom text-right' : 'big-spacer-top'}>
- <Tooltip overlay={creationTooltip} mouseLeaveDelay={0.25}>
+ <CreationTooltip alm={alm} preventCreation={preventCreation}>
<Button
data-test="settings__alm-create"
disabled={preventCreation}
onClick={props.onCreate}>
{translate('settings.almintegration.create')}
</Button>
- </Tooltip>
+ </CreationTooltip>
</div>
{definitions.map(def => (
<AlmBindingDefinitionBox
alm={alm}
+ branchesEnabled={branchesEnabled}
definition={def}
key={def.key}
multipleDefinitions={definitions.length > 1}
import AzureForm from './AzureForm';
export interface AzureTabProps {
+ branchesEnabled: boolean;
definitions: AzureBindingDefinition[];
definitionStatus: T.Dict<AlmSettingsBindingStatus>;
loadingAlmDefinitions: boolean;
export default function AzureTab(props: AzureTabProps) {
const {
+ branchesEnabled,
multipleAlmEnabled,
definitions,
definitionStatus,
<div className="bordered">
<AlmTab
alm={AlmKeys.Azure}
+ branchesEnabled={branchesEnabled}
createConfiguration={createAzureConfiguration}
defaultBinding={{ key: '', personalAccessToken: '', url: '' }}
definitions={definitions}
import BitbucketForm from './BitbucketForm';
export interface BitbucketTabProps {
+ branchesEnabled: boolean;
definitions: BitbucketBindingDefinition[];
definitionStatus: T.Dict<AlmSettingsBindingStatus>;
loadingAlmDefinitions: boolean;
export default function BitbucketTab(props: BitbucketTabProps) {
const {
+ branchesEnabled,
multipleAlmEnabled,
definitions,
definitionStatus,
<div className="bordered">
<AlmTab
alm={AlmKeys.Bitbucket}
+ branchesEnabled={branchesEnabled}
createConfiguration={createBitbucketConfiguration}
defaultBinding={{ key: '', url: '', personalAccessToken: '' }}
definitions={definitions}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 Tooltip from 'sonar-ui-common/components/controls/Tooltip';
+import { translate } from 'sonar-ui-common/helpers/l10n';
+import { withAppState } from '../../../../components/hoc/withAppState';
+import { getEdition, getEditionUrl } from '../../../../helpers/editions';
+import { AlmKeys } from '../../../../types/alm-settings';
+import { EditionKey } from '../../../../types/editions';
+
+export interface CreationTooltipProps {
+ alm: AlmKeys;
+ appState: T.AppState;
+ children: React.ReactElement<{}>;
+ preventCreation: boolean;
+}
+
+export function CreationTooltip(props: CreationTooltipProps) {
+ const {
+ alm,
+ appState: { edition },
+ children,
+ preventCreation
+ } = props;
+
+ const sourceEdition = edition ? EditionKey[edition] : undefined;
+
+ return (
+ <Tooltip
+ overlay={
+ preventCreation ? (
+ <FormattedMessage
+ id="settings.almintegration.create.tooltip"
+ defaultMessage={translate('settings.almintegration.create.tooltip')}
+ values={{
+ link: (
+ <a
+ href={getEditionUrl(getEdition(EditionKey.enterprise), {
+ sourceEdition
+ })}
+ rel="noopener noreferrer"
+ target="_blank">
+ {translate('settings.almintegration.create.tooltip.link')}
+ </a>
+ ),
+ alm: translate('alm', alm)
+ }}
+ />
+ ) : null
+ }
+ mouseLeaveDelay={0.25}>
+ {children}
+ </Tooltip>
+ );
+}
+
+export default withAppState(CreationTooltip);
return (
<div className="bordered">
- {branchesEnabled && (
- <>
- <AlmTab
- alm={AlmKeys.GitHub}
- createConfiguration={createGithubConfiguration}
- defaultBinding={{
- key: '',
- appId: '',
- clientId: '',
- clientSecret: '',
- url: '',
- privateKey: ''
+ <AlmTab
+ alm={AlmKeys.GitHub}
+ branchesEnabled={branchesEnabled}
+ createConfiguration={createGithubConfiguration}
+ defaultBinding={{
+ key: '',
+ appId: '',
+ clientId: '',
+ clientSecret: '',
+ url: '',
+ privateKey: ''
+ }}
+ definitions={definitions}
+ definitionStatus={definitionStatus}
+ form={childProps => <GithubForm {...childProps} />}
+ help={
+ <FormattedMessage
+ defaultMessage={translate(`settings.almintegration.github.info`)}
+ id="settings.almintegration.github.info"
+ values={{
+ link: (
+ <Link target="_blank" to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub]}>
+ {translate('learn_more')}
+ </Link>
+ )
}}
- definitions={definitions}
- definitionStatus={definitionStatus}
- form={childProps => <GithubForm {...childProps} />}
- help={
- <FormattedMessage
- defaultMessage={translate(`settings.almintegration.github.info`)}
- id="settings.almintegration.github.info"
- values={{
- link: (
- <Link target="_blank" to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub]}>
- {translate('learn_more')}
- </Link>
- )
- }}
- />
- }
- loadingAlmDefinitions={loadingAlmDefinitions}
- loadingProjectCount={loadingProjectCount}
- multipleAlmEnabled={multipleAlmEnabled}
- onCheck={props.onCheck}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateGithubConfiguration}
/>
+ }
+ loadingAlmDefinitions={loadingAlmDefinitions}
+ loadingProjectCount={loadingProjectCount}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onCheck={props.onCheck}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateGithubConfiguration}
+ />
- <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
- </>
- )}
+ <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
<div className="big-padded">
<CategoryDefinitionsList
return (
<div className="bordered">
- {branchesEnabled && (
- <>
- <AlmTab
- alm={AlmKeys.GitLab}
- createConfiguration={createGitlabConfiguration}
- defaultBinding={{ key: '', personalAccessToken: '', url: '' }}
- definitions={definitions}
- definitionStatus={definitionStatus}
- form={childProps => <GitlabForm {...childProps} />}
- help={
- <FormattedMessage
- defaultMessage={translate(`settings.almintegration.gitlab.info`)}
- id="settings.almintegration.gitlab.info"
- values={{
- link: (
- <Link target="_blank" to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab]}>
- {translate('learn_more')}
- </Link>
- )
- }}
- />
- }
- loadingAlmDefinitions={loadingAlmDefinitions}
- loadingProjectCount={loadingProjectCount}
- multipleAlmEnabled={multipleAlmEnabled}
- onCheck={props.onCheck}
- onDelete={props.onDelete}
- onUpdateDefinitions={props.onUpdateDefinitions}
- updateConfiguration={updateGitlabConfiguration}
+ <AlmTab
+ alm={AlmKeys.GitLab}
+ branchesEnabled={branchesEnabled}
+ createConfiguration={createGitlabConfiguration}
+ defaultBinding={{ key: '', personalAccessToken: '', url: '' }}
+ definitions={definitions}
+ definitionStatus={definitionStatus}
+ form={childProps => <GitlabForm {...childProps} />}
+ help={
+ <FormattedMessage
+ defaultMessage={translate(`settings.almintegration.gitlab.info`)}
+ id="settings.almintegration.gitlab.info"
+ values={{
+ link: (
+ <Link target="_blank" to={ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab]}>
+ {translate('learn_more')}
+ </Link>
+ )
+ }}
/>
+ }
+ loadingAlmDefinitions={loadingAlmDefinitions}
+ loadingProjectCount={loadingProjectCount}
+ multipleAlmEnabled={multipleAlmEnabled}
+ onCheck={props.onCheck}
+ onDelete={props.onDelete}
+ onUpdateDefinitions={props.onUpdateDefinitions}
+ updateConfiguration={updateGitlabConfiguration}
+ />
- <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
- </>
- )}
+ <div className="huge-spacer-top huge-spacer-bottom bordered-top" />
<div className="big-padded">
<CategoryDefinitionsList
expect(
shallowRender({ alm: AlmKeys.Azure, definition: mockAzureBindingDefinition() })
).toMatchSnapshot('Azure DevOps');
+
+ expect(
+ shallowRender({
+ branchesEnabled: false,
+ status: mockAlmSettingsBindingStatus({
+ alertSuccess: true,
+ type: AlmSettingsBindingStatusType.Success
+ })
+ })
+ ).toMatchSnapshot('success with branches disabled');
});
function shallowRender(props: Partial<AlmBindingDefinitionBoxProps> = {}) {
return shallow(
<AlmBindingDefinitionBox
alm={AlmKeys.GitHub}
+ branchesEnabled={true}
definition={mockGithubBindingDefinition()}
multipleDefinitions={false}
onCheck={jest.fn()}
return shallow<AlmTab<AzureBindingDefinition>>(
<AlmTab
alm={AlmKeys.Azure}
+ branchesEnabled={true}
createConfiguration={jest.fn()}
defaultBinding={DEFAULT_BINDING}
definitions={[mockAzureBindingDefinition()]}
return shallow(
<AlmTabRenderer
alm={AlmKeys.Azure}
+ branchesEnabled={true}
defaultBinding={{} as any}
definitions={[]}
definitionStatus={{}}
function shallowRender(props: Partial<AzureTabProps> = {}) {
return shallow(
<AzureTab
+ branchesEnabled={true}
definitions={[mockAzureBindingDefinition()]}
definitionStatus={{}}
loadingAlmDefinitions={false}
function shallowRender(props: Partial<BitbucketTabProps> = {}) {
return shallow(
<BitbucketTab
+ branchesEnabled={true}
definitions={[mockBitbucketBindingDefinition()]}
definitionStatus={{}}
loadingAlmDefinitions={false}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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 { mockAppState } from '../../../../../helpers/testMocks';
+import { AlmKeys } from '../../../../../types/alm-settings';
+import { EditionKey } from '../../../../../types/editions';
+import { CreationTooltip, CreationTooltipProps } from '../CreationTooltip';
+
+it('should render correctly', () => {
+ expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ preventCreation: false })).toMatchSnapshot();
+});
+
+function shallowRender(props: Partial<CreationTooltipProps> = {}) {
+ return shallow(
+ <CreationTooltip
+ alm={AlmKeys.Azure}
+ appState={mockAppState({ edition: EditionKey.community })}
+ preventCreation={true}
+ {...props}>
+ <span>Child</span>
+ </CreationTooltip>
+ );
+}
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('with branch support');
- expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support');
});
function shallowRender(props: Partial<GithubTabProps> = {}) {
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot('with branch support');
- expect(shallowRender({ branchesEnabled: false })).toMatchSnapshot('without branch support');
expect(
shallowRender({
definitions: [mockGitlabBindingDefinition({ url: 'https://gitlab.com/api/v4' })]
<div
className="display-flex-row spacer-bottom"
>
- <Tooltip
- overlay="settings.almintegration.feature.pr_decoration.description"
+ <div
+ className="huge-spacer-right"
>
- <div
- className="huge-spacer-right"
+ <Tooltip
+ overlay="settings.almintegration.feature.pr_decoration.description"
>
- settings.almintegration.feature.pr_decoration.title
- <AlertErrorIcon
- className="spacer-left"
- />
- </div>
- </Tooltip>
+ <span>
+ settings.almintegration.feature.pr_decoration.title
+ </span>
+ </Tooltip>
+ <AlertErrorIcon
+ className="spacer-left"
+ />
+ </div>
<div>
<Tooltip
overlay="settings.almintegration.feature.alm_repo_import.description"
<div
className="display-flex-row spacer-bottom"
>
- <Tooltip
- overlay="settings.almintegration.feature.pr_decoration.description"
+ <div
+ className="huge-spacer-right"
>
- <div
- className="huge-spacer-right"
+ <Tooltip
+ overlay="settings.almintegration.feature.pr_decoration.description"
>
- settings.almintegration.feature.pr_decoration.title
- <AlertSuccessIcon
- className="spacer-left"
- />
- </div>
- </Tooltip>
+ <span>
+ settings.almintegration.feature.pr_decoration.title
+ </span>
+ </Tooltip>
+ <AlertSuccessIcon
+ className="spacer-left"
+ />
+ </div>
<div>
<Tooltip
overlay="settings.almintegration.feature.alm_repo_import.description"
<div
className="display-flex-row spacer-bottom"
>
- <Tooltip
- overlay="settings.almintegration.feature.pr_decoration.description"
+ <div
+ className="huge-spacer-right"
+ >
+ <Tooltip
+ overlay="settings.almintegration.feature.pr_decoration.description"
+ >
+ <span>
+ settings.almintegration.feature.pr_decoration.title
+ </span>
+ </Tooltip>
+ <AlertSuccessIcon
+ className="spacer-left"
+ />
+ </div>
+ <div>
+ <Tooltip
+ overlay="settings.almintegration.feature.alm_repo_import.description"
+ >
+ <span>
+ settings.almintegration.feature.alm_repo_import.title
+ </span>
+ </Tooltip>
+ <AlertSuccessIcon
+ className="spacer-left"
+ />
+ </div>
+ </div>
+ <div
+ className="width-50"
+ >
+ <Alert
+ variant="success"
+ >
+ settings.almintegration.configuration_valid
+ </Alert>
+ </div>
+ <Button
+ className="big-spacer-top"
+ onClick={[Function]}
+ >
+ settings.almintegration.check_configuration
+ </Button>
+</div>
+`;
+
+exports[`should render correctly: success with branches disabled 1`] = `
+<div
+ className="boxed-group-inner bordered spacer-top spacer-bottom it__alm-binding-definition"
+>
+ <div
+ className="actions pull-right"
+ >
+ <Button
+ onClick={[Function]}
+ >
+ <EditIcon
+ className="spacer-right"
+ />
+ edit
+ </Button>
+ <Button
+ className="button-red spacer-left"
+ onClick={[Function]}
+ >
+ <DeleteIcon
+ className="spacer-right"
+ />
+ delete
+ </Button>
+ </div>
+ <div
+ className="big-spacer-bottom"
+ >
+ <h3>
+ key
+ </h3>
+ <span>
+ http://github.enterprise.com
+ </span>
+ </div>
+ <div
+ className="display-flex-row spacer-bottom"
+ >
+ <div
+ className="huge-spacer-right"
>
+ <Tooltip
+ overlay="settings.almintegration.feature.pr_decoration.description"
+ >
+ <span>
+ settings.almintegration.feature.pr_decoration.title
+ </span>
+ </Tooltip>
<div
- className="huge-spacer-right"
+ className="display-inline-flex-center"
>
- settings.almintegration.feature.pr_decoration.title
- <AlertSuccessIcon
+ <strong
className="spacer-left"
+ >
+ settings.almintegration.feature.pr_decoration.disabled
+ </strong>
+ <HelpTooltip
+ className="little-spacer-left"
+ overlay={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.feature.pr_decoration.disabled.no_branches"
+ id="settings.almintegration.feature.pr_decoration.disabled.no_branches"
+ values={
+ Object {
+ "link": <a
+ href="https://redirect.sonarsource.com/editions/developer.html?sourceEdition=community"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ settings.almintegration.feature.pr_decoration.disabled.no_branches.link
+ </a>,
+ }
+ }
+ />
+ }
/>
</div>
- </Tooltip>
+ </div>
<div>
<Tooltip
overlay="settings.almintegration.feature.alm_repo_import.description"
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
/>
<AzureTab
+ branchesEnabled={true}
definitionStatus={Object {}}
definitions={Array []}
loadingAlmDefinitions={false}
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
/>
<BitbucketTab
+ branchesEnabled={true}
definitionStatus={Object {}}
definitions={Array []}
loadingAlmDefinitions={false}
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
/>
GitHub
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "bitbucket",
/>
Bitbucket Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "azure",
/>
Azure DevOps Server
</React.Fragment>,
- "requiresBranchesEnabled": true,
+ "requiresBranchesEnabled": false,
},
Object {
"key": "gitlab",
/>
GitLab
</React.Fragment>,
+ "requiresBranchesEnabled": false,
},
]
}
exports[`should render correctly 1`] = `
<AlmTabRenderer
alm="azure"
+ branchesEnabled={true}
defaultBinding={
Object {
"key": "",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={
- <FormattedMessage
- defaultMessage="settings.almintegration.create.tooltip"
- id="settings.almintegration.create.tooltip"
- values={
- Object {
- "alm": "alm.azure",
- "link": <a
- href="https://redirect.sonarsource.com/editions/enterprise.html?sourceEdition=developer"
- rel="noopener noreferrer"
- target="_blank"
- >
- settings.almintegration.create.tooltip.link
- </a>,
- }
- }
- />
- }
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={true}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={
- <FormattedMessage
- defaultMessage="settings.almintegration.create.tooltip"
- id="settings.almintegration.create.tooltip"
- values={
- Object {
- "alm": "alm.azure",
- "link": <a
- href="https://redirect.sonarsource.com/editions/enterprise.html?sourceEdition=developer"
- rel="noopener noreferrer"
- target="_blank"
- >
- settings.almintegration.create.tooltip.link
- </a>,
- }
- }
- />
- }
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={true}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={
- <FormattedMessage
- defaultMessage="settings.almintegration.create.tooltip"
- id="settings.almintegration.create.tooltip"
- values={
- Object {
- "alm": "alm.azure",
- "link": <a
- href="https://redirect.sonarsource.com/editions/enterprise.html?sourceEdition=developer"
- rel="noopener noreferrer"
- target="_blank"
- >
- settings.almintegration.create.tooltip.link
- </a>,
- }
- }
- />
- }
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={true}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={
- <FormattedMessage
- defaultMessage="settings.almintegration.create.tooltip"
- id="settings.almintegration.create.tooltip"
- values={
- Object {
- "alm": "alm.azure",
- "link": <a
- href="https://redirect.sonarsource.com/editions/enterprise.html?sourceEdition=developer"
- rel="noopener noreferrer"
- target="_blank"
- >
- settings.almintegration.create.tooltip.link
- </a>,
- }
- }
- />
- }
+ <Connect(withAppState(CreationTooltip))
+ alm="azure"
+ preventCreation={true}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="azure"
+ branchesEnabled={true}
definition={
Object {
"key": "key",
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="github"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="github"
+ branchesEnabled={true}
definition={
Object {
"appId": "123456",
<div
className="big-spacer-top"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="github"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionForm
bindingDefinition={
<div
className="spacer-bottom text-right"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="github"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
<AlmBindingDefinitionBox
alm="github"
+ branchesEnabled={true}
definition={
Object {
"appId": "123456",
<div
className="big-spacer-top"
>
- <Tooltip
- mouseLeaveDelay={0.25}
- overlay={null}
+ <Connect(withAppState(CreationTooltip))
+ alm="github"
+ preventCreation={false}
>
<Button
data-test="settings__alm-create"
>
settings.almintegration.create
</Button>
- </Tooltip>
+ </Connect(withAppState(CreationTooltip))>
</div>
</DeferredSpinner>
</div>
>
<AlmTab
alm="azure"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
>
<AlmTab
alm="bitbucket"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
--- /dev/null
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly 1`] = `
+<Tooltip
+ mouseLeaveDelay={0.25}
+ overlay={
+ <FormattedMessage
+ defaultMessage="settings.almintegration.create.tooltip"
+ id="settings.almintegration.create.tooltip"
+ values={
+ Object {
+ "alm": "alm.azure",
+ "link": <a
+ href="https://redirect.sonarsource.com/editions/enterprise.html?sourceEdition=community"
+ rel="noopener noreferrer"
+ target="_blank"
+ >
+ settings.almintegration.create.tooltip.link
+ </a>,
+ }
+ }
+ />
+ }
+>
+ <span>
+ Child
+ </span>
+</Tooltip>
+`;
+
+exports[`should render correctly 2`] = `
+<Tooltip
+ mouseLeaveDelay={0.25}
+ overlay={null}
+>
+ <span>
+ Child
+ </span>
+</Tooltip>
+`;
>
<AlmTab
alm="github"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
</div>
</div>
`;
-
-exports[`should render correctly: without branch support 1`] = `
-<div
- className="bordered"
->
- <div
- className="big-padded"
- >
- <Connect(SubCategoryDefinitionsList)
- category="almintegration"
- subCategory="github"
- />
- </div>
-</div>
-`;
>
<AlmTab
alm="gitlab"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
>
<AlmTab
alm="gitlab"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
>
<AlmTab
alm="gitlab"
+ branchesEnabled={true}
createConfiguration={[Function]}
defaultBinding={
Object {
</div>
</div>
`;
-
-exports[`should render correctly: without branch support 1`] = `
-<div
- className="bordered"
->
- <div
- className="big-padded"
- >
- <Connect(SubCategoryDefinitionsList)
- category="almintegration"
- subCategory="gitlab"
- />
- </div>
-</div>
-`;
settings.almintegration.feature.pr_decoration.description=Add analysis and a Quality Gate to your Pull Requests directly in your ALM provider's interface.
settings.almintegration.feature.mr_decoration.title=Merge Request Decoration
settings.almintegration.feature.mr_decoration.description=Add analysis and a Quality Gate to your Merge Requests directly in your ALM provider's interface.
+settings.almintegration.feature.pr_decoration.disabled=Disabled
+settings.almintegration.feature.pr_decoration.disabled.no_branches=Upgrade to {link} to enable this feature.
+settings.almintegration.feature.pr_decoration.disabled.no_branches.link=Developer Edition
settings.almintegration.feature.alm_repo_import.title=Import repositories from your ALM
settings.almintegration.feature.alm_repo_import.description=Select repositories from your ALM, and import them into SonarQube.
settings.almintegration.feature.alm_repo_import.disabled=Disabled