From 8d86fc62891d37a618ccd950b20b38e45625750c Mon Sep 17 00:00:00 2001 From: Philippe Perrin Date: Wed, 17 Mar 2021 11:49:05 +0100 Subject: [PATCH] SONAR-14598 Add the mono repo checkbox for Bitbucket Cloud bindings --- .../AlmSpecificForm.tsx | 87 ++-- .../PRDecorationBinding.tsx | 10 +- .../__tests__/AlmSpecificForm-test.tsx | 27 +- .../__tests__/PRDecorationBinding-test.tsx | 90 ++-- .../PRDecorationBindingRenderer-test.tsx | 6 +- .../AlmSpecificForm-test.tsx.snap | 439 +----------------- .../PRDecorationBinding-test.tsx.snap | 1 + .../PRDecorationBindingRenderer-test.tsx.snap | 1 + .../src/main/js/helpers/mocks/alm-settings.ts | 1 + .../src/main/js/types/alm-settings.ts | 11 +- 10 files changed, 123 insertions(+), 550 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 7e1ce81ba09..d476039cc8b 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 @@ -115,37 +115,6 @@ function renderField( ); } -function renderMonoRepoField(props: { - monorepoEnabled: boolean; - value?: boolean; - docLink: string; - onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void; -}) { - if (!props.monorepoEnabled) { - return null; - } - - return renderBooleanField({ - help: true, - helpParams: { - doc_link: ( - - {translate('learn_more')} - - ) - }, - id: 'monorepo', - onFieldChange: props.onFieldChange, - propKey: 'monorepo', - value: props.value ?? false, - inputExtra: props.value && ( - - {translate('settings.pr_decoration.binding.form.monorepo.warning')} - - ) - }); -} - export default function AlmSpecificForm(props: AlmSpecificFormProps) { const { alm, @@ -153,18 +122,11 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { monorepoEnabled } = props; - const renderMonoRepoFieldWithDocLink = (docLink: string) => { - return renderMonoRepoField({ - monorepoEnabled, - value: monorepo, - docLink, - onFieldChange: props.onFieldChange - }); - }; + let formFields: JSX.Element; switch (alm) { case AlmKeys.Azure: - return ( + formFields = ( <> {renderField({ help: true, @@ -180,11 +142,11 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'repository', value: repository || '' })} - {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.Azure])} ); + break; case AlmKeys.BitbucketServer: - return ( + formFields = ( <> {renderField({ help: true, @@ -218,11 +180,11 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'slug', value: slug || '' })} - {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer])} ); + break; case AlmKeys.BitbucketCloud: - return ( + formFields = ( <> {renderField({ help: true, @@ -241,8 +203,9 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { })} ); + break; case AlmKeys.GitHub: - return ( + formFields = ( <> {renderField({ help: true, @@ -259,11 +222,11 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'summaryCommentEnabled', value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled })} - {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub])} ); + break; case AlmKeys.GitLab: - return ( + formFields = ( <> {renderField({ id: 'gitlab.repository', @@ -271,10 +234,34 @@ export default function AlmSpecificForm(props: AlmSpecificFormProps) { propKey: 'repository', value: repository || '' })} - {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab])} ); - default: - return null; + break; } + + return ( + <> + {formFields} + {monorepoEnabled && + renderBooleanField({ + help: true, + helpParams: { + doc_link: ( + + {translate('learn_more')} + + ) + }, + id: 'monorepo', + onFieldChange: props.onFieldChange, + propKey: 'monorepo', + value: monorepo, + inputExtra: monorepo && ( + + {translate('settings.pr_decoration.binding.form.monorepo.warning')} + + ) + })} + + ); } 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 c00b8403d59..5636df54c9b 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 @@ -75,7 +75,7 @@ const REQUIRED_FIELDS_BY_ALM: { export class PRDecorationBinding extends React.PureComponent { mounted = false; state: State = { - formData: { key: '' }, + formData: { key: '', monorepo: false }, instances: [], isChanged: false, isConfigured: false, @@ -145,7 +145,8 @@ export class PRDecorationBinding extends React.PureComponent { - expect(shallowRender(alm, { monorepoEnabled })).toMatchSnapshot(); + [AlmKeys.Azure], + [AlmKeys.BitbucketServer], + [AlmKeys.BitbucketCloud], + [AlmKeys.GitHub], + [AlmKeys.GitLab] +])('it should render correctly for %s', alm => { + expect(shallowRender(alm)).toMatchSnapshot(); }); -it('should render an alert for azure when the monorepo option is activated', () => { - expect( - shallowRender(AlmKeys.Azure, { monorepoEnabled: true, formData: { key: '', monorepo: true } }) - ).toMatchSnapshot(); +it('should render the monorepo field when the feature is supported', () => { + expect(shallowRender(AlmKeys.Azure, { monorepoEnabled: true })).toMatchSnapshot(); }); function shallowRender(alm: AlmKeys, props: Partial = {}) { @@ -49,7 +43,8 @@ function shallowRender(alm: AlmKeys, props: Partial = {}) formData={{ key: '', repository: '', - slug: '' + slug: '', + monorepo: false }} onFieldChange={jest.fn()} monorepoEnabled={false} diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx index 1232291c993..4c1cc68e4a9 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBinding-test.tsx @@ -79,7 +79,8 @@ it('should handle reset', async () => { wrapper.setState({ formData: { key: 'whatever', - repository: 'something/else' + repository: 'something/else', + monorepo: false } }); @@ -87,7 +88,7 @@ it('should handle reset', async () => { await waitAndUpdate(wrapper); expect(deleteProjectAlmBinding).toBeCalledWith(PROJECT_KEY); - expect(wrapper.state().formData).toEqual({ key: '', repository: '', slug: '' }); + expect(wrapper.state().formData).toEqual({ key: '', repository: '', slug: '', monorepo: false }); expect(wrapper.state().isChanged).toBe(false); }); @@ -196,19 +197,21 @@ describe('handleSubmit', () => { await waitAndUpdate(wrapper); const bitbucketKey = 'bitbucketcloud'; const repository = 'repoKey'; - wrapper.setState({ formData: { key: bitbucketKey, repository }, instances: [] }); + const monorepo = true; + wrapper.setState({ formData: { key: bitbucketKey, repository, monorepo }, instances: [] }); wrapper.instance().handleSubmit(); await waitAndUpdate(wrapper); expect(setProjectBitbucketCloudBinding).not.toBeCalled(); - wrapper.setState({ formData: { key: bitbucketKey, repository }, instances }); + wrapper.setState({ formData: { key: bitbucketKey, repository, monorepo }, instances }); wrapper.instance().handleSubmit(); await waitAndUpdate(wrapper); expect(setProjectBitbucketCloudBinding).toBeCalledWith({ almSetting: bitbucketKey, project: PROJECT_KEY, - repository + repository, + monorepo }); expect(wrapper.state().success).toBe(true); }); @@ -218,7 +221,8 @@ describe.each([[500], [404]])('For status %i', status => { it('should handle failures gracefully', async () => { const newFormData = { key: 'whatever', - repository: 'something/else' + repository: 'something/else', + monorepo: false }; (getProjectAlmBinding as jest.Mock).mockRejectedValueOnce({ status }); @@ -256,20 +260,23 @@ it('should handle field changes', async () => { wrapper.instance().handleFieldChange('key', 'instance2'); await waitAndUpdate(wrapper); expect(wrapper.state().formData).toEqual({ - key: 'instance2' + key: 'instance2', + monorepo: false }); wrapper.instance().handleFieldChange('repository', repository); await waitAndUpdate(wrapper); expect(wrapper.state().formData).toEqual({ key: 'instance2', - repository + repository, + monorepo: false }); wrapper.instance().handleFieldChange('summaryCommentEnabled', true); await waitAndUpdate(wrapper); expect(wrapper.state().formData).toEqual({ key: 'instance2', + monorepo: false, repository, summaryCommentEnabled: true }); @@ -285,23 +292,26 @@ it('should handle field changes', async () => { }); it.each([ - [AlmKeys.Azure, {}], - [AlmKeys.Azure, { slug: 'test' }], - [AlmKeys.Azure, { repository: 'test' }], - [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: {}) => { - const wrapper = shallowRender(); + [AlmKeys.Azure, { monorepo: false }], + [AlmKeys.Azure, { slug: 'test', monorepo: false }], + [AlmKeys.Azure, { repository: 'test', monorepo: false }], + [AlmKeys.BitbucketServer, { monorepo: false }], + [AlmKeys.BitbucketServer, { slug: 'test', monorepo: false }], + [AlmKeys.BitbucketServer, { repository: 'test', monorepo: false }], + [AlmKeys.BitbucketCloud, { monorepo: false }], + [AlmKeys.GitHub, { monorepo: false }], + [AlmKeys.GitLab, { monorepo: false }] +])( + 'should properly reject promise for %s & %s', + async (almKey: AlmKeys, params: { monorepo: boolean }) => { + const wrapper = shallowRender(); - expect.assertions(1); - await expect( - wrapper.instance().submitProjectAlmBinding(almKey, 'binding', params) - ).rejects.toBeUndefined(); -}); + expect.assertions(1); + await expect( + wrapper.instance().submitProjectAlmBinding(almKey, 'binding', params) + ).rejects.toBeUndefined(); + } +); it('should validate form', async () => { const wrapper = shallowRender(); @@ -309,8 +319,8 @@ it('should validate form', async () => { const validateMethod = wrapper.instance().validateForm; - expect(validateMethod({ key: '', repository: '' })).toBe(false); - expect(validateMethod({ key: '', repository: 'c' })).toBe(false); + expect(validateMethod({ key: '', repository: '', monorepo: false })).toBe(false); + expect(validateMethod({ key: '', repository: 'c', monorepo: false })).toBe(false); wrapper.setState({ instances: [ @@ -323,17 +333,23 @@ it('should validate form', async () => { }); [ - { 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: 'bitbucketcloud', repository: '' }, result: false }, - { values: { key: 'bitbucketcloud', repository: 'key' }, result: true }, - { values: { key: 'gitlab' }, result: false }, - { values: { key: 'gitlab', repository: 'key' }, result: true } + { values: { key: 'azure', monorepo: false, repository: 'rep' }, result: false }, + { values: { key: 'azure', monorepo: false, slug: 'project' }, result: false }, + { + values: { key: 'azure', monorepo: false, repository: 'repo', slug: 'project' }, + result: true + }, + { values: { key: 'github', monorepo: false, repository: '' }, result: false }, + { values: { key: 'github', monorepo: false, repository: 'asdf' }, result: true }, + { values: { key: 'bitbucket', monorepo: false, repository: 'key' }, result: false }, + { + values: { key: 'bitbucket', monorepo: false, repository: 'key', slug: 'slug' }, + result: true + }, + { values: { key: 'bitbucketcloud', monorepo: false, repository: '' }, result: false }, + { values: { key: 'bitbucketcloud', monorepo: false, repository: 'key' }, result: true }, + { values: { key: 'gitlab', monorepo: false }, result: false }, + { values: { key: 'gitlab', monorepo: false, repository: 'key' }, result: true } ].forEach(({ values, result }) => { expect(validateMethod(values)).toBe(result); }); diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx index b0520110cf0..859aeaf10a8 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/PRDecorationBindingRenderer-test.tsx @@ -82,7 +82,8 @@ it('should render multiple instances correctly', () => { shallowRender({ formData: { key: 'i1', - repository: 'account/repo' + repository: 'account/repo', + monorepo: false }, isChanged: false, isConfigured: true, @@ -134,7 +135,8 @@ function shallowRender(props: Partial = {}) {
`; -exports[`it should render correctly for azure and monorepo=true 1`] = ` - -
- - -
-
- - -
-
- -
- -
-
-
-`; - -exports[`it should render correctly for bitbucket and monorepo=false 1`] = ` +exports[`it should render correctly for bitbucket 1`] = `
`; -exports[`it should render correctly for bitbucket and monorepo=true 1`] = ` - -
- - -
-
- - -
-
- -
- -
-
-
-`; - -exports[`it should render correctly for bitbucketcloud and monorepo=false 1`] = ` +exports[`it should render correctly for bitbucketcloud 1`] = `
`; -exports[`it should render correctly for github and monorepo=false 1`] = ` +exports[`it should render correctly for github 1`] = `
`; -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 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`] = ` +exports[`should render the monorepo field when the feature is supported 1`] = `
- - settings.pr_decoration.binding.form.monorepo.warning -
diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBinding-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBinding-test.tsx.snap index 9faa94ac571..7694d79b05d 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBinding-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBinding-test.tsx.snap @@ -5,6 +5,7 @@ exports[`should render correctly 1`] = ` formData={ Object { "key": "", + "monorepo": false, } } instances={Array []} diff --git a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap index 35bf2eecea1..cd949808fd3 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/settings/components/pullRequestDecorationBinding/__tests__/__snapshots__/PRDecorationBindingRenderer-test.tsx.snap @@ -421,6 +421,7 @@ exports[`should render multiple instances correctly 2`] = ` formData={ Object { "key": "i1", + "monorepo": false, "repository": "account/repo", } } 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 cff3a5b4ff4..93aa836d8ee 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 @@ -107,6 +107,7 @@ export function mockProjectAlmBindingResponse( return { alm: AlmKeys.GitHub, key: 'foo', + monorepo: false, ...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 7a546ccbbb9..dff01841cfa 100644 --- a/server/sonar-web/src/main/js/types/alm-settings.ts +++ b/server/sonar-web/src/main/js/types/alm-settings.ts @@ -65,7 +65,7 @@ export interface ProjectAlmBindingResponse { repository?: string; slug?: string; summaryCommentEnabled?: boolean; - monorepo?: boolean; + monorepo: boolean; } export interface ProjectAzureBindingResponse extends ProjectAlmBindingResponse { @@ -73,44 +73,39 @@ export interface ProjectAzureBindingResponse extends ProjectAlmBindingResponse { repository: string; slug: string; url: string; - monorepo: boolean; } export interface ProjectBitbucketBindingResponse extends ProjectAlmBindingResponse { alm: AlmKeys.BitbucketServer; repository: string; slug: string; - monorepo: boolean; } export interface ProjectGitHubBindingResponse extends ProjectAlmBindingResponse { alm: AlmKeys.GitHub; repository: string; - monorepo: boolean; } export interface ProjectGitLabBindingResponse extends ProjectAlmBindingResponse { alm: AlmKeys.GitLab; repository: string; url: string; - monorepo: boolean; } export interface ProjectAlmBindingParams { almSetting: string; project: string; + monorepo: boolean; } export interface AzureProjectAlmBindingParams extends ProjectAlmBindingParams { projectName: string; repositoryName: string; - monorepo: boolean; } export interface BitbucketProjectAlmBindingParams extends ProjectAlmBindingParams { repository: string; slug: string; - monorepo: boolean; } export interface BitbucketCloudProjectAlmBindingParams extends ProjectAlmBindingParams { @@ -120,12 +115,10 @@ export interface BitbucketCloudProjectAlmBindingParams extends ProjectAlmBinding export interface GithubProjectAlmBindingParams extends ProjectAlmBindingParams { repository: string; summaryCommentEnabled: boolean; - monorepo: boolean; } export interface GitlabProjectAlmBindingParams extends ProjectAlmBindingParams { repository?: string; - monorepo: boolean; } export interface AlmSettingsInstance { -- 2.39.5