From 7e37d5382c62f067dd4ed760341342224a26193d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Tue, 26 Feb 2019 11:52:56 +0100 Subject: [PATCH] SONARCLOUD-380 Drop members sync feature for Bitbucket --- .../organization/OrganizationAlmBinding.java | 2 +- .../organization/AutoOrganizationBind.tsx | 28 +++--- .../organization/AutoOrganizationCreate.tsx | 42 ++++---- .../__tests__/AutoOrganizationBind-test.tsx | 8 ++ .../__tests__/AutoOrganizationCreate-test.tsx | 10 +- .../AutoOrganizationCreate-test.tsx.snap | 24 ++--- .../organizationMembers/MembersPageHeader.tsx | 4 +- .../organizationMembers/SyncMemberForm.tsx | 4 +- .../__tests__/MembersPageHeader-test.tsx | 9 +- .../__tests__/SyncMemberForm-test.tsx | 19 +--- .../MembersPageHeader-test.tsx.snap | 70 ++++++++++++- .../SyncMemberForm-test.tsx.snap | 98 +------------------ .../src/main/js/helpers/testMocks.ts | 10 +- .../resources/org/sonar/l10n/core.properties | 2 - 14 files changed, 155 insertions(+), 175 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationAlmBinding.java b/server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationAlmBinding.java index 452e948eba6..80584ff7f47 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationAlmBinding.java +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationAlmBinding.java @@ -26,5 +26,5 @@ import org.sonar.db.organization.OrganizationDto; @ServerSide public interface OrganizationAlmBinding { - void bindOrganization(DbSession dbSession, OrganizationDto organization, String installationId, boolean enableMembersSync); + void bindOrganization(DbSession dbSession, OrganizationDto organization, String installationId, boolean isNewOrganization); } diff --git a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationBind.tsx b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationBind.tsx index 77a7d627ff1..7936eaa3df2 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationBind.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationBind.tsx @@ -24,6 +24,7 @@ import DeferredSpinner from '../../../components/common/DeferredSpinner'; import { Alert } from '../../../components/ui/Alert'; import { SubmitButton } from '../../../components/ui/buttons'; import { translate, translateWithParameters } from '../../../helpers/l10n'; +import { isGithub } from '../../../helpers/almIntegrations'; interface Props { almKey: string; @@ -79,6 +80,7 @@ export default class AutoOrganizationBind extends React.PureComponent @@ -87,18 +89,20 @@ export default class AutoOrganizationBind extends React.PureComponent - - {translateWithParameters( - 'onboarding.import_organization.bind_members_not_sync_info_x', - translate('organization', this.props.almKey) - )} - - {translate('learn_more')} - - + {isGithub(almKey) && ( + + {translateWithParameters( + 'onboarding.import_organization.bind_members_not_sync_info_x', + translate('organization', almKey) + )} + + {translate('learn_more')} + + + )}
{translate('onboarding.import_organization.bind')} diff --git a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx index 3a40718de56..4df6b9d29d8 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/AutoOrganizationCreate.tsx @@ -28,7 +28,7 @@ import { Alert } from '../../../components/ui/Alert'; import { DeleteButton } from '../../../components/ui/buttons'; import RadioToggle from '../../../components/controls/RadioToggle'; import { bindAlmOrganization } from '../../../api/alm-integration'; -import { sanitizeAlmId, getAlmMembersUrl } from '../../../helpers/almIntegrations'; +import { sanitizeAlmId, getAlmMembersUrl, isGithub } from '../../../helpers/almIntegrations'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getBaseUrl } from '../../../helpers/urls'; @@ -164,25 +164,27 @@ export default class AutoOrganizationCreate extends React.PureComponent -

- {translateWithParameters( - 'onboarding.import_organization.members_sync_info_x', - translate('organization', almKey), - almOrganization.name, - translate(almKey) - )} -

- - {translateWithParameters( - 'organization.members.see_all_members_on_x', - translate(almKey) - )} - - + isGithub(almKey) && ( + +

+ {translateWithParameters( + 'onboarding.import_organization.members_sync_info_x', + translate('organization', almKey), + almOrganization.name, + translate(almKey) + )} +

+ + {translateWithParameters( + 'organization.members.see_all_members_on_x', + translate(almKey) + )} + +
+ ) } onContinue={this.props.handleOrgDetailsFinish} organization={almOrganization} diff --git a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationBind-test.tsx b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationBind-test.tsx index 729c237a4c1..76234a23f86 100644 --- a/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationBind-test.tsx +++ b/server/sonar-web/src/main/js/apps/create/organization/__tests__/AutoOrganizationBind-test.tsx @@ -32,6 +32,14 @@ it('should render correctly', () => { expect(onBindOrganization).toHaveBeenCalled(); }); +it('should not show member sync info box for Bitbucket', () => { + expect( + shallowRender({ almKey: 'bitbucket' }) + .find('Alert') + .exists() + ).toBe(false); +}); + function shallowRender(props: Partial = {}) { return shallow( { const createOrganization = jest.fn().mockResolvedValue({ key: 'foo' }); const handleOrgDetailsFinish = jest.fn(); - const almApplication = mockAlmApplication({ key: 'github' }); const almOrganization = mockAlmOrganization({ almUrl: 'http://github.com/thing' }); const wrapper = shallowRender({ - almApplication, almOrganization, createOrganization, handleOrgDetailsFinish @@ -96,6 +94,14 @@ it('should bind existing organization', async () => { expect(onOrgCreated).toHaveBeenCalledWith('foo'); }); +it('should not show member sync info box for Bitbucket', () => { + expect( + shallowRender({ almApplication: mockAlmApplication({ key: 'bitbucket-cloud' }) }) + .find('Alert') + .exists() + ).toBe(false); +}); + function shallowRender(props: Partial = {}) { return shallow( , "name": @@ -59,11 +59,11 @@ exports[`should display choice between import or creation 1`] = ` {almKey && + isGithub(almKey) && !showSyncNotif && ( )} @@ -82,6 +83,7 @@ export default function MembersPageHeader(props: Props) { }} /> {almKey && + isGithub(almKey) && showSyncNotif && ( {translateWithParameters( diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/SyncMemberForm.tsx b/server/sonar-web/src/main/js/apps/organizationMembers/SyncMemberForm.tsx index 9276aa1df56..826f70a4b1c 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/SyncMemberForm.tsx +++ b/server/sonar-web/src/main/js/apps/organizationMembers/SyncMemberForm.tsx @@ -25,7 +25,7 @@ import RadioCard from '../../components/controls/RadioCard'; import { Alert } from '../../components/ui/Alert'; import { Button } from '../../components/ui/buttons'; import { setOrganizationMemberSync, syncMembers } from '../../api/organizations'; -import { sanitizeAlmId, isGithub } from '../../helpers/almIntegrations'; +import { sanitizeAlmId } from '../../helpers/almIntegrations'; import { translate, translateWithParameters } from '../../helpers/l10n'; import { fetchOrganization } from '../../store/rootActions'; @@ -56,7 +56,7 @@ export class SyncMemberForm extends React.PureComponent { enabled: membersSync }).then(() => { this.props.fetchOrganization(organization.key); - if (membersSync && isGithub(organization.alm && organization.alm.key)) { + if (membersSync) { return this.handleMemberSync(); } return Promise.resolve(); diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/MembersPageHeader-test.tsx b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/MembersPageHeader-test.tsx index bc81f0149f4..43921cdcace 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/MembersPageHeader-test.tsx +++ b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/MembersPageHeader-test.tsx @@ -36,7 +36,14 @@ it('should render for admin', () => { ).toMatchSnapshot(); }); -it('should render for bound organization without sync', () => { +it('should render for Bitbucket bound organization', () => { + const organization = mockOrganizationWithAlm(mockOrganizationWithAdminActions(), { + key: 'bitbucket' + }); + expect(shallowRender({ organization })).toMatchSnapshot(); +}); + +it('should render for GitHub bound organization without sync', () => { const organization = mockOrganizationWithAlm(mockOrganizationWithAdminActions()); expect(shallowRender({ organization })).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/SyncMemberForm-test.tsx b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/SyncMemberForm-test.tsx index 1218009c845..2d959fdb109 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/SyncMemberForm-test.tsx +++ b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/SyncMemberForm-test.tsx @@ -33,7 +33,7 @@ beforeEach(() => { jest.clearAllMocks(); }); -it('should allow to switch to automatic mode with github', async () => { +it('should allow to switch to automatic mode', async () => { const fetchOrganization = jest.fn(); const refreshMembers = jest.fn().mockResolvedValue({}); const wrapper = shallowRender({ fetchOrganization, refreshMembers }); @@ -49,23 +49,6 @@ it('should allow to switch to automatic mode with github', async () => { expect(refreshMembers).toBeCalled(); }); -it('should allow to switch to automatic mode with bitbucket', async () => { - const fetchOrganization = jest.fn(); - const wrapper = shallowRender({ - fetchOrganization, - organization: mockOrganizationWithAlm({}, { key: 'bitbucket' }) - }); - expect(wrapper).toMatchSnapshot(); - - wrapper.setState({ membersSync: true }); - wrapper.find('ConfirmButton').prop('onConfirm')(); - expect(setOrganizationMemberSync).toHaveBeenCalledWith({ organization: 'foo', enabled: true }); - - await waitAndUpdate(wrapper); - expect(fetchOrganization).toHaveBeenCalledWith('foo'); - expect(syncMembers).not.toHaveBeenCalled(); -}); - it('should allow to switch to manual mode', async () => { const fetchOrganization = jest.fn(); const wrapper = shallowRender({ diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/MembersPageHeader-test.tsx.snap b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/MembersPageHeader-test.tsx.snap index c21bb177f1c..ca7ac6f19fb 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/MembersPageHeader-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/MembersPageHeader-test.tsx.snap @@ -36,7 +36,7 @@ exports[`should render correctly 1`] = ` `; -exports[`should render for admin 1`] = ` +exports[`should render for Bitbucket bound organization 1`] = `
@@ -63,6 +63,11 @@ exports[`should render for admin 1`] = ` "actions": Object { "admin": true, }, + "alm": Object { + "key": "bitbucket", + "membersSync": false, + "url": "https://github.com/foo", + }, "key": "foo", "name": "Foo", } @@ -97,7 +102,7 @@ exports[`should render for admin 1`] = `
`; -exports[`should render for bound organization without sync 1`] = ` +exports[`should render for GitHub bound organization without sync 1`] = `
@@ -190,3 +195,64 @@ exports[`should render for bound organization without sync 1`] = `
`; + +exports[`should render for admin 1`] = ` +
+

+ organization.members.page +

+ +
+
+ + +
+
+
+ + organization.members.manage_a_team + , + } + } + /> +
+
+`; diff --git a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/SyncMemberForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/SyncMemberForm-test.tsx.snap index 1be6de36a4c..c0a6253566e 100644 --- a/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/SyncMemberForm-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/organizationMembers/__tests__/__snapshots__/SyncMemberForm-test.tsx.snap @@ -1,102 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should allow to switch to automatic mode with bitbucket 1`] = ` - - -
-
    -
  • - organization.members.management.manual.add_members_manually -
  • -
  • - organization.members.management.choose_members_permissions -
  • -
-
-
- -
-
    - -
  • - organization.members.management.automatic.synchronized_from_x.organization.bitbucket -
  • -
  • - organization.members.management.automatic.members_changes_reflected.bitbucket -
  • -
    -
  • - organization.members.management.choose_members_permissions -
  • -
-
- - organization.members.management.automatic.warning - -
- - } - modalHeader="organization.members.management.title" - modalHeaderDescription={ -

- organization.members.management.description - - learn_more - -

- } - onConfirm={[Function]} - size="medium" -> - -
-`; - -exports[`should allow to switch to automatic mode with github 1`] = ` +exports[`should allow to switch to automatic mode 1`] = ` = {}): T.AlmApplication { return { - backgroundColor: '#0052CC', - iconPath: '"/static/authbitbucket/bitbucket.svg"', - installationUrl: 'https://bitbucket.org/install/app', - key: 'bitbucket', - name: 'BitBucket', + backgroundColor: '#444444', + iconPath: '/images/sonarcloud/github-white.svg', + installationUrl: 'https://github.com/apps/greg-sonarcloud/installations/new', + key: 'github', + name: 'GitHub', ...overrides }; } diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 605b0e96f03..0aa845d5b52 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2680,7 +2680,6 @@ organization.members.add_to_members=Add to members organization.members.config_synchro=Configure Synchronization organization.members.auto_sync_with_x=Automatic sync with {0} organization.members.auto_sync_members_from_org_x=Now your members can be automatically synchronized with your {0}. -organization.members.auto_sync_total_help.bitbucket=You might not see all members from your Bitbucket team yet, as they need to reconnect to SonarCloud to be members of the organization. organization.members.auto_sync_total_help.github=You might not see all members from your GitHub organization yet, as they need to connect to SonarCloud at least once to appear in this list. organization.members.see_all_members_on_x=See all members on {0} organization.members.management.title=Members Management @@ -2689,7 +2688,6 @@ organization.members.management.manual=Manual organization.members.management.manual.add_members_manually=Admin add members manually from SonarCloud existing users organization.members.management.automatic=Automatic sync with {0} organization.members.management.automatic.synchronized_from_x=Members are synchronized automatically from your {0} -organization.members.management.automatic.members_changes_reflected.bitbucket=Your team members must reconnect to SonarCloud to be automatically added to correct SonarCloud organization organization.members.management.automatic.members_changes_reflected.github=If you add or remove a member on GitHub, SonarCloud immediately reflects the changes organization.members.management.automatic.warning=This will override your current Members and Permissions configuration organization.members.management.choose_members_permissions=Admin manages permissions for each member in SonarCloud -- 2.39.5