Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SELC-5956] feat: added check of uniqueness group name in creation and editing api #216

Merged
merged 4 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ public class ResourceAlreadyExistsException extends RuntimeException {
public ResourceAlreadyExistsException(String msg, Throwable cause) {
super(msg, cause);
}

public ResourceAlreadyExistsException(String msg) {
super(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import it.pagopa.selfcare.commons.base.security.SelfCareUser;
import it.pagopa.selfcare.user_group.connector.api.UserGroupConnector;
import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
import it.pagopa.selfcare.user_group.connector.exception.ResourceAlreadyExistsException;
import it.pagopa.selfcare.user_group.connector.exception.ResourceNotFoundException;
import it.pagopa.selfcare.user_group.connector.exception.ResourceUpdateException;
import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
Expand Down Expand Up @@ -31,6 +32,7 @@ class UserGroupServiceImpl implements UserGroupService {
private static final String USER_GROUP_ID_REQUIRED_MESSAGE = "A user group id is required";
private static final String TRYING_TO_MODIFY_SUSPENDED_GROUP = "Trying to modify suspended group";
private static final String MEMBER_ID_REQUIRED = "A member id is required";
private static final String GROUP_NAME_ALREADY_EXISTS = "A group with the same name already exists in ACTIVE or SUSPENDED state";
private final List<String> allowedSortingParams;

@Autowired
Expand All @@ -49,12 +51,24 @@ public UserGroupOperations createGroup(UserGroupOperations group) {
Assert.state(authentication.getPrincipal() instanceof SelfCareUser, "Not SelfCareUser principal");
Assert.notNull(group, "A group is required");

checkNameUniqueness(group.getName(), group.getProductId(), group.getInstitutionId());
UserGroupOperations insert = groupConnector.insert(group);
log.debug("insert = {}", insert);
log.trace("createGroup end");
return insert;
}

private void checkNameUniqueness(String groupName, String productId, String institutionId) {
UserGroupFilter filter = new UserGroupFilter();
filter.setProductId(productId);
filter.setInstitutionId(institutionId);
filter.setStatus(Arrays.asList(UserGroupStatus.ACTIVE, UserGroupStatus.SUSPENDED));

Page<UserGroupOperations> existingGroups = groupConnector.findAll(filter, Pageable.unpaged());
if (existingGroups.stream().anyMatch(g -> g.getName().equals(groupName))) {
throw new ResourceAlreadyExistsException(GROUP_NAME_ALREADY_EXISTS);
}
empassaro marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public void addMember(String id, UUID memberId) {
Expand Down Expand Up @@ -160,6 +174,8 @@ public UserGroupOperations updateGroup(String id, UserGroupOperations group) {
if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
}
checkNameUniqueness(group.getName(), foundGroup.getProductId(), foundGroup.getInstitutionId());
empassaro marked this conversation as resolved.
Show resolved Hide resolved

foundGroup.setMembers(group.getMembers());
foundGroup.setName(group.getName());
foundGroup.setDescription(group.getDescription());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import it.pagopa.selfcare.user_group.connector.DummyGroup;
import it.pagopa.selfcare.user_group.connector.api.UserGroupConnector;
import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
import it.pagopa.selfcare.user_group.connector.exception.ResourceAlreadyExistsException;
import it.pagopa.selfcare.user_group.connector.exception.ResourceNotFoundException;
import it.pagopa.selfcare.user_group.connector.exception.ResourceUpdateException;
import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
Expand Down Expand Up @@ -33,8 +34,6 @@

import javax.validation.ValidationException;
import java.util.*;
import java.util.stream.Collectors;

import static java.util.UUID.randomUUID;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
Expand Down Expand Up @@ -117,10 +116,10 @@ void createGroup_ok() {
.build();
TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
TestSecurityContextHolder.setAuthentication(authenticationToken);
Set<UUID> members = Set.of(randomUUID(), randomUUID());
UserGroupOperations input = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
input.setId("id");
input.setMembers(members.stream().map(UUID::toString).collect(Collectors.toSet()));
Page<UserGroupOperations> existingGroups = getPage(Collections.emptyList(), Pageable.unpaged(), () -> 0L);
when(groupConnectorMock.findAll(any(), any()))
.thenReturn(existingGroups);
when(groupConnectorMock.insert(any(UserGroupOperations.class)))
.thenAnswer(invocation -> invocation.getArgument(0, UserGroupOperations.class));
//when
Expand All @@ -130,6 +129,39 @@ void createGroup_ok() {

verify(groupConnectorMock, times(1))
.insert(any(UserGroupOperations.class));
verify(groupConnectorMock, times(1))
.findAll(filter.capture(), any());
verifyNoMoreInteractions(groupConnectorMock);
}

@Test
void createGroup_conflict() {
//given
SelfCareUser selfCareUser = SelfCareUser.builder("userId")
.email("[email protected]")
.name("name")
.surname("surname")
.build();
TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
TestSecurityContextHolder.setAuthentication(authenticationToken);
UserGroupOperations input = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
input.setName("existingGroupName");

UserGroupOperations existingGroup = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
existingGroup.setName("existingGroupName");
Page<UserGroupOperations> existingGroups = getPage(Collections.singletonList(existingGroup), Pageable.unpaged(), () -> 1L);

when(groupConnectorMock.findAll(any(), any()))
.thenReturn(existingGroups);

//when
Executable executable = () -> groupService.createGroup(input);

//then
assertThrows(ResourceAlreadyExistsException.class, executable);

verify(groupConnectorMock, times(1))
.findAll(filter.capture(), any());
verifyNoMoreInteractions(groupConnectorMock);
}

Expand Down Expand Up @@ -266,11 +298,15 @@ void updateGroup_notExists() {
}

@Test
void updateGroup_exists() {
void updateGroup_exists_ok() {
//given
String id = "id";
UserGroupOperations group = TestUtils.mockInstance(new DummyGroup(), "setId");
UserGroupOperations foundGroup = TestUtils.mockInstance(new DummyGroup());
Page<UserGroupOperations> existingGroups = getPage(Collections.emptyList(), Pageable.unpaged(), () -> 0L);

when(groupConnectorMock.findAll(any(), any()))
.thenReturn(existingGroups);
when(groupConnectorMock.findById(Mockito.anyString()))
.thenReturn(Optional.of(foundGroup));
when(groupConnectorMock.save(any()))
Expand All @@ -283,11 +319,47 @@ void updateGroup_exists() {
assertEquals(saved.getName(), group.getName());
verify(groupConnectorMock, times(1))
.findById(id);
verify(groupConnectorMock, times(1))
.findAll(any(), any());
verify(groupConnectorMock, times(1))
.save(any());
verifyNoMoreInteractions(groupConnectorMock);
}

@Test
void updateGroup_exists_conflict() {
//given
String id = "id";
UserGroupOperations group = TestUtils.mockInstance(new DummyGroup(), "setId");
group.setName("existingGroupName");
UserGroupOperations foundGroup = TestUtils.mockInstance(new DummyGroup());
foundGroup.setStatus(UserGroupStatus.ACTIVE);

UserGroupOperations existingGroup = TestUtils.mockInstance(new DummyGroup(), "setId");
existingGroup.setName("existingGroupName");
existingGroup.setId("differentId");
Page<UserGroupOperations> existingGroups = getPage(Collections.singletonList(existingGroup), Pageable.unpaged(), () -> 1L);

when(groupConnectorMock.findAll(any(), any()))
.thenReturn(existingGroups);
when(groupConnectorMock.findById(Mockito.anyString()))
.thenReturn(Optional.of(foundGroup));
when(groupConnectorMock.save(any()))
.thenAnswer(invocationOnMock -> invocationOnMock.getArgument(0, UserGroupOperations.class));

//when
Executable executable = () -> groupService.updateGroup(id, group);

//then
assertThrows(ResourceAlreadyExistsException.class, executable);

verify(groupConnectorMock, times(1))
.findById(id);
verify(groupConnectorMock, times(1))
.findAll(any(), any());
verifyNoMoreInteractions(groupConnectorMock);
}

@Test
void addMember_nullId() {
//given
Expand Down
Loading