import { differenceBy } from 'lodash';
import * as React from 'react';
import { connect } from 'react-redux';
+import { getProjectAlmBinding } from '../../api/alm-settings';
import { getBranches, getPullRequests } from '../../api/branches';
import { getAnalysisStatus, getTasksForComponent } from '../../api/ce';
import { getComponentData } from '../../api/components';
} from '../../helpers/branch-like';
import { getPortfolioUrl } from '../../helpers/urls';
import { registerBranchStatus, requireAuthorization } from '../../store/rootActions';
+import { ProjectAlmBindingResponse } from '../../types/alm-settings';
import { BranchLike } from '../../types/branch-like';
import { isPortfolioLike } from '../../types/component';
import { Task, TaskStatuses, TaskWarning } from '../../types/tasks';
currentTask?: Task;
isPending: boolean;
loading: boolean;
+ projectBinding?: ProjectAlmBindingResponse;
tasksInProgress?: Task[];
warnings: TaskWarning[];
}
Promise.all([
getComponentNavigation({ component: key, branch, pullRequest }),
- getComponentData({ component: key, branch, pullRequest })
+ getComponentData({ component: key, branch, pullRequest }),
+ getProjectAlmBinding(key).catch(() => undefined)
])
- .then(([nav, { component }]) => {
+ .then(([nav, { component }, projectBinding]) => {
const componentWithQualifier = this.addQualifier({ ...nav, ...component });
/*
this.props.router.replace(getPortfolioUrl(component.key));
}
+ if (this.mounted) {
+ this.setState({ projectBinding });
+ }
+
return componentWithQualifier;
}, onError)
.then(this.fetchBranches)
return <PageUnavailableDueToIndexation component={component} />;
}
- const { branchLike, branchLikes, currentTask, isPending, tasksInProgress } = this.state;
+ const {
+ branchLike,
+ branchLikes,
+ currentTask,
+ isPending,
+ projectBinding,
+ tasksInProgress
+ } = this.state;
const isInProgress = tasksInProgress && tasksInProgress.length > 0;
return (
isPending={isPending}
onComponentChange={this.handleComponentChange}
onWarningDismiss={this.handleWarningDismiss}
+ projectBinding={projectBinding}
warnings={this.state.warnings}
/>
)}
isInProgress,
isPending,
onBranchesChange: this.handleBranchesChange,
- onComponentChange: this.handleComponentChange
+ onComponentChange: this.handleComponentChange,
+ projectBinding
})}
</ComponentContext.Provider>
)}
import { shallow } from 'enzyme';
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
+import { getProjectAlmBinding } from '../../../api/alm-settings';
import { getBranches, getPullRequests } from '../../../api/branches';
import { getAnalysisStatus, getTasksForComponent } from '../../../api/ce';
import { getComponentData } from '../../../api/components';
import { mockBranch, mockMainBranch, mockPullRequest } from '../../../helpers/mocks/branch-like';
import { mockTask } from '../../../helpers/mocks/tasks';
import { mockComponent, mockLocation, mockRouter } from '../../../helpers/testMocks';
+import { AlmKeys } from '../../../types/alm-settings';
import { ComponentQualifier } from '../../../types/component';
import { TaskStatuses } from '../../../types/tasks';
import { ComponentContainer } from '../ComponentContainer';
})
}));
+jest.mock('../../../api/alm-settings', () => ({
+ getProjectAlmBinding: jest.fn().mockResolvedValue(undefined)
+}));
+
// mock this, because some of its children are using redux store
jest.mock('../nav/component/ComponentNav', () => ({
default: () => null
expect(wrapper.state().component).toEqual({ qualifier: 'TRK', visibility: 'private' });
});
+it('loads the project binding, if any', async () => {
+ (getProjectAlmBinding as jest.Mock).mockResolvedValueOnce(undefined).mockResolvedValueOnce({
+ alm: AlmKeys.GitHub,
+ key: 'foo'
+ });
+
+ const wrapper = shallowRender();
+ await waitAndUpdate(wrapper);
+ expect(getProjectAlmBinding).toBeCalled();
+ expect(wrapper.state().projectBinding).toBeUndefined();
+
+ wrapper.setProps({ location: mockLocation({ query: { id: 'bar' } }) });
+ await waitAndUpdate(wrapper);
+ expect(wrapper.state().projectBinding).toEqual({ alm: AlmKeys.GitHub, key: 'foo' });
+});
+
it("doesn't load branches portfolio", async () => {
const wrapper = shallowRender({ location: mockLocation({ query: { id: 'portfolioKey' } }) });
await new Promise(setImmediate);
import * as classNames from 'classnames';
import * as React from 'react';
import ContextNavBar from 'sonar-ui-common/components/ui/ContextNavBar';
+import { ProjectAlmBindingResponse } from '../../../../types/alm-settings';
import { BranchLike } from '../../../../types/branch-like';
import { ComponentQualifier } from '../../../../types/component';
import { Task, TaskStatuses, TaskWarning } from '../../../../types/tasks';
isPending?: boolean;
onComponentChange: (changes: Partial<T.Component>) => void;
onWarningDismiss: () => void;
+ projectBinding?: ProjectAlmBindingResponse;
warnings: TaskWarning[];
}
currentTaskOnSameBranch,
isInProgress,
isPending,
+ projectBinding,
warnings
} = props;
const { contextNavHeightRaw, globalNavHeightRaw } = rawSizes;
branchLikes={branchLikes}
component={component}
currentBranchLike={currentBranchLike}
+ projectBinding={projectBinding}
/>
<HeaderMeta
branchLike={currentBranchLike}
import Favorite from '../../../../components/controls/Favorite';
import { isLoggedIn } from '../../../../helpers/users';
import { getCurrentUser, Store } from '../../../../store/rootReducer';
+import { ProjectAlmBindingResponse } from '../../../../types/alm-settings';
import { BranchLike } from '../../../../types/branch-like';
import BranchLikeNavigation from './branch-like/BranchLikeNavigation';
import CurrentBranchLikeMergeInformation from './branch-like/CurrentBranchLikeMergeInformation';
component: T.Component;
currentBranchLike: BranchLike | undefined;
currentUser: T.CurrentUser;
+ projectBinding?: ProjectAlmBindingResponse;
}
export function Header(props: HeaderProps) {
- const { branchLikes, component, currentBranchLike, currentUser } = props;
+ const { branchLikes, component, currentBranchLike, currentUser, projectBinding } = props;
return (
<>
branchLikes={branchLikes}
component={component}
currentBranchLike={currentBranchLike}
+ projectBinding={projectBinding}
/>
<CurrentBranchLikeMergeInformation currentBranchLike={currentBranchLike} />
</>
import * as React from 'react';
import Toggler from 'sonar-ui-common/components/controls/Toggler';
import { withAppState } from '../../../../../components/hoc/withAppState';
+import { ProjectAlmBindingResponse } from '../../../../../types/alm-settings';
import { BranchLike } from '../../../../../types/branch-like';
import './BranchLikeNavigation.css';
import CurrentBranchLike from './CurrentBranchLike';
branchLikes: BranchLike[];
component: T.Component;
currentBranchLike: BranchLike;
+ projectBinding?: ProjectAlmBindingResponse;
}
export function BranchLikeNavigation(props: BranchLikeNavigationProps) {
branchLikes,
component,
component: { configuration },
- currentBranchLike
+ currentBranchLike,
+ projectBinding
} = props;
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
component={component}
currentBranchLike={currentBranchLike}
hasManyBranches={hasManyBranches}
+ projectBinding={projectBinding}
/>
);
import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
import DropdownIcon from 'sonar-ui-common/components/icons/DropdownIcon';
import PlusCircleIcon from 'sonar-ui-common/components/icons/PlusCircleIcon';
-import { translate } from 'sonar-ui-common/helpers/l10n';
+import { translate, translateWithParameters } from 'sonar-ui-common/helpers/l10n';
import DocumentationTooltip from '../../../../../components/common/DocumentationTooltip';
import BranchLikeIcon from '../../../../../components/icons/BranchLikeIcon';
import { getBranchLikeDisplayName } from '../../../../../helpers/branch-like';
import { getApplicationAdminUrl } from '../../../../../helpers/urls';
+import { AlmKeys, ProjectAlmBindingResponse } from '../../../../../types/alm-settings';
import { BranchLike } from '../../../../../types/branch-like';
import { ComponentQualifier } from '../../../../../types/component';
import { colors } from '../../../../theme';
component: T.Component;
currentBranchLike: BranchLike;
hasManyBranches: boolean;
+ projectBinding?: ProjectAlmBindingResponse;
}
export function CurrentBranchLike(props: CurrentBranchLikeProps) {
component,
component: { configuration },
currentBranchLike,
- hasManyBranches
+ hasManyBranches,
+ projectBinding
} = props;
const displayName = getBranchLikeDisplayName(currentBranchLike);
const isApplication = component.qualifier === ComponentQualifier.Application;
const canAdminComponent = configuration && configuration.showSettings;
+ const isGitLab = projectBinding !== undefined && projectBinding.alm === AlmKeys.GitLab;
const additionalIcon = () => {
const plusIcon = <PlusCircleIcon fill={colors.blue} size={12} />;
if (!branchesEnabled) {
return (
<DocumentationTooltip
- content={translate('branch_like_navigation.no_branch_support.content')}
+ content={
+ projectBinding !== undefined
+ ? translateWithParameters(
+ `branch_like_navigation.no_branch_support.content_x.${isGitLab ? 'mr' : 'pr'}`,
+ translate('alm', projectBinding.alm)
+ )
+ : translate('branch_like_navigation.no_branch_support.content')
+ }
data-test="branches-support-disabled"
links={[
{
label: translate('learn_more')
}
]}
- title={translate('branch_like_navigation.no_branch_support.title')}>
+ title={
+ projectBinding !== undefined
+ ? translate(
+ 'branch_like_navigation.no_branch_support.title',
+ isGitLab ? 'mr' : 'pr'
+ )
+ : translate('branch_like_navigation.no_branch_support.title')
+ }>
{plusIcon}
</DocumentationTooltip>
);
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import {
+ mockProjectGithubBindingResponse,
+ mockProjectGitLabBindingResponse
+} from '../../../../../../helpers/mocks/alm-settings';
import { mockMainBranch } from '../../../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../../../helpers/testMocks';
import { ComponentQualifier } from '../../../../../../types/component';
import { CurrentBranchLike, CurrentBranchLikeProps } from '../CurrentBranchLike';
-describe('CurrentBranchLikeRenderer should render correctly for application when', () => {
- it('there is only one branch and the user can admin the application', () => {
+describe('applications', () => {
+ it('should render correctly when there is only one branch and the user can admin the application', () => {
const wrapper = shallowRender({
component: mockComponent({
configuration: { showSettings: true },
expect(wrapper).toMatchSnapshot();
});
- it("there is only one branch and the user CAN'T admin the application", () => {
+ it("should render correctly when there is only one branch and the user CAN'T admin the application", () => {
const wrapper = shallowRender({
component: mockComponent({
configuration: { showSettings: false },
expect(wrapper).toMatchSnapshot();
});
- it('there are many branchlikes', () => {
+ it('should render correctly when there are many branchlikes', () => {
const wrapper = shallowRender({
branchesEnabled: true,
component: mockComponent({
});
});
-describe('CurrentBranchLikeRenderer should render correctly for project when', () => {
- it('branches support is disabled', () => {
- const wrapper = shallowRender({
- branchesEnabled: false,
- component: mockComponent({
- qualifier: ComponentQualifier.Project
+describe('projects', () => {
+ it('should render correctly when branches support is disabled', () => {
+ expect(
+ shallowRender({
+ branchesEnabled: false,
+ component: mockComponent({
+ qualifier: ComponentQualifier.Project
+ })
})
- });
- expect(wrapper).toMatchSnapshot();
+ ).toMatchSnapshot('default');
+ expect(
+ shallowRender({
+ branchesEnabled: false,
+ component: mockComponent({
+ qualifier: ComponentQualifier.Project
+ }),
+ projectBinding: mockProjectGithubBindingResponse()
+ })
+ ).toMatchSnapshot('alm with prs');
+ expect(
+ shallowRender({
+ branchesEnabled: false,
+ component: mockComponent({
+ qualifier: ComponentQualifier.Project
+ }),
+ projectBinding: mockProjectGitLabBindingResponse()
+ })
+ ).toMatchSnapshot('alm with mrs');
});
- it('there is only one branchlike', () => {
+ it('should render correctly when there is only one branchlike', () => {
const wrapper = shallowRender({
branchesEnabled: true,
component: mockComponent({
expect(wrapper).toMatchSnapshot();
});
- it('there are many branchlikes', () => {
+ it('should render correctly when there are many branchlikes', () => {
const wrapper = shallowRender({
branchesEnabled: true,
component: mockComponent({
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`CurrentBranchLikeRenderer should render correctly for application when there are many branchlikes 1`] = `
+exports[`applications should render correctly when there are many branchlikes 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
</span>
`;
-exports[`CurrentBranchLikeRenderer should render correctly for application when there is only one branch and the user CAN'T admin the application 1`] = `
+exports[`applications should render correctly when there is only one branch and the user CAN'T admin the application 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
</span>
`;
-exports[`CurrentBranchLikeRenderer should render correctly for application when there is only one branch and the user can admin the application 1`] = `
+exports[`applications should render correctly when there is only one branch and the user can admin the application 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
</span>
`;
-exports[`CurrentBranchLikeRenderer should render correctly for project when branches support is disabled 1`] = `
+exports[`projects should render correctly when branches support is disabled: alm with mrs 1`] = `
+<span
+ className="display-flex-center flex-shrink text-ellipsis"
+>
+ <BranchLikeIcon
+ branchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": true,
+ "name": "master",
+ }
+ }
+ />
+ <span
+ className="spacer-left spacer-right flex-shrink text-ellipsis js-branch-like-name"
+ title="master"
+ >
+ master
+ </span>
+ <DocumentationTooltip
+ content="branch_like_navigation.no_branch_support.content_x.mr.alm.gitlab"
+ data-test="branches-support-disabled"
+ links={
+ Array [
+ Object {
+ "href": "https://redirect.sonarsource.com/editions/developer.html",
+ "label": "learn_more",
+ },
+ ]
+ }
+ title="branch_like_navigation.no_branch_support.title.mr"
+ >
+ <PlusCircleIcon
+ fill="#4b9fd5"
+ size={12}
+ />
+ </DocumentationTooltip>
+</span>
+`;
+
+exports[`projects should render correctly when branches support is disabled: alm with prs 1`] = `
+<span
+ className="display-flex-center flex-shrink text-ellipsis"
+>
+ <BranchLikeIcon
+ branchLike={
+ Object {
+ "analysisDate": "2018-01-01",
+ "excludedFromPurge": true,
+ "isMain": true,
+ "name": "master",
+ }
+ }
+ />
+ <span
+ className="spacer-left spacer-right flex-shrink text-ellipsis js-branch-like-name"
+ title="master"
+ >
+ master
+ </span>
+ <DocumentationTooltip
+ content="branch_like_navigation.no_branch_support.content_x.pr.alm.github"
+ data-test="branches-support-disabled"
+ links={
+ Array [
+ Object {
+ "href": "https://redirect.sonarsource.com/editions/developer.html",
+ "label": "learn_more",
+ },
+ ]
+ }
+ title="branch_like_navigation.no_branch_support.title.pr"
+ >
+ <PlusCircleIcon
+ fill="#4b9fd5"
+ size={12}
+ />
+ </DocumentationTooltip>
+</span>
+`;
+
+exports[`projects should render correctly when branches support is disabled: default 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
</span>
`;
-exports[`CurrentBranchLikeRenderer should render correctly for project when there are many branchlikes 1`] = `
+exports[`projects should render correctly when there are many branchlikes 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
</span>
`;
-exports[`CurrentBranchLikeRenderer should render correctly for project when there is only one branchlike 1`] = `
+exports[`projects should render correctly when there is only one branchlike 1`] = `
<span
className="display-flex-center flex-shrink text-ellipsis"
>
import Suggestions from '../../../app/components/embed-docs-modal/Suggestions';
import { Router, withRouter } from '../../../components/hoc/withRouter';
import { isPullRequest } from '../../../helpers/branch-like';
+import { ProjectAlmBindingResponse } from '../../../types/alm-settings';
import { BranchLike } from '../../../types/branch-like';
import { isPortfolioLike } from '../../../types/component';
import BranchOverview from '../branches/BranchOverview';
component: T.Component;
isInProgress?: boolean;
isPending?: boolean;
+ projectBinding?: ProjectAlmBindingResponse;
router: Pick<Router, 'replace'>;
}
};
render() {
- const { branchLike, branchLikes, component } = this.props;
+ const { branchLike, branchLikes, component, projectBinding } = this.props;
if (this.isPortfolio()) {
return null;
branchLikes={branchLikes}
component={component}
hasAnalyses={this.props.isPending || this.props.isInProgress}
+ projectBinding={projectBinding}
/>
) : (
<BranchOverview branch={branchLike} component={component} />
import { getBranchLikeDisplayName, isBranch, isMainBranch } from '../../../helpers/branch-like';
import { isLoggedIn } from '../../../helpers/users';
import { getCurrentUser, Store } from '../../../store/rootReducer';
+import { ProjectAlmBindingResponse } from '../../../types/alm-settings';
import { BranchLike } from '../../../types/branch-like';
import { ComponentQualifier } from '../../../types/component';
-interface Props {
+export interface EmptyOverviewProps {
branchLike?: BranchLike;
branchLikes: BranchLike[];
component: T.Component;
currentUser: T.CurrentUser;
hasAnalyses?: boolean;
+ projectBinding?: ProjectAlmBindingResponse;
}
-export function EmptyOverview(props: Props) {
- const { branchLike, branchLikes, component, currentUser, hasAnalyses } = props;
+export function EmptyOverview(props: EmptyOverviewProps) {
+ const { branchLike, branchLikes, component, currentUser, hasAnalyses, projectBinding } = props;
if (component.qualifier === ComponentQualifier.Application) {
return (
{isLoggedIn(currentUser) ? (
<>
{showWarning && <Alert variant="warning">{warning}</Alert>}
- {showTutorial && <TutorialSelection component={component} currentUser={currentUser} />}
+ {showTutorial && (
+ <TutorialSelection
+ component={component}
+ currentUser={currentUser}
+ projectBinding={projectBinding}
+ />
+ )}
</>
) : (
<Alert variant="warning">{warning}</Alert>
*/
import { shallow } from 'enzyme';
import * as React from 'react';
+import { mockProjectGithubBindingResponse } from '../../../../helpers/mocks/alm-settings';
import { mockBranch, mockMainBranch, mockPullRequest } from '../../../../helpers/mocks/branch-like';
import { mockComponent, mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { ComponentQualifier } from '../../../../types/component';
-import { EmptyOverview } from '../EmptyOverview';
+import { EmptyOverview, EmptyOverviewProps } from '../EmptyOverview';
it('renders correctly', () => {
expect(shallowRender()).toMatchSnapshot();
expect(shallowRender({ hasAnalyses: true })).toMatchSnapshot();
expect(shallowRender({ currentUser: mockCurrentUser() })).toMatchSnapshot();
+ expect(shallowRender({ projectBinding: mockProjectGithubBindingResponse() })).toMatchSnapshot();
});
it('should render another message when there are branches', () => {
).toMatchSnapshot();
});
-function shallowRender(props = {}) {
- return shallow(
+function shallowRender(props: Partial<EmptyOverviewProps> = {}) {
+ return shallow<EmptyOverviewProps>(
<EmptyOverview
branchLike={mockMainBranch()}
branchLikes={[mockMainBranch()]}
</div>
`;
+exports[`renders correctly 4`] = `
+<div
+ className="page page-limited"
+>
+ <withRouter(TutorialSelection)
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ "version": "0.0.1",
+ }
+ }
+ currentUser={
+ Object {
+ "groups": Array [],
+ "isLoggedIn": true,
+ "login": "luke",
+ "name": "Skywalker",
+ "scmAccounts": Array [],
+ }
+ }
+ projectBinding={
+ Object {
+ "alm": "github",
+ "key": "foo",
+ "monorepo": true,
+ "repository": "PROJECT_KEY",
+ }
+ }
+ />
+</div>
+`;
+
exports[`should not render the tutorial for applications 1`] = `
<div
className="page page-limited"
import { withCurrentUser } from '../../../components/hoc/withCurrentUser';
import TutorialSelection from '../../../components/tutorials/TutorialSelection';
import { isLoggedIn } from '../../../helpers/users';
+import { ProjectAlmBindingResponse } from '../../../types/alm-settings';
export interface TutorialsAppProps {
component: T.Component;
currentUser: T.CurrentUser;
+ projectBinding?: ProjectAlmBindingResponse;
}
export function TutorialsApp(props: TutorialsAppProps) {
- const { component, currentUser } = props;
+ const { component, currentUser, projectBinding } = props;
if (!isLoggedIn(currentUser)) {
handleRequiredAuthentication();
return (
<div className="page page-limited">
- <TutorialSelection component={component} currentUser={currentUser} />
+ <TutorialSelection
+ component={component}
+ currentUser={currentUser}
+ projectBinding={projectBinding}
+ />
</div>
);
}
import { shallow } from 'enzyme';
import * as React from 'react';
import handleRequiredAuthentication from 'sonar-ui-common/helpers/handleRequiredAuthentication';
+import { mockProjectAzureBindingResponse } from '../../../../helpers/mocks/alm-settings';
import { mockComponent, mockCurrentUser, mockLoggedInUser } from '../../../../helpers/testMocks';
import { TutorialsApp, TutorialsAppProps } from '../TutorialsApp';
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
+ expect(shallowRender({ projectBinding: mockProjectAzureBindingResponse() })).toMatchSnapshot();
});
it('should redirect if user is not logged in', () => {
/>
</div>
`;
+
+exports[`should render correctly 2`] = `
+<div
+ className="page page-limited"
+>
+ <withRouter(TutorialSelection)
+ component={
+ Object {
+ "breadcrumbs": Array [],
+ "key": "my-project",
+ "name": "MyProject",
+ "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 [],
+ }
+ }
+ projectBinding={
+ Object {
+ "alm": "azure",
+ "key": "foo",
+ "monorepo": false,
+ "repository": "REPOSITORY_NAME",
+ "slug": "PROJECT_NAME",
+ "url": "https://ado.my_company.com/mycollection",
+ }
+ }
+ />
+</div>
+`;
import * as React from 'react';
import { WithRouterProps } from 'react-router';
import { getHostUrl } from 'sonar-ui-common/helpers/urls';
-import { getAlmDefinitionsNoCatch, getProjectAlmBinding } from '../../api/alm-settings';
+import { getAlmDefinitionsNoCatch } from '../../api/alm-settings';
import { getValues } from '../../api/settings';
import { AlmBindingDefinition, ProjectAlmBindingResponse } from '../../types/alm-settings';
import { SettingsKey } from '../../types/settings';
interface Props extends Pick<WithRouterProps, 'router' | 'location'> {
component: T.Component;
currentUser: T.LoggedInUser;
+ projectBinding?: ProjectAlmBindingResponse;
}
interface State {
baseUrl: string;
forceManual: boolean;
loading: boolean;
- projectBinding?: ProjectAlmBindingResponse;
}
export class TutorialSelection extends React.PureComponent<Props, State> {
}
fetchAlmBindings = async () => {
- const { component } = this.props;
+ const { projectBinding } = this.props;
- const [almDefinitions, projectBinding] = await Promise.all([
- getAlmDefinitionsNoCatch().catch(() => undefined),
- getProjectAlmBinding(component.key).catch(() => undefined)
- ]);
-
- if (this.mounted) {
- if (projectBinding === undefined) {
- this.setState({ forceManual: true });
- } else {
+ if (projectBinding === undefined) {
+ this.setState({ forceManual: true });
+ } else {
+ const almDefinitions = await getAlmDefinitionsNoCatch().catch(() => undefined);
+ if (this.mounted) {
let almBinding;
if (almDefinitions !== undefined) {
const specificDefinitions = almDefinitions[projectBinding.alm] as AlmBindingDefinition[];
almBinding = specificDefinitions.find(d => d.key === projectBinding.key);
}
- this.setState({ almBinding, forceManual: false, projectBinding });
+ this.setState({ almBinding, forceManual: false });
}
}
};
};
render() {
- const { component, currentUser, location } = this.props;
- const { almBinding, baseUrl, forceManual, loading, projectBinding } = this.state;
+ const { component, currentUser, location, projectBinding } = this.props;
+ const { almBinding, baseUrl, forceManual, loading } = this.state;
const selectedTutorial: TutorialModes | undefined = forceManual
? TutorialModes.Manual
import * as React from 'react';
import { waitAndUpdate } from 'sonar-ui-common/helpers/testUtils';
import { getHostUrl } from 'sonar-ui-common/helpers/urls';
-import { getAlmDefinitionsNoCatch, getProjectAlmBinding } from '../../../api/alm-settings';
+import { getAlmDefinitionsNoCatch } from '../../../api/alm-settings';
import { getValues } from '../../../api/settings';
-import { mockBitbucketBindingDefinition } from '../../../helpers/mocks/alm-settings';
+import {
+ mockBitbucketBindingDefinition,
+ mockProjectBitbucketBindingResponse
+} from '../../../helpers/mocks/alm-settings';
import {
mockComponent,
mockLocation,
}));
jest.mock('../../../api/alm-settings', () => ({
- getProjectAlmBinding: jest.fn().mockRejectedValue(null),
getAlmDefinitionsNoCatch: jest.fn().mockRejectedValue(null)
}));
});
it('should not select anything if project is bound', async () => {
- (getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.BitbucketServer });
- const wrapper = shallowRender();
+ const wrapper = shallowRender({ projectBinding: mockProjectBitbucketBindingResponse() });
await waitAndUpdate(wrapper);
expect(wrapper.state().forceManual).toBe(false);
});
it('should correctly find the global ALM binding definition', async () => {
const key = 'foo';
const almBinding = mockBitbucketBindingDefinition({ key });
- (getProjectAlmBinding as jest.Mock).mockResolvedValueOnce({ alm: AlmKeys.BitbucketServer, key });
(getAlmDefinitionsNoCatch as jest.Mock).mockResolvedValueOnce({
[AlmKeys.BitbucketServer]: [almBinding]
});
- const wrapper = shallowRender();
+ const wrapper = shallowRender({ projectBinding: mockProjectBitbucketBindingResponse({ key }) });
await waitAndUpdate(wrapper);
expect(wrapper.state().almBinding).toBe(almBinding);
});
branch_like_navigation.orphan_pull_requests=Orphan Pull Requests
branch_like_navigation.orphan_pull_requests.tooltip=When the base of a Pull Request is deleted, this Pull Request becomes orphan.
branch_like_navigation.for_merge_into_x_from_y=for merge into {target} from {branch}
-branch_like_navigation.no_branch_support.title=Get the most out of SonarQube with branches analysis
-branch_like_navigation.no_branch_support.content=Analyze each branch of your project separately with the Developer Edition.
+branch_like_navigation.no_branch_support.title=Get the most out of SonarQube with branch and PR/MR analysis
+branch_like_navigation.no_branch_support.title.pr=Get the most out of SonarQube with branch and PR analysis
+branch_like_navigation.no_branch_support.title.mr=Get the most out of SonarQube with branch and MR analysis
+branch_like_navigation.no_branch_support.content=With Developer Edition you can analyze every pull/merge request. You can also watch the quality of your release branches by analyzing each one individually in SonarQube.
+branch_like_navigation.no_branch_support.content_x.pr=With Developer Edition you can analyze every pull request and get the results in {0}. You can also watch the quality of your release branches by analyzing each one individually in SonarQube.
+branch_like_navigation.no_branch_support.content_x.mr=With Developer Edition you can analyze every merge request and get the results in {0}. You can also watch the quality of your release branches by analyzing each one individually in SonarQube.
branch_like_navigation.only_one_branch.title=Learn how to analyze branches in SonarQube
branch_like_navigation.only_one_branch.content=Quickly setup branch analysis and get separate insights for each of your branches and Pull Requests.
branch_like_navigation.only_one_branch.documentation=Branches documentation