Browse Source

SONAR-14394 Add frontend for bitbucket cloud project binding.

tags/8.7.0.41497
Mathieu Suen 3 years ago
parent
commit
0da0c9feef

+ 5
- 0
server/sonar-web/src/main/js/api/alm-settings.ts View File

@@ -26,6 +26,7 @@ import {
AzureProjectAlmBindingParams,
BitbucketBindingDefinition,
BitbucketCloudBindingDefinition,
BitbucketCloudProjectAlmBindingParams,
BitbucketProjectAlmBindingParams,
GithubBindingDefinition,
GithubProjectAlmBindingParams,
@@ -132,6 +133,10 @@ export function setProjectBitbucketBinding(data: BitbucketProjectAlmBindingParam
return post('/api/alm_settings/set_bitbucket_binding', data).catch(throwGlobalError);
}

export function setProjectBitbucketCloudBinding(data: BitbucketCloudProjectAlmBindingParams) {
return post('/api/alm_settings/set_bitbucketcloud_binding', data).catch(throwGlobalError);
}

export function setProjectGithubBinding(data: GithubProjectAlmBindingParams) {
return post('/api/alm_settings/set_github_binding', data).catch(throwGlobalError);
}

+ 38
- 9
server/sonar-web/src/main/js/apps/projects/components/__tests__/ProjectCreationMenu-test.tsx View File

@@ -53,19 +53,48 @@ it('should not fetch alm bindings if user cannot create projects', async () => {
});

it('should filter alm bindings appropriately', async () => {
(getAlmSettings as jest.Mock).mockResolvedValueOnce([
{ alm: AlmKeys.Azure },
{ alm: AlmKeys.BitbucketServer, url: 'b1' },
{ alm: AlmKeys.BitbucketServer, url: 'b2' },
{ alm: AlmKeys.GitHub },
{ alm: AlmKeys.GitLab, url: 'gitlab.com' }
]);
(getAlmSettings as jest.Mock)
.mockResolvedValueOnce([
// Only faulty configs.
{ alm: AlmKeys.Azure }, // Missing some configuration; will be ignored.
{ alm: AlmKeys.BitbucketCloud }, // Bitbucket Cloud isn't supported.
{ alm: AlmKeys.GitLab } // Missing some configuration; will be ignored.
])
.mockResolvedValueOnce([
// All correct configs.
{ alm: AlmKeys.Azure, url: 'http://ado.example.com' },
{ alm: AlmKeys.BitbucketServer, url: 'b1' },
{ alm: AlmKeys.GitHub },
{ alm: AlmKeys.GitLab, url: 'gitlab.com' }
])
.mockResolvedValueOnce([
// Only duplicate ALMs; should all be ignored.
{ alm: AlmKeys.Azure, url: 'http://ado.example.com' },
{ alm: AlmKeys.Azure, url: 'http://ado.example.com' },
{ alm: AlmKeys.BitbucketServer, url: 'b1' },
{ alm: AlmKeys.BitbucketServer, url: 'b1' },
{ alm: AlmKeys.GitHub },
{ alm: AlmKeys.GitHub },
{ alm: AlmKeys.GitLab, url: 'gitlab.com' },
{ alm: AlmKeys.GitLab, url: 'gitlab.com' }
]);

const wrapper = shallowRender();
let wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.state().boundAlms).toEqual([]);

wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.state().boundAlms).toEqual([
AlmKeys.Azure,
AlmKeys.BitbucketServer,
AlmKeys.GitHub,
AlmKeys.GitLab
]);

expect(wrapper.state().boundAlms).toEqual([AlmKeys.GitHub, AlmKeys.GitLab]);
wrapper = shallowRender();
await waitAndUpdate(wrapper);
expect(wrapper.state().boundAlms).toEqual([]);
});

function shallowRender(overrides: Partial<ProjectCreationMenu['props']> = {}) {

+ 21
- 1
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx View File

@@ -217,7 +217,27 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) {
propKey: 'slug',
value: slug || ''
})}
{renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.Bitbucket])}
{renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer])}
</>
);
case AlmKeys.BitbucketCloud:
return (
<>
{renderField({
help: true,
helpParams: {
example: (
<>
{'https://bitbucket.org/{workspace}/'}
<strong>{'{repository}'}</strong>
</>
)
},
id: 'bitbucketcloud.repository',
onFieldChange: props.onFieldChange,
propKey: 'repository',
value: repository || ''
})}
</>
);
case AlmKeys.GitHub:

+ 11
- 0
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx View File

@@ -26,6 +26,7 @@ import {
getProjectAlmBinding,
setProjectAzureBinding,
setProjectBitbucketBinding,
setProjectBitbucketCloudBinding,
setProjectGithubBinding,
setProjectGitlabBinding
} from '../../../../api/alm-settings';
@@ -193,6 +194,16 @@ export class PRDecorationBinding extends React.PureComponent<Props & StateProps,
monorepo
});
}
case AlmKeys.BitbucketCloud: {
if (!repository) {
return Promise.reject();
}
return setProjectBitbucketCloudBinding({
almSetting,
project,
repository
});
}
case AlmKeys.GitHub: {
// By default it must remain true.
const summaryCommentEnabled =

+ 1
- 0
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/AlmSpecificForm-test.tsx View File

@@ -27,6 +27,7 @@ it.each([
[AlmKeys.Azure, true],
[AlmKeys.BitbucketServer, false],
[AlmKeys.BitbucketServer, true],
[AlmKeys.BitbucketCloud, false],
[AlmKeys.GitHub, false],
[AlmKeys.GitHub, true],
[AlmKeys.GitLab, false],

+ 30
- 1
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx View File

@@ -26,6 +26,7 @@ import {
getProjectAlmBinding,
setProjectAzureBinding,
setProjectBitbucketBinding,
setProjectBitbucketCloudBinding,
setProjectGithubBinding,
setProjectGitlabBinding
} from '../../../../../api/alm-settings';
@@ -40,6 +41,7 @@ jest.mock('../../../../../api/alm-settings', () => ({
setProjectBitbucketBinding: jest.fn().mockResolvedValue(undefined),
setProjectGithubBinding: jest.fn().mockResolvedValue(undefined),
setProjectGitlabBinding: jest.fn().mockResolvedValue(undefined),
setProjectBitbucketCloudBinding: jest.fn().mockResolvedValue(undefined),
deleteProjectAlmBinding: jest.fn().mockResolvedValue(undefined)
}));

@@ -94,7 +96,8 @@ describe('handleSubmit', () => {
{ key: 'github', alm: AlmKeys.GitHub },
{ key: 'azure', alm: AlmKeys.Azure },
{ key: 'bitbucket', alm: AlmKeys.BitbucketServer },
{ key: 'gitlab', alm: AlmKeys.GitLab }
{ key: 'gitlab', alm: AlmKeys.GitLab },
{ key: 'bitbucketcloud', alm: AlmKeys.BitbucketCloud }
];

it('should work for github', async () => {
@@ -187,6 +190,28 @@ describe('handleSubmit', () => {
});
expect(wrapper.state().success).toBe(true);
});

it('should work for bitbucket cloud', async () => {
const wrapper = shallowRender();
await waitAndUpdate(wrapper);
const bitbucketKey = 'bitbucketcloud';
const repository = 'repoKey';
wrapper.setState({ formData: { key: bitbucketKey, repository }, instances: [] });
wrapper.instance().handleSubmit();
await waitAndUpdate(wrapper);
expect(setProjectBitbucketCloudBinding).not.toBeCalled();

wrapper.setState({ formData: { key: bitbucketKey, repository }, instances });
wrapper.instance().handleSubmit();
await waitAndUpdate(wrapper);

expect(setProjectBitbucketCloudBinding).toBeCalledWith({
almSetting: bitbucketKey,
project: PROJECT_KEY,
repository
});
expect(wrapper.state().success).toBe(true);
});
});

describe.each([[500], [404]])('For status %i', status => {
@@ -266,6 +291,7 @@ it.each([
[AlmKeys.BitbucketServer, {}],
[AlmKeys.BitbucketServer, { slug: 'test' }],
[AlmKeys.BitbucketServer, { repository: 'test' }],
[AlmKeys.BitbucketCloud, {}],
[AlmKeys.GitHub, {}],
[AlmKeys.GitLab, {}]
])('should properly reject promise for %s & %s', async (almKey: AlmKeys, params: {}) => {
@@ -290,6 +316,7 @@ it('should validate form', async () => {
instances: [
{ key: 'azure', alm: AlmKeys.Azure },
{ key: 'bitbucket', alm: AlmKeys.BitbucketServer },
{ key: 'bitbucketcloud', alm: AlmKeys.BitbucketCloud },
{ key: 'github', alm: AlmKeys.GitHub },
{ key: 'gitlab', alm: AlmKeys.GitLab }
]
@@ -303,6 +330,8 @@ it('should validate form', async () => {
{ values: { key: 'github', repository: 'asdf' }, result: true },
{ values: { key: 'bitbucket', repository: 'key' }, result: false },
{ values: { key: 'bitbucket', repository: 'key', slug: 'slug' }, result: true },
{ values: { key: 'bitbucketcloud', repository: '' }, result: false },
{ values: { key: 'bitbucketcloud', repository: 'key' }, result: true },
{ values: { key: 'gitlab' }, result: false },
{ values: { key: 'gitlab', repository: 'key' }, result: true }
].forEach(({ values, result }) => {

+ 49
- 0
server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap View File

@@ -424,6 +424,55 @@ exports[`it should render correctly for bitbucket and monorepo=true 1`] = `
</Fragment>
`;

exports[`it should render correctly for bitbucketcloud and monorepo=false 1`] = `
<Fragment>
<div
className="form-field"
>
<label
className="display-flex-center"
htmlFor="bitbucketcloud.repository"
>
settings.pr_decoration.binding.form.bitbucketcloud.repository
<em
className="mandatory"
>
*
</em>
<HelpTooltip
className="spacer-left"
overlay={
<FormattedMessage
defaultMessage="settings.pr_decoration.binding.form.bitbucketcloud.repository.help"
id="settings.pr_decoration.binding.form.bitbucketcloud.repository.help"
values={
Object {
"example": <React.Fragment>
https://bitbucket.org/{workspace}/
<strong>
{repository}
</strong>
</React.Fragment>,
}
}
/>
}
placement="right"
/>
</label>
<input
className="input-super-large"
id="bitbucketcloud.repository"
maxLength={256}
name="bitbucketcloud.repository"
onChange={[Function]}
type="text"
value=""
/>
</div>
</Fragment>
`;

exports[`it should render correctly for github and monorepo=false 1`] = `
<Fragment>
<div

+ 4
- 0
server/sonar-web/src/main/js/types/alm-settings.ts View File

@@ -113,6 +113,10 @@ export interface BitbucketProjectAlmBindingParams extends ProjectAlmBindingParam
monorepo: boolean;
}

export interface BitbucketCloudProjectAlmBindingParams extends ProjectAlmBindingParams {
repository: string;
}

export interface GithubProjectAlmBindingParams extends ProjectAlmBindingParams {
repository: string;
summaryCommentEnabled: boolean;

+ 3
- 0
sonar-core/src/main/resources/org/sonar/l10n/core.properties View File

@@ -1165,6 +1165,9 @@ settings.pr_decoration.binding.form.bitbucket.repository=Project Key
settings.pr_decoration.binding.form.bitbucket.repository.help=The project key is part of your Bitbucket Server repository URL. Example: ({example})
settings.pr_decoration.binding.form.bitbucket.slug=Repository SLUG
settings.pr_decoration.binding.form.bitbucket.slug.help=The Repository Slug is part of your Bitbucket Server repository URL. Example: ({example})
settings.pr_decoration.binding.form.bitbucketcloud.repository=Repository SLUG
settings.pr_decoration.binding.form.bitbucketcloud.repository.help=The Repository SLUG is part of your Bitbucket Cloud URL. Example: {example}

settings.pr_decoration.binding.form.gitlab.repository=Project ID

property.category.general=General

Loading…
Cancel
Save