diff --git a/apps/pom.xml b/apps/pom.xml
index f6a81700..ca693ae0 100644
--- a/apps/pom.xml
+++ b/apps/pom.xml
@@ -13,14 +13,14 @@
pom
- 0.4.1
+ 0.3.2
it.pagopa.selfcare
onboarding-sdk-azure-storage
- ${onboarding-sdk.version}
+ 0.3.2
it.pagopa.selfcare
diff --git a/apps/user-group-ms/app/pom.xml b/apps/user-group-ms/app/pom.xml
deleted file mode 100644
index 269786c5..00000000
--- a/apps/user-group-ms/app/pom.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-
-
-
- user-group-ms
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
-
- user-group-ms-app
-
-
-
- it.pagopa.selfcare
- user-group-ms-web
-
-
- it.pagopa.selfcare
- user-group-ms-connector-dao
- runtime
-
-
-
-
-
-
- org.springframework.boot
- spring-boot-maven-plugin
-
- false
- ${project.parent.artifactId}-${project.parent.version}-FATJAR
- ../target
-
-
- org.projectlombok
- lombok
-
-
-
-
-
-
-
-
diff --git a/apps/user-group-ms/connector-api/pom.xml b/apps/user-group-ms/connector-api/pom.xml
deleted file mode 100644
index 50b303e9..00000000
--- a/apps/user-group-ms/connector-api/pom.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
- user-group-ms
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
-
- user-group-ms-connector-api
-
-
-
- org.springframework.data
- spring-data-commons
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
-
- true
-
-
-
-
- test-jar
-
-
-
-
-
-
-
-
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupConnector.java b/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupConnector.java
deleted file mode 100644
index 9a57401f..00000000
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupConnector.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package it.pagopa.selfcare.user_group.connector.api;
-
-import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-
-import java.util.Optional;
-
-public interface UserGroupConnector {
- UserGroupOperations insert(UserGroupOperations entity);
-
- UserGroupOperations save(UserGroupOperations entity);
-
- void insertMember(String id, String memberId);
-
- void deleteMember(String id, String memberId);
-
- void deleteMembers(String memberId, String institutionId, String productId);
-
- Optional findById(String id);
-
- Page findAll(UserGroupFilter filter, Pageable pageable);
-
- void activateById(String id);
-
- void deleteById(String id);
-
- void suspendById(String id);
-}
diff --git a/apps/user-group-ms/connector/dao/pom.xml b/apps/user-group-ms/connector/dao/pom.xml
deleted file mode 100644
index 8991f8ca..00000000
--- a/apps/user-group-ms/connector/dao/pom.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
- user-group-ms-connector
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
-
- user-group-ms-connector-dao
-
-
-
- org.springframework.boot
- spring-boot-starter-data-mongodb
-
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo
- test
-
-
-
-
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImpl.java b/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImpl.java
deleted file mode 100644
index 89f1149b..00000000
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImpl.java
+++ /dev/null
@@ -1,219 +0,0 @@
-package it.pagopa.selfcare.user_group.connector.dao;
-
-import com.mongodb.client.result.UpdateResult;
-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.dao.model.CriteriaBuilder;
-import it.pagopa.selfcare.user_group.connector.dao.model.UserGroupEntity;
-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;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.data.domain.AuditorAware;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.core.query.Update;
-import org.springframework.data.support.PageableExecutionUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.util.StringUtils;
-
-import javax.validation.ValidationException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-
-@Service
-@Slf4j
-public class UserGroupConnectorImpl implements UserGroupConnector {
-
- private final UserGroupRepository repository;
- private final MongoTemplate mongoTemplate;
- private final AuditorAware auditorAware;
- private static final String COULD_NOT_UPDATE_MESSAGE = "Couldn't update resource";
-
-
- @Autowired
- public UserGroupConnectorImpl(UserGroupRepository repository, MongoTemplate mongoTemplate, AuditorAware auditorAware) {
- this.repository = repository;
- this.mongoTemplate = mongoTemplate;
- this.auditorAware = auditorAware;
- }
-
- @Override
- public UserGroupOperations insert(UserGroupOperations entity) {
- log.trace("insert start");
- log.debug("insert entity = {}", entity);
- UserGroupEntity insert;
- try {
- insert = repository.insert(new UserGroupEntity(entity));
- } catch (DuplicateKeyException e) {
- throw new ResourceAlreadyExistsException("Failed _id or unique index constraint.", e);
- }
-
- log.trace("insert end");
- return insert;
- }
-
- @Override
- public UserGroupOperations save(UserGroupOperations entity) {
- log.trace("save start");
- log.debug("save entity = {}", entity);
- UserGroupEntity result;
- try {
- result = repository.save(new UserGroupEntity(entity));
- } catch (DuplicateKeyException e) {
- throw new ResourceAlreadyExistsException("Failed _id or unique index constraint.", e);
- }
- log.debug("save result = {}", result);
- log.trace("save end");
- return result;
- }
-
- @Override
- public void insertMember(String id, String memberId) {
- log.trace("insertMember start");
- log.debug("insertMember id = {}, memberId = {}", id, memberId);
-
- UpdateResult updateResult = mongoTemplate.updateFirst(
- Query.query(Criteria.where(UserGroupEntity.Fields.id).is(id)
- .and(UserGroupEntity.Fields.status).is(UserGroupStatus.ACTIVE)),
- new Update().push(UserGroupEntity.Fields.members, memberId)
- .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
- .currentDate(UserGroupEntity.Fields.modifiedAt),
- UserGroupEntity.class);
- if (updateResult.getModifiedCount() == 0) {
- throw new ResourceUpdateException(COULD_NOT_UPDATE_MESSAGE);
- }
- log.trace("insertMember end");
-
- }
-
- @Override
- public void deleteMember(String id, String memberId) {
- log.trace("deleteMember start");
- log.debug("deleteMember id = {}, memberId = {}", id, memberId);
-
- UpdateResult updateResult = mongoTemplate.updateFirst(
- Query.query(Criteria.where(UserGroupEntity.Fields.id).is(id)
- .and(UserGroupEntity.Fields.status).is(UserGroupStatus.ACTIVE)),
- new Update().pull(UserGroupEntity.Fields.members, memberId)
- .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
- .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
- UserGroupEntity.class);
- if (updateResult.getModifiedCount() == 0) {
- throw new ResourceUpdateException(COULD_NOT_UPDATE_MESSAGE);
- }
- log.trace("deleteMember end");
- }
-
- public void deleteMembers(String memberId, String institutionId, String productId) {
- log.trace("deleteMembers start");
- log.debug("deleteMembers id = {}, institutionId = {}, productId= {}", memberId, institutionId, productId);
-
- UpdateResult updateResult = mongoTemplate.updateMulti(
- Query.query(Criteria.where(UserGroupEntity.Fields.members).is(memberId)
- .and(UserGroupEntity.Fields.institutionId).is(institutionId)
- .and(UserGroupEntity.Fields.productId).is(productId)),
- new Update().pull(UserGroupEntity.Fields.members, memberId)
- .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
- .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
- UserGroupEntity.class);
- if (updateResult.getModifiedCount() == 0) {
- log.warn("No user to delete from UserGroup");
- }
- log.trace("deleteMembers end");
- }
-
- @Override
- public Optional findById(String id) {
- log.trace("findById start");
- log.debug("findById id = {} ", id);
- Optional result = repository.findById(id).map(Function.identity());
- log.debug("findById result = {}", result);
- log.trace("findById end");
-
- return result;
- }
-
- @Override
- public Page findAll(UserGroupFilter filter, Pageable pageable) {
- log.trace("findAll start");
- log.debug("findAll institutionId= {} , productId = {}, userId = {}, pageable = {}", filter.getInstitutionId(), filter.getProductId(), filter.getUserId(), pageable);
- if (pageable.getSort().isSorted() && !StringUtils.hasText(filter.getProductId()) && !StringUtils.hasText(filter.getInstitutionId())) {
- throw new ValidationException("Sorting not allowed without productId or institutionId");
- }
- if (filter.getStatus().size() == 1 && !StringUtils.hasText(filter.getUserId()) && !StringUtils.hasText(filter.getProductId()) && !StringUtils.hasText(filter.getInstitutionId())) {
- throw new ValidationException("At least one of productId, institutionId and userId must be provided with status filter");
- }
- Query query = new Query(constructCriteria(filter));
- long count = this.mongoTemplate.count(query, UserGroupEntity.class);
- List userGroupOperations = new ArrayList<>(mongoTemplate.find(query.with(pageable), UserGroupEntity.class));
- final Page result = PageableExecutionUtils.getPage(userGroupOperations, pageable, () -> count);
- log.debug("findAll result = {}", result);
- log.trace("findAll end");
- return result;
- }
-
-
- @Override
- public void activateById(String id) {
- log.trace("activateById start");
- log.debug("activateById id = {} ", id);
- updateUserById(id, UserGroupStatus.ACTIVE);
- log.trace("activateById end");
-
- }
-
-
- @Override
- public void deleteById(String id) {
- log.trace("deleteById start");
- log.debug("deleteById id = {} ", id);
- updateUserById(id, UserGroupStatus.DELETED);
- log.trace("deleteById end");
- }
-
- @Override
- public void suspendById(String id) {
- log.trace("suspendById start");
- log.debug("suspendById id = {} ", id);
- updateUserById(id, UserGroupStatus.SUSPENDED);
- log.trace("suspendById end");
-
- }
-
- private void updateUserById(String id, UserGroupStatus status) {
- log.trace("updateUserById start");
- log.debug("updateUserById id = {}, status = {}", id, status);
- UpdateResult updateResult = mongoTemplate.updateFirst(
- Query.query(Criteria.where(UserGroupEntity.Fields.id).is(id)),
- Update.update(UserGroupEntity.Fields.status, status)
- .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
- .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
- UserGroupEntity.class);
- if (updateResult.getMatchedCount() == 0) {
- throw new ResourceNotFoundException();
- }
- log.trace("updateUserById end");
-
- }
-
- private Criteria constructCriteria(UserGroupFilter filter) {
- return CriteriaBuilder.builder()
- .isIfNotNull(UserGroupEntity.Fields.institutionId, filter.getInstitutionId())
- .isIfNotNull(UserGroupEntity.Fields.productId, filter.getProductId())
- .isIfNotNull(UserGroupEntity.Fields.members, filter.getUserId())
- .inIfNotEmpty(UserGroupEntity.Fields.status, filter.getStatus())
- .build();
-
- }
-
-}
diff --git a/apps/user-group-ms/connector/dao/src/main/resources/config/dao-config.properties b/apps/user-group-ms/connector/dao/src/main/resources/config/dao-config.properties
deleted file mode 100644
index 1d25e708..00000000
--- a/apps/user-group-ms/connector/dao/src/main/resources/config/dao-config.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-spring.data.mongodb.uri=${MONGODB_CONNECTION_URI:mongodb://localhost:27017/?readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false}&appname=${MONGODB_APPNAME:selcUserGroup}
-spring.data.mongodb.database=${MONGODB_NAME:selcUserGroup}
\ No newline at end of file
diff --git a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImplTest.java b/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImplTest.java
deleted file mode 100644
index b2c01ef2..00000000
--- a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImplTest.java
+++ /dev/null
@@ -1,894 +0,0 @@
-package it.pagopa.selfcare.user_group.connector.dao;
-
-import com.mongodb.client.result.DeleteResult;
-import com.mongodb.client.result.UpdateResult;
-import it.pagopa.selfcare.commons.base.security.SelfCareUser;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.dao.auditing.SpringSecurityAuditorAware;
-import it.pagopa.selfcare.user_group.connector.dao.model.UserGroupEntity;
-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;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import org.bson.BsonValue;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.function.Executable;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-import org.springframework.dao.DuplicateKeyException;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.core.query.Update;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.test.context.TestSecurityContextHolder;
-
-import javax.validation.ValidationException;
-import java.time.Instant;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-
-import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.*;
-
-class UserGroupConnectorImplTest {
-
- private final static String LOGGED_USER_ID = "id";
-
- private final UserGroupRepository repositoryMock;
-
- @AfterEach
- void clear() {
- repositoryMock.deleteAll();
- Mockito.reset(repositoryMock, mongoTemplateMock);
- }
-
- private final MongoTemplate mongoTemplateMock;
-
- private final UserGroupConnectorImpl groupConnector;
-
- private final SelfCareUser selfCareUser;
-
- public UserGroupConnectorImplTest() {
- selfCareUser = SelfCareUser.builder(LOGGED_USER_ID).build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- repositoryMock = Mockito.mock(UserGroupRepository.class);
- mongoTemplateMock = Mockito.mock(MongoTemplate.class);
- groupConnector = new UserGroupConnectorImpl(repositoryMock, mongoTemplateMock, new SpringSecurityAuditorAware());
- }
-
- @Test
- void insert_duplicateKey() {
- UserGroupEntity entity = mockInstance(new UserGroupEntity());
- Mockito.doThrow(DuplicateKeyException.class)
- .when(repositoryMock)
- .insert(any(UserGroupEntity.class));
- //when
- Executable executable = () -> groupConnector.insert(entity);
- //then
- ResourceAlreadyExistsException e = assertThrows(ResourceAlreadyExistsException.class, executable);
- assertEquals("Failed _id or unique index constraint.", e.getMessage());
- verify(repositoryMock, times(1))
- .insert(entity);
- verifyNoMoreInteractions(repositoryMock);
- }
-
- @Test
- void insert() {
- //given
- UserGroupEntity entity = mockInstance(new UserGroupEntity());
- when(repositoryMock.insert(any(UserGroupEntity.class)))
- .thenReturn(entity);
- //when
- UserGroupOperations saved = groupConnector.insert(entity);
- //then
- Assertions.assertEquals(entity, saved);
- verify(repositoryMock, times(1))
- .insert(entity);
- verifyNoMoreInteractions(repositoryMock);
- }
-
- @Test
- void findById() {
- // given
- String id = "id";
- Optional entity = Optional.of(mockInstance(new UserGroupEntity()));
- when(repositoryMock.findById(any()))
- .thenReturn(entity);
- // when
- Optional found = groupConnector.findById(id);
- // then
- Assertions.assertEquals(entity, found);
- verify(repositoryMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(repositoryMock);
- }
-
- @Test
- void findAll_fullyValued() {
- //given
- String institutionId = "institutionId";
- String productId = "productId";
- String userId = UUID.randomUUID().toString();
- List allowedStatus = List.of(UserGroupStatus.ACTIVE);
- Pageable pageable = PageRequest.of(1, 3, Sort.by("name"));
- UserGroupFilter groupFilter = new UserGroupFilter(institutionId, productId, userId, allowedStatus);
-
- List entities = List.of(mockInstance(new UserGroupEntity()));
-
- final long countResult = pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + entities.size()
- : entities.size();
- when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(countResult);
- when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(entities);
- //when
- Page page = groupConnector.findAll(groupFilter, pageable);
- //then
- assertEquals(pageable, page.getPageable());
- assertEquals(pageable.getSort(), page.getSort());
- assertEquals(entities.size(), page.getContent().size());
- assertEquals(countResult, page.getTotalElements());
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- verify(mongoTemplateMock, times(1))
- .count(queryCaptor.capture(), eq(UserGroupEntity.class));
- Query queryCount = queryCaptor.getValue();
- verify(mongoTemplateMock, times(1))
- .find(queryCaptor.capture(), eq(UserGroupEntity.class));
- Query query = queryCaptor.getValue();
- assertEquals(queryCount, query);
- assertEquals(pageable.getSort().isSorted(), query.isSorted());
- assertEquals(pageable.isPaged() ? pageable.getPageSize() : 0, query.getLimit());
- assertTrue(query.toString().contains(institutionId));
- assertTrue(query.toString().contains(userId));
- assertTrue(query.toString().contains(productId));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void findAll_fullyNull() {
- //given
- Pageable pageable = Pageable.unpaged();
- UserGroupFilter groupFilter = new UserGroupFilter();
- List entities = List.of(mockInstance(new UserGroupEntity()));
- final long countResult = pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + entities.size()
- : entities.size();
- when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(countResult);
- when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(entities);
- //when
- Page page = groupConnector.findAll(groupFilter, pageable);
- //then
- assertEquals(pageable, page.getPageable());
- assertEquals(pageable.getSort(), page.getSort());
- assertEquals(entities.size(), page.getContent().size());
- assertEquals(countResult, page.getTotalElements());
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- verify(mongoTemplateMock, times(1))
- .count(queryCaptor.capture(), eq(UserGroupEntity.class));
- Query queryCount = queryCaptor.getValue();
- verify(mongoTemplateMock, times(1))
- .find(queryCaptor.capture(), any());
- Query query = queryCaptor.getValue();
- assertEquals(queryCount, query);
- assertEquals(pageable.getSort().isSorted(), query.isSorted());
- assertEquals(pageable.isPaged() ? pageable.getPageSize() : 0, query.getLimit());
- assertTrue(query.getFieldsObject().isEmpty());
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void findAll_differentFilterCombination1() {
- //given
- String productId = "productId";
- List allowedStatus = List.of(UserGroupStatus.ACTIVE);
- Pageable pageable = PageRequest.of(1, 3, Sort.by("name"));
- UserGroupFilter groupFilter = new UserGroupFilter(null, productId, "", allowedStatus);
- List entities = List.of(mockInstance(new UserGroupEntity()));
- final long countResult = pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + entities.size()
- : entities.size();
- when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(countResult);
- when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(entities);
- //when
- Page page = groupConnector.findAll(groupFilter, pageable);
- //then
- assertEquals(pageable, page.getPageable());
- assertEquals(pageable.getSort(), page.getSort());
- assertEquals(entities.size(), page.getContent().size());
- assertEquals(countResult, page.getTotalElements());
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- verify(mongoTemplateMock, times(1))
- .count(queryCaptor.capture(), eq(UserGroupEntity.class));
- Query queryCount = queryCaptor.getValue();
- verify(mongoTemplateMock, times(1))
- .find(queryCaptor.capture(), any());
- Query query = queryCaptor.getValue();
- assertEquals(queryCount, query);
- assertEquals(pageable.getSort().isSorted(), query.isSorted());
- assertEquals(pageable.isPaged() ? pageable.getPageSize() : 0, query.getLimit());
- assertTrue(query.toString().contains(productId));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void findAll_differentFilterCombination2() {
- //given
- String institutionId = "institutionId";
- UserGroupStatus allowedStatus = UserGroupStatus.ACTIVE;
- Pageable pageable = PageRequest.of(1, 3, Sort.by("name"));
- UserGroupFilter groupFilter = new UserGroupFilter(institutionId, null, "", List.of(allowedStatus));
- List entities = List.of(mockInstance(new UserGroupEntity()));
- final long countResult = pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + entities.size()
- : entities.size();
- when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(countResult);
- when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class)))
- .thenReturn(entities);
- //when
- Page page = groupConnector.findAll(groupFilter, pageable);
- //then
- assertEquals(pageable, page.getPageable());
- assertEquals(pageable.getSort(), page.getSort());
- assertEquals(entities.size(), page.getContent().size());
- assertEquals(countResult, page.getTotalElements());
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- verify(mongoTemplateMock, times(1))
- .count(queryCaptor.capture(), eq(UserGroupEntity.class));
- Query queryCount = queryCaptor.getValue();
- verify(mongoTemplateMock, times(1))
- .find(queryCaptor.capture(), any());
- Query query = queryCaptor.getValue();
- assertEquals(queryCount, query);
- assertEquals(pageable.getSort().isSorted(), query.isSorted());
- assertEquals(pageable.isPaged() ? pageable.getPageSize() : 0, query.getLimit());
- assertTrue(query.toString().contains(institutionId));
- assertTrue(query.toString().contains(allowedStatus.name()));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void findAll_sortNotAllowedException() {
- //given
- Pageable pageable = PageRequest.of(0, 3, Sort.by("name"));
- UserGroupFilter groupFilter = new UserGroupFilter();
- //when
- Executable executable = () -> groupConnector.findAll(groupFilter, pageable);
- //then
- ValidationException e = assertThrows(ValidationException.class, executable);
- assertEquals("Sorting not allowed without productId or institutionId", e.getMessage());
- verifyNoInteractions(mongoTemplateMock);
- }
-
- @Test
- void findAll_filterNotAllowedException() {
- //given
- Pageable pageable = Pageable.unpaged();
- UserGroupStatus allowedStatus = UserGroupStatus.ACTIVE;
- UserGroupFilter groupFilter = new UserGroupFilter(null, null, "", List.of(allowedStatus));
- //when
- Executable executable = () -> groupConnector.findAll(groupFilter, pageable);
- //then
- ValidationException e = assertThrows(ValidationException.class, executable);
- assertEquals("At least one of productId, institutionId and userId must be provided with status filter", e.getMessage());
- verifyNoInteractions(mongoTemplateMock);
- }
-
- @Test
- void deleteById() {
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteById(groupId);
- //then
- assertDoesNotThrow(executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.DELETED, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
-
- }
-
- @Test
- void deleteById_resourceNotFound() {
- //given
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 0;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteById(groupId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.DELETED, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void suspendById() {
- //given
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.suspendById(groupId);
- //then
- assertDoesNotThrow(executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.SUSPENDED, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
-
-
- }
-
- @Test
- void suspendById_resourceNotFound() {
- //given
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 0;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.suspendById(groupId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.SUSPENDED, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
-
- }
-
- @Test
- void activateById() {
- //given
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.activateById(groupId);
- //then
- assertDoesNotThrow(executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.ACTIVE, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
-
-
- }
-
- @Test
- void activateById_resourceNotFound() {
- //given
- String groupId = "groupId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 0;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.activateById(groupId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.ACTIVE, set.get("status"));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void insertMember_updateError() {
- //given
- String groupId = "groupId";
- String memberId = UUID.randomUUID().toString();
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 0;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.insertMember(groupId, memberId);
- //then
- ResourceUpdateException resourceUpdateException = assertThrows(ResourceUpdateException.class, executable);
- assertEquals("Couldn't update resource", resourceUpdateException.getMessage());
-
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.ACTIVE, query.getQueryObject().get("status", UserGroupStatus.class));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void insertMember() {
- //given
- String groupId = "groupId";
- String memberId = UUID.randomUUID().toString();
-
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.insertMember(groupId, memberId);
- //then
- assertDoesNotThrow(executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.ACTIVE, query.getQueryObject().get("status", UserGroupStatus.class));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void deleteMember_updateError() {
- //given
- String groupId = "groupId";
- String memberId = UUID.randomUUID().toString();
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 0;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteMember(groupId, memberId);
- //then
- ResourceUpdateException resourceUpdateException = assertThrows(ResourceUpdateException.class, executable);
- assertEquals("Couldn't update resource", resourceUpdateException.getMessage());
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateFirst(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(groupId, query.getQueryObject().get(UserGroupEntity.Fields.id));
- assertEquals(UserGroupStatus.ACTIVE, query.getQueryObject().get("status", UserGroupStatus.class));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void deleteMember() {
- //given
- String groupId = "groupId";
- String memberId = UUID.randomUUID().toString();
-
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteMember(groupId, memberId);
- //then
- assertDoesNotThrow(executable);
- verify(mongoTemplateMock, times(1))
- .updateFirst(any(Query.class), any(Update.class), (Class>) any());
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void deleteMembers_updateError() {
- //given
- String memberId = UUID.randomUUID().toString();
- String institutionId = "institutionId";
- String productId = "productId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 0;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateMulti(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteMembers(memberId, institutionId, productId);
- //then
- Assertions.assertDoesNotThrow(executable);
-
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateMulti(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(memberId, query.getQueryObject().get(UserGroupEntity.Fields.members));
- assertEquals(institutionId, query.getQueryObject().get(UserGroupEntity.Fields.institutionId));
- assertEquals(productId, query.getQueryObject().get(UserGroupEntity.Fields.productId));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void deleteMembers() {
- //given
- String memberId = UUID.randomUUID().toString();
- String institutionId = "institutionId";
- String productId = "productId";
- UpdateResult result = mockInstance(new UpdateResult() {
- @Override
- public boolean wasAcknowledged() {
- return false;
- }
-
- @Override
- public long getMatchedCount() {
- return 1;
- }
-
- @Override
- public long getModifiedCount() {
- return 1;
- }
-
- @Override
- public BsonValue getUpsertedId() {
- return null;
- }
- });
- when(mongoTemplateMock.updateMulti(any(Query.class), any(Update.class), (Class>) any()))
- .thenReturn(result);
- //when
- Executable executable = () -> groupConnector.deleteMembers(memberId, institutionId, productId);
- //then
- assertDoesNotThrow(executable);
- ArgumentCaptor queryCaptor = ArgumentCaptor.forClass(Query.class);
- ArgumentCaptor updateCaptor = ArgumentCaptor.forClass(Update.class);
- verify(mongoTemplateMock, times(1))
- .updateMulti(queryCaptor.capture(), updateCaptor.capture(), (Class>) any());
- Query query = queryCaptor.getValue();
- Update update = updateCaptor.getValue();
- Map set = (Map) update.getUpdateObject().get("$set");
- Map currentDate = (Map) update.getUpdateObject().get("$currentDate");
- assertEquals(memberId, query.getQueryObject().get(UserGroupEntity.Fields.members));
- assertEquals(institutionId, query.getQueryObject().get(UserGroupEntity.Fields.institutionId));
- assertEquals(productId, query.getQueryObject().get(UserGroupEntity.Fields.productId));
- assertEquals(selfCareUser.getId(), set.get("modifiedBy"));
- assertTrue(currentDate.containsKey("modifiedAt"));
- verifyNoMoreInteractions(mongoTemplateMock);
- }
-
- @Test
- void save() {
- //given
- UserGroupEntity entity = mockInstance(new UserGroupEntity());
- when(repositoryMock.save(any()))
- .thenReturn(entity);
- //when
- UserGroupOperations saved = groupConnector.save(entity);
- //then
- assertEquals(entity, saved);
- ArgumentCaptor entityCaptor = ArgumentCaptor.forClass(UserGroupEntity.class);
- verify(repositoryMock, times(1))
- .save(entityCaptor.capture());
- UserGroupEntity capturedEntity = entityCaptor.getValue();
- assertEquals(entity, capturedEntity);
- verifyNoMoreInteractions(repositoryMock);
- }
-
- @Test
- void save_duplicateKey() {
- //givenn
- UserGroupEntity entity = mockInstance(new UserGroupEntity());
- Mockito.doThrow(DuplicateKeyException.class)
- .when(repositoryMock)
- .save(any(UserGroupEntity.class));
- //when
- Executable executable = () -> groupConnector.save(entity);
- //then
- ResourceAlreadyExistsException e = assertThrows(ResourceAlreadyExistsException.class, executable);
- assertEquals("Failed _id or unique index constraint.", e.getMessage());
- verify(repositoryMock, times(1))
- .save(entity);
- verifyNoMoreInteractions(repositoryMock);
- }
-
-
-}
\ No newline at end of file
diff --git a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepositoryTest.java b/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepositoryTest.java
deleted file mode 100644
index 30fde6da..00000000
--- a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepositoryTest.java
+++ /dev/null
@@ -1,372 +0,0 @@
-package it.pagopa.selfcare.user_group.connector.dao;
-
-import com.mongodb.client.result.UpdateResult;
-import it.pagopa.selfcare.commons.base.security.SelfCareUser;
-import it.pagopa.selfcare.commons.utils.TestUtils;
-import it.pagopa.selfcare.user_group.connector.dao.config.DaoTestConfig;
-import it.pagopa.selfcare.user_group.connector.dao.model.UserGroupEntity;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
-import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
-import org.springframework.data.domain.AuditorAware;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.mongodb.core.MongoTemplate;
-import org.springframework.data.mongodb.core.query.Criteria;
-import org.springframework.data.mongodb.core.query.Query;
-import org.springframework.data.mongodb.core.query.Update;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.test.context.TestSecurityContextHolder;
-import org.springframework.test.context.ContextConfiguration;
-
-import javax.validation.ValidationException;
-import java.time.Instant;
-import java.util.*;
-
-import static org.junit.jupiter.api.Assertions.*;
-
-@DataMongoTest
-@EnableAutoConfiguration
-@ContextConfiguration(classes = {UserGroupEntity.class, UserGroupRepository.class, DaoTestConfig.class})
-class UserGroupRepositoryTest {
-
- @Autowired
- private UserGroupRepository repository;
-
- @Autowired
- private MongoTemplate mongoTemplate;
-
- @Autowired
- private AuditorAware auditorAware;
-
- @AfterEach
- void clear() {
- repository.deleteAll();
- }
-
-
- @Test
- void create() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- //when
- UserGroupEntity savedGroup = repository.insert(group);
- //then
- assertTrue(now.isBefore(savedGroup.getCreatedAt()));
- assertEquals(selfCareUser.getId(), savedGroup.getCreatedBy());
- assertNull(savedGroup.getModifiedBy());
- assertNotNull(savedGroup, "id cannot be null after entity creation");
- }
-
-
- @Test
- void delete() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- UserGroupEntity savedGroup = repository.insert(group);
- Optional found = repository.findById(savedGroup.getId());
- //when
- mongoTemplate.remove(Query.query(Criteria.where("_id").is(savedGroup.getId())), UserGroupEntity.class);
- //then
- Optional deleted = repository.findById(savedGroup.getId());
- assertEquals(Optional.empty(), deleted);
-
- }
-
- @Test
- void update() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- UserGroupEntity savedGroup = repository.insert(group);
-
- Optional groupMod = repository.findById(savedGroup.getId());
- groupMod.get().setId(savedGroup.getId());
- groupMod.get().setStatus(UserGroupStatus.SUSPENDED);
- //when
- UserGroupEntity modifiedGroup = repository.save(groupMod.get());
- //then
- assertNull(savedGroup.getModifiedBy());
- assertEquals(selfCareUser.getId(), modifiedGroup.getModifiedBy());
- assertTrue(modifiedGroup.getModifiedAt().isAfter(savedGroup.getCreatedAt()));
- assertEquals(UserGroupStatus.ACTIVE, savedGroup.getStatus());
- assertEquals(UserGroupStatus.SUSPENDED, modifiedGroup.getStatus());
- }
-
- @Test
- void addMember() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- UserGroupEntity savedGroup = repository.insert(group);
- UUID memberUID = UUID.randomUUID();
- //when
- UpdateResult updateResult1 = mongoTemplate.updateFirst(
- Query.query(Criteria.where("_id").is(savedGroup.getId())),
- new Update().push("members", memberUID.toString()),
- UserGroupEntity.class);
- UpdateResult updateResult2 = mongoTemplate.updateFirst(
- Query.query(Criteria.where("_id").is(savedGroup.getId())),
- new Update().push("members", UUID.randomUUID()),
- UserGroupEntity.class);
- UpdateResult updateResult3 = mongoTemplate.updateFirst(
- Query.query(Criteria.where("_id").is(savedGroup.getId())),
- new Update().push("members", memberUID.toString()),
- UserGroupEntity.class);
- //then
- Optional groupMod = repository.findById(savedGroup.getId());
- assertEquals(selfCareUser.getId(), savedGroup.getCreatedBy());
- assertEquals(1, updateResult1.getMatchedCount());
- assertEquals(1, updateResult2.getMatchedCount());
- assertEquals(1, updateResult3.getMatchedCount());
- assertEquals(2, groupMod.get().getMembers().size());
- }
-
- @Test
- void suspend() {
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- UserGroupEntity savedGroup = repository.insert(group);
- UUID memberUID = UUID.randomUUID();
- //when
- UpdateResult updateResult = mongoTemplate.updateFirst(
- Query.query(Criteria.where(UserGroupEntity.Fields.id).is(savedGroup.getId())),
- Update.update(UserGroupEntity.Fields.status, UserGroupStatus.SUSPENDED)
- .set("modifiedBy", auditorAware.getCurrentAuditor().get())
- .set("modifiedAt", now),
- UserGroupEntity.class);
- //then
- Optional groupMod = repository.findById(savedGroup.getId());
- assertEquals(selfCareUser.getId(), groupMod.get().getModifiedBy());
- assertEquals(selfCareUser.getId(), savedGroup.getCreatedBy());
- }
-
- @Test
- void findAll() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group1 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- String institutionId = "institutionId";
- String productId = "productId";
- String userId = "userId";
- group1.setProductId(productId);
- group1.setName("alfa");
- group1.setMembers(Set.of("userId", "userId2"));
- group1.setInstitutionId(institutionId);
- UserGroupEntity savedGroup = repository.insert(group1);
- UserGroupEntity group2 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- group2.setProductId(productId);
- group2.setName("beta");
- group2.setInstitutionId(institutionId);
- group2.setMembers(Set.of("userId"));
- UserGroupEntity savedGroup1 = repository.insert(group2);
-
- Pageable pageable = PageRequest.of(0, 3);
- UserGroupFilter filter = new UserGroupFilter(institutionId, productId, userId, Collections.emptyList());
-
- Query query = new Query();
- if (pageable.getSort().isSorted() && filter.getProductId().isEmpty() && filter.getInstitutionId().isEmpty()) {
- throw new ValidationException();
- }
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.institutionId).is(institutionId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.productId).is(productId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.members).is(userId));
- //when
- List foundGroups = mongoTemplate.find(query.with(pageable), UserGroupEntity.class);
- //then
- assertEquals(2, foundGroups.size());
- }
-
- @Test
- void findAll_allowedState() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- String institutionId = "institutionId";
- String productId = "productId";
- String userId = "userId";
- List allowedStatus = List.of(UserGroupStatus.ACTIVE);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group1 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- group1.setProductId(productId);
- group1.setName("alfa");
- group1.setMembers(Set.of("userId", "userId2"));
- group1.setInstitutionId(institutionId);
- group1.setStatus(UserGroupStatus.SUSPENDED);
- UserGroupEntity savedGroup = repository.insert(group1);
- UserGroupEntity group2 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- group2.setProductId(productId);
- group2.setName("beta");
- group2.setInstitutionId(institutionId);
- group2.setMembers(Set.of("userId"));
- UserGroupEntity savedGroup1 = repository.insert(group2);
- UserGroupFilter filter = new UserGroupFilter(institutionId, productId, userId, allowedStatus);
- Pageable pageable = PageRequest.of(0, 3);
- Query query = new Query();
- if (pageable.getSort().isSorted() && filter.getProductId().isEmpty() && filter.getInstitutionId().isEmpty()) {
- throw new ValidationException();
- }
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.institutionId).is(institutionId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.productId).is(productId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.members).is(userId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.status).in(allowedStatus));
- //when
- List foundGroups = mongoTemplate.find(query.with(pageable), UserGroupEntity.class);
- //then
- assertEquals(1, foundGroups.size());
- }
-
- @Test
- void deleteMembers() {
- //given
- Instant now = Instant.now().minusSeconds(1);
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupEntity group1 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- String productId = "productId";
- String institutionId = "institutionId";
- group1.setProductId(productId);
- group1.setName("alfa");
- group1.setMembers(Set.of("userId", "userId2"));
- group1.setInstitutionId(institutionId);
- UserGroupEntity savedGroup = repository.insert(group1);
- UserGroupEntity group2 = TestUtils.mockInstance(new UserGroupEntity(), "setId",
- "setCreatedAt",
- "setCreateBy",
- "setModifiedAt",
- "setModifiedBy");
- group2.setProductId(productId);
- group2.setName("beta");
- group2.setInstitutionId(institutionId);
- group2.setMembers(Set.of("userId"));
- UserGroupEntity savedGroup1 = repository.insert(group2);
- Pageable pageable = PageRequest.of(0, 3);
- UserGroupFilter filter = new UserGroupFilter();
- String userId = "userId";
- filter.setInstitutionId(institutionId);
- filter.setProductId(productId);
- Query query = new Query();
- if (pageable.getSort().isSorted() && filter.getProductId().isEmpty() && filter.getInstitutionId().isEmpty()) {
- throw new ValidationException();
- }
-
- //when
- UpdateResult updateResult = mongoTemplate.updateMulti(
- Query.query(Criteria.where(UserGroupEntity.Fields.members).is("userId2")
- .and(UserGroupEntity.Fields.institutionId).is(institutionId)
- .and(UserGroupEntity.Fields.productId).is(productId)),
- new Update().pull("members", "userId2")
- .set("modifiedBy", auditorAware.getCurrentAuditor().get())
- .set("modifiedAt", now),
- UserGroupEntity.class);
-
- //then
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.institutionId).is(institutionId));
- query.addCriteria(Criteria.where(UserGroupEntity.Fields.productId).is(productId));
- List foundGroups = mongoTemplate.find(query.with(pageable), UserGroupEntity.class);
-
- assertEquals(1, foundGroups.get(1).getMembers().size());
- assertEquals(1, foundGroups.get(0).getMembers().size());
- assertEquals(1, updateResult.getModifiedCount());
- }
-
-
-}
\ No newline at end of file
diff --git a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoTestConfig.java b/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoTestConfig.java
deleted file mode 100644
index eaceb49a..00000000
--- a/apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoTestConfig.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package it.pagopa.selfcare.user_group.connector.dao.config;
-
-import org.springframework.boot.test.context.TestConfiguration;
-import org.springframework.context.annotation.Import;
-
-@TestConfiguration
-@Import(DaoConfig.class)
-public class DaoTestConfig {
-}
\ No newline at end of file
diff --git a/apps/user-group-ms/connector/pom.xml b/apps/user-group-ms/connector/pom.xml
deleted file mode 100644
index be850795..00000000
--- a/apps/user-group-ms/connector/pom.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
- user-group-ms
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
- user-group-ms-connector
- pom
-
- dao
-
-
-
-
- it.pagopa.selfcare
- user-group-ms-connector-api
-
-
-
diff --git a/apps/user-group-ms/core/pom.xml b/apps/user-group-ms/core/pom.xml
deleted file mode 100644
index 10d41b6e..00000000
--- a/apps/user-group-ms/core/pom.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
- user-group-ms
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
-
- user-group-ms-core
-
-
-
- it.pagopa.selfcare
- user-group-ms-connector-api
-
-
- it.pagopa.selfcare
- user-group-ms-connector-api
- test-jar
- test
-
-
-
-
diff --git a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImpl.java b/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImpl.java
deleted file mode 100644
index 46cfa08c..00000000
--- a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImpl.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package it.pagopa.selfcare.user_group.core;
-
-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;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import lombok.extern.slf4j.Slf4j;
-import org.owasp.encoder.Encode;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.Pageable;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Service;
-import org.springframework.util.Assert;
-
-import javax.validation.ValidationException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-
-@Slf4j
-@Service
-class UserGroupServiceImpl implements UserGroupService {
-
- private final UserGroupConnector groupConnector;
- 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 allowedSortingParams;
-
- @Autowired
- UserGroupServiceImpl(UserGroupConnector groupConnector,
- @Value("${user-group.allowed.sorting.parameters}") String[] allowedSortingParams) {
- this.groupConnector = groupConnector;
- this.allowedSortingParams = Arrays.asList(allowedSortingParams);
- }
-
- @Override
- public UserGroupOperations createGroup(UserGroupOperations group) {
- log.trace("createGroup start");
- log.debug("createGroup group = {}", group);
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- Assert.state(authentication != null, "Authentication is required");
- Assert.state(authentication.getPrincipal() instanceof SelfCareUser, "Not SelfCareUser principal");
- Assert.notNull(group, "A group is required");
-
- checkNameUniqueness(group.getId(), 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 currentGroupId, 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 existingGroups = groupConnector.findAll(filter, Pageable.unpaged());
- boolean isDuplicate = existingGroups.stream()
- .anyMatch(g -> g.getName().equals(groupName) && !g.getId().equals(currentGroupId));
-
- if (isDuplicate) {
- log.warn("Attempted to create/update group with duplicate name: {}", groupName);
- throw new ResourceAlreadyExistsException(GROUP_NAME_ALREADY_EXISTS);
- }
- }
-
- @Override
- public void addMember(String id, UUID memberId) {
- log.trace("addMember start");
- log.debug("addMember id = {}, memberId ={}", Encode.forJava(id), memberId);
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- Assert.notNull(memberId, MEMBER_ID_REQUIRED);
- UserGroupOperations foundGroup = groupConnector.findById(id).orElseThrow(ResourceNotFoundException::new);
- if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
- throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
- }
- groupConnector.insertMember(id, memberId.toString());
- log.trace("addMember end");
- }
-
- @Override
- public void deleteMember(String groupId, String memberId) {
- log.trace("deleteMember start");
- log.debug("deleteMember groupId = {}, memberId = {}", Encode.forJava(groupId), Encode.forJava(memberId));
- Assert.hasText(groupId, USER_GROUP_ID_REQUIRED_MESSAGE);
- Assert.hasText(memberId, MEMBER_ID_REQUIRED);
- UserGroupOperations foundGroup = groupConnector.findById(groupId).orElseThrow(ResourceNotFoundException::new);
- if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
- throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
- }
- groupConnector.deleteMember(groupId, memberId);
- log.trace("deleteMember end");
- }
-
- @Override
- public void deleteMembers(String memberId, String institutionId, String productId) {
- log.trace("deleteMembers start");
- log.debug("deleteMembers memberId = {}, institutionId = {}, productId= {}", Encode.forJava(memberId), Encode.forJava(institutionId), Encode.forJava(productId));
- Assert.hasText(memberId, MEMBER_ID_REQUIRED);
- Assert.hasText(institutionId, "A institution id is required");
- Assert.hasText(productId, "A product id is required");
- groupConnector.deleteMembers(memberId, institutionId, productId);
- log.trace("deleteMembers end");
- }
-
- @Override
- public UserGroupOperations getUserGroup(String id) {
- log.trace("getUserGroup start");
- log.debug("getUserGroup id = {}", id);
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- UserGroupOperations foundGroup = groupConnector.findById(id).orElseThrow(ResourceNotFoundException::new);
- log.debug("getUserGroup result = {}", foundGroup);
- log.trace("getUserGroup end");
-
- return foundGroup;
- }
-
-
- @Override
- public Page getUserGroups(UserGroupFilter filter, Pageable pageable) {
- log.trace("getUserGroups start");
- log.debug("getUserGroups filter = {}, pageable = {}", filter, pageable);
- boolean match = pageable.getSort().stream().allMatch(order -> allowedSortingParams.contains(order.getProperty()));
- if (!match) {
- throw new ValidationException("Given sort parameters aren't valid");
- }
- Page result = groupConnector.findAll(filter, pageable);
- log.debug("getUserGroups result = {}", result);
- log.trace("getUserGroups end");
- return result;
- }
-
-
- @Override
- public void deleteGroup(String id) {
- log.trace("deleteGroup start");
- log.debug("deleteGroup id = {}", Encode.forJava(id));
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- groupConnector.deleteById(id);
- log.trace("deleteProduct end");
- }
-
- @Override
- public void suspendGroup(String id) {
- log.trace("suspendGroup start");
- log.debug("suspendGroup id = {}", Encode.forJava(id));
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- groupConnector.suspendById(id);
- log.trace("suspendGroup end");
- }
-
- @Override
- public void activateGroup(String id) {
- log.trace("activateGroup start");
- log.debug("activateGroup id = {}", Encode.forJava(id));
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- groupConnector.activateById(id);
- log.trace("activateGroup end");
- }
-
- @Override
- public UserGroupOperations updateGroup(String id, UserGroupOperations group) {
- log.trace("updateGroup start");
- log.debug("updateGroup id = {}, group = {}", Encode.forJava(id), group);
- Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
- Assert.notNull(group, "A user group is required");
- UserGroupOperations foundGroup = groupConnector.findById(id).orElseThrow(ResourceNotFoundException::new);
- if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
- throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
- }
- checkNameUniqueness(id, group.getName(), foundGroup.getProductId(), foundGroup.getInstitutionId());
-
- foundGroup.setMembers(group.getMembers());
- foundGroup.setName(group.getName());
- foundGroup.setDescription(group.getDescription());
- UserGroupOperations updatedGroup = groupConnector.save(foundGroup);
- log.debug("updateGroup updatedGroup = {}", updatedGroup);
- log.trace("updateGroup end");
- return updatedGroup;
- }
-}
diff --git a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/config/CoreConfig.java b/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/config/CoreConfig.java
deleted file mode 100644
index 95dd8a4e..00000000
--- a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/config/CoreConfig.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package it.pagopa.selfcare.user_group.core.config;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-
-@Configuration
-@PropertySource("classpath:config/core-config.properties")
-class CoreConfig {
-
-}
diff --git a/apps/user-group-ms/core/src/main/resources/config/core-config.properties b/apps/user-group-ms/core/src/main/resources/config/core-config.properties
deleted file mode 100644
index 439b256a..00000000
--- a/apps/user-group-ms/core/src/main/resources/config/core-config.properties
+++ /dev/null
@@ -1 +0,0 @@
-user-group.allowed.sorting.parameters=${ALLOWED_SORTING_PARAMETERS:name}
\ No newline at end of file
diff --git a/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImplTest.java b/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImplTest.java
deleted file mode 100644
index 56624b30..00000000
--- a/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImplTest.java
+++ /dev/null
@@ -1,700 +0,0 @@
-package it.pagopa.selfcare.user_group.core;
-
-import it.pagopa.selfcare.commons.base.security.SelfCareUser;
-import it.pagopa.selfcare.commons.utils.TestUtils;
-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;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import it.pagopa.selfcare.user_group.core.config.CoreTestConfig;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.junit.jupiter.api.function.Executable;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mockito;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.test.context.TestSecurityContextHolder;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-import javax.validation.ValidationException;
-import java.util.*;
-import static java.util.UUID.randomUUID;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.*;
-import static org.springframework.data.support.PageableExecutionUtils.getPage;
-
-@ExtendWith(SpringExtension.class)
-@ContextConfiguration(classes = {UserGroupServiceImpl.class, CoreTestConfig.class})
-@TestPropertySource(properties = {
- "ALLOWED_SORTING_PARAMETERS=name"
-})
-class UserGroupServiceImplTest {
-
- @BeforeEach
- void beforeEach() {
- TestSecurityContextHolder.clearContext();
- }
-
- @MockBean
- private UserGroupConnector groupConnectorMock;
-
- @Autowired
- private UserGroupServiceImpl groupService;
-
- @Captor
- private ArgumentCaptor filter;
-
- @Test
- void createGroup_nullAuth() {
- //given
- UserGroupOperations input = null;
- //when
- Executable executable = () -> groupService.createGroup(input);
- //then
- IllegalStateException e = assertThrows(IllegalStateException.class, executable);
- assertEquals("Authentication is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void createGroup_nullPrincipal() {
- //given
- UserGroupOperations input = null;
- Authentication authentication = new TestingAuthenticationToken(null, null);
- TestSecurityContextHolder.setAuthentication(authentication);
- //when
- Executable executable = () -> groupService.createGroup(input);
- //then
- IllegalStateException illegalStateException = Assertions.assertThrows(IllegalStateException.class, executable);
- Assertions.assertEquals("Not SelfCareUser principal", illegalStateException.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void createGroup_nullGroup() {
- //given
- SelfCareUser selfCareUser = SelfCareUser.builder("id")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupOperations input = null;
- //when
- Executable executable = () -> groupService.createGroup(input);
- //then
- IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class, executable);
- Assertions.assertEquals("A group is required", illegalArgumentException.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void createGroup_ok() {
- //given
- SelfCareUser selfCareUser = SelfCareUser.builder("userId")
- .email("test@example.com")
- .name("name")
- .surname("surname")
- .build();
- TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
- TestSecurityContextHolder.setAuthentication(authenticationToken);
- UserGroupOperations input = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
- Page 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
- UserGroupOperations output = groupService.createGroup(input);
- //then
- assertNotNull(output);
-
- 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("test@example.com")
- .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(), "setCreateAt", "setModifiedAt");
- existingGroup.setName("existingGroupName");
- Page 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);
- }
-
- @Test
- void deleteGroup() {
- //given
- String id = "id";
- //when
- groupService.deleteGroup(id);
- //then
- verify(groupConnectorMock, times(1))
- .deleteById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
-
- @Test
- void deleteGroup_nullId() {
- //given
- String id = null;
- //when
- Executable executable = () -> groupService.deleteGroup(id);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void suspendGroup() {
- //given
- String id = "id";
- //when
- groupService.suspendGroup(id);
- //then
- verify(groupConnectorMock, times(1))
- .suspendById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
-
- @Test
- void suspendGroup_nullId() {
- //given
- String id = null;
- //when
- Executable executable = () -> groupService.suspendGroup(id);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void activateGroup() {
- //given
- String id = "id";
- //when
- groupService.activateGroup(id);
- //then
- verify(groupConnectorMock, times(1))
- .activateById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void activateGroup_nullId() {
- //given
- String id = null;
- //when
- Executable executable = () -> groupService.activateGroup(id);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void updateGroup_nullId() {
- //given
- String id = null;
- UserGroupOperations input = new DummyGroup();
- //when
- Executable executable = () -> groupService.updateGroup(id, input);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void updateGroup_nullGroup() {
- //given
- String id = "id";
- UserGroupOperations input = null;
- //when
- Executable executable = () -> groupService.updateGroup(id, input);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void updateGroup_foundGroupSuspended() {
- //given
- String id = "id";
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup());
- group.setStatus(UserGroupStatus.SUSPENDED);
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenReturn(Optional.of(group));
- //when
- Executable executable = () -> groupService.updateGroup(id, group);
- //then
- ResourceUpdateException e = assertThrows(ResourceUpdateException.class, executable);
- assertEquals("Trying to modify suspended group", e.getMessage());
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void updateGroup_notExists() {
- //given
- String id = "id";
- UserGroupOperations input = new DummyGroup();
- //when
- Executable executable = () -> groupService.updateGroup(id, input);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void updateGroup_exists_ok() {
- //given
- String id = "id";
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup(), "setId");
- UserGroupOperations foundGroup = TestUtils.mockInstance(new DummyGroup());
- Page 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()))
- .thenAnswer(invocationOnMock -> invocationOnMock.getArgument(0, UserGroupOperations.class));
- //when
- UserGroupOperations saved = groupService.updateGroup(id, group);
- //then
- assertEquals(saved.getDescription(), group.getDescription());
- assertEquals(saved.getMembers(), group.getMembers());
- 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_notChangingName() {
- //given
- String id = "id";
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup(), "setId");
- group.setName("existingGroupName");
-
- UserGroupOperations foundGroup = TestUtils.mockInstance(new DummyGroup());
- foundGroup.setId(id);
- foundGroup.setName("existingGroupName");
- foundGroup.setStatus(UserGroupStatus.ACTIVE);
-
- // existing group find the same group without changing the name
- Page existingGroups = getPage(Collections.singletonList(foundGroup), 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
- UserGroupOperations saved = groupService.updateGroup(id, group);
- //then
- assertEquals(saved.getDescription(), group.getDescription());
- assertEquals(saved.getMembers(), group.getMembers());
- 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 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
- String id = null;
- UUID memberId = randomUUID();
- //when
- Executable executable = () -> groupService.addMember(id, memberId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void addMember_nullMemberId() {
- //given
- String id = "id";
- UUID memberId = null;
- //when
- Executable executable = () -> groupService.addMember(id, memberId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A member id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void addMember_doesNotExist() {
- //given
- String id = "id";
- UUID memberId = randomUUID();
- //when
- Executable executable = () -> groupService.addMember(id, memberId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
-
- }
-
- @Test
- void addMember_groupSuspended() {
- //given
- String id = "id";
- UUID memberId = randomUUID();
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup());
- group.setStatus(UserGroupStatus.SUSPENDED);
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenReturn(Optional.of(group));
- //when
- Executable executable = () -> groupService.addMember(id, memberId);
- //then
- ResourceUpdateException e = assertThrows(ResourceUpdateException.class, executable);
- assertEquals("Trying to modify suspended group", e.getMessage());
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void addMember() {
- //given
- String id = "id";
- UUID memberUUID = randomUUID();
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup());
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenReturn(Optional.of(group));
- //when
- groupService.addMember(id, memberUUID);
- //then
- verify(groupConnectorMock, times(1))
- .findById(id);
- verify(groupConnectorMock, times(1))
- .insertMember(Mockito.anyString(), Mockito.anyString());
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMember_nullId() {
- //given
- String id = null;
- String memberId = randomUUID().toString();
- //when
- Executable executable = () -> groupService.deleteMember(id, memberId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMember_nullMemberId() {
- //given
- String id = "id";
- String memberId = null;
- //when
- Executable executable = () -> groupService.deleteMember(id, memberId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A member id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMember_doesNotExist() {
- //given
- String id = "id";
- String memberId = randomUUID().toString();
- //when
- Executable executable = () -> groupService.deleteMember(id, memberId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
-
- }
-
- @Test
- void deleteMember_groupSuspended() {
- //given
- String id = "id";
- String memberId = randomUUID().toString();
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup());
- group.setStatus(UserGroupStatus.SUSPENDED);
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenReturn(Optional.of(group));
- //when
- Executable executable = () -> groupService.deleteMember(id, memberId);
- //then
- ResourceUpdateException e = assertThrows(ResourceUpdateException.class, executable);
- assertEquals("Trying to modify suspended group", e.getMessage());
- verify(groupConnectorMock, times(1))
- .findById(id);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMember() {
- //given
- String id = "id";
- String memberId = randomUUID().toString();
-
- UserGroupOperations group = TestUtils.mockInstance(new DummyGroup());
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenReturn(Optional.of(group));
- //when
- Executable executable = () -> groupService.deleteMember(id, memberId);
- //then
- assertDoesNotThrow(executable);
- verify(groupConnectorMock, times(1))
- .findById(id);
- verify(groupConnectorMock, times(1))
- .deleteMember(Mockito.anyString(), Mockito.anyString());
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMembers_nullMemberId() {
- //given
- String memberId = null;
- String institutionId = "institutionId";
- String productId = "productId";
- //when
- Executable executable = () -> groupService.deleteMembers(memberId, institutionId, productId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A member id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMembers_nullInstitutionId() {
- //given
- String memberId = "memberid";
- String institutionId = null;
- String productId = "productId";
- //when
- Executable executable = () -> groupService.deleteMembers(memberId, institutionId, productId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A institution id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMembers_nullProductId() {
- //given
- String memberId = "memberId";
- String institutionId = "institutionId";
- String productId = null;
- //when
- Executable executable = () -> groupService.deleteMembers(memberId, institutionId, productId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A product id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void deleteMembers() {
- //given
- String memberId = "memberId";
- String institutionId = "institutionId";
- String productId = "productId";
- //when
- Executable executable = () -> groupService.deleteMembers(memberId, institutionId, productId);
- //then
- assertDoesNotThrow(executable);
- verify(groupConnectorMock, times(1))
- .deleteMembers(memberId, institutionId, productId);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
-
- @Test
- void getGroup() {
- //given
- String groupId = "groupId";
- when(groupConnectorMock.findById(Mockito.anyString()))
- .thenAnswer(invocation -> Optional.of(new DummyGroup()));
- //when
- UserGroupOperations group = groupService.getUserGroup(groupId);
- //then
- assertNotNull(group);
- verify(groupConnectorMock, times(1))
- .findById(groupId);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void getGroup_null() {
- //given
- String groupId = "groupId";
- //when
- Executable executable = () -> groupService.getUserGroup(groupId);
- //then
- assertThrows(ResourceNotFoundException.class, executable);
- verify(groupConnectorMock, times(1))
- .findById(groupId);
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void getGroup_nullId() {
- //given
- String groupId = null;
- //when
- Executable executable = () -> groupService.getUserGroup(groupId);
- //then
- IllegalArgumentException e = assertThrows(IllegalArgumentException.class, executable);
- assertEquals("A user group id is required", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
- @Test
- void getUserGroups() {
- //given
- String institutionId = "institutionId";
- String productId = "productId";
- String userId = randomUUID().toString();
- List allowedStatus = List.of(UserGroupStatus.ACTIVE);
- UserGroupFilter filterMock = new UserGroupFilter(institutionId, productId, userId, allowedStatus);
- Pageable pageable = PageRequest.of(0, 3, Sort.by("name"));
- when(groupConnectorMock.findAll(any(), any()))
- .thenReturn(getPage(List.of(new DummyGroup()), pageable, () -> pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + 1
- : 1));
- //when
- Page page = groupService.getUserGroups(filterMock, pageable);
- //then
- assertEquals(1, page.getContent().size());
- verify(groupConnectorMock, times(1))
- .findAll(filter.capture(), any());
- UserGroupFilter capturedFilter = filter.getValue();
- assertEquals(capturedFilter.getInstitutionId(), filterMock.getInstitutionId());
- assertEquals(capturedFilter.getProductId(), filterMock.getProductId());
- assertEquals(capturedFilter.getUserId(), filterMock.getUserId());
- assertEquals(capturedFilter.getStatus(), filterMock.getStatus());
- verifyNoMoreInteractions(groupConnectorMock);
- }
-
- @Test
- void getUserGroups_invalidSortParams() {
- //given
- Pageable pageable = PageRequest.of(0, 3, Sort.by("description"));
- when(groupConnectorMock.findAll(any(), any()))
- .thenReturn(getPage(Collections.singletonList(new DummyGroup()), pageable, () -> pageable.isPaged()
- ? (long) pageable.getPageSize() * pageable.getPageNumber() + 1
- : 1));
- //when
- Executable executable = () -> groupService.getUserGroups(null, pageable);
- //then
- ValidationException e = assertThrows(ValidationException.class, executable);
- assertEquals("Given sort parameters aren't valid", e.getMessage());
- verifyNoInteractions(groupConnectorMock);
- }
-
-}
\ No newline at end of file
diff --git a/apps/user-group-ms/pom.xml b/apps/user-group-ms/pom.xml
index b6345be3..760a8cfb 100644
--- a/apps/user-group-ms/pom.xml
+++ b/apps/user-group-ms/pom.xml
@@ -1,8 +1,9 @@
-
-
+
+
4.0.0
-
+
it.pagopa.selfcare
selc-starter-parent
@@ -12,7 +13,7 @@
user-group-ms
- pom
+ jar
1.0.0-SNAPSHOT
user-group-ms
Microservice to manage Self Care User Group
@@ -21,66 +22,27 @@
2.5.1
https://sonarcloud.io/
true
+ 17
+ 17
+ UTF-8
+
- it.pagopa.selfcare
- user-group-ms-connector-api
- 1.0.0-SNAPSHOT
-
-
-
- it.pagopa.selfcare
- user-group-ms-connector-api
- 1.0.0-SNAPSHOT
- test-jar
-
-
-
- it.pagopa.selfcare
- user-group-ms-core
- 1.0.0-SNAPSHOT
-
-
-
- it.pagopa.selfcare
- user-group-ms-web
- 1.0.0-SNAPSHOT
+ io.cucumber
+ cucumber-bom
+ 7.20.1
+ pom
+ import
-
- it.pagopa.selfcare
- selc-commons-base
- ${selc-commons.version}
+ org.junit
+ junit-bom
+ 5.10.1
+ pom
+ import
-
-
- it.pagopa.selfcare
- selc-commons-base
- ${selc-commons.version}
- test-jar
-
-
-
- it.pagopa.selfcare
- selc-commons-web
- ${selc-commons.version}
-
-
-
- it.pagopa.selfcare
- selc-commons-web
- ${selc-commons.version}
- test-jar
-
-
-
- it.pagopa.selfcare
- user-group-ms-connector-dao
- 1.0.0-SNAPSHOT
-
-
@@ -88,6 +50,24 @@
it.pagopa.selfcare
selc-commons-base
+ 2.5.4
+
+
+ it.pagopa.selfcare
+ selc-commons-base
+ 2.5.4
+ test-jar
+
+
+ it.pagopa.selfcare
+ selc-commons-web
+ 2.5.4
+
+
+ it.pagopa.selfcare
+ selc-commons-web
+ 2.5.4
+ test-jar
@@ -97,25 +77,88 @@
- it.pagopa.selfcare
- selc-commons-base
- test-jar
+ org.springframework.data
+ spring-data-commons
+
+
+ io.springfox
+ springfox-boot-starter
+
+
+ io.cucumber
+ cucumber-java
+ 7.20.1
test
-
-
-
- core
- web
- app
- connector-api
- connector
-
+
+ io.rest-assured
+ rest-assured
+ 5.3.0
+ test
+
+
+ io.rest-assured
+ rest-assured-common
+ 5.3.0
+
+
+ io.rest-assured
+ json-path
+ 5.3.0
+
+
+ io.rest-assured
+ xml-path
+ 5.3.0
+
+
+ org.junit.platform
+ junit-platform-suite
+ 1.10.1
+ test
+
+
+ io.cucumber
+ cucumber-junit-platform-engine
+ 7.20.1
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ io.cucumber
+ cucumber-spring
+ 7.19.0
+
+
+ org.springframework.boot
+ spring-boot-starter-data-mongodb
+
+
+ com.fasterxml.jackson.dataformat
+ jackson-dataformat-yaml
+ 2.14.0
+
+
+ de.flapdoodle.embed
+ de.flapdoodle.embed.mongo
+ 4.18.1
+ test
+
+
+ org.springframework
+ spring-webmvc
+ 5.3.24
+ test
+
+
-
@@ -160,8 +203,35 @@
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ false
+ ${project.parent.artifactId}-${project.parent.version}-FATJAR
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+ true
+
+
+
+
+ test-jar
+
+
+
+
-
@@ -172,4 +242,4 @@
-
+
\ No newline at end of file
diff --git a/apps/user-group-ms/app/src/main/docs/openapi.json b/apps/user-group-ms/src/main/docs/openapi.json
similarity index 99%
rename from apps/user-group-ms/app/src/main/docs/openapi.json
rename to apps/user-group-ms/src/main/docs/openapi.json
index c9875eb7..17fdef00 100644
--- a/apps/user-group-ms/app/src/main/docs/openapi.json
+++ b/apps/user-group-ms/src/main/docs/openapi.json
@@ -1,7 +1,7 @@
{
"openapi" : "3.0.3",
"info" : {
- "title" : "user-group-ms",
+ "title" : "selc-starter-parent",
"description" : "The services described in this section deal with the management of UserGroup entity, providing the necessary methods for its creation, consultation and activation.",
"version" : "1.0.0-SNAPSHOT"
},
diff --git a/apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java
similarity index 100%
rename from apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java
similarity index 87%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java
index 48b47821..cc7956b8 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java
@@ -1,6 +1,7 @@
-package it.pagopa.selfcare.user_group.connector.api;
+package it.pagopa.selfcare.user_group.api;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
+
+import it.pagopa.selfcare.user_group.model.UserGroupStatus;
import java.time.Instant;
import java.util.Set;
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java
similarity index 93%
rename from apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java
index 726d4248..deb0ac62 100644
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.dao.auditing;
+package it.pagopa.selfcare.user_group.auditing;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.AuditorAware;
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java
similarity index 67%
rename from apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java
index bf61e6f8..f02e02ea 100644
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java
@@ -1,6 +1,6 @@
-package it.pagopa.selfcare.user_group.connector.dao.config;
+package it.pagopa.selfcare.user_group.config;
-import it.pagopa.selfcare.user_group.connector.dao.auditing.SpringSecurityAuditorAware;
+import it.pagopa.selfcare.user_group.auditing.SpringSecurityAuditorAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@@ -9,12 +9,10 @@
@Configuration
@EnableMongoAuditing(modifyOnCreate = false)
-@PropertySource("classpath:config/dao-config.properties")
-class DaoConfig {
-
+@PropertySource("classpath:config/core-config.properties")
+public class CoreConfig {
@Bean
public AuditorAware myAuditorProvider() {
return new SpringSecurityAuditorAware();
}
-
}
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java
similarity index 95%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java
index 24bf6715..ca3d3b81 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.config;
+package it.pagopa.selfcare.user_group.config;
import com.fasterxml.classmate.TypeResolver;
import it.pagopa.selfcare.commons.web.model.Problem;
@@ -29,20 +29,20 @@
*/
@Configuration
@Import(BaseSwaggerConfig.class)
-class SwaggerConfig {
+public class SwaggerConfig {
private static final String AUTH_SCHEMA_NAME = "bearerAuth";
@Configuration
@Profile("swaggerIT")
@PropertySource("classpath:/swagger/swagger_it.properties")
- public static class itConfig {
+ public static class ItConfig {
}
@Configuration
@Profile("swaggerEN")
@PropertySource("classpath:/swagger/swagger_en.properties")
- public static class enConfig {
+ public static class EnConfig {
}
private final Environment environment;
@@ -61,7 +61,7 @@ public Docket swaggerSpringPlugin(@Autowired TypeResolver typeResolver) {
.description(environment.getProperty("swagger.description", "Api and Models"))
.version(environment.getProperty("swagger.version", environment.getProperty("spring.application.version")))
.build())
- .select().apis(RequestHandlerSelectors.basePackage("it.pagopa.selfcare.user_group.web.controller")).build()
+ .select().apis(RequestHandlerSelectors.basePackage("it.pagopa.selfcare.user_group.controller")).build()
.tags(new Tag("UserGroup", environment.getProperty("swagger.user-group.api.description")))
.directModelSubstitute(LocalTime.class, String.class)
.ignoredParameterTypes(Pageable.class)
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java
similarity index 89%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java
index a6e76d05..128cbe96 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.config;
+package it.pagopa.selfcare.user_group.config;
import it.pagopa.selfcare.commons.web.config.SecurityConfig;
import lombok.extern.slf4j.Slf4j;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java
similarity index 75%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java
index 0b81dc86..ebdb3a28 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.config;
+package it.pagopa.selfcare.user_group.config;
import it.pagopa.selfcare.commons.web.config.BaseWebConfig;
import org.springframework.context.annotation.Configuration;
@@ -6,5 +6,5 @@
@Configuration
@Import(BaseWebConfig.class)
-class WebConfig {
+public class WebConfig {
}
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java
similarity index 93%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java
index d21c5cc5..75e033b8 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.controller;
+package it.pagopa.selfcare.user_group.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -10,14 +10,10 @@
import it.pagopa.selfcare.commons.web.model.Page;
import it.pagopa.selfcare.commons.web.model.Problem;
import it.pagopa.selfcare.commons.web.model.mapper.PageMapper;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import it.pagopa.selfcare.user_group.core.UserGroupService;
-import it.pagopa.selfcare.user_group.web.model.CreateUserGroupDto;
-import it.pagopa.selfcare.user_group.web.model.UpdateUserGroupDto;
-import it.pagopa.selfcare.user_group.web.model.UserGroupResource;
-import it.pagopa.selfcare.user_group.web.model.mapper.UserGroupMapper;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.model.*;
+import it.pagopa.selfcare.user_group.model.mapper.UserGroupMapper;
+import it.pagopa.selfcare.user_group.service.UserGroupService;
import lombok.extern.slf4j.Slf4j;
import org.owasp.encoder.Encode;
import org.springframework.beans.factory.annotation.Autowired;
@@ -57,7 +53,7 @@ public UserGroupV1Controller(UserGroupService groupService,
})
public UserGroupResource createGroup(@RequestBody
@Valid
- CreateUserGroupDto group) {
+ CreateUserGroupDto group) {
log.trace("createGroup start");
log.debug("createGroup group = {}", group);
UserGroupOperations groupOperations = groupService.createGroup(userGroupMapper.fromDto(group));
@@ -122,7 +118,7 @@ public UserGroupResource updateUserGroup(@ApiParam("${swagger.user-group.model.i
String id,
@RequestBody
@Valid
- UpdateUserGroupDto groupDto) {
+ UpdateUserGroupDto groupDto) {
log.trace("updateUserGroup start");
log.debug("updateUserGroup id = {}", Encode.forJava(id));
UserGroupOperations updatedGroup = groupService.updateGroup(id, userGroupMapper.toUserGroupOperations(groupDto));
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java
similarity index 55%
rename from apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java
index 75742161..e7a4396d 100644
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java
@@ -1,6 +1,6 @@
-package it.pagopa.selfcare.user_group.connector.dao;
+package it.pagopa.selfcare.user_group.dao;
-import it.pagopa.selfcare.user_group.connector.dao.model.UserGroupEntity;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface UserGroupRepository extends MongoRepository {
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java
similarity index 81%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java
index 89623f06..efcb5405 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.exception;
+package it.pagopa.selfcare.user_group.exception;
public class ResourceAlreadyExistsException extends RuntimeException {
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java
similarity index 53%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java
index f3351e83..05b6906e 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.exception;
+package it.pagopa.selfcare.user_group.exception;
public class ResourceNotFoundException extends RuntimeException {
}
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java
similarity index 70%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java
index 1fbab29f..89bb5569 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.exception;
+package it.pagopa.selfcare.user_group.exception;
public class ResourceUpdateException extends RuntimeException {
public ResourceUpdateException(String msg) {
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java
similarity index 77%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java
index 23ca627b..f2d78377 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java
@@ -1,11 +1,11 @@
-package it.pagopa.selfcare.user_group.web.handler;
+package it.pagopa.selfcare.user_group.handler;
import it.pagopa.selfcare.commons.web.model.Problem;
import it.pagopa.selfcare.commons.web.model.mapper.ProblemMapper;
-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.web.controller.UserGroupV1Controller;
+import it.pagopa.selfcare.user_group.controller.UserGroupV1Controller;
+import it.pagopa.selfcare.user_group.exception.ResourceAlreadyExistsException;
+import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException;
+import it.pagopa.selfcare.user_group.exception.ResourceUpdateException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java
similarity index 91%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java
index 265f720d..1661e1f3 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java
@@ -1,8 +1,7 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
import lombok.Data;
import javax.validation.constraints.NotBlank;
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java
similarity index 95%
rename from apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java
index 81db9ee5..75e8166e 100644
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.dao.model;
+package it.pagopa.selfcare.user_group.model;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.lang.NonNull;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java
similarity index 71%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java
index 9c047c18..0a62e52e 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java
@@ -1,7 +1,6 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
import lombok.Data;
import java.time.Instant;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java
similarity index 88%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java
index c2229031..793163f9 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java
similarity index 94%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java
index b6932fd2..ac0d5c7f 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
diff --git a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java
similarity index 80%
rename from apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java
index 327b2114..1b9328b0 100644
--- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java
@@ -1,11 +1,7 @@
-package it.pagopa.selfcare.user_group.connector.dao.model;
+package it.pagopa.selfcare.user_group.model;
-
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import lombok.*;
import lombok.experimental.FieldNameConstants;
import org.springframework.data.annotation.*;
import org.springframework.data.mongodb.core.mapping.Document;
@@ -58,9 +54,10 @@ public UserGroupEntity(UserGroupOperations userGroup) {
@FieldNameConstants.Include
private String modifiedBy;
-
+ @NoArgsConstructor(access = AccessLevel.NONE)
+ @AllArgsConstructor(access = AccessLevel.NONE)
public static class Fields {
- public static String id = org.springframework.data.mongodb.core.aggregation.Fields.UNDERSCORE_ID;
+ public static final String ID = org.springframework.data.mongodb.core.aggregation.Fields.UNDERSCORE_ID;
}
}
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java
similarity index 93%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java
index 28f6132d..148cadcc 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.model;
+package it.pagopa.selfcare.user_group.model;
import lombok.AllArgsConstructor;
import lombok.Data;
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java
similarity index 92%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java
index 30fe95b8..7dfbed65 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java
@@ -1,7 +1,6 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import io.swagger.annotations.ApiModelProperty;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
import lombok.Data;
import javax.validation.constraints.NotBlank;
diff --git a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java
similarity index 56%
rename from apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java
index 5cea8344..0fc589ac 100644
--- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.connector.model;
+package it.pagopa.selfcare.user_group.model;
public enum UserGroupStatus {
ACTIVE,
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java
similarity index 78%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java
index 01f6e6af..77c5afe5 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java
@@ -1,10 +1,10 @@
-package it.pagopa.selfcare.user_group.web.model.mapper;
+package it.pagopa.selfcare.user_group.model.mapper;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.web.model.CreateUserGroupDto;
-import it.pagopa.selfcare.user_group.web.model.GroupDto;
-import it.pagopa.selfcare.user_group.web.model.UpdateUserGroupDto;
-import it.pagopa.selfcare.user_group.web.model.UserGroupResource;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.model.CreateUserGroupDto;
+import it.pagopa.selfcare.user_group.model.GroupDto;
+import it.pagopa.selfcare.user_group.model.UpdateUserGroupDto;
+import it.pagopa.selfcare.user_group.model.UserGroupResource;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
diff --git a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java
similarity index 79%
rename from apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java
index cc6661c2..eb10e483 100644
--- a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java
@@ -1,7 +1,7 @@
-package it.pagopa.selfcare.user_group.core;
+package it.pagopa.selfcare.user_group.service;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.model.UserGroupFilter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
diff --git a/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java
new file mode 100644
index 00000000..28ece021
--- /dev/null
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java
@@ -0,0 +1,358 @@
+package it.pagopa.selfcare.user_group.service;
+
+import com.mongodb.client.result.UpdateResult;
+import it.pagopa.selfcare.commons.base.security.SelfCareUser;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.dao.UserGroupRepository;
+import it.pagopa.selfcare.user_group.exception.ResourceAlreadyExistsException;
+import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException;
+import it.pagopa.selfcare.user_group.exception.ResourceUpdateException;
+import it.pagopa.selfcare.user_group.model.CriteriaBuilder;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import it.pagopa.selfcare.user_group.model.UserGroupFilter;
+import it.pagopa.selfcare.user_group.model.UserGroupStatus;
+import lombok.extern.slf4j.Slf4j;
+import org.owasp.encoder.Encode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.data.domain.AuditorAware;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.data.support.PageableExecutionUtils;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+import javax.validation.ValidationException;
+import java.util.*;
+import java.util.function.Function;
+
+@Slf4j
+@Service
+public 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 allowedSortingParams;
+ private final UserGroupRepository repository;
+ private final MongoTemplate mongoTemplate;
+ private final AuditorAware auditorAware;
+ private static final String COULD_NOT_UPDATE_MESSAGE = "Couldn't update resource";
+
+ @Autowired
+ UserGroupServiceImpl(@Value("${user-group.allowed.sorting.parameters}") String[] allowedSortingParams,
+ UserGroupRepository repository, MongoTemplate mongoTemplate, AuditorAware auditorAware) {
+ this.allowedSortingParams = Arrays.asList(allowedSortingParams);
+ this.repository = repository;
+ this.mongoTemplate = mongoTemplate;
+ this.auditorAware = auditorAware;
+ }
+
+ @Override
+ public UserGroupOperations createGroup(UserGroupOperations group) {
+ log.trace("createGroup start");
+ log.debug("createGroup group = {}", group);
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ Assert.state(authentication != null, "Authentication is required");
+ Assert.state(authentication.getPrincipal() instanceof SelfCareUser, "Not SelfCareUser principal");
+ Assert.notNull(group, "A group is required");
+
+ checkNameUniqueness(group.getId(), group.getName(), group.getProductId(), group.getInstitutionId());
+ return insertUserGroupEntity(group);
+ }
+
+ @Override
+ public void addMember(String id, UUID memberId) {
+ log.trace("addMember start");
+ log.debug("addMember id = {}, memberId ={}", Encode.forJava(id), memberId);
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ Assert.notNull(memberId, MEMBER_ID_REQUIRED);
+ UserGroupOperations foundGroup = findById(id).orElseThrow(ResourceNotFoundException::new);
+ if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
+ throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
+ }
+ insertMember(id, memberId.toString());
+ log.trace("addMember end");
+ }
+
+ @Override
+ public void deleteMember(String groupId, String memberId) {
+ log.trace("deleteMember start");
+ log.debug("deleteMember groupId = {}, memberId = {}", Encode.forJava(groupId), Encode.forJava(memberId));
+ Assert.hasText(groupId, USER_GROUP_ID_REQUIRED_MESSAGE);
+ Assert.hasText(memberId, MEMBER_ID_REQUIRED);
+ UserGroupOperations foundGroup = findById(groupId).orElseThrow(ResourceNotFoundException::new);
+ if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
+ throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
+ }
+ removeMemberFromActiveGroup(groupId, memberId);
+ log.trace("deleteMember end");
+ }
+
+ @Override
+ public void deleteMembers(String memberId, String institutionId, String productId) {
+ log.trace("deleteMembers start");
+ log.debug("deleteMembers memberId = {}, institutionId = {}, productId= {}", Encode.forJava(memberId), Encode.forJava(institutionId), Encode.forJava(productId));
+ Assert.hasText(memberId, MEMBER_ID_REQUIRED);
+ Assert.hasText(institutionId, "A institution id is required");
+ Assert.hasText(productId, "A product id is required");
+ removeMembers(memberId, institutionId, productId);
+ log.trace("deleteMembers end");
+ }
+
+ @Override
+ public UserGroupOperations getUserGroup(String id) {
+ log.trace("getUserGroup start");
+ log.debug("getUserGroup id = {}", id);
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ UserGroupOperations foundGroup = findById(id).orElseThrow(ResourceNotFoundException::new);
+ log.debug("getUserGroup result = {}", foundGroup);
+ log.trace("getUserGroup end");
+
+ return foundGroup;
+ }
+
+ @Override
+ public Page getUserGroups(UserGroupFilter filter, Pageable pageable) {
+ log.trace("getUserGroups start");
+ log.debug("getUserGroups filter = {}, pageable = {}", filter, pageable);
+ boolean match = pageable.getSort().stream().allMatch(order -> allowedSortingParams.contains(order.getProperty()));
+ if (!match) {
+ throw new ValidationException("Given sort parameters aren't valid");
+ }
+ Page result = findAll(filter, pageable);
+ log.debug("getUserGroups result = {}", result);
+ log.trace("getUserGroups end");
+ return result;
+ }
+
+ @Override
+ public void deleteGroup(String id) {
+ log.trace("deleteGroup start");
+ log.debug("deleteGroup id = {}", Encode.forJava(id));
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ deleteById(id);
+ log.trace("deleteProduct end");
+ }
+
+ @Override
+ public void suspendGroup(String id) {
+ log.trace("suspendGroup start");
+ log.debug("suspendGroup id = {}", Encode.forJava(id));
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ suspendById(id);
+ log.trace("suspendGroup end");
+ }
+
+ @Override
+ public void activateGroup(String id) {
+ log.trace("activateGroup start");
+ log.debug("activateGroup id = {}", Encode.forJava(id));
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ activateById(id);
+ log.trace("activateGroup end");
+ }
+
+ @Override
+ public UserGroupOperations updateGroup(String id, UserGroupOperations group) {
+ log.trace("updateGroup start");
+ log.debug("updateGroup id = {}, group = {}", Encode.forJava(id), group);
+ Assert.hasText(id, USER_GROUP_ID_REQUIRED_MESSAGE);
+ Assert.notNull(group, "A user group is required");
+ UserGroupOperations foundGroup = findById(id).orElseThrow(ResourceNotFoundException::new);
+ if (UserGroupStatus.SUSPENDED.equals(foundGroup.getStatus())) {
+ throw new ResourceUpdateException(TRYING_TO_MODIFY_SUSPENDED_GROUP);
+ }
+ checkNameUniqueness(id, group.getName(), foundGroup.getProductId(), foundGroup.getInstitutionId());
+
+ foundGroup.setMembers(group.getMembers());
+ foundGroup.setName(group.getName());
+ foundGroup.setDescription(group.getDescription());
+ UserGroupOperations updatedGroup = save(foundGroup);
+ log.debug("updateGroup updatedGroup = {}", updatedGroup);
+ log.trace("updateGroup end");
+ return updatedGroup;
+ }
+
+ private UserGroupEntity insertUserGroupEntity(UserGroupOperations group) {
+ log.trace("insert start");
+ log.debug("insert entity = {}", group);
+ UserGroupEntity insert;
+ try {
+ insert = repository.insert(new UserGroupEntity(group));
+ } catch (DuplicateKeyException e) {
+ throw new ResourceAlreadyExistsException("Failed _id or unique index constraint.", e);
+ }
+ log.debug("insert = {}", insert);
+ log.trace("createGroup end");
+ return insert;
+ }
+
+ private void checkNameUniqueness(String currentGroupId, 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 existingGroups = findAll(filter, Pageable.unpaged());
+ boolean isDuplicate = existingGroups.stream()
+ .anyMatch(g -> g.getName().equals(groupName) && !g.getId().equals(currentGroupId));
+
+ if (isDuplicate) {
+ log.warn("Attempted to create/update group with duplicate name: {}", groupName);
+ throw new ResourceAlreadyExistsException(GROUP_NAME_ALREADY_EXISTS);
+ }
+ }
+
+ private Query createActiveGroupQuery(String id) {
+ return Query.query(Criteria.where(UserGroupEntity.Fields.ID).is(id)
+ .and(UserGroupEntity.Fields.status).is(UserGroupStatus.ACTIVE));
+ }
+
+ private void insertMember(String id, String memberId) {
+ log.trace("insertMember start");
+ log.debug("insertMember id = {}, memberId = {}", id, memberId);
+ UpdateResult updateResult = mongoTemplate.updateFirst(
+ createActiveGroupQuery(id),
+ new Update().push(UserGroupEntity.Fields.members, memberId)
+ .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
+ .currentDate(UserGroupEntity.Fields.modifiedAt),
+ UserGroupEntity.class);
+ if (updateResult.getModifiedCount() == 0) {
+ throw new ResourceUpdateException(COULD_NOT_UPDATE_MESSAGE);
+ }
+ log.trace("insertMember end");
+ }
+
+ private void removeMemberFromActiveGroup(String id, String memberId) {
+ log.trace("deleteMember start");
+ log.debug("deleteMember id = {}, memberId = {}", id, memberId);
+
+ UpdateResult updateResult = mongoTemplate.updateFirst(
+ createActiveGroupQuery(id),
+ new Update().pull(UserGroupEntity.Fields.members, memberId)
+ .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
+ .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
+ UserGroupEntity.class);
+ if (updateResult.getModifiedCount() == 0) {
+ throw new ResourceUpdateException(COULD_NOT_UPDATE_MESSAGE);
+ }
+ log.trace("deleteMember end");
+ }
+
+ private void removeMembers(String memberId, String institutionId, String productId) {
+ log.trace("deleteMembers start");
+ log.debug("deleteMembers id = {}, institutionId = {}, productId= {}", memberId, institutionId, productId);
+
+ UpdateResult updateResult = mongoTemplate.updateMulti(
+ Query.query(Criteria.where(UserGroupEntity.Fields.members).is(memberId)
+ .and(UserGroupEntity.Fields.institutionId).is(institutionId)
+ .and(UserGroupEntity.Fields.productId).is(productId)),
+ new Update().pull(UserGroupEntity.Fields.members, memberId)
+ .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
+ .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
+ UserGroupEntity.class);
+ if (updateResult.getModifiedCount() == 0) {
+ log.warn("No user to delete from UserGroup");
+ }
+ log.trace("deleteMembers end");
+ }
+
+ private Optional findById(String id) {
+ log.trace("findById start");
+ log.debug("findById id = {} ", id);
+ Optional result = repository.findById(id).map(Function.identity());
+ log.debug("findById result = {}", result);
+ log.trace("findById end");
+
+ return result;
+ }
+
+ private Page findAll(UserGroupFilter filter, Pageable pageable) {
+ log.trace("findAll start");
+ log.debug("findAll institutionId= {} , productId = {}, userId = {}, pageable = {}", filter.getInstitutionId(), filter.getProductId(), filter.getUserId(), pageable);
+ if (pageable.getSort().isSorted() && !StringUtils.hasText(filter.getProductId()) && !StringUtils.hasText(filter.getInstitutionId())) {
+ throw new ValidationException("Sorting not allowed without productId or institutionId");
+ }
+ if (filter.getStatus().size() == 1 && !StringUtils.hasText(filter.getUserId()) && !StringUtils.hasText(filter.getProductId()) && !StringUtils.hasText(filter.getInstitutionId())) {
+ throw new ValidationException("At least one of productId, institutionId and userId must be provided with status filter");
+ }
+ Query query = new Query(constructCriteria(filter));
+ long count = this.mongoTemplate.count(query, UserGroupEntity.class);
+ List userGroupOperations = new ArrayList<>(mongoTemplate.find(query.with(pageable), UserGroupEntity.class));
+ final Page result = PageableExecutionUtils.getPage(userGroupOperations, pageable, () -> count);
+ log.debug("findAll result = {}", result);
+ log.trace("findAll end");
+ return result;
+ }
+
+ private Criteria constructCriteria(UserGroupFilter filter) {
+ return CriteriaBuilder.builder()
+ .isIfNotNull(UserGroupEntity.Fields.institutionId, filter.getInstitutionId())
+ .isIfNotNull(UserGroupEntity.Fields.productId, filter.getProductId())
+ .isIfNotNull(UserGroupEntity.Fields.members, filter.getUserId())
+ .inIfNotEmpty(UserGroupEntity.Fields.status, filter.getStatus())
+ .build();
+
+ }
+
+ private void activateById(String id) {
+ log.trace("activateById start");
+ log.debug("activateById id = {} ", id);
+ updateUserById(id, UserGroupStatus.ACTIVE);
+ log.trace("activateById end");
+
+ }
+
+ private void deleteById(String id) {
+ log.trace("deleteById start");
+ log.debug("deleteById id = {} ", id);
+ updateUserById(id, UserGroupStatus.DELETED);
+ log.trace("deleteById end");
+ }
+
+ private void suspendById(String id) {
+ log.trace("suspendById start");
+ log.debug("suspendById id = {} ", id);
+ updateUserById(id, UserGroupStatus.SUSPENDED);
+ log.trace("suspendById end");
+ }
+
+ private void updateUserById(String id, UserGroupStatus status) {
+ log.trace("updateUserById start");
+ log.debug("updateUserById id = {}, status = {}", id, status);
+ UpdateResult updateResult = mongoTemplate.updateFirst(
+ Query.query(Criteria.where(UserGroupEntity.Fields.ID).is(id)),
+ Update.update(UserGroupEntity.Fields.status, status)
+ .set(UserGroupEntity.Fields.modifiedBy, auditorAware.getCurrentAuditor().orElse(null))
+ .currentTimestamp(UserGroupEntity.Fields.modifiedAt),
+ UserGroupEntity.class);
+ if (updateResult.getMatchedCount() == 0) {
+ throw new ResourceNotFoundException();
+ }
+ log.trace("updateUserById end");
+ }
+
+ private UserGroupOperations save(UserGroupOperations group) {
+ log.trace("save start");
+ log.debug("save entity = {}", group);
+ UserGroupEntity result;
+ try {
+ result = repository.save(new UserGroupEntity(group));
+ } catch (DuplicateKeyException e) {
+ throw new ResourceAlreadyExistsException("Failed _id or unique index constraint.", e);
+ }
+ log.debug("save result = {}", result);
+ log.trace("save end");
+ return result;
+ }
+}
\ No newline at end of file
diff --git a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java
similarity index 93%
rename from apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java
rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java
index d461704e..1571b690 100644
--- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java
+++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.validator;
+package it.pagopa.selfcare.user_group.validator;
import it.pagopa.selfcare.commons.web.validator.ControllerResponseValidator;
import org.aspectj.lang.annotation.Aspect;
diff --git a/apps/user-group-ms/app/src/main/resources/config/application.yml b/apps/user-group-ms/src/main/resources/config/application.yml
similarity index 100%
rename from apps/user-group-ms/app/src/main/resources/config/application.yml
rename to apps/user-group-ms/src/main/resources/config/application.yml
diff --git a/apps/user-group-ms/src/main/resources/config/core-config.properties b/apps/user-group-ms/src/main/resources/config/core-config.properties
new file mode 100644
index 00000000..6e45af83
--- /dev/null
+++ b/apps/user-group-ms/src/main/resources/config/core-config.properties
@@ -0,0 +1,5 @@
+user-group.allowed.sorting.parameters=${ALLOWED_SORTING_PARAMETERS:name}
+spring.data.mongodb.uri=${MONGODB_CONNECTION_URI:mongodb://localhost:27017}
+spring.data.mongodb.database=${MONGODB_NAME:selcUserGroup}
+rest-assured.base-url=http://localhost
+rest-assured.port=8082
\ No newline at end of file
diff --git a/apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties b/apps/user-group-ms/src/main/resources/swagger/swagger_en.properties
similarity index 100%
rename from apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties
rename to apps/user-group-ms/src/main/resources/swagger/swagger_en.properties
diff --git a/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java
similarity index 79%
rename from apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java
index 9b294139..0e694d97 100644
--- a/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.core.config;
+package it.pagopa.selfcare.user_group.config;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Import;
diff --git a/apps/user-group-ms/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java
similarity index 91%
rename from apps/user-group-ms/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java
index 112eeef6..01c31f58 100644
--- a/apps/user-group-ms/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java
@@ -1,8 +1,8 @@
-package it.pagopa.selfcare.user_group.web.config;
+package it.pagopa.selfcare.user_group.config;
import com.fasterxml.jackson.databind.ObjectMapper;
-import it.pagopa.selfcare.user_group.core.UserGroupService;
-import it.pagopa.selfcare.user_group.web.model.mapper.UserGroupMapper;
+import it.pagopa.selfcare.user_group.model.mapper.UserGroupMapper;
+import it.pagopa.selfcare.user_group.service.UserGroupService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@@ -31,7 +31,7 @@
})
@EnableOpenApi
@EnableWebMvc
-@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.web.controller")
+@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.controller")
@TestPropertySource(locations = "classpath:config/application.yml")
class SwaggerConfigTest {
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java
similarity index 79%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java
index f7ce419c..f35005ba 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.config;
+package it.pagopa.selfcare.user_group.config;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Import;
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java
similarity index 80%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java
index 5cdeb06c..962bcfd7 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.controller;
+package it.pagopa.selfcare.user_group.controller;
import org.springframework.web.bind.annotation.RestController;
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java
similarity index 95%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java
index 03d67b17..d9578e0a 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java
@@ -1,15 +1,13 @@
-package it.pagopa.selfcare.user_group.web.controller;
+package it.pagopa.selfcare.user_group.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.exception.ResourceNotFoundException;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
-import it.pagopa.selfcare.user_group.core.UserGroupService;
-import it.pagopa.selfcare.user_group.web.config.WebTestConfig;
-import it.pagopa.selfcare.user_group.web.handler.UserGroupExceptionHandler;
-import it.pagopa.selfcare.user_group.web.model.*;
-import it.pagopa.selfcare.user_group.web.model.mapper.UserGroupMapperImpl;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.config.WebTestConfig;
+import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException;
+import it.pagopa.selfcare.user_group.handler.UserGroupExceptionHandler;
+import it.pagopa.selfcare.user_group.model.*;
+import it.pagopa.selfcare.user_group.model.mapper.UserGroupMapperImpl;
+import it.pagopa.selfcare.user_group.service.UserGroupService;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
@@ -23,6 +21,8 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import it.pagopa.selfcare.user_group.model.DummyCreateUserGroupDto;
+import it.pagopa.selfcare.user_group.model.DummyUpdateUserGroupDto;
import java.util.List;
import java.util.Set;
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java
similarity index 89%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java
index 1bc2ebdd..e0299198 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java
@@ -1,9 +1,9 @@
-package it.pagopa.selfcare.user_group.web.handler;
+package it.pagopa.selfcare.user_group.handler;
+import it.pagopa.selfcare.user_group.exception.ResourceAlreadyExistsException;
+import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException;
+import it.pagopa.selfcare.user_group.exception.ResourceUpdateException;
import it.pagopa.selfcare.commons.web.model.Problem;
-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 org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.http.ResponseEntity;
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberConfig.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberConfig.java
new file mode 100644
index 00000000..10ae6d7c
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberConfig.java
@@ -0,0 +1,15 @@
+package it.pagopa.selfcare.user_group.integration_test;
+
+import io.restassured.RestAssured;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CucumberConfig {
+
+ public CucumberConfig( @Value("${rest-assured.base-url}") String restAssuredBaseUrl, @Value("${rest-assured.port}")int restAssuredPort) {
+ RestAssured.baseURI = restAssuredBaseUrl;
+ RestAssured.port = restAssuredPort;
+ }
+
+}
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberSuite.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberSuite.java
new file mode 100644
index 00000000..5ef02773
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberSuite.java
@@ -0,0 +1,19 @@
+package it.pagopa.selfcare.user_group.integration_test;
+
+import io.cucumber.spring.CucumberContextConfiguration;
+import it.pagopa.selfcare.user_group.SelfCareUserGroupApplication;
+import org.junit.platform.suite.api.*;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
+
+@Suite
+@IncludeEngines("cucumber")
+@SelectClasspathResource("features")
+@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
+@CucumberContextConfiguration
+@SpringBootTest(classes = {SelfCareUserGroupApplication.class})
+@ExcludeTags({"FeatureCreate","FeatureRetrieve", "FeatureUpdate", "FeatureMembers"})
+public class CucumberSuite {
+}
+
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java
new file mode 100644
index 00000000..2fefe49b
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java
@@ -0,0 +1,140 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import io.cucumber.java.After;
+import io.cucumber.java.Before;
+import io.cucumber.java.DataTableType;
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import io.restassured.RestAssured;
+import io.restassured.response.ExtractableResponse;
+import io.restassured.specification.RequestSpecification;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import it.pagopa.selfcare.user_group.model.UserGroupStatus;
+import org.junit.jupiter.api.Assertions;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+public class CreateUserGroupSteps extends UserGroupSteps {
+
+ @Before("@DuplicateGroupName")
+ public void beforeScenarioOfCreateDuplicatedGroup() throws IOException {
+ initializeCollection();
+ }
+
+ @After("@DuplicateGroupName")
+ public void afterScenarioOfCreateDuplicatedGroup() {
+ userGroupRepository.deleteAllById(userGroupsIds);
+ }
+
+ @After("@CreateNewGroup")
+ public void afterScenarioOfCreateGroup() {
+ userGroupRepository.deleteById(userGroupId);
+ }
+
+ @Override
+ @Then("[CREATE] the response status should be {int}")
+ public void verifyResponseStatus(int expectedStatusCode) {
+ super.verifyResponseStatus(expectedStatusCode);
+ }
+
+ @Override
+ @Then("[CREATE] the response should contain an error message {string}")
+ public void verifyErrorMessage(String expectedErrorMessage) {
+ super.verifyErrorMessage(expectedErrorMessage);
+ }
+
+ @DataTableType
+ public UserGroupEntity convertRequest(Map entry) {
+ UserGroupEntity userGroupEntity = new UserGroupEntity();
+ userGroupEntity.setInstitutionId(entry.get("institutionId"));
+ userGroupEntity.setProductId(entry.get("productId"));
+ userGroupEntity.setName(entry.get("name"));
+ userGroupEntity.setDescription(entry.get("description"));
+ userGroupEntity.setStatus(Optional.ofNullable(entry.get("status")).map(s -> UserGroupStatus.valueOf(entry.get("status"))).orElse(null));
+ userGroupEntity.setMembers(Optional.ofNullable(entry.get("members")).map(s -> Set.of(entry.get("members").split(","))).orElse(null));
+ return userGroupEntity;
+ }
+
+ @When("I send a POST request to {string} with the given details, with authentication {string}")
+ public void iSendAPOSTRequestToWithTheGivenDetails(String url, String isAuthenticated) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .contentType("application/json");
+
+ if(Boolean.parseBoolean(isAuthenticated)){
+ requestSpecification.header("Authorization", "Bearer " + token);
+ }
+
+ ExtractableResponse> response = requestSpecification
+ .body(userGroupDetails)
+ .when()
+ .post(url)
+ .then()
+ .extract();
+
+ status = response.statusCode();
+ if(status == 201) {
+ userGroupEntityResponse = response.body().as(UserGroupEntity.class);
+ userGroupId = userGroupEntityResponse.getId();
+ }else {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @Given("the following user group details:")
+ public void givenUserGroupDetails(List userGroupEntityList) {
+ if (userGroupEntityList != null && userGroupEntityList.size() == 1)
+ this.userGroupDetails = userGroupEntityList.get(0);
+ }
+
+ @Then("the response should contain a valid user group resource with name {string}")
+ public void verifyUserGroupName(String expectedName) {
+ Assertions.assertEquals(expectedName, userGroupEntityResponse.getName());
+ }
+
+ @Then("the response should contain the productId {string}")
+ public void verifyProductId(String expectedProductId) {
+ Assertions.assertEquals(expectedProductId, userGroupEntityResponse.getProductId());
+ }
+
+ @Then("the response should contain the institutionId {string}")
+ public void verifyInstitutionId(String expectedInstitutionId) {
+ Assertions.assertEquals(expectedInstitutionId, userGroupEntityResponse.getInstitutionId());
+ }
+
+ @And("the response should contain the status {string}")
+ public void theResponseShouldContainTheStatus(String expectedStatus) {
+ Assertions.assertEquals(expectedStatus, userGroupEntityResponse.getStatus().name());
+ }
+
+ @And("the response should contain {int} members")
+ public void theResponseShouldContainMembers(int expectedMembersCount) {
+ Assertions.assertEquals(expectedMembersCount, userGroupEntityResponse.getMembers().size());
+ }
+
+ @And("the response should contain the createdBy {string}")
+ public void theResponseShouldContainTheCreatedBy(String expectedCreatedBy) {
+ Assertions.assertEquals(expectedCreatedBy, userGroupEntityResponse.getCreatedBy());
+ }
+
+ @And("the response should contain the createdAt notNull")
+ public void theResponseShouldContainTheCreatedAtNotNull() {
+ verifyNotNull(userGroupEntityResponse.getCreatedAt());
+ }
+
+ @And("the response should contain the modified data null")
+ public void theResponseShouldContainTheModifiedDataNull() {
+ verifyNull(userGroupEntityResponse.getModifiedAt(), userGroupEntityResponse.getModifiedBy());
+ }
+
+ @And("the response should contain the description {string}")
+ public void theResponseShouldContainTheDescription(String expectedDescription) {
+ Assertions.assertEquals(expectedDescription, userGroupEntityResponse.getDescription());
+ }
+}
+
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/FakeSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/FakeSteps.java
new file mode 100644
index 00000000..cbc6f917
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/FakeSteps.java
@@ -0,0 +1,20 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+
+public class FakeSteps extends UserGroupSteps {
+
+
+
+ @Override
+ @Then("[FAKE] the response status should be {int}")
+ public void verifyResponseStatus(int expectedStatusCode) {
+ super.verifyResponseStatus(expectedStatusCode);
+ }
+
+ @When("I send a request to {string}")
+ public void iSendARequestTo(String url) {
+ status = 200;
+ }
+}
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java
new file mode 100644
index 00000000..92349197
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java
@@ -0,0 +1,198 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import io.cucumber.java.After;
+import io.cucumber.java.Before;
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import io.restassured.response.ExtractableResponse;
+import io.restassured.response.Response;
+import io.restassured.response.ResponseOptions;
+import io.restassured.specification.RequestSpecification;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import it.pagopa.selfcare.user_group.model.UserGroupStatus;
+import org.junit.jupiter.api.Assertions;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+
+public class RetrieveUserGroupSteps extends UserGroupSteps {
+
+ @Before("@FirstRetrieveGroupScenario")
+ public void beforeFeature() throws IOException {
+ initializeCollection();
+ }
+
+ @After("@LastRetrieveGroupScenario")
+ public void afterFeature() {
+ userGroupRepository.deleteAllById(userGroupsIds);
+ }
+
+ @Override
+ @Then("[RETRIEVE] the response status should be {int}")
+ public void verifyResponseStatus(int status) {
+ super.verifyResponseStatus(status);
+ }
+
+ @Override
+ @Then("[RETRIEVE] the response should contain an error message {string}")
+ public void verifyErrorMessage(String expectedErrorMessage) {
+ super.verifyErrorMessage(expectedErrorMessage);
+ }
+
+
+ @Given("I have a valid group ID to retrieve: {string}")
+ public void iHaveAValidGroupId(String validGroupId) {
+ userGroupId = validGroupId;
+ }
+
+ @Given("I have a non-existent group ID to retrieve {string}")
+ public void iHaveANonExistentGroupId(String nonExistentGroupId) {
+ userGroupId = nonExistentGroupId;
+ }
+
+ @Given("I have a filter with status {string} but no productId, institutionId or userId")
+ public void iHaveAFilterWithStatusButNoOr(String status) {
+ userGroupEntityFilter = new UserGroupEntity();
+ userGroupEntityFilter.setStatus(UserGroupStatus.valueOf(status));
+ }
+
+ @Given("I have a filter with sorting by {string} but no filter")
+ public void iHaveAFilterWithSortingByButNoFilter(String sortBy) {
+ Sort sort = Sort.by(Sort.Order.asc(sortBy));
+ pageable = PageRequest.of(0, 10, sort);
+ }
+
+ @And("I set the page number to {int} and page size to {int}")
+ public void iSetThePageNumberToAndPageSizeTo(int page, int size) {
+ pageable = Pageable.ofSize(size).withPage(page);
+ }
+
+ @Given("I have no filters")
+ public void iHaveNoFilters() {
+ userGroupEntityFilter = new UserGroupEntity();
+ }
+
+ @When("I send a GET request to {string}")
+ public void iSendAGETRequestTo(String url) {
+ ResponseOptions response = RestAssured.given()
+ .pathParam("id", userGroupId)
+ .header("Authorization", "Bearer " + token)
+ .when()
+ .get(url);
+ status = response.statusCode();
+ if (status == 200) {
+ userGroupEntityResponse = response.getBody().as(UserGroupEntity.class);
+ } else {
+ errorMessage = response.getBody().asString();
+ }
+ }
+
+ @When("I send a GET request to {string} to retrieve userGroups")
+ public void iSendAGETRequestToRetrieveUserGroups(String url) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .contentType("application/json")
+ .header("Authorization", "Bearer " + token);
+
+ if (Objects.nonNull(userGroupEntityFilter)) {
+ if (Objects.nonNull(userGroupEntityFilter.getProductId())) {
+ requestSpecification.queryParam("productId", userGroupEntityFilter.getProductId());
+ }
+ if (Objects.nonNull(userGroupEntityFilter.getInstitutionId())) {
+ requestSpecification.queryParam("institutionId", userGroupEntityFilter.getInstitutionId());
+ }
+ if (Objects.nonNull(userGroupEntityFilter.getStatus())) {
+ requestSpecification.queryParam("status", userGroupEntityFilter.getStatus());
+ }
+ }
+
+ if (Objects.nonNull(pageable)) {
+ requestSpecification.queryParam("size",pageable.getPageSize());
+ requestSpecification.queryParam("page",pageable.getPageNumber());
+ if(pageable.getSort().isSorted()){
+ requestSpecification.queryParam("sort", pageable.getSort().toString());
+ }
+ }
+
+ ExtractableResponse> response = requestSpecification
+ .when()
+ .get(url)
+ .then()
+ .extract();
+
+ status = response.statusCode();
+ if (status == 200) {
+ userGroupEntityResponsePage = response.body().as(new TypeRef<>() {
+ });
+ if (Objects.nonNull(userGroupEntityResponsePage) && !userGroupEntityResponsePage.getContent().isEmpty()) {
+ userGroupEntityResponse = userGroupEntityResponsePage.getContent().get(0);
+ userGroupId = userGroupEntityResponse.getId();
+ }
+ } else {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @Then("the response should contain the group details")
+ public void the_response_should_contain_the_group_details() {
+ Assertions.assertEquals(userGroupId, userGroupEntityResponse.getId());
+ Assertions.assertEquals("io group", userGroupEntityResponse.getName());
+ Assertions.assertEquals("io group description", userGroupEntityResponse.getDescription());
+ Assertions.assertEquals("9c8ae123-d990-4400-b043-67a60aff31bc", userGroupEntityResponse.getInstitutionId());
+ Assertions.assertEquals("prod-test", userGroupEntityResponse.getProductId());
+ Assertions.assertEquals("ACTIVE", userGroupEntityResponse.getStatus().name());
+ Assertions.assertEquals(1, userGroupEntityResponse.getMembers().size());
+ Assertions.assertEquals("75003d64-7b8c-4768-b20c-cf66467d44c7", userGroupEntityResponse.getMembers().iterator().next());
+ Assertions.assertNotNull(userGroupEntityResponse.getCreatedAt());
+ Assertions.assertEquals("4ba2832d-9c4c-40f3-9126-e1c72905ef14", userGroupEntityResponse.getCreatedBy());
+ Assertions.assertNull(userGroupEntityResponse.getModifiedBy());
+ }
+
+ @And("the response should contain a paginated list of user groups of {int} items on page {int}")
+ public void theResponseShouldContainAPaginatedListOfUserGroups(int count, int page) {
+ Assertions.assertEquals(count, userGroupEntityResponsePage.getContent().size());
+ Assertions.assertEquals(3, userGroupEntityResponsePage.getTotalElements());
+ Assertions.assertEquals(2, userGroupEntityResponsePage.getTotalPages());
+ Assertions.assertEquals(2, userGroupEntityResponsePage.getSize());
+ Assertions.assertEquals(page, userGroupEntityResponsePage.getNumber());
+ }
+
+ @Given("I have valid filters institutionId {string} productId {string} and status {string}")
+ public void iHaveValidFiltersAndAnd(String institutionId, String productId, String status) {
+ userGroupEntityFilter = new UserGroupEntity();
+ userGroupEntityFilter.setInstitutionId(institutionId);
+ userGroupEntityFilter.setProductId(productId);
+ userGroupEntityFilter.setStatus(UserGroupStatus.valueOf(status));
+ }
+
+ @And("the response should contains groupIds {string}")
+ public void theResponseShouldContainGroupIds(String ids) {
+ List idsList = Arrays.asList(ids.split(","));
+ Assertions.assertEquals(idsList, userGroupEntityResponsePage.getContent().stream().map(UserGroupEntity::getId).toList());
+ }
+
+ @And("the response should contain an empty list")
+ public void theResponseShouldContainAnEmptyList() {
+ Assertions.assertEquals(0, userGroupEntityResponsePage.getContent().size());
+ }
+
+ @And("the response should contain {int} item")
+ public void theResponseShouldContainOneItem(int expectedItemsCount) {
+ Assertions.assertEquals(expectedItemsCount, userGroupEntityResponsePage.getContent().size());
+ }
+
+ @Then("I should receive a response of retrieve user group operation with status code {int}")
+ public void iShouldReceiveAResponseWithStatusCode(int expectedStatusCode) {
+ Assertions.assertEquals(expectedStatusCode, status);
+ }
+}
+
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java
new file mode 100644
index 00000000..4bfbd9be
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java
@@ -0,0 +1,172 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import io.cucumber.java.After;
+import io.cucumber.java.Before;
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import io.restassured.RestAssured;
+import io.restassured.common.mapper.TypeRef;
+import io.restassured.response.ExtractableResponse;
+import io.restassured.specification.RequestSpecification;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import org.junit.jupiter.api.Assertions;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+public class UpdateUserGroupSteps extends UserGroupSteps {
+
+ @Before("@FirstUpdateScenario")
+ public void beforeFeature() throws IOException {
+ List groupsToInsert = objectMapper.readValue(new File("src/test/resources/dataPopulation/groupEntities.json"),
+ objectMapper.getTypeFactory().constructCollectionType(List.class, UserGroupEntity.class));
+ userGroupRepository.insert(groupsToInsert);
+ }
+
+ @After("@LastUpdateScenario")
+ public void afterFeature() {
+ userGroupRepository.deleteAllById(userGroupsIds);
+ }
+
+ @Override
+ @Then("[UPDATE] the response status should be {int}")
+ public void verifyResponseStatus(int status) {
+ super.verifyResponseStatus(status);
+ }
+
+ @Override
+ @Then("[UPDATE] the response should contain an error message {string}")
+ public void verifyErrorMessage(String expectedErrorMessage) {
+ super.verifyErrorMessage(expectedErrorMessage);
+ }
+
+ @Given("I have a valid group ID to update: {string}")
+ public void iHaveAValidGroupIDToUpdate(String groupId) {
+ userGroupId = groupId;
+ }
+
+ @Given("I have a non-existent group ID {string}")
+ public void i_have_a_non_existent_group_ID(String nonExistentGroupId) {
+ userGroupId = nonExistentGroupId;
+ }
+
+ @And("I have data to update:")
+ public void iHaveDataToUpdate(List userGroupEntityList) {
+ if (userGroupEntityList != null && userGroupEntityList.size() == 1)
+ this.userGroupDetails = userGroupEntityList.get(0);
+ }
+
+ @When("I send a POST request to {string} with authentication {string}")
+ public void iSendAPOSTRequestTo(String url, String isAuthenticated) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .contentType("application/json");
+
+ if(Boolean.parseBoolean(isAuthenticated)){
+ requestSpecification.header("Authorization", "Bearer " + token);
+ }
+
+ ExtractableResponse> response = requestSpecification
+ .pathParam("groupId", userGroupId)
+ .when()
+ .post(url)
+ .then()
+ .extract();
+
+ this.status = response.statusCode();
+ if(status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @When("I send a PUT request to {string} with authentication {string}")
+ public void iSendAPUTRequestTo(String url, String isAuthenticated) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .contentType("application/json");
+
+ if(Boolean.parseBoolean(isAuthenticated)){
+ requestSpecification.header("Authorization", "Bearer " + token);
+ }
+
+ ExtractableResponse> response = requestSpecification
+ .pathParam("groupId", userGroupId)
+ .when()
+ .body(userGroupDetails)
+ .put(url)
+ .then()
+ .extract();
+
+ this.status = response.statusCode();
+ if(status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @When("I send a DELETE request to {string} with authentication {string}")
+ public void iSendADeleteRequestTo(String url, String isAuthenticated) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .contentType("application/json");
+
+ if(Boolean.parseBoolean(isAuthenticated)){
+ requestSpecification.header("Authorization", "Bearer " + token);
+ }
+
+ ExtractableResponse> response = requestSpecification
+ .pathParam("groupId", userGroupId)
+ .when()
+ .delete(url)
+ .then()
+ .extract();
+
+ this.status = response.statusCode();
+ if(status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @And("the retrieved group should be updated")
+ public void theRetrievedGroupShouldBeUpdated() {
+ ExtractableResponse> response = RestAssured.given()
+ .contentType("application/json")
+ .header("Authorization", "Bearer " + token)
+ .when()
+ .get("/v1/user-groups/" + userGroupId)
+ .then()
+ .extract();
+
+ status = response.statusCode();
+ if (status == 200) {
+ updatedUserGroupEntity = response.body().as(new TypeRef<>() {
+ });
+ Assertions.assertNotEquals("io group", updatedUserGroupEntity.getName());
+ Assertions.assertNotEquals("io group description", updatedUserGroupEntity.getDescription());
+ Assertions.assertNotEquals(Set.of("75003d64-7b8c-4768-b20c-cf66467d44c7"), updatedUserGroupEntity.getMembers());
+ Assertions.assertNotNull(updatedUserGroupEntity.getModifiedAt());
+ Assertions.assertNotNull(updatedUserGroupEntity.getModifiedBy());
+ }
+ }
+
+ @And("the retrieved group should be changed status to {string}")
+ public void theRetrievedGroupShouldBeChangedStatusTo(String changedStatus) {
+ ExtractableResponse> response = RestAssured.given()
+ .contentType("application/json")
+ .header("Authorization", "Bearer " + token)
+ .when()
+ .get("/v1/user-groups/" + userGroupId)
+ .then()
+ .extract();
+
+ status = response.statusCode();
+ if (status == 200) {
+ updatedUserGroupEntity = response.body().as(new TypeRef<>() {
+ });
+ Assertions.assertEquals(changedStatus, updatedUserGroupEntity.getStatus().name());
+ Assertions.assertNotNull(updatedUserGroupEntity.getModifiedAt());
+ Assertions.assertNotNull(updatedUserGroupEntity.getModifiedBy());
+ }
+ }
+
+}
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java
new file mode 100644
index 00000000..a4b36aef
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java
@@ -0,0 +1,130 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import io.cucumber.java.After;
+import io.cucumber.java.Before;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import io.restassured.RestAssured;
+import io.restassured.response.Response;
+import io.restassured.response.ResponseOptions;
+import io.restassured.specification.RequestSpecification;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+
+import java.io.IOException;
+import java.util.UUID;
+
+public class UserGroupMemberSteps extends UserGroupSteps {
+
+ @Before("@FirstGroupMembersScenario")
+ public void beforeFeature() throws IOException {
+ initializeCollection();
+ }
+
+ @After("@LastGroupMembersScenario")
+ public void afterFeature() {
+ userGroupRepository.deleteAllById(userGroupsIds);
+ }
+
+ @Override
+ @Then("[MEMBERS] the response status should be {int}")
+ public void verifyResponseStatus(int status) {
+ super.verifyResponseStatus(status);
+ }
+
+ @Override
+ @Then("[MEMBERS] the response should contain an error message {string}")
+ public void verifyErrorMessage(String expectedErrorMessage) {
+ super.verifyErrorMessage(expectedErrorMessage);
+ }
+
+
+ @Given("I have group ID {string} and member ID {string}")
+ public void iHaveGroupIdMemberId(String groupId, String memberId) {
+ userGroupId = groupId;
+ userGroupMemberId = UUID.fromString(memberId);
+ }
+
+ @Given("I have a missing group ID and a valid member ID {string}")
+ public void i_have_a_missing_group_ID_and_a_valid_member_ID(String memberId) {
+ userGroupMemberId = UUID.fromString(memberId);
+ }
+
+ @Given("I have a member id {string}, institution id {string} and product id {string}")
+ public void iHaveAValidMemberIDInstitutionIDAndProductID(String memberId, String institutionId, String productId) {
+ userGroupMemberId = UUID.fromString(memberId);
+ userGroupEntityFilter = new UserGroupEntity();
+ userGroupEntityFilter.setInstitutionId(institutionId);
+ userGroupEntityFilter.setProductId(productId);
+ }
+
+ @Given("I have a member id {string} and institution id {string}")
+ public void iHaveAValidMemberIDAndInstitutionIDAndAMissingProductID(String memberId, String institutionId) {
+ userGroupMemberId = UUID.fromString(memberId);
+ userGroupEntityFilter = new UserGroupEntity();
+ userGroupEntityFilter.setInstitutionId(institutionId);
+ }
+
+ @Given("I have a member id {string} and product id {string}")
+ public void iHaveAValidMemberIDAndAMissingInstitutionIDAndProductID(String memberId, String productId) {
+ userGroupMemberId = UUID.fromString(memberId);
+ userGroupEntityFilter = new UserGroupEntity();
+ userGroupEntityFilter.setProductId(productId);
+ }
+
+
+ @When("I send a PUT request to {string}")
+ public void iSendAPutRequestTo(String url) {
+ ResponseOptions response = RestAssured.given()
+ .header("Authorization", "Bearer " + token)
+ .pathParam("id", userGroupId)
+ .pathParam("memberId", userGroupMemberId)
+ .when()
+ .put(url);
+
+ status = response.statusCode();
+ if (status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @When("I send a DELETE request to {string}")
+ public void iSendADELETERequestTo(String url) {
+ ResponseOptions response = RestAssured.given()
+ .header("Authorization", "Bearer " + token)
+ .pathParam("id", userGroupId)
+ .pathParam("memberId", userGroupMemberId)
+ .when()
+ .delete(url);
+
+ status = response.statusCode();
+ if (status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+
+ @When("I send a DELETE request to {string} with query parameters")
+ public void iSendADELETERequestToWithQueryParameters(String url) {
+ RequestSpecification requestSpecification = RestAssured.given()
+ .header("Authorization", "Bearer " + token)
+ .pathParam("memberId", userGroupMemberId);
+
+ if (userGroupEntityFilter.getInstitutionId() != null) {
+ requestSpecification.queryParam("institutionId", userGroupEntityFilter.getInstitutionId());
+ }
+ if (userGroupEntityFilter.getProductId() != null) {
+ requestSpecification.queryParam("productId", userGroupEntityFilter.getProductId());
+ }
+
+ ResponseOptions response = requestSpecification
+ .queryParam("institutionId", userGroupEntityFilter.getInstitutionId())
+ .queryParam("productId", userGroupEntityFilter.getProductId())
+ .when()
+ .delete(url);
+
+ status = response.statusCode();
+ if (status != 204) {
+ errorMessage = response.body().asString();
+ }
+ }
+}
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupSteps.java
new file mode 100644
index 00000000..a732ba3b
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupSteps.java
@@ -0,0 +1,77 @@
+package it.pagopa.selfcare.user_group.integration_test.steps;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.restassured.RestAssured;
+import it.pagopa.selfcare.user_group.model.TestProperties;
+import it.pagopa.selfcare.user_group.model.UserGroupEntityPageable;
+import it.pagopa.selfcare.user_group.dao.UserGroupRepository;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import org.junit.jupiter.api.Assertions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.domain.Pageable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+public class UserGroupSteps {
+
+ @Autowired
+ protected UserGroupRepository userGroupRepository;
+
+ @Autowired
+ protected ObjectMapper objectMapper;
+
+ protected String userGroupId;
+ protected UUID userGroupMemberId;
+ protected UserGroupEntity userGroupDetails;
+ protected UserGroupEntity userGroupEntityResponse;
+ protected UserGroupEntity updatedUserGroupEntity;
+ protected UserGroupEntityPageable userGroupEntityResponsePage;
+ protected Pageable pageable;
+ protected UserGroupEntity userGroupEntityFilter;
+ protected int status;
+ protected String errorMessage;
+ protected List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a", "6759f8df78b6af202b222d2b");
+ protected String token = readDataPopulation().getToken();
+
+ public TestProperties readDataPopulation() {
+ TestProperties testProperties = null;
+ ObjectMapper objectMapper = new ObjectMapper();
+ try {
+ testProperties = objectMapper.readValue(new File("src/test/resources/dataPopulation/data.json"), new TypeReference<>() {
+ });
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return testProperties;
+ }
+
+ public void verifyErrorMessage(String expectedErrorMessage) {
+ String[] errorMessageArray = expectedErrorMessage.split(",");
+ Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s)));
+ }
+
+ public void verifyResponseStatus(int expectedStatusCode) {
+ Assertions.assertEquals(expectedStatusCode, status);
+ }
+
+ public void verifyNotNull(Object... objects) {
+ Arrays.stream(objects).forEach(Assertions::assertNotNull);
+ }
+
+ public void verifyNull(Object... objects) {
+ Arrays.stream(objects).forEach(Assertions::assertNull);
+ }
+
+ public void initializeCollection() throws IOException {
+ List groupsToInsert = objectMapper.readValue(new File("src/test/resources/dataPopulation/groupEntities.json"),
+ objectMapper.getTypeFactory().constructCollectionType(List.class, UserGroupEntity.class));
+ userGroupRepository.insert(groupsToInsert);
+ }
+
+}
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java
similarity index 98%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java
index 51828516..24fb557d 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import it.pagopa.selfcare.commons.utils.TestUtils;
import org.junit.jupiter.api.BeforeEach;
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java
similarity index 73%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java
index 0c88bc5c..e0ea7346 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java
@@ -1,6 +1,5 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
import lombok.Data;
import java.util.List;
diff --git a/apps/user-group-ms/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java
similarity index 73%
rename from apps/user-group-ms/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java
index d1b18345..7469d808 100644
--- a/apps/user-group-ms/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java
@@ -1,7 +1,6 @@
-package it.pagopa.selfcare.user_group.connector;
+package it.pagopa.selfcare.user_group.model;
-import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations;
-import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
import lombok.Data;
import java.time.Instant;
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java
similarity index 82%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java
index 4ec3d794..c7f74db3 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import lombok.Data;
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/TestProperties.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/TestProperties.java
new file mode 100644
index 00000000..98daa47c
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/TestProperties.java
@@ -0,0 +1,8 @@
+package it.pagopa.selfcare.user_group.model;
+
+import lombok.Data;
+
+@Data
+public class TestProperties {
+ private String token;
+}
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java
similarity index 98%
rename from apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java
rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java
index 2afd0828..2d4bff0b 100644
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java
@@ -1,4 +1,4 @@
-package it.pagopa.selfcare.user_group.web.model;
+package it.pagopa.selfcare.user_group.model;
import it.pagopa.selfcare.commons.utils.TestUtils;
import org.junit.jupiter.api.BeforeEach;
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java
new file mode 100644
index 00000000..818fc961
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java
@@ -0,0 +1,14 @@
+package it.pagopa.selfcare.user_group.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UserGroupEntityPageable {
+ private List content;
+ private Integer totalElements;
+ private Integer totalPages;
+ private Integer size;
+ private Integer number;
+}
diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java
new file mode 100644
index 00000000..3607458d
--- /dev/null
+++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java
@@ -0,0 +1,856 @@
+package it.pagopa.selfcare.user_group.service;
+
+import com.mongodb.client.result.UpdateResult;
+import it.pagopa.selfcare.user_group.api.UserGroupOperations;
+import it.pagopa.selfcare.user_group.config.CoreTestConfig;
+import it.pagopa.selfcare.user_group.dao.UserGroupRepository;
+import it.pagopa.selfcare.user_group.exception.ResourceAlreadyExistsException;
+import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException;
+import it.pagopa.selfcare.user_group.exception.ResourceUpdateException;
+import it.pagopa.selfcare.user_group.model.DummyGroup;
+import it.pagopa.selfcare.user_group.model.UserGroupEntity;
+import it.pagopa.selfcare.user_group.model.UserGroupFilter;
+import it.pagopa.selfcare.user_group.model.UserGroupStatus;
+import it.pagopa.selfcare.commons.base.security.SelfCareUser;
+import it.pagopa.selfcare.commons.utils.TestUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.function.Executable;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.dao.DuplicateKeyException;
+import org.springframework.data.domain.*;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.security.authentication.TestingAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.test.context.TestSecurityContextHolder;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.validation.ValidationException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@ExtendWith(SpringExtension.class)
+@ContextConfiguration(classes = {UserGroupServiceImpl.class, CoreTestConfig.class, UserGroupRepository.class, MongoTemplate.class})
+@TestPropertySource(properties = {
+ "ALLOWED_SORTING_PARAMETERS=name"
+})
+class UserGroupServiceImplTest {
+
+ @BeforeEach
+ void beforeEach() {
+ TestSecurityContextHolder.clearContext();
+ }
+
+ @MockBean
+ private UserGroupRepository userGroupRepository;
+
+ @MockBean
+ private AuditorAware auditorAware;
+
+ @MockBean
+ private MappingMongoConverter mappingMongoConverter;
+
+ @MockBean
+ private MongoTemplate mongoTemplateMock;
+
+ @Autowired
+ private UserGroupServiceImpl groupService;
+
+ @Captor
+ private ArgumentCaptor filter;
+
+ @Test
+ void createGroup_nullAuth() {
+ //given
+ UserGroupOperations input = null;
+ //when
+ Executable executable = () -> groupService.createGroup(input);
+ //then
+ IllegalStateException e = assertThrows(IllegalStateException.class, executable);
+ assertEquals("Authentication is required", e.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void createGroup_nullPrincipal() {
+ //given
+ UserGroupOperations input = null;
+ Authentication authentication = new TestingAuthenticationToken(null, null);
+ TestSecurityContextHolder.setAuthentication(authentication);
+ //when
+ Executable executable = () -> groupService.createGroup(input);
+ //then
+ IllegalStateException illegalStateException = Assertions.assertThrows(IllegalStateException.class, executable);
+ Assertions.assertEquals("Not SelfCareUser principal", illegalStateException.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void createGroup_nullGroup() {
+ //given
+ SelfCareUser selfCareUser = SelfCareUser.builder("id")
+ .email("test@example.com")
+ .name("name")
+ .surname("surname")
+ .build();
+ TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
+ TestSecurityContextHolder.setAuthentication(authenticationToken);
+ UserGroupOperations input = null;
+ //when
+ Executable executable = () -> groupService.createGroup(input);
+ //then
+ IllegalArgumentException illegalArgumentException = Assertions.assertThrows(IllegalArgumentException.class, executable);
+ Assertions.assertEquals("A group is required", illegalArgumentException.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void createGroup_ok() {
+ //given
+ SelfCareUser selfCareUser = SelfCareUser.builder("userId")
+ .email("test@example.com")
+ .name("name")
+ .surname("surname")
+ .build();
+ TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
+ TestSecurityContextHolder.setAuthentication(authenticationToken);
+ UserGroupOperations input = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
+
+ when(userGroupRepository.insert(any(UserGroupEntity.class))).thenReturn(new UserGroupEntity());
+ when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class))).thenReturn(Collections.emptyList());
+
+ //when
+ UserGroupOperations output = groupService.createGroup(input);
+ //then
+ assertNotNull(output);
+ verify(userGroupRepository).insert(any(UserGroupEntity.class));
+ verify(mongoTemplateMock).find(any(Query.class), eq(UserGroupEntity.class));
+ }
+
+ @Test
+ void createGroup_duplicateKey() {
+ //given
+ SelfCareUser selfCareUser = SelfCareUser.builder("userId")
+ .email("test@example.com")
+ .name("name")
+ .surname("surname")
+ .build();
+ TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken(selfCareUser, null);
+ TestSecurityContextHolder.setAuthentication(authenticationToken);
+ UserGroupOperations input = TestUtils.mockInstance(new DummyGroup(), "setId", "setCreateAt", "setModifiedAt");
+
+ when(userGroupRepository.insert(any(UserGroupEntity.class))).thenThrow(new DuplicateKeyException("Duplicate key"));
+ when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class))).thenReturn(Collections.emptyList());
+
+ //when
+ Executable executable = () -> groupService.createGroup(input);
+
+ //then
+ ResourceAlreadyExistsException exception = assertThrows(ResourceAlreadyExistsException.class, executable);
+ assertEquals("Failed _id or unique index constraint.", exception.getMessage());
+ verify(userGroupRepository).insert(any(UserGroupEntity.class));
+ verify(mongoTemplateMock).find(any(Query.class), eq(UserGroupEntity.class));
+ }
+
+ @Test
+ void addMember_nullId() {
+ //given
+ UUID memberId = UUID.randomUUID();
+ //when
+ Executable executable = () -> groupService.addMember(null, memberId);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void addMember_nullMemberId() {
+ //given
+ String groupId = "groupId";
+ //when
+ Executable executable = () -> groupService.addMember(groupId, null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A member id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void addMember_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ UUID memberId = UUID.randomUUID();
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.empty());
+ //when
+ Executable executable = () -> groupService.addMember(groupId, memberId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void addMember_groupSuspended() {
+ //given
+ String groupId = "groupId";
+ UUID memberId = UUID.randomUUID();
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.SUSPENDED);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ //when
+ Executable executable = () -> groupService.addMember(groupId, memberId);
+ //then
+ ResourceUpdateException exception = assertThrows(ResourceUpdateException.class, executable);
+ assertEquals("Trying to modify suspended group", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void addMember_success() {
+ //given
+ String groupId = "groupId";
+ UUID memberId = UUID.randomUUID();
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.addMember(groupId, memberId);
+ //then
+ verify(userGroupRepository).findById(groupId);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void addMember_insertMemberFails() {
+ //given
+ String groupId = "groupId";
+ UUID memberId = UUID.randomUUID();
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ Executable executable = () -> groupService.addMember(groupId, memberId);
+ //then
+ ResourceUpdateException exception = assertThrows(ResourceUpdateException.class, executable);
+ assertEquals("Couldn't update resource", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_nullGroupId() {
+ //given
+ String memberId = "memberId";
+ //when
+ Executable executable = () -> groupService.deleteMember(null, memberId);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_nullMemberId() {
+ //given
+ String groupId = "groupId";
+ //when
+ Executable executable = () -> groupService.deleteMember(groupId, null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A member id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ String memberId = "memberId";
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.empty());
+ //when
+ Executable executable = () -> groupService.deleteMember(groupId, memberId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_groupSuspended() {
+ //given
+ String groupId = "groupId";
+ String memberId = "memberId";
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.SUSPENDED);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ //when
+ Executable executable = () -> groupService.deleteMember(groupId, memberId);
+ //then
+ ResourceUpdateException exception = assertThrows(ResourceUpdateException.class, executable);
+ assertEquals("Trying to modify suspended group", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_success() {
+ //given
+ String groupId = "groupId";
+ String memberId = "memberId";
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.deleteMember(groupId, memberId);
+ //then
+ verify(userGroupRepository).findById(groupId);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMember_updateFails() {
+ //given
+ String groupId = "groupId";
+ String memberId = "memberId";
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(group.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ Executable executable = () -> groupService.deleteMember(groupId, memberId);
+ //then
+ ResourceUpdateException exception = assertThrows(ResourceUpdateException.class, executable);
+ assertEquals("Couldn't update resource", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMembers_nullMemberId() {
+ //given
+ String institutionId = "institutionId";
+ String productId = "productId";
+ //when
+ Executable executable = () -> groupService.deleteMembers(null, institutionId, productId);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A member id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMembers_nullInstitutionId() {
+ //given
+ String memberId = "memberId";
+ String productId = "productId";
+ //when
+ Executable executable = () -> groupService.deleteMembers(memberId, null, productId);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A institution id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMembers_nullProductId() {
+ //given
+ String memberId = "memberId";
+ String institutionId = "institutionId";
+ //when
+ Executable executable = () -> groupService.deleteMembers(memberId, institutionId, null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A product id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMembers_success() {
+ //given
+ String memberId = "memberId";
+ String institutionId = "institutionId";
+ String productId = "productId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateMulti(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.deleteMembers(memberId, institutionId, productId);
+ //then
+ verify(mongoTemplateMock).updateMulti(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteMembers_noModification() {
+ //given
+ String memberId = "memberId";
+ String institutionId = "institutionId";
+ String productId = "productId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getModifiedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateMulti(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.deleteMembers(memberId, institutionId, productId);
+ //then
+ verify(mongoTemplateMock).updateMulti(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroup_nullId() {
+ //when
+ Executable executable = () -> groupService.getUserGroup(null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroup_emptyId() {
+ //when
+ Executable executable = () -> groupService.getUserGroup("");
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroup_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.empty());
+ //when
+ Executable executable = () -> groupService.getUserGroup(groupId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroup_success() {
+ //given
+ String groupId = "groupId";
+ UserGroupEntity group = mock(UserGroupEntity.class);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(group));
+ //when
+ UserGroupOperations result = groupService.getUserGroup(groupId);
+ //then
+ assertNotNull(result);
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroups_invalidSortParameter() {
+ //given
+ UserGroupFilter filter = new UserGroupFilter();
+ Pageable pageable = PageRequest.of(0, 10, Sort.by("invalidParam"));
+ //when
+ Executable executable = () -> groupService.getUserGroups(filter, pageable);
+ //then
+ ValidationException exception = assertThrows(ValidationException.class, executable);
+ assertEquals("Given sort parameters aren't valid", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroups_validSortParameter() {
+ //given
+ UserGroupFilter filter = new UserGroupFilter();
+ filter.setProductId("productId"); // Aggiungi un productId per soddisfare la condizione
+ Pageable pageable = PageRequest.of(0, 10, Sort.by("name"));
+ List userGroups = Collections.singletonList(mock(UserGroupEntity.class));
+ Page page = new PageImpl<>(userGroups, pageable, userGroups.size());
+ when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class))).thenReturn(userGroups);
+ when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class))).thenReturn((long) userGroups.size());
+ //when
+ Page result = groupService.getUserGroups(filter, pageable);
+ //then
+ assertNotNull(result);
+ assertEquals(1, result.getTotalElements());
+ verify(mongoTemplateMock).find(any(Query.class), eq(UserGroupEntity.class));
+ verify(mongoTemplateMock).count(any(Query.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroups_sortingNotAllowedWithoutProductIdOrInstitutionId() {
+ //given
+ UserGroupFilter filter = new UserGroupFilter();
+ Pageable pageable = PageRequest.of(0, 10, Sort.by("name"));
+ //when
+ Executable executable = () -> groupService.getUserGroups(filter, pageable);
+ //then
+ ValidationException exception = assertThrows(ValidationException.class, executable);
+ assertEquals("Sorting not allowed without productId or institutionId", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void getUserGroups_statusFilterWithoutRequiredFields() {
+ //given
+ UserGroupFilter filter = new UserGroupFilter();
+ filter.setStatus(Collections.singletonList(UserGroupStatus.ACTIVE));
+ Pageable pageable = PageRequest.of(0, 10);
+ //when
+ Executable executable = () -> groupService.getUserGroups(filter, pageable);
+ //then
+ ValidationException exception = assertThrows(ValidationException.class, executable);
+ assertEquals("At least one of productId, institutionId and userId must be provided with status filter", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteGroup_nullId() {
+ //when
+ Executable executable = () -> groupService.deleteGroup(null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteGroup_emptyId() {
+ //when
+ Executable executable = () -> groupService.deleteGroup("");
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteGroup_success() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.deleteGroup(groupId);
+ //then
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void suspendGroup_nullId() {
+ //when
+ Executable executable = () -> groupService.suspendGroup(null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void suspendGroup_emptyId() {
+ //when
+ Executable executable = () -> groupService.suspendGroup("");
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void suspendGroup_success() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.suspendGroup(groupId);
+ //then
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void activateGroup_nullId() {
+ //when
+ Executable executable = () -> groupService.activateGroup(null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void activateGroup_emptyId() {
+ //when
+ Executable executable = () -> groupService.activateGroup("");
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void activateGroup_success() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(1L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ groupService.activateGroup(groupId);
+ //then
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void activateGroup_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ Executable executable = () -> groupService.activateGroup(groupId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void deleteGroup_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ Executable executable = () -> groupService.deleteGroup(groupId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void suspendGroup_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ UpdateResult updateResult = mock(UpdateResult.class);
+ when(updateResult.getMatchedCount()).thenReturn(0L);
+ when(mongoTemplateMock.updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class))).thenReturn(updateResult);
+ //when
+ Executable executable = () -> groupService.suspendGroup(groupId);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(mongoTemplateMock).updateFirst(any(Query.class), any(Update.class), eq(UserGroupEntity.class));
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_nullId() {
+ //given
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ //when
+ Executable executable = () -> groupService.updateGroup(null, group);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_emptyId() {
+ //given
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ //when
+ Executable executable = () -> groupService.updateGroup("", group);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group id is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_nullGroup() {
+ //given
+ String groupId = "groupId";
+ //when
+ Executable executable = () -> groupService.updateGroup(groupId, null);
+ //then
+ IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, executable);
+ assertEquals("A user group is required", exception.getMessage());
+ verifyNoInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_groupNotFound() {
+ //given
+ String groupId = "groupId";
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.empty());
+ //when
+ Executable executable = () -> groupService.updateGroup(groupId, group);
+ //then
+ assertThrows(ResourceNotFoundException.class, executable);
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_groupSuspended() {
+ //given
+ String groupId = "groupId";
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ UserGroupEntity foundGroup = mock(UserGroupEntity.class);
+ when(foundGroup.getStatus()).thenReturn(UserGroupStatus.SUSPENDED);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(foundGroup));
+ //when
+ Executable executable = () -> groupService.updateGroup(groupId, group);
+ //then
+ ResourceUpdateException exception = assertThrows(ResourceUpdateException.class, executable);
+ assertEquals("Trying to modify suspended group", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verifyNoMoreInteractions(mongoTemplateMock, userGroupRepository);
+ }
+
+ @Test
+ void updateGroup_success() {
+ //given
+ String groupId = "groupId";
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ UserGroupEntity foundGroup = mock(UserGroupEntity.class);
+ when(foundGroup.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(foundGroup));
+ when(userGroupRepository.save(any(UserGroupEntity.class))).thenReturn(foundGroup);
+ //when
+ UserGroupOperations result = groupService.updateGroup(groupId, group);
+ //then
+ assertNotNull(result);
+ verify(userGroupRepository).findById(groupId);
+ verify(userGroupRepository).save(any(UserGroupEntity.class));
+ }
+
+ @Test
+ void updateGroup_duplicateKey() {
+ //given
+ String groupId = "groupId";
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ UserGroupEntity foundGroup = mock(UserGroupEntity.class);
+ when(foundGroup.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(foundGroup));
+ when(userGroupRepository.save(any(UserGroupEntity.class))).thenThrow(new DuplicateKeyException("Duplicate key"));
+ //when
+ Executable executable = () -> groupService.updateGroup(groupId, group);
+ //then
+ ResourceAlreadyExistsException exception = assertThrows(ResourceAlreadyExistsException.class, executable);
+ assertEquals("Failed _id or unique index constraint.", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verify(userGroupRepository).save(any(UserGroupEntity.class));
+ }
+
+ @Test
+ void createGroup_duplicateName() {
+ //given
+ SelfCareUser selfCareUser = SelfCareUser.builder("userId")
+ .email("test@example.com")
+ .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("duplicateName");
+ input.setProductId("productId");
+ input.setInstitutionId("institutionId");
+
+ UserGroupEntity existingGroup = new UserGroupEntity();
+ existingGroup.setId("existingGroupId");
+ existingGroup.setName("duplicateName");
+ existingGroup.setProductId("productId");
+ existingGroup.setInstitutionId("institutionId");
+ existingGroup.setStatus(UserGroupStatus.ACTIVE);
+
+ when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class))).thenReturn(Collections.singletonList(existingGroup));
+ when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class))).thenReturn(1L);
+
+ //when
+ Executable executable = () -> groupService.createGroup(input);
+
+ //then
+ ResourceAlreadyExistsException exception = assertThrows(ResourceAlreadyExistsException.class, executable);
+ assertEquals("A group with the same name already exists in ACTIVE or SUSPENDED state", exception.getMessage());
+ verify(mongoTemplateMock).find(any(Query.class), eq(UserGroupEntity.class));
+ verify(mongoTemplateMock).count(any(Query.class), eq(UserGroupEntity.class));
+ }
+
+ @Test
+ void updateGroup_duplicateName() {
+ //given
+ String groupId = "groupId";
+ UserGroupOperations group = mock(UserGroupOperations.class);
+ when(group.getName()).thenReturn("duplicateName");
+ UserGroupEntity foundGroup = mock(UserGroupEntity.class);
+ when(foundGroup.getStatus()).thenReturn(UserGroupStatus.ACTIVE);
+ when(foundGroup.getProductId()).thenReturn("productId");
+ when(foundGroup.getInstitutionId()).thenReturn("institutionId");
+ when(userGroupRepository.findById(groupId)).thenReturn(Optional.of(foundGroup));
+
+ UserGroupEntity existingGroup = new UserGroupEntity();
+ existingGroup.setId("existingGroupId");
+ existingGroup.setName("duplicateName");
+ existingGroup.setProductId("productId");
+ existingGroup.setInstitutionId("institutionId");
+ existingGroup.setStatus(UserGroupStatus.ACTIVE);
+
+ when(mongoTemplateMock.find(any(Query.class), eq(UserGroupEntity.class))).thenReturn(Collections.singletonList(existingGroup));
+ when(mongoTemplateMock.count(any(Query.class), eq(UserGroupEntity.class))).thenReturn(1L);
+
+ //when
+ Executable executable = () -> groupService.updateGroup(groupId, group);
+
+ //then
+ ResourceAlreadyExistsException exception = assertThrows(ResourceAlreadyExistsException.class, executable);
+ assertEquals("A group with the same name already exists in ACTIVE or SUSPENDED state", exception.getMessage());
+ verify(userGroupRepository).findById(groupId);
+ verify(mongoTemplateMock).find(any(Query.class), eq(UserGroupEntity.class));
+ verify(mongoTemplateMock).count(any(Query.class), eq(UserGroupEntity.class));
+ verify(group).getName();
+ }
+}
\ No newline at end of file
diff --git a/apps/user-group-ms/src/test/resources/application-test.properties b/apps/user-group-ms/src/test/resources/application-test.properties
new file mode 100644
index 00000000..a94cfa2a
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/application-test.properties
@@ -0,0 +1,5 @@
+user-group.allowed.sorting.parameters=name
+spring.data.mongodb.uri=mongodb://localhost:27017
+spring.data.mongodb.database=selcUserGroup
+rest-assured.base-url=http://localhost
+rest-assured.port=8082
diff --git a/apps/user-group-ms/src/test/resources/dataPopulation/data.json b/apps/user-group-ms/src/test/resources/dataPopulation/data.json
new file mode 100644
index 00000000..06eb0a47
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/dataPopulation/data.json
@@ -0,0 +1,3 @@
+{
+ "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzM0MDc4MzQ3LCJleHAiOjE3MzQxMTA3NDcsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8yZjYwM2E4YmMzNmIxMjMxYjFhNiJ9.MCSiqjxLAkdLiGE_1MAznFnKe0sfPS3V8nNL6PU07tUH6VStn2QwSENkGFcepeatQ7aNBsh9GFjQXdDfa00nSDmWJRaDeQ-aRwUWWcgf_3WxL6De6k9Ou4e8v8_jdOQ4bqkWMESCNLEgZiD-NuzbWemJnGSv6ysyU9iaL-38eQ3wrMn9xIVXmNkILpkuiAHLMnoPO82BMQ_ldTCfBRM9kfoo3JyAPf9bHqslOD_VRU6lGULV9gzJ_D6ZQVIyZNs_Wvx6KN0j3feDcfViURBQruE_UZ3SvsnYmqcTL7IOk4wLI_GdXOXjN49SmceLMM3tHYN9yfzyzA-yDaYJvg0QIA"
+}
\ No newline at end of file
diff --git a/apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json b/apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json
new file mode 100644
index 00000000..4867ac7c
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json
@@ -0,0 +1,44 @@
+[
+ {
+ "id": "6759f8df78b6af202b222d29",
+ "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc",
+ "productId": "prod-test",
+ "name": "io group",
+ "description": "io group description",
+ "status": "ACTIVE",
+ "members": [
+ "75003d64-7b8c-4768-b20c-cf66467d44c7"
+ ],
+ "createdAt": "2020-07-01T00:00:00.000Z",
+ "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14",
+ "modifiedAt": null
+ },
+ {
+ "id": "6759f8df78b6af202b222d2a",
+ "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc",
+ "productId": "prod-test",
+ "name": "io group 2",
+ "description": "pagopa group description",
+ "status": "SUSPENDED",
+ "members": [
+ "75003d64-7b8c-4768-b20c-cf66467d44c7"
+ ],
+ "createdAt": "2020-07-01T00:00:00.000Z",
+ "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14",
+ "modifiedAt": null
+ },
+ {
+ "id": "6759f8df78b6af202b222d2b",
+ "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc",
+ "productId": "prod-test2",
+ "name": "interop group",
+ "description": "interop group description",
+ "status": "SUSPENDED",
+ "members": [
+ "75003d64-7b8c-4768-b20c-cf66467d44c7"
+ ],
+ "createdAt": "2020-07-01T00:00:00.000Z",
+ "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14",
+ "modifiedAt": null
+ }
+]
\ No newline at end of file
diff --git a/apps/user-group-ms/src/test/resources/features/createGroup.feature b/apps/user-group-ms/src/test/resources/features/createGroup.feature
new file mode 100644
index 00000000..0e02b65d
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/features/createGroup.feature
@@ -0,0 +1,91 @@
+@FeatureCreate
+Feature: Create User Group
+
+ @CreateNewGroup
+ Scenario: Successfully create a new user group
+ Given the following user group details:
+ | name | description | productId | institutionId | status | members |
+ | Group Name | TestGroup | product123 | inst123 | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 201
+ And the response should contain a valid user group resource with name "Group Name"
+ And the response should contain the description "TestGroup"
+ And the response should contain the productId "product123"
+ And the response should contain the institutionId "inst123"
+ And the response should contain the status "ACTIVE"
+ And the response should contain 2 members
+ And the response should contain the createdBy "4ba2832d-9c4c-40f3-9126-e1c72905ef14"
+ And the response should contain the createdAt notNull
+ And the response should contain the modified data null
+
+ # Scenario negativo: Nome del gruppo giĆ esistente (conflitto)
+ @DuplicateGroupName
+ Scenario: Attempt to create a user group with a duplicate name
+ Given the following user group details:
+ | name | description | productId | institutionId | status | members |
+ | io group | TestGroup | prod-test | 9c8ae123-d990-4400-b043-67a60aff31bc | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 409
+ And [CREATE] the response should contain an error message "A group with the same name already exists in ACTIVE or SUSPENDED state"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (name non fornito)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | description | productId | institutionId | status | members |
+ | TestGroup | product123 | inst123 | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.name,must not be blank"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (institutionId non fornito)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | name | description | productId | status | members |
+ | Group Name | TestGroup | product123 | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.institutionId,must not be blank"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (productId non fornito)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | name | description | institutionId | status | members |
+ | Group Name | TestGroup | inst123 | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.productId,must not be blank"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (description non fornito)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | name | productId | institutionId | status | members |
+ | Group Name | product123 | inst123 | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.description,must not be blank"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (status non fornito)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | name | description | productId | institutionId | members |
+ | Group Name | TestGroup | product123 | inst123 | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.status,must not be null"
+
+ # Scenario negativo: Dettagli del gruppo mancanti (members vuoto)
+ Scenario: Attempt to create a user group with missing required fields
+ Given the following user group details:
+ | name | description | productId | institutionId | status | members |
+ | Group Name | TestGroup | product123 | inst123 | ACTIVE | |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "true"
+ Then [CREATE] the response status should be 400
+ And [CREATE] the response should contain an error message "createUserGroupDto.members,must not be empty"
+
+ # Scenario negativo: Autenticazione mancante (utente non autenticato)
+ Scenario: Attempt to create a user group without authentication
+ Given the following user group details:
+ | name | description | productId | institutionId | status | members |
+ | Group Name | Test Group | product123 | inst123 | ACTIVE | |
+ When I send a POST request to "/v1/user-groups" with the given details, with authentication "false"
+ Then [CREATE] the response status should be 401
diff --git a/apps/user-group-ms/src/test/resources/features/fake.feature b/apps/user-group-ms/src/test/resources/features/fake.feature
new file mode 100644
index 00000000..1e03e932
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/features/fake.feature
@@ -0,0 +1,5 @@
+Feature: fake
+
+Scenario: Successfully execute fake test
+When I send a request to "/fake"
+Then [FAKE] the response status should be 200
\ No newline at end of file
diff --git a/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature b/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature
new file mode 100644
index 00000000..7211fe6d
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature
@@ -0,0 +1,69 @@
+@FeatureRetrieve
+Feature: Get User Group
+
+ @FirstRetrieveGroupScenario
+ Scenario: Successfully retrieve a group with a valid ID
+ Given I have a valid group ID to retrieve: "6759f8df78b6af202b222d29"
+ When I send a GET request to "/v1/user-groups/{id}"
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain the group details
+
+ Scenario: Attempt to retrieve a non-existent group
+ Given I have a non-existent group ID to retrieve "99999"
+ When I send a GET request to "/v1/user-groups/{id}"
+ Then [RETRIEVE] the response status should be 404
+ And [RETRIEVE] the response should contain an error message "Not Found"
+
+ Scenario: Successfully retrieve user groups with valid filters
+ Given I have valid filters institutionId "9c8ae123-d990-4400-b043-67a60aff31bc" productId "prod-test" and status "ACTIVE"
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain 1 item
+ And the response should contain the group details
+
+ Scenario: Successfully retrieve user groups without any filters
+ Given I have no filters
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain 3 item
+ And the response should contains groupIds "6759f8df78b6af202b222d29,6759f8df78b6af202b222d2a,6759f8df78b6af202b222d2b"
+
+ Scenario: Attempt to retrieve user groups with a sorting parameter but no productId or institutionId
+ Given I have a filter with sorting by "name" but no filter
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 400
+ And [RETRIEVE] the response should contain an error message "Given sort parameters aren't valid"
+
+ Scenario: Attempt to retrieve user groups with a sorting parameter but no productId or institutionId
+ Given I have a filter with sorting by "invalidSort" but no filter
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 400
+ And [RETRIEVE] the response should contain an error message "Given sort parameters aren't valid"
+
+ Scenario: Attempt to retrieve user groups with status filter but no productId, institutionId, or userId
+ Given I have a filter with status "ACTIVE" but no productId, institutionId or userId
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 400
+ And [RETRIEVE] the response should contain an error message "At least one of productId, institutionId and userId must be provided with status filter"
+
+ Scenario: Successfully retrieve a paginated list of user groups
+ Given I have no filters
+ And I set the page number to 0 and page size to 2
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain a paginated list of user groups of 2 items on page 0
+
+ Scenario: Successfully retrieve a paginated list of user groups
+ Given I have no filters
+ And I set the page number to 1 and page size to 2
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain a paginated list of user groups of 1 items on page 1
+
+ @LastRetrieveGroupScenario
+ Scenario: No user groups found for the provided filters
+ Given I have valid filters institutionId "9c8ae123-d990-4400-b043-67a60affabcd" productId "prod-test" and status "ACTIVE"
+ When I send a GET request to "/v1/user-groups" to retrieve userGroups
+ Then [RETRIEVE] the response status should be 200
+ And the response should contain an empty list
+
diff --git a/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature b/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature
new file mode 100644
index 00000000..8cc540d1
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature
@@ -0,0 +1,70 @@
+@FeatureUpdate
+Feature: Update User Group
+
+ @FirstUpdateScenario
+ Scenario: Successfully suspend a group with a valid ID
+ Given I have a valid group ID to update: "6759f8df78b6af202b222d29"
+ When I send a POST request to "/v1/user-groups/{groupId}/suspend" with authentication "true"
+ Then [UPDATE] the response status should be 204
+ And the retrieved group should be changed status to "SUSPENDED"
+
+ Scenario: Attempt to suspend a group with a non-existent ID
+ Given I have a non-existent group ID "99999"
+ When I send a POST request to "/v1/user-groups/{groupId}/suspend" with authentication "true"
+ Then [UPDATE] the response status should be 404
+ And [UPDATE] the response should contain an error message "Not Found"
+
+ Scenario: Successfully activate a group with a valid ID
+ Given I have a valid group ID to update: "6759f8df78b6af202b222d29"
+ When I send a POST request to "/v1/user-groups/{groupId}/activate" with authentication "true"
+ Then [UPDATE] the response status should be 204
+ And the retrieved group should be changed status to "ACTIVE"
+
+ Scenario: Attempt to activate a group with a non-existent ID
+ Given I have a non-existent group ID "99999"
+ When I send a POST request to "/v1/user-groups/{groupId}/activate" with authentication "true"
+ Then [UPDATE] the response status should be 404
+ And [UPDATE] the response should contain an error message "Not Found"
+
+ Scenario: Successfully delete a group with a valid ID
+ Given I have a valid group ID to update: "6759f8df78b6af202b222d29"
+ When I send a DELETE request to "/v1/user-groups/{groupId}" with authentication "true"
+ Then [UPDATE] the response status should be 204
+ And the retrieved group should be changed status to "DELETED"
+
+ Scenario: Attempt to delete a group with a non-existent ID
+ Given I have a non-existent group ID "99999"
+ When I send a DELETE request to "/v1/user-groups/{groupId}" with authentication "true"
+ Then [UPDATE] the response status should be 404
+ And [UPDATE] the response should contain an error message "Not Found"
+
+ Scenario: Successfully update a group with a valid ID and valid data
+ Given I have a valid group ID to update: "6759f8df78b6af202b222d29"
+ And I have data to update:
+ | name | description | members |
+ | updated Name | updatedDescription | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a PUT request to "/v1/user-groups/{groupId}" with authentication "true"
+ Then [UPDATE] the response status should be 200
+ And the retrieved group should be updated
+
+ Scenario: Attempt to update a non-existent group
+ Given I have a non-existent group ID "99999"
+ And I have data to update:
+ | name | description | members |
+ | Group Name | TestGroup | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a PUT request to "/v1/user-groups/{groupId}" with authentication "true"
+ Then [UPDATE] the response status should be 404
+ And [UPDATE] the response should contain an error message "Not Found"
+
+ @LastUpdateScenario
+ Scenario: Attempt to update a suspended group
+ Given I have a valid group ID to update: "6759f8df78b6af202b222d2a"
+ And I have data to update:
+ | name | description | members |
+ | Group Name | TestGroup | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 |
+ When I send a PUT request to "/v1/user-groups/{groupId}" with authentication "true"
+ Then [UPDATE] the response status should be 400
+ And [UPDATE] the response should contain an error message "Trying to modify suspended group"
+
+
+
diff --git a/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature
new file mode 100644
index 00000000..090af0e8
--- /dev/null
+++ b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature
@@ -0,0 +1,66 @@
+@FeatureMembers
+Feature: User Group Members
+
+ @FirstGroupMembersScenario
+ Scenario: Successfully add a member to a group
+ Given I have group ID "6759f8df78b6af202b222d29" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 204
+
+ Scenario: Attempt to add a member to a non-existent group
+ Given I have group ID "99999" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 404
+ And [MEMBERS] the response should contain an error message "Not Found"
+
+ Scenario: Attempt to add a member to a suspended group
+ Given I have group ID "6759f8df78b6af202b222d2b" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 400
+ And [MEMBERS] the response should contain an error message "Trying to modify suspended group"
+
+ Scenario: Successfully delete a member from a group
+ Given I have group ID "6759f8df78b6af202b222d29" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 204
+
+ Scenario: Attempt to delete a member from a non-existent group
+ Given I have group ID "99999" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 404
+ And [MEMBERS] the response should contain an error message "Not Found"
+
+ Scenario: Attempt to delete a member from a suspended group
+ Given I have group ID "6759f8df78b6af202b222d2b" and member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf"
+ When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 400
+ And [MEMBERS] the response should contain an error message "Trying to modify suspended group"
+
+ Scenario: Attempt to delete a member with non-existent member ID
+ Given I have group ID "6759f8df78b6af202b222d29" and member ID "f71dcad0-3374-4b51-91b8-75a9b36a5696"
+ When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}"
+ Then [MEMBERS] the response status should be 204
+
+ Scenario: Successfully delete a member from all groups associated with institutionId and productId
+ Given I have a member id "75003d64-7b8c-4768-b20c-cf66467d44c7", institution id "9c8ae123-d990-4400-b043-67a60aff31bc" and product id "prod-test"
+ When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters
+ Then [MEMBERS] the response status should be 204
+
+ Scenario: Attempt to delete a member with a missing institution ID
+ Given I have a member id "75003d64-7b8c-4768-b20c-cf66467d44c7" and product id "prod-test"
+ When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters
+ Then [MEMBERS] the response status should be 500
+ And [MEMBERS] the response should contain an error message "A institution id is required"
+
+ Scenario: Attempt to delete a member with a missing product ID
+ Given I have a member id "75003d64-7b8c-4768-b20c-cf66467d44c7" and institution id "9c8ae123-d990-4400-b043-67a60aff31bc"
+ When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters
+ Then [MEMBERS] the response status should be 500
+ And [MEMBERS] the response should contain an error message "A product id is required"
+
+ @LastGroupMembersScenario
+ Scenario: Attempt to delete a member who is not in any group associated with the given institutionId and productId
+ Given I have a member id "19017fde-142a-4e11-9498-a12a746d0f15", institution id "9c8ae123-d990-4400-b043-67a60aff31bc" and product id "prod-test"
+ When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters
+ Then [MEMBERS] the response status should be 204
+
diff --git a/apps/user-group-ms/web/pom.xml b/apps/user-group-ms/web/pom.xml
deleted file mode 100644
index 64f4a30a..00000000
--- a/apps/user-group-ms/web/pom.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- user-group-ms
- it.pagopa.selfcare
- 1.0.0-SNAPSHOT
-
- 4.0.0
-
- user-group-ms-web
-
-
-
- it.pagopa.selfcare
- selc-commons-web
-
-
- it.pagopa.selfcare
- selc-commons-web
- test-jar
- test
-
-
- it.pagopa.selfcare
- user-group-ms-core
-
-
- io.springfox
- springfox-boot-starter
-
-
-
-
diff --git a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidatorTest.java b/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidatorTest.java
deleted file mode 100644
index f1482767..00000000
--- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidatorTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package it.pagopa.selfcare.user_group.web.validator;
-
-import it.pagopa.selfcare.commons.web.validator.ControllerResponseValidator;
-import it.pagopa.selfcare.commons.web.validator.PointcutControllerResponseValidatorBaseTest;
-import it.pagopa.selfcare.user_group.web.controller.DummyController;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.mock.mockito.SpyBean;
-import org.springframework.context.annotation.EnableAspectJAutoProxy;
-
-@SpringBootTest(classes = {
- ValidationAutoConfiguration.class,
- DummyController.class,
- UserGroupControllerResponseValidator.class
-})
-@EnableAspectJAutoProxy
-class UserGroupControllerResponseValidatorTest extends PointcutControllerResponseValidatorBaseTest {
- @Autowired
- private DummyController controller;
-
- @SpyBean
- private UserGroupControllerResponseValidator validator;
-
- @Override
- protected ControllerResponseValidator getValidatorSpy() {
- return validator;
- }
-
- @Override
- protected void invokeNotVoidMethod() {
- controller.notVoidMethod();
- }
-
- @Override
- protected void invokeVoidMethod() {
- controller.voidMethod();
- }
-}
\ No newline at end of file
diff --git a/test-coverage/pom.xml b/test-coverage/pom.xml
index 7656c10c..bd32a231 100644
--- a/test-coverage/pom.xml
+++ b/test-coverage/pom.xml
@@ -91,27 +91,7 @@
it.pagopa.selfcare
- user-group-ms-app
- 1.0.0-SNAPSHOT
-
-
- it.pagopa.selfcare
- user-group-ms-web
- 1.0.0-SNAPSHOT
-
-
- it.pagopa.selfcare
- user-group-ms-core
- 1.0.0-SNAPSHOT
-
-
- it.pagopa.selfcare
- user-group-ms-connector-dao
- 1.0.0-SNAPSHOT
-
-
- it.pagopa.selfcare
- user-group-ms-connector-api
+ user-group-ms
1.0.0-SNAPSHOT