From b5907dac5c5d72c8231596d1352e83b546bd93ff Mon Sep 17 00:00:00 2001 From: Wojtek Wajerowicz <115081248+wojciech-wajerowicz-sonarsource@users.noreply.github.com> Date: Fri, 3 Mar 2023 15:37:00 +0100 Subject: [PATCH] SONAR-18525 Rely on GroupService instead of GroupSupport for PUT /api/scim/v2/Groups/{groupId} endpoint --- .../server/usergroups/ws/CreateActionIT.java | 10 +- .../server/usergroups/ws/DeleteActionIT.java | 4 +- .../server/usergroups/ws/UpdateActionIT.java | 4 +- .../server/usergroups/ws/CreateAction.java | 23 +-- .../server/usergroups/ws/GroupService.java | 67 ++++++- .../server/usergroups/ws/GroupWsSupport.java | 44 ----- .../server/usergroups/ws/UpdateAction.java | 8 +- .../usergroups/ws/GroupServiceTest.java | 170 +++++++++++++++++- .../usergroups/ws/GroupWsSupportTest.java | 137 -------------- 9 files changed, 252 insertions(+), 215 deletions(-) delete mode 100644 server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupWsSupportTest.java diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java index ee83accb75c..91a5963a31e 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/CreateActionIT.java @@ -28,10 +28,10 @@ import org.sonar.api.utils.System2; import org.sonar.core.util.SequenceUuidFactory; import org.sonar.db.DbTester; import org.sonar.db.user.GroupDto; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.ServerException; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; @@ -45,7 +45,7 @@ public class CreateActionIT { @Rule public UserSessionRule userSession = UserSessionRule.standalone(); - private final CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupWsSupport(), new SequenceUuidFactory()); + private final CreateAction underTest = new CreateAction(db.getDbClient(), userSession, newGroupService()); private final WsActionTester tester = new WsActionTester(underTest); @Test @@ -143,7 +143,7 @@ public class CreateActionIT { .setParam("name", "AnYoNe") .execute(); }) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(BadRequestException.class); } @Test @@ -177,7 +177,7 @@ public class CreateActionIT { userSession.logIn().addPermission(ADMINISTER); } - private GroupWsSupport newGroupWsSupport() { - return new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); + private GroupService newGroupService() { + return new GroupService(db.getDbClient(), new SequenceUuidFactory()); } } diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java index c949c686c31..7fafc8b8a09 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/DeleteActionIT.java @@ -25,6 +25,7 @@ import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; import org.sonar.api.web.UserRole; +import org.sonar.core.util.UuidFactoryImpl; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; @@ -53,7 +54,7 @@ public class DeleteActionIT { public DbTester db = DbTester.create(new AlwaysIncreasingSystem2()); private final ComponentDbTester componentTester = new ComponentDbTester(db); - private final GroupService groupService = new GroupService(db.getDbClient()); + private final GroupService groupService = new GroupService(db.getDbClient(), UuidFactoryImpl.INSTANCE); private final WsActionTester ws = new WsActionTester(new DeleteAction(db.getDbClient(), userSession, groupService)); @Test @@ -196,7 +197,6 @@ public class DeleteActionIT { assertThat(db.countRowsOfTable("scim_groups")).isZero(); } - @Test public void fail_to_delete_default_group() { loginAsAdmin(); diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java index ff80fb8c4c6..e77c5088a13 100644 --- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java +++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/usergroups/ws/UpdateActionIT.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService.Action; import org.sonar.api.utils.System2; +import org.sonar.core.util.UuidFactoryImpl; import org.sonar.db.DbTester; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; @@ -32,7 +33,6 @@ import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.exceptions.ServerException; import org.sonar.server.tester.UserSessionRule; -import org.sonar.server.usergroups.DefaultGroupFinder; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; @@ -52,7 +52,7 @@ public class UpdateActionIT { public UserSessionRule userSession = UserSessionRule.standalone(); private final WsActionTester ws = new WsActionTester( - new UpdateAction(db.getDbClient(), userSession, new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())))); + new UpdateAction(db.getDbClient(), userSession, new GroupService(db.getDbClient(), UuidFactoryImpl.INSTANCE))); @Test public void verify_definition() { diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java index e2365557d11..2448bbfdae5 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/CreateAction.java @@ -24,8 +24,6 @@ import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService.NewAction; import org.sonar.api.server.ws.WebService.NewController; -import org.sonar.api.user.UserGroupValidation; -import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.GroupDto; @@ -45,14 +43,12 @@ public class CreateAction implements UserGroupsWsAction { private final DbClient dbClient; private final UserSession userSession; - private final GroupWsSupport support; - private final UuidFactory uuidFactory; + private final GroupService groupService; - public CreateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support, UuidFactory uuidFactory) { + public CreateAction(DbClient dbClient, UserSession userSession, GroupService groupService) { this.dbClient = dbClient; this.userSession = userSession; - this.support = support; - this.uuidFactory = uuidFactory; + this.groupService = groupService; } @Override @@ -85,18 +81,11 @@ public class CreateAction implements UserGroupsWsAction { try (DbSession dbSession = dbClient.openSession(false)) { userSession.checkPermission(ADMINISTER); - GroupDto group = new GroupDto() - .setUuid(uuidFactory.create()) - .setName(request.mandatoryParam(PARAM_GROUP_NAME)) - .setDescription(request.param(PARAM_GROUP_DESCRIPTION)); - // validations - UserGroupValidation.validateGroupName(group.getName()); - support.checkNameDoesNotExist(dbSession, group.getName()); - - dbClient.groupDao().insert(dbSession, group); + String groupName = request.mandatoryParam(PARAM_GROUP_NAME); + String groupDescription = request.param(PARAM_GROUP_DESCRIPTION); + GroupDto group = groupService.createGroup(dbSession, groupName, groupDescription); dbSession.commit(); - writeResponse(request, response, group); } } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupService.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupService.java index 629c3d88dee..d1369a20291 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupService.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupService.java @@ -20,25 +20,32 @@ package org.sonar.server.usergroups.ws; import java.util.Set; +import javax.annotation.Nullable; import org.sonar.api.security.DefaultGroups; import org.sonar.api.server.ServerSide; +import org.sonar.api.user.UserGroupValidation; +import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.GlobalPermission; import org.sonar.db.user.GroupDto; import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; +import static org.sonar.server.exceptions.BadRequestException.checkRequest; @ServerSide public class GroupService { private final DbClient dbClient; + private final UuidFactory uuidFactory; - public GroupService(DbClient dbClient) { + public GroupService(DbClient dbClient, UuidFactory uuidFactory) { this.dbClient = dbClient; + this.uuidFactory = uuidFactory; } public GroupDto findGroupDtoOrThrow(DbSession dbSession, String groupName) { @@ -60,7 +67,63 @@ public class GroupService { removeGroup(dbSession, group); } - void checkGroupIsNotDefault(DbSession dbSession, GroupDto groupDto) { + public GroupDto updateGroup(DbSession dbSession, GroupDto group, @Nullable String newName) { + checkGroupIsNotDefault(dbSession, group); + return updateName(dbSession, group, newName); + } + + public GroupDto updateGroup(DbSession dbSession, GroupDto group, @Nullable String newName, @Nullable String newDescription) { + checkGroupIsNotDefault(dbSession, group); + GroupDto withUpdatedName = updateName(dbSession, group, newName); + return updateDescription(dbSession, withUpdatedName, newDescription); + } + + + public GroupDto createGroup(DbSession dbSession, String name, @Nullable String description) { + validateGroupName(name); + checkNameDoesNotExist(dbSession, name); + + GroupDto group = new GroupDto() + .setUuid(uuidFactory.create()) + .setName(name) + .setDescription(description); + return dbClient.groupDao().insert(dbSession, group); + } + + private GroupDto updateName(DbSession dbSession, GroupDto group, @Nullable String newName) { + if (newName != null && !newName.equals(group.getName())) { + validateGroupName(newName); + checkNameDoesNotExist(dbSession, newName); + group.setName(newName); + return dbClient.groupDao().update(dbSession, group); + } + return group; + } + + private static void validateGroupName(String name) { + try { + UserGroupValidation.validateGroupName(name); + } catch (IllegalArgumentException e) { + BadRequestException.throwBadRequestException(e.getMessage()); + } + } + + private void checkNameDoesNotExist(DbSession dbSession, String name) { + // There is no database constraint on column groups.name + // because MySQL cannot create a unique index + // on a UTF-8 VARCHAR larger than 255 characters on InnoDB + checkRequest(!dbClient.groupDao().selectByName(dbSession, name).isPresent(), "Group '%s' already exists", name); + } + + private GroupDto updateDescription(DbSession dbSession, GroupDto group, @Nullable String newDescription) { + if (newDescription != null) { + group.setDescription(newDescription); + return dbClient.groupDao().update(dbSession, group); + } + return group; + } + + private void checkGroupIsNotDefault(DbSession dbSession, GroupDto groupDto) { GroupDto defaultGroup = findDefaultGroup(dbSession); checkArgument(!defaultGroup.getUuid().equals(groupDto.getUuid()), "Default group '%s' cannot be used to perform this action", groupDto.getName()); } diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java index 05c66b474ec..15034dec15e 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/GroupWsSupport.java @@ -20,15 +20,12 @@ package org.sonar.server.usergroups.ws; import java.util.Optional; -import javax.annotation.Nullable; import org.sonar.api.security.DefaultGroups; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.WebService; -import org.sonar.api.user.UserGroupValidation; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.user.GroupDto; -import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.permission.GroupUuid; import org.sonar.server.permission.GroupUuidOrAnyone; @@ -37,7 +34,6 @@ import org.sonarqube.ws.UserGroups; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Optional.ofNullable; -import static org.sonar.server.exceptions.BadRequestException.checkRequest; import static org.sonar.server.exceptions.NotFoundException.checkFoundWithOptional; /** @@ -98,46 +94,6 @@ public class GroupWsSupport { return GroupUuidOrAnyone.from(group.get()); } - public GroupDto updateGroup(DbSession dbSession, GroupDto group, @Nullable String newName) { - checkGroupIsNotDefault(dbSession, group); - return updateName(dbSession, group, newName); - } - - public GroupDto updateGroup(DbSession dbSession, GroupDto group, @Nullable String newName, @Nullable String newDescription) { - checkGroupIsNotDefault(dbSession, group); - GroupDto withUpdatedName = updateName(dbSession, group, newName); - return updateDescription(dbSession, withUpdatedName, newDescription); - } - - private GroupDto updateName(DbSession dbSession, GroupDto group, @Nullable String newName) { - if (newName != null && !newName.equals(group.getName())) { - try { - UserGroupValidation.validateGroupName(newName); - } catch (IllegalArgumentException e) { - BadRequestException.throwBadRequestException(e.getMessage()); - } - checkNameDoesNotExist(dbSession, newName); - group.setName(newName); - return dbClient.groupDao().update(dbSession, group); - } - return group; - } - - private GroupDto updateDescription(DbSession dbSession, GroupDto group, @Nullable String newDescription) { - if (newDescription != null) { - group.setDescription(newDescription); - return dbClient.groupDao().update(dbSession, group); - } - return group; - } - - void checkNameDoesNotExist(DbSession dbSession, String name) { - // There is no database constraint on column groups.name - // because MySQL cannot create a unique index - // on a UTF-8 VARCHAR larger than 255 characters on InnoDB - checkRequest(!dbClient.groupDao().selectByName(dbSession, name).isPresent(), "Group '%s' already exists", name); - } - void checkGroupIsNotDefault(DbSession dbSession, GroupDto groupDto) { GroupDto defaultGroup = defaultGroupFinder.findDefaultGroup(dbSession); checkArgument(!defaultGroup.getUuid().equals(groupDto.getUuid()), "Default group '%s' cannot be used to perform this action", groupDto.getName()); diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java index 7220c4db33f..7c31c49b206 100644 --- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java +++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/usergroups/ws/UpdateAction.java @@ -47,12 +47,12 @@ public class UpdateAction implements UserGroupsWsAction { private final DbClient dbClient; private final UserSession userSession; - private final GroupWsSupport support; + private final GroupService groupService; - public UpdateAction(DbClient dbClient, UserSession userSession, GroupWsSupport support) { + public UpdateAction(DbClient dbClient, UserSession userSession, GroupService groupService) { this.dbClient = dbClient; this.userSession = userSession; - this.support = support; + this.groupService = groupService; } @Override @@ -101,7 +101,7 @@ public class UpdateAction implements UserGroupsWsAction { String newName = request.param(PARAM_GROUP_NAME); String description = request.param(PARAM_GROUP_DESCRIPTION); - GroupDto updatedGroup = support.updateGroup(dbSession, group, newName, description); + GroupDto updatedGroup = groupService.updateGroup(dbSession, group, newName, description); dbSession.commit(); writeResponse(dbSession, request, response, updatedGroup); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupServiceTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupServiceTest.java index cc13153babb..0efaf7178ad 100644 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupServiceTest.java +++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupServiceTest.java @@ -19,15 +19,22 @@ */ package org.sonar.server.usergroups.ws; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.util.Optional; import java.util.Set; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; import org.sonar.api.security.DefaultGroups; +import org.sonar.core.util.UuidFactory; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.AuthorizationDao; @@ -41,27 +48,40 @@ import org.sonar.db.user.GroupDto; import org.sonar.db.user.RoleDao; import org.sonar.db.user.UserDto; import org.sonar.db.user.UserGroupDao; +import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.NotFoundException; import static java.lang.String.format; +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNoException; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@RunWith(DataProviderRunner.class) public class GroupServiceTest { + private static final String GROUP_NAME = "GROUP_NAME"; private static final String GROUP_UUID = "GROUP_UUID"; + private static final String DEFAULT_GROUP_NAME = "sonar-users"; + private static final String DEFAULT_GROUP_UUID = "DEFAULT_GROUP_UUID"; @Mock private DbSession dbSession; @Mock private DbClient dbClient; + @Mock + private UuidFactory uuidFactory; @InjectMocks private GroupService groupService; + @Rule + public MockitoRule rule = MockitoJUnit.rule(); + @Before public void setUp() { mockNeededDaos(); @@ -145,6 +165,144 @@ public class GroupServiceTest { verify(dbClient.userGroupDao()).deleteFromGroupByUserUuids(dbSession, groupDto, userDtos); } + @Test + public void updateGroup_updatesGroupNameAndDescription() { + GroupDto group = mockGroupDto(); + GroupDto groupWithUpdatedName = mockGroupDto(); + mockDefaultGroup(); + when(dbClient.groupDao().update(dbSession, group)).thenReturn(groupWithUpdatedName); + + groupService.updateGroup(dbSession, group, "new-name", "New Description"); + verify(group).setName("new-name"); + verify(groupWithUpdatedName).setDescription("New Description"); + verify(dbClient.groupDao()).update(dbSession, group); + verify(dbClient.groupDao()).update(dbSession, groupWithUpdatedName); + } + + @Test + public void updateGroup_updatesGroupName() { + GroupDto group = mockGroupDto(); + mockDefaultGroup(); + + groupService.updateGroup(dbSession, group, "new-name"); + verify(group).setName("new-name"); + verify(dbClient.groupDao()).update(dbSession, group); + } + + @Test + public void updateGroup_whenGroupIsDefault_throws() { + GroupDto defaultGroup = mockDefaultGroup(); + when(dbClient.groupDao().selectByName(dbSession, DEFAULT_GROUP_NAME)).thenReturn(Optional.of(defaultGroup)); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, defaultGroup, "new-name", "New Description")) + .withMessage("Default group 'sonar-users' cannot be used to perform this action"); + + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, defaultGroup, "new-name")) + .withMessage("Default group 'sonar-users' cannot be used to perform this action"); + } + + @Test + public void updateGroup_whenGroupNameDoesntChange_succeedsWithDescription() { + GroupDto group = mockGroupDto(); + mockDefaultGroup(); + + groupService.updateGroup(dbSession, group, group.getName(), "New Description"); + verify(group).setDescription("New Description"); + verify(dbClient.groupDao()).update(dbSession, group); + } + + @Test + public void updateGroup_whenGroupNameDoesntChange_succeeds() { + GroupDto group = mockGroupDto(); + mockDefaultGroup(); + + assertThatNoException() + .isThrownBy(() -> groupService.updateGroup(dbSession, group, group.getName())); + + verify(dbClient.groupDao(), never()).update(dbSession, group); + } + + @Test + public void updateGroup_whenGroupExist_throws() { + GroupDto group = mockGroupDto(); + GroupDto group2 = mockGroupDto(); + mockDefaultGroup(); + String group2Name = GROUP_NAME + "2"; + + when(dbClient.groupDao().selectByName(dbSession, group2Name)).thenReturn(Optional.of(group2)); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, group, group2Name, "New Description")) + .withMessage("Group '" + group2Name + "' already exists"); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, group, group2Name)) + .withMessage("Group '" + group2Name + "' already exists"); + } + + @Test + @UseDataProvider("invalidGroupNames") + public void updateGroup_whenGroupNameIsInvalid_throws(String groupName, String errorMessage) { + GroupDto group = mockGroupDto(); + mockDefaultGroup(); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, group, groupName, "New Description")) + .withMessage(errorMessage); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.updateGroup(dbSession, group, groupName)) + .withMessage(errorMessage); + } + + @Test + public void createGroup_whenNameAndDescriptionIsProvided_createsGroup() { + + when(uuidFactory.create()).thenReturn("1234"); + groupService.createGroup(dbSession, "Name", "Description"); + + ArgumentCaptor groupCaptor = ArgumentCaptor.forClass(GroupDto.class); + verify(dbClient.groupDao()).insert(eq(dbSession), groupCaptor.capture()); + GroupDto createdGroup = groupCaptor.getValue(); + assertThat(createdGroup.getName()).isEqualTo("Name"); + assertThat(createdGroup.getDescription()).isEqualTo("Description"); + assertThat(createdGroup.getUuid()).isEqualTo("1234"); + } + + @Test + public void createGroup_whenGroupExist_throws() { + GroupDto group = mockGroupDto(); + + when(dbClient.groupDao().selectByName(dbSession, GROUP_NAME)).thenReturn(Optional.of(group)); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.createGroup(dbSession, GROUP_NAME, "New Description")) + .withMessage("Group '" + GROUP_NAME + "' already exists"); + + } + + @Test + @UseDataProvider("invalidGroupNames") + public void createGroup_whenGroupNameIsInvalid_throws(String groupName, String errorMessage) { + mockDefaultGroup(); + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> groupService.createGroup(dbSession, groupName, "Description")) + .withMessage(errorMessage); + + } + + @DataProvider + public static Object[][] invalidGroupNames() { + return new Object[][] { + {"", "Group name cannot be empty"}, + {randomAlphanumeric(256), "Group name cannot be longer than 255 characters"}, + {"Anyone", "Anyone group cannot be used"}, + }; + } + private void mockNeededDaos() { when(dbClient.authorizationDao()).thenReturn(mock(AuthorizationDao.class)); when(dbClient.roleDao()).thenReturn(mock(RoleDao.class)); @@ -163,6 +321,14 @@ public class GroupServiceTest { return groupDto; } + private GroupDto mockDefaultGroup() { + GroupDto defaultGroup = mock(GroupDto.class); + when(defaultGroup.getName()).thenReturn(DEFAULT_GROUP_NAME); + when(defaultGroup.getUuid()).thenReturn(DEFAULT_GROUP_UUID); + when(dbClient.groupDao().selectByName(dbSession, DEFAULT_GROUP_NAME)).thenReturn(Optional.of(defaultGroup)); + return defaultGroup; + } + private void verifyNoGroupDelete(DbSession dbSession, GroupDto groupDto) { verify(dbClient.roleDao(), never()).deleteGroupRolesByGroupUuid(dbSession, groupDto.getUuid()); verify(dbClient.permissionTemplateDao(), never()).deleteByGroup(dbSession, groupDto.getUuid(), groupDto.getName()); diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupWsSupportTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupWsSupportTest.java deleted file mode 100644 index 9a65795595f..00000000000 --- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/usergroups/ws/GroupWsSupportTest.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2023 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.usergroups.ws; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.sonar.api.utils.System2; -import org.sonar.db.DbSession; -import org.sonar.db.DbTester; -import org.sonar.db.user.GroupDto; -import org.sonar.server.exceptions.BadRequestException; -import org.sonar.server.usergroups.DefaultGroupFinder; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.assertj.core.api.Assertions.assertThatNoException; - -@RunWith(DataProviderRunner.class) -public class GroupWsSupportTest { - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private final GroupWsSupport groupWsSupport = new GroupWsSupport(db.getDbClient(), new DefaultGroupFinder(db.getDbClient())); - - @Test - public void updateGroup_updatesGroupNameAndDescription() { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - groupWsSupport.updateGroup(db.getSession(), group, "new-name", "New Description"); - GroupDto updatedGroup = db.getDbClient().groupDao().selectByUuid(db.getSession(), group.getUuid()); - assertThat(updatedGroup.getName()).isEqualTo("new-name"); - assertThat(updatedGroup.getDescription()).isEqualTo("New Description"); - } - - public void updateGroup_updatesGroupName() { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - groupWsSupport.updateGroup(db.getSession(), group, "new-name"); - GroupDto updatedGroup = db.getDbClient().groupDao().selectByUuid(db.getSession(), group.getUuid()); - assertThat(updatedGroup.getName()).isEqualTo("new-name"); - } - - @Test - public void updateGroup_whenGroupIsDefault_throws() { - GroupDto defaultGroup = db.users().insertDefaultGroup(); - DbSession session = db.getSession(); - assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, defaultGroup, "new-name", "New Description")) - .withMessage("Default group 'sonar-users' cannot be used to perform this action"); - - assertThatExceptionOfType(IllegalArgumentException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, defaultGroup, "new-name")) - .withMessage("Default group 'sonar-users' cannot be used to perform this action"); - } - - @Test - public void updateGroup_whenGroupNameDoesntChange_succeedsWithDescription() { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - groupWsSupport.updateGroup(db.getSession(), group, group.getName(), "New Description"); - GroupDto updatedGroup = db.getDbClient().groupDao().selectByUuid(db.getSession(), group.getUuid()); - assertThat(updatedGroup.getDescription()).isEqualTo("New Description"); - } - - public void updateGroup_whenGroupNameDoesntChange_succeeds() { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - assertThatNoException() - .isThrownBy(() -> groupWsSupport.updateGroup(db.getSession(), group, group.getName())); - } - - @Test - public void updateGroup_whenGroupExist_throws() { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - GroupDto group2 = db.users().insertGroup(); - DbSession session = db.getSession(); - String group2Name = group2.getName(); - - assertThatExceptionOfType(BadRequestException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, group, group2Name, "New Description")) - .withMessage("Group '" + group2Name + "' already exists"); - - assertThatExceptionOfType(BadRequestException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, group, group2Name)) - .withMessage("Group '" + group2Name + "' already exists"); - } - - @Test - @UseDataProvider("invalidGroupNames") - public void updateGroup_whenGroupNameIsInvalid_throws(String groupName, String errorMessage) { - db.users().insertDefaultGroup(); - GroupDto group = db.users().insertGroup(); - DbSession session = db.getSession(); - - assertThatExceptionOfType(BadRequestException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, group, groupName, "New Description")) - .withMessage(errorMessage); - - assertThatExceptionOfType(BadRequestException.class) - .isThrownBy(() -> groupWsSupport.updateGroup(session, group, groupName)) - .withMessage(errorMessage); - } - - @DataProvider - public static Object[][] invalidGroupNames() { - return new Object[][] { - {"", "Group name cannot be empty"}, - {randomAlphanumeric(256), "Group name cannot be longer than 255 characters"}, - {"Anyone", "Anyone group cannot be used"}, - }; - } - -} -- 2.39.5