From 6263047cd45c7ac0e735196c29ed6148766166ee Mon Sep 17 00:00:00 2001 From: Philippe Perrin Date: Thu, 28 Jan 2021 17:58:17 +0100 Subject: [PATCH] SONAR-14405 Add monorepo checkbox for Gitlab bindings --- .../AlmSpecificForm.tsx | 47 +++-- .../PRDecorationBinding.tsx | 24 ++- .../__tests__/PRDecorationBinding-test.tsx | 165 ++++++------------ .../AlmSpecificForm-test.tsx.snap | 134 +++++++++----- .../TutorialSelectionRenderer-test.tsx.snap | 1 + .../src/main/js/helpers/mocks/alm-settings.ts | 1 + .../src/main/js/types/alm-settings.ts | 2 + 7 files changed, 183 insertions(+), 191 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx index 6aac5329007..1fc2a7e95b4 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/AlmSpecificForm.tsx @@ -151,6 +151,15 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { monorepoEnabled } = props; + const renderMonoRepoFieldWithDocLink = (docLink: string) => { + return renderMonoRepoField({ + monorepoEnabled, + value: monorepo, + docLink, + onFieldChange: props.onFieldChange + }); + }; + switch (alm) { case AlmKeys.Azure: return ( @@ -169,12 +178,7 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'repository', value: repository || '' })} - {renderMonoRepoField({ - monorepoEnabled, - value: monorepo, - docLink: '/documentation/analysis/azuredevops-integration/', - onFieldChange: props.onFieldChange - })} + {renderMonoRepoFieldWithDocLink('/documentation/analysis/azuredevops-integration/')} ); case AlmKeys.Bitbucket: @@ -212,12 +216,7 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'slug', value: slug || '' })} - {renderMonoRepoField({ - monorepoEnabled, - value: monorepo, - docLink: '/documentation/analysis/bitbucket-integration/', - onFieldChange: props.onFieldChange - })} + {renderMonoRepoFieldWithDocLink('/documentation/analysis/bitbucket-integration/')} ); case AlmKeys.GitHub: @@ -238,21 +237,21 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'summaryCommentEnabled', value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled })} - {renderMonoRepoField({ - monorepoEnabled, - value: monorepo, - docLink: '/documentation/analysis/github-integration/', - onFieldChange: props.onFieldChange - })} + {renderMonoRepoFieldWithDocLink('/documentation/analysis/github-integration/')} ); case AlmKeys.GitLab: - return renderField({ - id: 'gitlab.repository', - onFieldChange: props.onFieldChange, - propKey: 'repository', - value: repository || '' - }); + return ( + <> + {renderField({ + id: 'gitlab.repository', + onFieldChange: props.onFieldChange, + propKey: 'repository', + value: repository || '' + })} + {renderMonoRepoFieldWithDocLink('/documentation/analysis/gitlab-integration/')} + + ); default: return null; } diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx index 3d2368ed24b..3d9a226923e 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/PRDecorationBinding.tsx @@ -163,27 +163,24 @@ export class PRDecorationBinding extends React.PureComponent { const almSetting = key; const project = this.props.component.key; + const repository = almSpecificFields?.repository; + const slug = almSpecificFields?.slug; + const monorepo = almSpecificFields?.monorepo ?? false; switch (alm) { case AlmKeys.Azure: { - const projectName = almSpecificFields?.slug; - const repositoryName = almSpecificFields?.repository; - const monorepo = almSpecificFields?.monorepo ?? false; - if (!projectName || !repositoryName) { + if (!slug || !repository) { return Promise.reject(); } return setProjectAzureBinding({ almSetting, project, - projectName, - repositoryName, + projectName: slug, + repositoryName: repository, monorepo }); } case AlmKeys.Bitbucket: { - const repository = almSpecificFields?.repository; - const slug = almSpecificFields?.slug; - const monorepo = almSpecificFields?.monorepo ?? false; if (!repository || !slug) { return Promise.reject(); } @@ -196,13 +193,11 @@ export class PRDecorationBinding extends React.PureComponent ({ setProjectAzureBinding: jest.fn().mockResolvedValue(undefined), setProjectBitbucketBinding: jest.fn().mockResolvedValue(undefined), setProjectGithubBinding: jest.fn().mockResolvedValue(undefined), + setProjectGitlabBinding: jest.fn().mockResolvedValue(undefined), deleteProjectAlmBinding: jest.fn().mockResolvedValue(undefined) })); @@ -91,7 +93,8 @@ describe('handleSubmit', () => { const instances: AlmSettingsInstance[] = [ { key: 'github', alm: AlmKeys.GitHub }, { key: 'azure', alm: AlmKeys.Azure }, - { key: 'bitbucket', alm: AlmKeys.Bitbucket } + { key: 'bitbucket', alm: AlmKeys.Bitbucket }, + { key: 'gitlab', alm: AlmKeys.GitLab } ]; it('should work for github', async () => { @@ -162,6 +165,28 @@ describe('handleSubmit', () => { }); expect(wrapper.state().success).toBe(true); }); + + it('should work for gitlab', async () => { + const wrapper = shallowRender(); + await waitAndUpdate(wrapper); + const gitlabKey = 'gitlab'; + const repository = 'repo'; + const monorepo = true; + wrapper.setState({ + formData: { key: gitlabKey, repository, monorepo }, + instances + }); + wrapper.instance().handleSubmit(); + await waitAndUpdate(wrapper); + + expect(setProjectGitlabBinding).toBeCalledWith({ + almSetting: gitlabKey, + project: PROJECT_KEY, + repository, + monorepo + }); + expect(wrapper.state().success).toBe(true); + }); }); describe.each([[500], [404]])('For status %i', status => { @@ -234,107 +259,32 @@ it('should handle field changes', async () => { }); }); -it('should reject submitted azure settings', async () => { - const wrapper = shallowRender(); - - expect.assertions(2); - await expect( - wrapper.instance().submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { slug: 'project' }) - ).rejects.toBeUndefined(); - await expect( - wrapper - .instance() - .submitProjectAlmBinding(AlmKeys.Azure, 'azure-binding', { repository: 'repo' }) - ).rejects.toBeUndefined(); -}); - -it('should accept submit azure settings', async () => { - const wrapper = shallowRender(); - await wrapper - .instance() - .submitProjectAlmBinding(AlmKeys.Azure, 'azure', { repository: 'az-repo', slug: 'az-project' }); - expect(setProjectAzureBinding).toHaveBeenCalledWith({ - almSetting: 'azure', - project: PROJECT_KEY, - repositoryName: 'az-repo', - projectName: 'az-project', - monorepo: false - }); -}); - -it('should reject submitted bbs settings', async () => { - const wrapper = shallowRender(); - - expect.assertions(2); - await expect( - wrapper - .instance() - .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { slug: 'project' }) - ).rejects.toBeUndefined(); - await expect( - wrapper - .instance() - .submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs-binding', { repository: 'repo' }) - ).rejects.toBeUndefined(); -}); - -it('should accept submit bbs settings', async () => { - const wrapper = shallowRender(); - await wrapper.instance().submitProjectAlmBinding(AlmKeys.Bitbucket, 'bbs', { - repository: 'bbs-repo', - slug: 'bbs-project' - }); - expect(setProjectBitbucketBinding).toHaveBeenCalledWith({ - almSetting: 'bbs', - project: PROJECT_KEY, - repository: 'bbs-repo', - slug: 'bbs-project', - monorepo: false - }); -}); - -it('should reject submit github settings', async () => { +it.each([ + [AlmKeys.Azure, {}], + [AlmKeys.Azure, { slug: 'test' }], + [AlmKeys.Azure, { repository: 'test' }], + [AlmKeys.Bitbucket, {}], + [AlmKeys.Bitbucket, { slug: 'test' }], + [AlmKeys.Bitbucket, { repository: 'test' }], + [AlmKeys.GitHub, {}], + [AlmKeys.GitLab, {}] +])('should properly reject promise for %s & %s', async (almKey: AlmKeys, params: {}) => { const wrapper = shallowRender(); expect.assertions(1); await expect( - wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', {}) + wrapper.instance().submitProjectAlmBinding(almKey, 'binding', params) ).rejects.toBeUndefined(); }); -it('should accept submit github settings', async () => { - (setProjectGithubBinding as jest.Mock).mockRestore(); - const wrapper = shallowRender(); - await wrapper - .instance() - .submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', { repository: 'foo' }); - expect(setProjectGithubBinding).toHaveBeenCalledWith({ - almSetting: 'github-binding', - project: PROJECT_KEY, - repository: 'foo', - summaryCommentEnabled: true, - monorepo: false - }); - - await wrapper.instance().submitProjectAlmBinding(AlmKeys.GitHub, 'github-binding', { - repository: 'foo', - summaryCommentEnabled: true - }); - expect(setProjectGithubBinding).toHaveBeenCalledWith({ - almSetting: 'github-binding', - project: PROJECT_KEY, - repository: 'foo', - summaryCommentEnabled: true, - monorepo: false - }); -}); - it('should validate form', async () => { const wrapper = shallowRender(); await waitAndUpdate(wrapper); - expect(wrapper.instance().validateForm({ key: '', repository: '' })).toBe(false); - expect(wrapper.instance().validateForm({ key: '', repository: 'c' })).toBe(false); + const validateMethod = wrapper.instance().validateForm; + + expect(validateMethod({ key: '', repository: '' })).toBe(false); + expect(validateMethod({ key: '', repository: 'c' })).toBe(false); wrapper.setState({ instances: [ @@ -345,24 +295,19 @@ it('should validate form', async () => { ] }); - expect(wrapper.instance().validateForm({ key: 'azure', repository: 'rep' })).toBe(false); - expect(wrapper.instance().validateForm({ key: 'azure', slug: 'project' })).toBe(false); - expect( - wrapper - .instance() - .validateForm({ key: 'azure', repository: 'repo', slug: 'project', monorepo: true }) - ).toBe(true); - - expect(wrapper.instance().validateForm({ key: 'github', repository: '' })).toBe(false); - expect(wrapper.instance().validateForm({ key: 'github', repository: 'asdf' })).toBe(true); - - expect(wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key' })).toBe(false); - expect( - wrapper.instance().validateForm({ key: 'bitbucket', repository: 'key', slug: 'slug' }) - ).toBe(true); - - expect(wrapper.instance().validateForm({ key: 'gitlab' })).toBe(false); - expect(wrapper.instance().validateForm({ key: 'gitlab', repository: 'key' })).toBe(true); + [ + { values: { key: 'azure', repository: 'rep' }, result: false }, + { values: { key: 'azure', slug: 'project' }, result: false }, + { values: { key: 'azure', repository: 'repo', slug: 'project' }, result: true }, + { values: { key: 'github', repository: '' }, result: false }, + { 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: 'gitlab' }, result: false }, + { values: { key: 'gitlab', repository: 'key' }, result: true } + ].forEach(({ values, result }) => { + expect(validateMethod(values)).toBe(result); + }); }); function shallowRender(props: Partial = {}) { diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap index cc9dadc14c0..64af693dfb7 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/AlmSpecificForm-test.tsx.snap @@ -617,57 +617,103 @@ exports[`it should render correctly for github and monorepo=true 1`] = ` `; exports[`it should render correctly for gitlab and monorepo=false 1`] = ` -
- + +
+ `; exports[`it should render correctly for gitlab and monorepo=true 1`] = ` -
- + +
+
+ +
+ +
+
+ `; exports[`should render an alert for azure when the monorepo option is activated 1`] = ` diff --git a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap index c43527dccbd..bdc9b40712c 100644 --- a/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/tutorials/__tests__/__snapshots__/TutorialSelectionRenderer-test.tsx.snap @@ -86,6 +86,7 @@ exports[`should render correctly: gitlab tutorial 1`] = ` Object { "alm": "gitlab", "key": "foo", + "monorepo": true, "repository": "PROJECT_KEY", "url": "https://gitlab.com/api/v4", } diff --git a/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts b/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts index a1f23453a56..5e48a2c263c 100644 --- a/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts +++ b/server/sonar-web/src/main/js/helpers/mocks/alm-settings.ts @@ -131,6 +131,7 @@ export function mockProjectGitLabBindingResponse( key: 'foo', repository: 'PROJECT_KEY', url: 'https://gitlab.com/api/v4', + monorepo: true, ...overrides }; } diff --git a/server/sonar-web/src/main/js/types/alm-settings.ts b/server/sonar-web/src/main/js/types/alm-settings.ts index 08d14166359..ce3c5a0cb90 100644 --- a/server/sonar-web/src/main/js/types/alm-settings.ts +++ b/server/sonar-web/src/main/js/types/alm-settings.ts @@ -86,6 +86,7 @@ export interface ProjectGitLabBindingResponse extends ProjectAlmBindingResponse alm: AlmKeys.GitLab; repository: string; url: string; + monorepo: boolean; } export interface ProjectAlmBindingParams { @@ -113,6 +114,7 @@ export interface GithubProjectAlmBindingParams extends ProjectAlmBindingParams { export interface GitlabProjectAlmBindingParams extends ProjectAlmBindingParams { repository?: string; + monorepo: boolean; } export interface AlmSettingsInstance { -- 2.39.5