]> source.dussan.org Git - sonarqube.git/commitdiff
SONARCLOUD-379 Create POST /api/organizations/set_member_sync
authorBenoît Gianinetti <benoit.gianinetti@sonarsource.com>
Mon, 4 Feb 2019 16:18:53 +0000 (17:18 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 6 Mar 2019 10:30:40 +0000 (11:30 +0100)
15 files changed:
server/sonar-db-dao/src/test/java/org/sonar/db/alm/AlmAppInstallDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/alm/AlmDbTester.java
server/sonar-server/src/main/java/org/sonar/server/organization/OrganizationAlmBinding.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/AddMemberAction.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/CreateAction.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsSupport.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/RemoveMemberAction.java
server/sonar-server/src/main/java/org/sonar/server/organization/ws/SetMembersSyncAction.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/organization/ws/AddMemberActionTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/CreateActionTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/OrganizationsWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/RemoveMemberActionTest.java
server/sonar-server/src/test/java/org/sonar/server/organization/ws/SetMembersSyncActionTest.java [new file with mode: 0644]
server/sonar-server/src/test/java/org/sonar/server/organization/ws/UpdateActionTest.java

index 3a355ced2a40dc3380703f3be52487b46e236905..c07a4c1e8e04771c35f51cb58d130a5846d32fb8 100644 (file)
@@ -155,7 +155,7 @@ public class AlmAppInstallDaoTest {
     db.getDbClient().almAppInstallDao().insertOrUpdate(db.getSession(), ALM.GITHUB, "the-owner", false, "123456", null);
     // could be improved, insertOrUpdate should return the DTO with its uuid
     Optional<AlmAppInstallDto> install = db.getDbClient().almAppInstallDao().selectByOwnerId(db.getSession(), ALM.GITHUB, "the-owner");
-    db.getDbClient().organizationAlmBindingDao().insert(db.getSession(), organization, install.get(), "xxx", "xxx");
+    db.getDbClient().organizationAlmBindingDao().insert(db.getSession(), organization, install.get(), "xxx", "xxx", true);
     db.commit();
 
     assertThat(underTest.selectByOrganization(db.getSession(), GITHUB, organization).get().getUuid()).isEqualTo(install.get().getUuid());
index 5b015586bf133f37ceedf3980ae84be4f7958790..06b0e6f58102af55988ba993f99d841055b74352 100644 (file)
@@ -40,7 +40,7 @@ public class AlmDbTester {
 
   public OrganizationAlmBindingDto insertOrganizationAlmBinding(OrganizationDto organization, AlmAppInstallDto almAppInstall) {
     UserDto user = db.users().insertUser();
-    db.getDbClient().organizationAlmBindingDao().insert(db.getSession(), organization, almAppInstall, randomAlphabetic(10), user.getUuid());
+    db.getDbClient().organizationAlmBindingDao().insert(db.getSession(), organization, almAppInstall, randomAlphabetic(10), user.getUuid(), true);
     db.commit();
     return db.getDbClient().organizationAlmBindingDao().selectByOrganization(db.getSession(), organization).get();
   }
@@ -65,5 +65,4 @@ public class AlmDbTester {
     db.commit();
     return db.getDbClient().almAppInstallDao().selectByOwnerId(db.getSession(), dto.getAlm(), dto.getOwnerId()).get();
   }
-
 }
index ae188f79ca9756d3d601de3625299f686ec92bc1..452e948eba696d99ceb8001ab04c28f4d599e7f8 100644 (file)
@@ -26,5 +26,5 @@ import org.sonar.db.organization.OrganizationDto;
 @ServerSide
 public interface OrganizationAlmBinding {
 
-  void bindOrganization(DbSession dbSession, OrganizationDto organization, String installationId);
+  void bindOrganization(DbSession dbSession, OrganizationDto organization, String installationId, boolean enableMembersSync);
 }
index 6ac410110999c2d4e60350fce62fae57c99a3291..a4f4ceec2777f6a7c68e302af1375cd07cf14a34 100644 (file)
@@ -54,13 +54,16 @@ public class AddMemberAction implements OrganizationsWsAction {
   private final UserIndexer userIndexer;
   private final DefaultGroupFinder defaultGroupFinder;
   private final AvatarResolver avatarResolver;
+  private final OrganizationsWsSupport wsSupport;
 
-  public AddMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer, DefaultGroupFinder defaultGroupFinder, AvatarResolver avatarResolver) {
+  public AddMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer, DefaultGroupFinder defaultGroupFinder,
+    AvatarResolver avatarResolver, OrganizationsWsSupport wsSupport) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.userIndexer = userIndexer;
     this.defaultGroupFinder = defaultGroupFinder;
     this.avatarResolver = avatarResolver;
+    this.wsSupport = wsSupport;
   }
 
   @Override
@@ -96,6 +99,8 @@ public class AddMemberAction implements OrganizationsWsAction {
       OrganizationDto organization = checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, organizationKey), "Organization '%s' is not found",
         organizationKey);
       UserDto user = checkFound(dbClient.userDao().selectByLogin(dbSession, login), "User '%s' is not found", login);
+      wsSupport.checkMemberSyncIsDisabled(dbSession, organization);
+
       addMember(dbSession, organization, user);
 
       int groups = dbClient.groupMembershipDao().countGroups(dbSession, GroupMembershipQuery.builder()
index 52abb4c00adf3a1c5891fda205cfe0880b05849a..06294edf160d7854a4a090f3d0b4cc98bf884029 100644 (file)
@@ -156,7 +156,7 @@ public class CreateAction implements OrganizationsWsAction {
     if (installationId == null) {
       return;
     }
-    organizationAlmBinding.bindOrganization(dbSession, organization, installationId);
+    organizationAlmBinding.bindOrganization(dbSession, organization, installationId, true);
   }
 
   @CheckForNull
index 4a89e9ec3bd89810d014a60f89cc0d13b16f8c0b..695466e83e1184840a1da80f38b67f0976c644ec 100644 (file)
@@ -50,7 +50,8 @@ public class OrganizationsWsModule extends Module {
         CreateAction.class,
         DeleteAction.class,
         RemoveMemberAction.class,
-        UpdateAction.class);
+        UpdateAction.class,
+        SetMembersSyncAction.class);
     }
   }
 
index 44116152c8870b2a0d6d4f9e49a8c9f6b1059792..7d3a103079c57854c568173a9abb2a50b519c284 100644 (file)
@@ -22,10 +22,13 @@ package org.sonar.server.organization.ws;
 import javax.annotation.CheckForNull;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.organization.OrganizationValidation;
 import org.sonarqube.ws.Organizations.Organization;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Optional.ofNullable;
 import static org.sonar.server.organization.OrganizationValidation.DESCRIPTION_MAX_LENGTH;
 import static org.sonar.server.organization.OrganizationValidation.NAME_MAX_LENGTH;
@@ -45,9 +48,11 @@ public class OrganizationsWsSupport {
   static final String PARAM_LOGIN = "login";
 
   private final OrganizationValidation organizationValidation;
+  private final DbClient dbClient;
 
-  public OrganizationsWsSupport(OrganizationValidation organizationValidation) {
+  public OrganizationsWsSupport(OrganizationValidation organizationValidation, DbClient dbClient) {
     this.organizationValidation = organizationValidation;
+    this.dbClient = dbClient;
   }
 
   String getAndCheckMandatoryName(Request request) {
@@ -118,4 +123,10 @@ public class OrganizationsWsSupport {
     ofNullable(dto.getAvatarUrl()).ifPresent(builder::setAvatar);
     return builder;
   }
+
+
+  void checkMemberSyncIsDisabled(DbSession dbSession, OrganizationDto organization) {
+    dbClient.organizationAlmBindingDao().selectByOrganization(dbSession, organization).ifPresent(orgAlmBindingDto ->
+      checkArgument(!orgAlmBindingDto.isMembersSyncEnable(), "You can't add or remove members when synchronization of organization with alm is enabled."));
+  }
 }
index 21b66707dd1f5c3f7f529f1f96fe9fdc107e6aee..02e085860b892bb80f71ce460e0e6202e92a590b 100644 (file)
@@ -44,11 +44,13 @@ public class RemoveMemberAction implements OrganizationsWsAction {
   private final DbClient dbClient;
   private final UserSession userSession;
   private final UserIndexer userIndexer;
+  private final OrganizationsWsSupport wsSupport;
 
-  public RemoveMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer) {
+  public RemoveMemberAction(DbClient dbClient, UserSession userSession, UserIndexer userIndexer, OrganizationsWsSupport wsSupport) {
     this.dbClient = dbClient;
     this.userSession = userSession;
     this.userIndexer = userIndexer;
+    this.wsSupport = wsSupport;
   }
 
   @Override
@@ -84,7 +86,7 @@ public class RemoveMemberAction implements OrganizationsWsAction {
         "Organization '%s' is not found", organizationKey);
       UserDto user = checkFound(dbClient.userDao().selectActiveUserByLogin(dbSession, login), "User '%s' is not found", login);
       userSession.checkPermission(ADMINISTER, organization);
-
+      wsSupport.checkMemberSyncIsDisabled(dbSession, organization);
       dbClient.organizationMemberDao().select(dbSession, organization.getUuid(), user.getId())
         .ifPresent(om -> removeMember(dbSession, organization, user));
     }
diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SetMembersSyncAction.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SetMembersSyncAction.java
new file mode 100644 (file)
index 0000000..0c2a45d
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.organization.ws;
+
+import java.util.Optional;
+import org.sonar.api.server.ws.Request;
+import org.sonar.api.server.ws.Response;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.alm.OrganizationAlmBindingDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.user.UserSession;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
+import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_ORGANIZATION;
+import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
+
+public class SetMembersSyncAction implements OrganizationsWsAction {
+
+  private static final String ENABLED = "enabled";
+  private DbClient dbClient;
+  private UserSession userSession;
+
+  public SetMembersSyncAction(DbClient dbClient, UserSession userSession) {
+    this.dbClient = dbClient;
+    this.userSession = userSession;
+  }
+
+  @Override
+  public void define(WebService.NewController context) {
+    WebService.NewAction action = context.createAction("set_members_sync")
+      .setDescription("Enable or disable organization members synchronization.<br/>" +
+        "Requires 'Administer System' permission on the specified organization.")
+      .setSince("7.7")
+      .setPost(true)
+      .setInternal(true)
+      .setHandler(this);
+
+    action.createParam(PARAM_ORGANIZATION)
+      .setDescription("Organization key")
+      .setInternal(true)
+      .setRequired(true);
+
+    action.createParam(ENABLED)
+      .setDescription("True to enable members sync, false otherwise.")
+      .setInternal(true)
+      .setRequired(true)
+      .setBooleanPossibleValues();
+  }
+
+  @Override
+  public void handle(Request request, Response response) throws Exception {
+    String organizationKey = request.mandatoryParam(PARAM_ORGANIZATION);
+
+    try (DbSession dbSession = dbClient.openSession(false)) {
+
+      OrganizationDto organization = checkFoundWithOptional(dbClient.organizationDao().selectByKey(dbSession, organizationKey),
+        "Organization '%s' does not exist", organizationKey);
+
+      userSession.checkPermission(ADMINISTER, organization);
+
+      Optional<OrganizationAlmBindingDto> orgAlmBindingDto = dbClient.organizationAlmBindingDao().selectByOrganization(dbSession, organization);
+      checkArgument(orgAlmBindingDto.isPresent(), "Organization '%s' is not bound to an ALM", organization.getKey());
+
+      dbClient.organizationAlmBindingDao().updateMembersSync(dbSession, orgAlmBindingDto.get(), request.mandatoryParamAsBoolean(ENABLED));
+
+      dbSession.commit();
+    }
+
+    response.noContent();
+  }
+
+}
index 37a52d66dac25fef1332aed9e9f3c07bde41762f..659c02040c0939e47f3727e296fc908a2b2139bb 100644 (file)
@@ -40,6 +40,7 @@ import org.sonar.server.es.SearchOptions;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.issue.ws.AvatarResolverImpl;
+import org.sonar.server.organization.OrganizationValidationImpl;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.index.UserDoc;
 import org.sonar.server.user.index.UserIndex;
@@ -71,9 +72,9 @@ public class AddMemberActionTest {
   public DbTester db = DbTester.create();
   private DbClient dbClient = db.getDbClient();
   private DbSession dbSession = db.getSession();
-
+  private OrganizationsWsSupport wsSupport = new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient);
   private WsActionTester ws = new WsActionTester(
-    new AddMemberAction(dbClient, userSession, new UserIndexer(dbClient, es.client()), new DefaultGroupFinder(dbClient), new AvatarResolverImpl()));
+    new AddMemberAction(dbClient, userSession, new UserIndexer(dbClient, es.client()), new DefaultGroupFinder(dbClient), new AvatarResolverImpl(), wsSupport));
 
   @Test
   public void add_member_in_db_and_user_index() {
@@ -225,6 +226,17 @@ public class AddMemberActionTest {
     call(organization.getKey(), user.getLogin());
   }
 
+  @Test
+  public void fail_if_org_is_bind_to_alm_and_members_sync_is_enabled() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+    UserDto user = db.users().insertUser();
+
+    expectedException.expect(IllegalArgumentException.class);
+
+    call(organization.getKey(), user.getLogin());
+  }
+
   @Test
   public void json_example() {
     OrganizationDto organization = db.organizations().insert();
index afa0a78fc6d142426d523c6e7e4f44c7c6b9b5da..84bd85739c7d00f5435c63e43b152164b81799d7 100644 (file)
@@ -115,7 +115,7 @@ public class CreateActionTest {
   private OrganizationAlmBinding organizationAlmBinding = mock(OrganizationAlmBinding.class);
 
   private WsActionTester wsTester = new WsActionTester(
-    new CreateAction(settings.asConfig(), userSession, dbClient, new OrganizationsWsSupport(organizationValidation),
+    new CreateAction(settings.asConfig(), userSession, dbClient, new OrganizationsWsSupport(organizationValidation, dbClient),
       organizationValidation,
       organizationUpdater, organizationFlags, organizationAlmBinding));
 
@@ -267,13 +267,13 @@ public class CreateActionTest {
       .setParam("installationId", "ABCD")
       .execute();
 
-    verify(organizationAlmBinding).bindOrganization(any(DbSession.class), any(OrganizationDto.class), eq("ABCD"));
+    verify(organizationAlmBinding).bindOrganization(any(DbSession.class), any(OrganizationDto.class), eq("ABCD"), eq(true));
   }
 
   @Test
   public void does_not_bind_organization_when_organizationAlmBinding_is_null() {
     wsTester = new WsActionTester(
-      new CreateAction(settings.asConfig(), userSession, dbClient, new OrganizationsWsSupport(organizationValidation),
+      new CreateAction(settings.asConfig(), userSession, dbClient, new OrganizationsWsSupport(organizationValidation, dbClient),
         organizationValidation, organizationUpdater, organizationFlags, null));
     createUserAndLogInAsSystemAdministrator();
     db.qualityGates().insertBuiltInQualityGate();
index f1a4db9baf6a04d9fd78d238814cba8813cc0955..89448f24806016efebfa594d040d4e308438d412 100644 (file)
@@ -49,7 +49,7 @@ public class OrganizationsWsModuleTest {
     underTest.configure(container);
 
     assertThat(container.getPicoContainer().getComponentAdapters())
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 11);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 12);
   }
 
 }
index b29f2f0d3f01417db5bb4e819ca5f596318157e8..b5e01453546c821a4cf01f403125c1c095885702 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.server.es.SearchOptions;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.organization.OrganizationValidationImpl;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexDefinition;
@@ -86,8 +87,9 @@ public class RemoveMemberActionTest {
 
   private UserIndex userIndex = new UserIndex(es.client(), System2.INSTANCE);
   private UserIndexer userIndexer = new UserIndexer(dbClient, es.client());
+  private OrganizationsWsSupport wsSupport = new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient);
 
-  private WsActionTester ws = new WsActionTester(new RemoveMemberAction(dbClient, userSession, userIndexer));
+  private WsActionTester ws = new WsActionTester(new RemoveMemberAction(dbClient, userSession, userIndexer, wsSupport));
 
   private OrganizationDto organization;
   private ComponentDto project;
@@ -334,6 +336,17 @@ public class RemoveMemberActionTest {
     call(organization.getKey(), user.getLogin());
   }
 
+  @Test
+  public void fail_if_org_is_bind_to_alm_and_members_sync_is_enabled() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+    UserDto user = db.users().insertUser();
+
+    expectedException.expect(IllegalArgumentException.class);
+
+    call(organization.getKey(), user.getLogin());
+  }
+
   @Test
   public void remove_org_admin_is_allowed_when_another_org_admin_exists() {
     OrganizationDto anotherOrganization = db.organizations().insert();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SetMembersSyncActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SetMembersSyncActionTest.java
new file mode 100644 (file)
index 0000000..ad6da83
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.server.organization.ws;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.alm.OrganizationAlmBindingDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.user.UserDto;
+import org.sonar.server.exceptions.ForbiddenException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.tester.UserSessionRule;
+import org.sonar.server.ws.TestRequest;
+import org.sonar.server.ws.TestResponse;
+import org.sonar.server.ws.WsActionTester;
+
+import static java.net.HttpURLConnection.HTTP_NO_CONTENT;
+import static java.util.Optional.ofNullable;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.tuple;
+import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_ORGANIZATION;
+
+public class SetMembersSyncActionTest {
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot();
+  @Rule
+  public DbTester db = DbTester.create();
+
+  private DbClient dbClient = db.getDbClient();
+
+  private DbSession dbSession = db.getSession();
+
+  private WsActionTester ws = new WsActionTester(new SetMembersSyncAction(dbClient, userSession));
+
+  @Test
+  public void definition() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+
+    WebService.Action definition = ws.getDef();
+
+    assertThat(definition.key()).isEqualTo("set_members_sync");
+    assertThat(definition.since()).isEqualTo("7.7");
+    assertThat(definition.isPost()).isTrue();
+    assertThat(definition.isInternal()).isTrue();
+    assertThat(definition.params())
+      .extracting(WebService.Param::key, WebService.Param::isRequired)
+      .containsExactlyInAnyOrder(tuple("organization", true), tuple("enabled", true));
+  }
+
+  @Test
+  public void update_members_sync() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+
+    sendRequest(organization.getKey(), true);
+
+    Optional<OrganizationAlmBindingDto> dto = dbClient.organizationAlmBindingDao().selectByOrganization(dbSession, organization);
+    assertThat(dto).isPresent();
+    assertThat(dto.get().isMembersSyncEnable()).isTrue();
+  }
+
+  @Test
+  public void returns_no_content() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+
+    TestResponse result = sendRequest(organization.getKey(), true);
+
+    assertThat(result.getStatus()).isEqualTo(HTTP_NO_CONTENT);
+    assertThat(result.getInput()).isEmpty();
+  }
+
+  @Test
+  public void fail_if_org_is_not_admin_of_the_org() {
+    OrganizationDto organization = db.organizations().insert();
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user);
+
+    expectedException.expect(ForbiddenException.class);
+    expectedException.expectMessage("Insufficient privileges");
+
+    sendRequest(organization.getKey(), true);
+  }
+
+  @Test
+  public void fail_if_org_is_not_bound_to_an_alm() {
+    OrganizationDto organization = db.organizations().insert();
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage(String.format("Organization '%s' is not bound to an ALM", organization.getKey()));
+
+    sendRequest(organization.getKey(), true);
+  }
+
+  @Test
+  public void fail_if_org_does_not_exist() {
+    OrganizationDto organization = db.organizations().insert();
+    db.alm().insertOrganizationAlmBinding(organization, db.alm().insertAlmAppInstall());
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage("Organization '1234' does not exist");
+
+    sendRequest("1234", true);
+  }
+
+  private TestResponse sendRequest(@Nullable String organizationKey, @Nullable Boolean enabled) {
+    TestRequest request = ws.newRequest();
+    ofNullable(organizationKey).ifPresent(o -> request.setParam(PARAM_ORGANIZATION, o));
+    ofNullable(enabled).ifPresent(e -> request.setParam("enabled", String.valueOf(e)));
+
+    return request.execute();
+  }
+}
index af065de44f91c2f45c0c275290bc5ce515735848..400d56b5817a5175aa60cf84938769ad717dd62b 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
 import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
 import org.sonar.server.exceptions.ForbiddenException;
@@ -57,9 +58,12 @@ public class UpdateActionTest {
   public UserSessionRule userSession = UserSessionRule.standalone();
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public DbTester db = DbTester.create();
+  private DbClient dbClient = db.getDbClient();
 
   private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone().setEnabled(true);
-  private UpdateAction underTest = new UpdateAction(userSession, new OrganizationsWsSupport(new OrganizationValidationImpl()), dbTester.getDbClient(), organizationFlags);
+  private UpdateAction underTest = new UpdateAction(userSession, new OrganizationsWsSupport(new OrganizationValidationImpl(), dbClient), dbTester.getDbClient(), organizationFlags);
   private WsActionTester wsTester = new WsActionTester(underTest);
 
   @Test