From 2497378f753913887593f70aed0df18ac6a14d7f Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Sun, 8 Dec 2024 22:41:49 +0100 Subject: [PATCH 1/8] [SELC-5969] First commit for user-group refactor --- apps/user-group-ms-2/Dockerfile | 48 + apps/user-group-ms-2/Dockerfile.dockerignore | 117 +++ apps/user-group-ms-2/README.md | 39 + apps/user-group-ms-2/app/pom.xml | 90 ++ .../app/src/main/docs/openapi.json | 36 + .../SelfCareUserGroupApplication.java | 13 + .../user_group/api/UserGroupOperations.java | 54 ++ .../auditing/SpringSecurityAuditorAware.java | 25 + .../user_group/config/CoreConfig.java | 16 + .../user_group/config/SwaggerConfig.java | 93 ++ .../config/UserGroupSecurityConfig.java | 14 + .../selfcare/user_group/config/WebConfig.java | 10 + .../controller/UserGroupV1Controller.java | 231 +++++ .../user_group/dao/UserGroupRepository.java | 8 + .../ResourceAlreadyExistsException.java | 12 + .../exception/ResourceNotFoundException.java | 4 + .../exception/ResourceUpdateException.java | 7 + .../handler/UserGroupExceptionHandler.java | 37 + .../user_group/model/CreateUserGroupDto.java | 47 + .../user_group/model/CriteriaBuilder.java | 50 + .../selfcare/user_group/model/GroupDto.java | 22 + .../selfcare/user_group/model/MemberUUID.java | 16 + .../user_group/model/UpdateUserGroupDto.java | 28 + .../user_group/model/UserGroupEntity.java | 64 ++ .../user_group/model/UserGroupFilter.java | 30 + .../user_group/model/UserGroupResource.java | 54 ++ .../user_group/model/UserGroupStatus.java | 7 + .../model/mapper/UserGroupMapper.java | 53 ++ .../user_group/service/UserGroupService.java | 31 + .../service/UserGroupServiceImpl.java | 358 ++++++++ .../UserGroupControllerResponseValidator.java | 26 + .../src/main/resources/config/application.yml | 31 + .../resources/config/core-config.properties | 3 + .../resources/swagger/swagger_en.properties | 29 + .../user_group/config/CoreTestConfig.java | 9 + .../user_group/config/SwaggerConfigTest.java | 69 ++ .../user_group/config/WebTestConfig.java | 9 + .../controller/DummyController.java | 14 + .../controller/UserGroupV1ControllerTest.java | 369 ++++++++ .../dao/UserGroupRepositoryTest.java | 375 ++++++++ .../UserGroupExceptionHandlerTest.java | 68 ++ .../model/CreateUserGroupDtoTest.java | 73 ++ .../model/DummyCreateUserGroupDto.java | 17 + .../selfcare/user_group/model/DummyGroup.java | 24 + .../model/DummyUpdateUserGroupDto.java | 13 + .../model/UpdateUserGroupDtoTest.java | 68 ++ .../service/UserGroupServiceImplTest.java | 856 ++++++++++++++++++ apps/user-group-ms-2/lombok.config | 1 + apps/user-group-ms-2/mvnw | 310 +++++++ apps/user-group-ms-2/mvnw.cmd | 182 ++++ apps/user-group-ms-2/pom.xml | 136 +++ 51 files changed, 4296 insertions(+) create mode 100644 apps/user-group-ms-2/Dockerfile create mode 100644 apps/user-group-ms-2/Dockerfile.dockerignore create mode 100644 apps/user-group-ms-2/README.md create mode 100644 apps/user-group-ms-2/app/pom.xml create mode 100644 apps/user-group-ms-2/app/src/main/docs/openapi.json create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java create mode 100644 apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java create mode 100644 apps/user-group-ms-2/app/src/main/resources/config/application.yml create mode 100644 apps/user-group-ms-2/app/src/main/resources/config/core-config.properties create mode 100644 apps/user-group-ms-2/app/src/main/resources/swagger/swagger_en.properties create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java create mode 100644 apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java create mode 100644 apps/user-group-ms-2/lombok.config create mode 100644 apps/user-group-ms-2/mvnw create mode 100644 apps/user-group-ms-2/mvnw.cmd create mode 100644 apps/user-group-ms-2/pom.xml diff --git a/apps/user-group-ms-2/Dockerfile b/apps/user-group-ms-2/Dockerfile new file mode 100644 index 00000000..3b15bfa1 --- /dev/null +++ b/apps/user-group-ms-2/Dockerfile @@ -0,0 +1,48 @@ +# syntax=docker/dockerfile:1.6@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021 +FROM maven:3-eclipse-temurin-17@sha256:0d328fa6843bb26b60cf44d69833f241ffe96218fb29fa19df7a6603863eaae7 AS builder + +WORKDIR /src +COPY --link pom.xml . + +WORKDIR /src/test-coverage +COPY --link ./test-coverage/pom.xml . + +WORKDIR /src/apps +COPY --link ./apps/pom.xml . + +WORKDIR /src/apps/user-group-ms +COPY --link ./apps/user-group-ms/pom.xml . +COPY ./apps/user-group-ms/ ./ + +RUN echo "\n" \ + "\n" \ + "\n" \ + "\${repositoryId}\n" \ + "\${repoLogin}\n" \ + "\${repoPwd}\n" \ + "\n" \ + "\n" \ + "\n" > settings.xml + +ARG REPO_ONBOARDING +ARG REPO_USERNAME +ARG REPO_PASSWORD + +RUN mvn --global-settings settings.xml --projects :user-group-ms -DrepositoryId=${REPO_ONBOARDING} -DrepoLogin=${REPO_USERNAME} -DrepoPwd=${REPO_PASSWORD} --also-make-dependents clean package -DskipTests + + +FROM openjdk:17-jdk@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 AS runtime + +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' + +WORKDIR /app + +COPY --from=builder /src/apps/user-group-ms/target/*.jar ./app.jar + +ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.2.11/applicationinsights-agent-3.2.11.jar ./applicationinsights-agent.jar +RUN chmod 755 ./applicationinsights-agent.jar + +EXPOSE 8080 +USER 1001 + +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/apps/user-group-ms-2/Dockerfile.dockerignore b/apps/user-group-ms-2/Dockerfile.dockerignore new file mode 100644 index 00000000..427b8ce4 --- /dev/null +++ b/apps/user-group-ms-2/Dockerfile.dockerignore @@ -0,0 +1,117 @@ +**/.dockerignore +**/.git +**/bin +**/docker-compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md + +**/.idea +.idea +**/.mvn +.mvn + +**/target + +# Created by .ignore support plugin (hsz.mobi) +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests \ No newline at end of file diff --git a/apps/user-group-ms-2/README.md b/apps/user-group-ms-2/README.md new file mode 100644 index 00000000..89ace93d --- /dev/null +++ b/apps/user-group-ms-2/README.md @@ -0,0 +1,39 @@ +# selfcare-ms-user-group +microservice to manage group of users + +## Description +This Spring Boot-based microservice is designed to handle several key functionalities in the selfcare user-group operations domain and business logic for CRUD groups. + +## Prerequisites +Before running the microservice, ensure you have installed: + +- Java JDK 17 or higher +- Maven 3.6 or higher +- Connection to VPN selc-d-vnet + +## Configuration +Look at app/src/main/resources/`application.yml` file to set up environment-specific settings, such as database details. + +## Installation and Local Startup +To run the microservice locally, follow these steps: + +1. **Build the Project** + +```shell script +mvn clean install +``` + +2. **Start the Application** + +```shell script +mvn spring-boot:run -pl app +``` + +Remember to set environment-specific settings (look above). + +## Usage +After starting, the microservice will be available at `http://localhost:8080/`. + +To use the API, refer to the Swagger UI documentation (if available) at `http://localhost:8080/swagger-ui.html`. + + diff --git a/apps/user-group-ms-2/app/pom.xml b/apps/user-group-ms-2/app/pom.xml new file mode 100644 index 00000000..1a6c160e --- /dev/null +++ b/apps/user-group-ms-2/app/pom.xml @@ -0,0 +1,90 @@ + + + + user-group-ms-2 + it.pagopa.selfcare + 1.0.0-SNAPSHOT + + 4.0.0 + + user-group-ms-app + + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + de.flapdoodle.embed + de.flapdoodle.embed.mongo + test + + + org.springframework.data + spring-data-commons + + + it.pagopa.selfcare + selc-commons-web + + + it.pagopa.selfcare + selc-commons-web + test-jar + test + + + io.springfox + springfox-boot-starter + + + + + + + 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 + + + + + + org.apache.maven.plugins + maven-jar-plugin + + true + + + + + test-jar + + + + + + + + diff --git a/apps/user-group-ms-2/app/src/main/docs/openapi.json b/apps/user-group-ms-2/app/src/main/docs/openapi.json new file mode 100644 index 00000000..587bf75c --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/docs/openapi.json @@ -0,0 +1,36 @@ +{ + "openapi" : "3.0.3", + "info" : { + "title" : "user-group-ms-2", + "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" + }, + "servers" : [ { + "url" : "{url}:{port}{basePath}", + "variables" : { + "url" : { + "default" : "http://localhost" + }, + "port" : { + "default" : "80" + }, + "basePath" : { + "default" : "" + } + } + } ], + "tags" : [ { + "name" : "UserGroup", + "description" : "User group endpoint CRUD operations" + } ], + "components" : { + "securitySchemes" : { + "bearerAuth" : { + "type" : "http", + "description" : "A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725)", + "scheme" : "bearer", + "bearerFormat" : "JWT" + } + } + } +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java new file mode 100644 index 00000000..b1f71755 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java @@ -0,0 +1,13 @@ +package it.pagopa.selfcare.user_group; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SelfCareUserGroupApplication { + + public static void main(String[] args) { + SpringApplication.run(SelfCareUserGroupApplication.class, args); + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java new file mode 100644 index 00000000..e9721504 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java @@ -0,0 +1,54 @@ +package it.pagopa.selfcare.user_group.api; + +import it.pagopa.selfcare.user_group.model.UserGroupStatus; + +import java.time.Instant; +import java.util.Set; + +public interface UserGroupOperations { + + String getId(); + + void setId(String id); + + String getInstitutionId(); + + void setInstitutionId(String institutionId); + + String getProductId(); + + void setProductId(String productId); + + String getName(); + + void setName(String name); + + String getDescription(); + + void setDescription(String description); + + UserGroupStatus getStatus(); + + void setStatus(UserGroupStatus status); + + Set getMembers(); + + void setMembers(Set members); + + Instant getCreatedAt(); + + void setCreatedAt(Instant createdAt); + + String getCreatedBy(); + + void setCreatedBy(String createdBy); + + Instant getModifiedAt(); + + void setModifiedAt(Instant modifiedAt); + + String getModifiedBy(); + + void setModifiedBy(String modifiedBy); + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java new file mode 100644 index 00000000..deb0ac62 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java @@ -0,0 +1,25 @@ +package it.pagopa.selfcare.user_group.auditing; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.AuditorAware; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.Optional; + +@Slf4j +public class SpringSecurityAuditorAware implements AuditorAware { + + @Override + public Optional getCurrentAuditor() { + log.trace("getCurrentAuditor start"); + Optional result = Optional.ofNullable(SecurityContextHolder.getContext()) + .map(SecurityContext::getAuthentication) + .map(Authentication::getName); + log.debug("getCurrentAuditor result = {}", result); + log.trace("getCurrentAuditor end"); + return result; + } + +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java new file mode 100644 index 00000000..2c649212 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java @@ -0,0 +1,16 @@ +package it.pagopa.selfcare.user_group.config; + +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; +import org.springframework.data.domain.AuditorAware; + +@Configuration +@PropertySource("classpath:config/core-config.properties") +public class CoreConfig { + @Bean + public AuditorAware myAuditorProvider() { + return new SpringSecurityAuditorAware(); + } +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java new file mode 100644 index 00000000..31579c4a --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java @@ -0,0 +1,93 @@ +package it.pagopa.selfcare.user_group.config; + +import com.fasterxml.classmate.TypeResolver; +import it.pagopa.selfcare.commons.web.model.Problem; +import it.pagopa.selfcare.commons.web.swagger.BaseSwaggerConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.*; +import org.springframework.core.env.Environment; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpMethod; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.AuthorizationScope; +import springfox.documentation.service.HttpAuthenticationScheme; +import springfox.documentation.service.SecurityReference; +import springfox.documentation.service.Tag; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; + +import java.time.LocalTime; +import java.util.Collections; +import java.util.List; + +import static it.pagopa.selfcare.commons.web.swagger.BaseSwaggerConfig.*; + +/** + * The Class SwaggerConfig. + */ +@Configuration +@Import(BaseSwaggerConfig.class) +class SwaggerConfig { + + private static final String AUTH_SCHEMA_NAME = "bearerAuth"; + + @Configuration + @Profile("swaggerIT") + @PropertySource("classpath:/swagger/swagger_it.properties") + public static class ItConfig { + } + + @Configuration + @Profile("swaggerEN") + @PropertySource("classpath:/swagger/swagger_en.properties") + public static class EnConfig { + } + + private final Environment environment; + + + @Autowired + SwaggerConfig(Environment environment) { + this.environment = environment; + } + + @Bean + public Docket swaggerSpringPlugin(@Autowired TypeResolver typeResolver) { + return new Docket(DocumentationType.OAS_30) + .apiInfo(new ApiInfoBuilder() + .title(environment.getProperty("swagger.title", environment.getProperty("spring.application.name"))) + .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() + .tags(new Tag("UserGroup", environment.getProperty("swagger.user-group.api.description"))) + .directModelSubstitute(LocalTime.class, String.class) + .ignoredParameterTypes(Pageable.class) + .forCodeGeneration(true) + .useDefaultResponseMessages(false) + .globalResponses(HttpMethod.GET, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE, NOT_FOUND_RESPONSE)) + .globalResponses(HttpMethod.DELETE, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) + .globalResponses(HttpMethod.POST, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) + .globalResponses(HttpMethod.PUT, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) + .globalResponses(HttpMethod.PATCH, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) + .additionalModels(typeResolver.resolve(Problem.class)) + .securityContexts(Collections.singletonList(SecurityContext.builder() + .securityReferences(defaultAuth()) + .build())) + .securitySchemes(Collections.singletonList(HttpAuthenticationScheme.JWT_BEARER_BUILDER + .name(AUTH_SCHEMA_NAME) + .description(environment.getProperty("swagger.security.schema.bearer.description")) + .build())); + } + + + private List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return Collections.singletonList(new SecurityReference(AUTH_SCHEMA_NAME, authorizationScopes)); + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java new file mode 100644 index 00000000..128cbe96 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java @@ -0,0 +1,14 @@ +package it.pagopa.selfcare.user_group.config; + +import it.pagopa.selfcare.commons.web.config.SecurityConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; + +@Slf4j +@Configuration +@EnableWebSecurity +@Import(SecurityConfig.class) +class UserGroupSecurityConfig { +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java new file mode 100644 index 00000000..ebf46036 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java @@ -0,0 +1,10 @@ +package it.pagopa.selfcare.user_group.config; + +import it.pagopa.selfcare.commons.web.config.BaseWebConfig; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Configuration +@Import(BaseWebConfig.class) +class WebConfig { +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java new file mode 100644 index 00000000..f8342c15 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java @@ -0,0 +1,231 @@ +package it.pagopa.selfcare.user_group.controller; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +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.api.UserGroupOperations; +import it.pagopa.selfcare.user_group.model.UserGroupFilter; +import it.pagopa.selfcare.user_group.model.UserGroupStatus; +import it.pagopa.selfcare.user_group.service.UserGroupService; +import it.pagopa.selfcare.user_group.model.CreateUserGroupDto; +import it.pagopa.selfcare.user_group.model.UpdateUserGroupDto; +import it.pagopa.selfcare.user_group.model.UserGroupResource; +import it.pagopa.selfcare.user_group.model.mapper.UserGroupMapper; +import lombok.extern.slf4j.Slf4j; +import org.owasp.encoder.Encode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; +import java.util.UUID; + +@Slf4j +@RestController +@RequestMapping(value = "/v1/user-groups", produces = MediaType.APPLICATION_JSON_VALUE) +@Api(tags = "UserGroup") +public class UserGroupV1Controller { + + private final UserGroupService groupService; + private final UserGroupMapper userGroupMapper; + + @Autowired + public UserGroupV1Controller(UserGroupService groupService, + UserGroupMapper userGroupMapper) { + this.groupService = groupService; + this.userGroupMapper = userGroupMapper; + } + + @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.CREATED) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.createUserGroup}") + @ApiResponse(responseCode = "409", + description = "Conflict", + content = { + @Content(mediaType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, + schema = @Schema(implementation = Problem.class)) + }) + public UserGroupResource createGroup(@RequestBody + @Valid + CreateUserGroupDto group) { + log.trace("createGroup start"); + log.debug("createGroup group = {}", group); + UserGroupOperations groupOperations = groupService.createGroup(userGroupMapper.fromDto(group)); + UserGroupResource result = userGroupMapper.toResource(groupOperations); + log.debug("createGroup result = {}", result); + log.trace("createGroup end"); + return result; + } + + + @DeleteMapping("/{id}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteUserGroup}") + public void deleteGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id) { + log.trace("deteleGroup start"); + log.debug("deleteGroup id = {}", Encode.forJava(id)); + groupService.deleteGroup(id); + log.trace("deteleGroup end"); + + } + + + @PostMapping("/{id}/activate") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.activateUserGroup}") + public void activateGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id) { + log.trace("activateGroup start"); + log.debug("activateGroup id = {}", Encode.forJava(id)); + groupService.activateGroup(id); + log.trace("activateGroup end"); + } + + + @PostMapping("/{id}/suspend") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.suspendUserGroup}") + public void suspendGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id) { + log.trace("suspendGroup start"); + log.debug("suspendGroup id = {}", Encode.forJava(id)); + groupService.suspendGroup(id); + log.trace("suspendGroup end"); + } + + + @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) + @ResponseStatus(HttpStatus.OK) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.updateUserGroup}") + @ApiResponse(responseCode = "409", + description = "Conflict", + content = { + @Content(mediaType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, + schema = @Schema(implementation = Problem.class)) + }) + public UserGroupResource updateUserGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id, + @RequestBody + @Valid + UpdateUserGroupDto groupDto) { + log.trace("updateUserGroup start"); + log.debug("updateUserGroup id = {}", Encode.forJava(id)); + UserGroupOperations updatedGroup = groupService.updateGroup(id, userGroupMapper.toUserGroupOperations(groupDto)); + UserGroupResource result = userGroupMapper.toResource(updatedGroup); + log.debug("updateUserGroup result = {}", result); + log.trace("updateUserGroup end"); + return result; + } + + + @PutMapping(value = "/{id}/members/{memberId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.addMember}") + public void addMemberToUserGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id, + @ApiParam("${swagger.user-group.model.memberId}") + @PathVariable("memberId") + UUID userId) { + log.trace("addMemberToUserGroup start"); + log.debug("addMemberToUserGroup id = {}", Encode.forJava(id)); + groupService.addMember(id, userId); + log.trace("addMemberToUserGroup end"); + } + + + @Tag(name = "UserGroup") + @Tag(name = "external-v2") + @GetMapping(value = "/{id}") + @ResponseStatus(HttpStatus.OK) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.getUserGroup}") + public UserGroupResource getUserGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String id) { + log.trace("getUserGroup start"); + log.debug("getUserGroup id = {}", Encode.forJava(id)); + UserGroupOperations group = groupService.getUserGroup(id); + UserGroupResource groupResource = userGroupMapper.toResource(group); + log.debug("getUserGroup result = {}", groupResource); + log.trace("getUserGroup end"); + return groupResource; + } + + + @Tag(name = "support") + @Tag(name = "external-v2") + @Tag(name = "UserGroup") + @Tag(name = "support-pnpg") + @Tag(name = "external-pnpg") + @GetMapping() + @ResponseStatus(HttpStatus.OK) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.getUserGroups}") + public Page getUserGroups(@ApiParam("${swagger.user-group.model.institutionId}") + @RequestParam(value = "institutionId", required = false) + String institutionId, + @ApiParam("${swagger.user-group.model.productId}") + @RequestParam(value = "productId", required = false) + String productId, + @ApiParam("${swagger.user-group.model.memberId}") + @RequestParam(value = "userId", required = false) + UUID memberId, + @ApiParam("${swagger.user-group.model.statusFilter}") + @RequestParam(value = "status", required = false) + List status, + Pageable pageable) { + log.trace("getUserGroups start"); + log.debug("getUserGroups institutionId = {}, productId = {}, pageable = {}, status = {}", Encode.forJava(institutionId), Encode.forJava(productId), pageable, status); + UserGroupFilter filter = new UserGroupFilter(institutionId, productId, memberId, status); + Page result = PageMapper.map(groupService.getUserGroups(filter, pageable) + .map(userGroupMapper::toResource)); + log.debug("getUserGroups result = {}", result); + log.trace("getUserGroups end"); + return result; + } + + @DeleteMapping(value = "/{id}/members/{memberId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteMember}") + public void deleteMemberFromUserGroup(@ApiParam("${swagger.user-group.model.id}") + @PathVariable("id") + String userGroupId, + @ApiParam("${swagger.user-group.model.memberId}") + @PathVariable("memberId") + UUID memberId) { + log.trace("deleteMemberFromUserGroup start"); + log.debug("deleteMemberFromUserGroup userGroupId = {}, memberId = {}", Encode.forJava(userGroupId), memberId); + groupService.deleteMember(userGroupId, memberId.toString()); + log.trace("deleteMemberFromUserGroup end"); + } + + + @DeleteMapping(value = "/members/{memberId}") + @ResponseStatus(HttpStatus.NO_CONTENT) + @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteMember}") + public void deleteMemberFromUserGroups(@ApiParam("${swagger.user-group.model.memberId}") + @PathVariable("memberId") + UUID memberId, + @RequestParam(value = "institutionId") String institutionId, + @RequestParam(value = "productId") String productId) { + log.trace("deleteMemberFromUserGroups start"); + log.debug("deleteMemberFromUserGroups memberId = {}, institutionId = {}, productId = {}", memberId, Encode.forJava(institutionId), Encode.forJava(productId)); + groupService.deleteMembers(memberId.toString(), institutionId, productId); + log.trace("deleteMemberFromUserGroups end"); + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java new file mode 100644 index 00000000..e7a4396d --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java @@ -0,0 +1,8 @@ +package it.pagopa.selfcare.user_group.dao; + +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-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java new file mode 100644 index 00000000..efcb5405 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java @@ -0,0 +1,12 @@ +package it.pagopa.selfcare.user_group.exception; + +public class ResourceAlreadyExistsException extends RuntimeException { + + public ResourceAlreadyExistsException(String msg, Throwable cause) { + super(msg, cause); + } + + public ResourceAlreadyExistsException(String msg) { + super(msg); + } +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java new file mode 100644 index 00000000..05b6906e --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java @@ -0,0 +1,4 @@ +package it.pagopa.selfcare.user_group.exception; + +public class ResourceNotFoundException extends RuntimeException { +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java new file mode 100644 index 00000000..89bb5569 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java @@ -0,0 +1,7 @@ +package it.pagopa.selfcare.user_group.exception; + +public class ResourceUpdateException extends RuntimeException { + public ResourceUpdateException(String msg) { + super(msg); + } +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java new file mode 100644 index 00000000..2a745add --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java @@ -0,0 +1,37 @@ +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.exception.ResourceAlreadyExistsException; +import it.pagopa.selfcare.user_group.exception.ResourceNotFoundException; +import it.pagopa.selfcare.user_group.exception.ResourceUpdateException; +import it.pagopa.selfcare.user_group.controller.UserGroupV1Controller; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +import static org.springframework.http.HttpStatus.*; + +@ControllerAdvice(assignableTypes = {UserGroupV1Controller.class}) +@Slf4j +public class UserGroupExceptionHandler { + + @ExceptionHandler({ResourceAlreadyExistsException.class}) + ResponseEntity handleResourceAlreadyExistsException(ResourceAlreadyExistsException e) { + log.warn(e.toString()); + return ProblemMapper.toResponseEntity(new Problem(CONFLICT, e.getMessage())); + } + + @ExceptionHandler({ResourceUpdateException.class}) + ResponseEntity handleResourceUpdateException(ResourceUpdateException e) { + log.warn(e.toString()); + return ProblemMapper.toResponseEntity(new Problem(BAD_REQUEST, e.getMessage())); + } + + @ExceptionHandler({ResourceNotFoundException.class}) + ResponseEntity handleResourceNotFoundException(ResourceNotFoundException e) { + log.warn(e.toString()); + return ProblemMapper.toResponseEntity(new Problem(NOT_FOUND, e.getMessage())); + } +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java new file mode 100644 index 00000000..1661e1f3 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java @@ -0,0 +1,47 @@ +package it.pagopa.selfcare.user_group.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Set; +import java.util.UUID; + +@Data +public class CreateUserGroupDto { + + + @ApiModelProperty(value = "${swagger.user-group.model.institutionId}", required = true) + @JsonProperty(required = true) + @NotBlank + private String institutionId; + + @ApiModelProperty(value = "${swagger.user-group.model.productId}", required = true) + @JsonProperty(required = true) + @NotBlank + private String productId; + + @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) + @JsonProperty(required = true) + @NotBlank + private String name; + + @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) + @JsonProperty(required = true) + @NotBlank + private String description; + + @ApiModelProperty(value = "${swagger.user-group.model.status}", required = true) + @JsonProperty(required = true) + @NotNull + private UserGroupStatus status; + + @ApiModelProperty(value = "${swagger.user-group.model.members}", required = true) + @JsonProperty(required = true) + @NotEmpty + private Set members; + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java new file mode 100644 index 00000000..75e8166e --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java @@ -0,0 +1,50 @@ +package it.pagopa.selfcare.user_group.model; + +import org.springframework.data.mongodb.core.query.Criteria; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; + +import java.util.List; + +public class CriteriaBuilder { + + private Criteria criteria; + private boolean first; + + private CriteriaBuilder() { + criteria = new Criteria(); + first = true; + } + + public static CriteriaBuilder builder() { + return new CriteriaBuilder(); + } + + public Criteria build() { + return criteria; + } + + public CriteriaBuilder inIfNotEmpty(@NonNull String key, @Nullable List value) { + if (value != null && !value.isEmpty()) { + if (first) { + criteria = Criteria.where(key).in(value); + first = false; + } else { + criteria = criteria.and(key).in(value); + } + } + return this; + } + + public CriteriaBuilder isIfNotNull(@NonNull String key, @Nullable Object value) { + if (value != null) { + if (first) { + criteria = Criteria.where(key).is(value); + first = false; + } else { + criteria = criteria.and(key).is(value); + } + } + return this; + } +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java new file mode 100644 index 00000000..0a62e52e --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java @@ -0,0 +1,22 @@ +package it.pagopa.selfcare.user_group.model; + +import it.pagopa.selfcare.user_group.api.UserGroupOperations; +import lombok.Data; + +import java.time.Instant; +import java.util.Set; + +@Data +public class GroupDto implements UserGroupOperations { + private String id; + private String institutionId; + private String productId; + private String name; + private String description; + private UserGroupStatus status; + private Set members; + private Instant createdAt; + private String createdBy; + private Instant modifiedAt; + private String modifiedBy; +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java new file mode 100644 index 00000000..793163f9 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java @@ -0,0 +1,16 @@ +package it.pagopa.selfcare.user_group.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.UUID; + +@Data +public class MemberUUID { + @ApiModelProperty(value = "${swagger.user-group.model.memberId}", required = true) + @JsonProperty(required = true) + @NotNull + private UUID member; +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java new file mode 100644 index 00000000..ac0d5c7f --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java @@ -0,0 +1,28 @@ +package it.pagopa.selfcare.user_group.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.Set; +import java.util.UUID; + +@Data +public class UpdateUserGroupDto { + @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) + @JsonProperty(required = true) + @NotBlank + private String name; + + @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) + @JsonProperty(required = true) + @NotBlank + private String description; + + @ApiModelProperty(value = "${swagger.user-group.model.members}", required = true) + @JsonProperty(required = true) + @NotEmpty + private Set members; +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java new file mode 100644 index 00000000..cc5e5e0d --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java @@ -0,0 +1,64 @@ +package it.pagopa.selfcare.user_group.model; + + +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; + +import java.time.Instant; +import java.util.Set; + +@Data +@NoArgsConstructor +@EqualsAndHashCode(of = "id") +@Document("UserGroups") +@FieldNameConstants(onlyExplicitlyIncluded = true) +public class UserGroupEntity implements UserGroupOperations { + + public UserGroupEntity(UserGroupOperations userGroup) { + this(); + id = userGroup.getId(); + institutionId = userGroup.getInstitutionId(); + productId = userGroup.getProductId(); + name = userGroup.getName(); + description = userGroup.getDescription(); + status = userGroup.getStatus(); + members = userGroup.getMembers(); + createdAt = userGroup.getCreatedAt(); + createdBy = userGroup.getCreatedBy(); + modifiedAt = userGroup.getModifiedAt(); + modifiedBy = userGroup.getModifiedBy(); + } + + @Id + private String id; + @FieldNameConstants.Include + private String institutionId; + @FieldNameConstants.Include + private String productId; + private String name; + private String description; + @FieldNameConstants.Include + private UserGroupStatus status; + @FieldNameConstants.Include + private Set members; + @CreatedDate + private Instant createdAt; + @CreatedBy + private String createdBy; + @LastModifiedDate + @FieldNameConstants.Include + private Instant modifiedAt; + @LastModifiedBy + @FieldNameConstants.Include + private String modifiedBy; + + @NoArgsConstructor(access = AccessLevel.NONE) + @AllArgsConstructor(access = AccessLevel.NONE) + public static class Fields { + public static final String ID = org.springframework.data.mongodb.core.aggregation.Fields.UNDERSCORE_ID; + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java new file mode 100644 index 00000000..148cadcc --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java @@ -0,0 +1,30 @@ +package it.pagopa.selfcare.user_group.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.util.CollectionUtils; + +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +@Data +@AllArgsConstructor +public class UserGroupFilter { + private String institutionId; + private String productId; + private String userId; + private List status; + + public UserGroupFilter(String institutionId, String productId, UUID userId, List status) { + this.institutionId = institutionId; + this.productId = productId; + this.userId = userId != null ? userId.toString() : null; + this.status = CollectionUtils.isEmpty(status) ? Collections.emptyList() : status; + } + + public UserGroupFilter(){ + this.status = Collections.emptyList(); + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java new file mode 100644 index 00000000..7dfbed65 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java @@ -0,0 +1,54 @@ +package it.pagopa.selfcare.user_group.model; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.Instant; +import java.util.List; +import java.util.UUID; + +@Data +public class UserGroupResource { + + @ApiModelProperty(value = "${swagger.user-group.model.id}", required = true) + @NotBlank + private String id; + + @ApiModelProperty(value = "${swagger.user-group.model.institutionId}", required = true) + @NotBlank + private String institutionId; + + @ApiModelProperty(value = "${swagger.user-group.model.productId}", required = true) + @NotBlank + private String productId; + + @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) + @NotBlank + private String name; + + @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) + @NotBlank + private String description; + + @ApiModelProperty(value = "${swagger.user-group.model.status}", required = true) + @NotNull + private UserGroupStatus status; + + @ApiModelProperty(value = "${swagger.user-group.model.members}") + private List members; + + @ApiModelProperty(value = "${swagger.user-group.model.createdAt}") + private Instant createdAt; + + @ApiModelProperty(value = "${swagger.user-group.model.createdBy}") + private String createdBy; + + @ApiModelProperty(value = "${swagger.user-group.model.modifiedAt}") + private Instant modifiedAt; + + @ApiModelProperty(value = "${swagger.user-group.model.modifiedBy}") + private String modifiedBy; + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java new file mode 100644 index 00000000..0fc589ac --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java @@ -0,0 +1,7 @@ +package it.pagopa.selfcare.user_group.model; + +public enum UserGroupStatus { + ACTIVE, + SUSPENDED, + DELETED +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java new file mode 100644 index 00000000..77c5afe5 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java @@ -0,0 +1,53 @@ +package it.pagopa.selfcare.user_group.model.mapper; + +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; + +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +@Mapper(componentModel = "spring") +public interface UserGroupMapper { + + @Mapping(source = ".", target = "members", qualifiedByName = "getMembersUUID") + UserGroupResource toResource(UserGroupOperations entity); + + @Mapping(source = ".", target = "members", qualifiedByName = "getMembers") + GroupDto fromDto(CreateUserGroupDto dto); + + @Mapping(source = ".", target = "members", qualifiedByName = "getOperationMembers") + GroupDto toUserGroupOperations(UpdateUserGroupDto dto); + + @Named("getMembersUUID") + default List getMembersUUID(UserGroupOperations entity) { + return entity.getMembers() + .stream() + .map(UUID::fromString) + .collect(Collectors.toList()); + } + + @Named("getMembers") + default Set getMembers(CreateUserGroupDto entity) { + return entity.getMembers() + .stream() + .map(UUID::toString) + .collect(Collectors.toSet()); + } + + @Named("getOperationMembers") + default Set getOperationMembers(UpdateUserGroupDto entity) { + return entity.getMembers() + .stream() + .map(UUID::toString) + .collect(Collectors.toSet()); + } + +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java new file mode 100644 index 00000000..eb10e483 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java @@ -0,0 +1,31 @@ +package it.pagopa.selfcare.user_group.service; + +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; + +import java.util.UUID; + +public interface UserGroupService { + + UserGroupOperations createGroup(UserGroupOperations group); + + void addMember(String id, UUID memberId); + + void deleteMember(String groupId, String memberId); + + void deleteMembers(String userId, String institutionId, String memberId); + + UserGroupOperations getUserGroup(String id); + + Page getUserGroups(UserGroupFilter filter, Pageable pageable); + + void deleteGroup(String id); + + void suspendGroup(String id); + + void activateGroup(String id); + + UserGroupOperations updateGroup(String id, UserGroupOperations group); +} diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java new file mode 100644 index 00000000..dcde818c --- /dev/null +++ b/apps/user-group-ms-2/app/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 +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-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java new file mode 100644 index 00000000..1571b690 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java @@ -0,0 +1,26 @@ +package it.pagopa.selfcare.user_group.validator; + +import it.pagopa.selfcare.commons.web.validator.ControllerResponseValidator; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.validation.Validator; + +@Aspect +@Component +public class UserGroupControllerResponseValidator extends ControllerResponseValidator { + + @Autowired + public UserGroupControllerResponseValidator(Validator validator) { + super(validator); + } + + @Override + @Pointcut("execution(* it.pagopa.selfcare.user_group.web.controller.*.*(..))") + public void controllersPointcut() { + // Do nothing because is a pointcut + } + +} diff --git a/apps/user-group-ms-2/app/src/main/resources/config/application.yml b/apps/user-group-ms-2/app/src/main/resources/config/application.yml new file mode 100644 index 00000000..e7eff680 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/resources/config/application.yml @@ -0,0 +1,31 @@ +server: + port: ${MS_USER_GROUP_SERVER_PORT:8080} + +spring: + application: + name: "@project.parent.artifactId@" + version: "@project.version@" + profiles: + include: + # TO enable specific-language documentations + - swaggerEN + zipkin: + enabled: false + sleuth: + baggage: + remote-fields: X-Client-Ip + correlation-fields: X-Client-Ip + +info: + build: + artifact: "@project.parent.artifactId@" + name: "@project.parent.artifactId@" + description: "@project.description@" + version: "@project.version@" + + +logging: + level: + it.pagopa.selfcare: ${MS_USER_GROUP_LOG_LEVEL:DEBUG} + pattern: + additional-info: ",%X{X-Client-Ip:-}]" diff --git a/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties b/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties new file mode 100644 index 00000000..7f702443 --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties @@ -0,0 +1,3 @@ +user-group.allowed.sorting.parameters=${ALLOWED_SORTING_PARAMETERS:name} +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-2/app/src/main/resources/swagger/swagger_en.properties b/apps/user-group-ms-2/app/src/main/resources/swagger/swagger_en.properties new file mode 100644 index 00000000..0d6de28b --- /dev/null +++ b/apps/user-group-ms-2/app/src/main/resources/swagger/swagger_en.properties @@ -0,0 +1,29 @@ +swagger.description=The services described in this section deal with the management of UserGroup entity, providing the necessary methods for its creation, consultation and activation. +swagger.security.schema.bearer.description=A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725) +swagger.pageable.page=Results page you want to retrieve (0..N) +swagger.pageable.size=Number of records per page. Default page size is 20 +swagger.pageable.sort=Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported. +swagger.user-group.api.description=User group endpoint CRUD operations +swagger.user-group.groups.api.createUserGroup=Service that allows the insert of a new occurrence for the UserGroup entity +swagger.user-group.groups.api.deleteUserGroup=Service that allows the deletion of a specific occurrence for the UserGroup entity by an Admin user +swagger.user-group.groups.api.activateUserGroup=Service that allows the activation of a specific occurrence for the UserGroup entity by an Admin user +swagger.user-group.groups.api.suspendUserGroup=Service that allows the suspension of a specific occurrence for the UserGroup entity by an Admin user +swagger.user-group.groups.api.updateUserGroup=Service that allows the modification of a specific occurrence for the UserGroup entity by an Admin user +swagger.user-group.groups.api.getUserGroups=Service that allows to get a list of UserGroup entities +swagger.user-group.groups.api.getUserGroup=Service to get a specific UserGroup entity +swagger.user-group.groups.api.addMember=Service to add a member to a specific UserGroup entity +swagger.user-group.groups.api.deleteMember=Service to delete a member from a specific UserGroup entity +swagger.user-group.model.id=Users group's unique identifier +swagger.user-group.model.institutionId=Users group's institutionId +swagger.user-group.model.productId=Users group's productId +swagger.user-group.model.name=Users group's name +swagger.user-group.model.description=Users group's description +swagger.user-group.model.status=Users group's status +swagger.user-group.model.members=List of all the members of the group +swagger.user-group.model.pageable=Details for retrieving usergroups based on size and index +swagger.user-group.model.memberId=Member's unique identifier +swagger.user-group.model.createdAt=Date on which the group was created +swagger.user-group.model.createdBy=User by which the group was created +swagger.user-group.model.modifiedAt=Date on which the group was modified +swagger.user-group.model.modifiedBy=User by which the group was modified +swagger.user-group.model.statusFilter=If filter on status is present, it must be used with at least one of the other filters \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java new file mode 100644 index 00000000..0e694d97 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java @@ -0,0 +1,9 @@ +package it.pagopa.selfcare.user_group.config; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Import; + +@TestConfiguration +@Import(CoreConfig.class) +public class CoreTestConfig { +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java new file mode 100644 index 00000000..1bc8b101 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java @@ -0,0 +1,69 @@ +package it.pagopa.selfcare.user_group.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +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; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.MediaType; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import springfox.documentation.oas.annotations.EnableOpenApi; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@SpringBootTest(classes = { + SwaggerConfig.class, + CoreConfig.class, + WebConfig.class, +}) +@EnableOpenApi +@EnableWebMvc +@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.controller") +@TestPropertySource(locations = "classpath:config/application.yml") +class SwaggerConfigTest { + + @MockBean + private UserGroupService userGroupService; + + @Autowired + WebApplicationContext context; + + @MockBean + private UserGroupMapper userGroupMapper; + + @Autowired + private ObjectMapper objectMapper; + + @Test + void swaggerSpringPlugin() throws Exception { + MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); + mockMvc.perform(MockMvcRequestBuilders.get("/v3/api-docs").accept(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.status().is2xxSuccessful()) + .andDo((result) -> { + assertNotNull(result); + assertNotNull(result.getResponse()); + final String content = result.getResponse().getContentAsString(); + assertFalse(content.isBlank()); + assertFalse(content.contains("${"), "Generated swagger contains placeholders"); + Object swagger = objectMapper.readValue(result.getResponse().getContentAsString(), Object.class); + String formatted = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(swagger); + Path basePath = Paths.get("src/main/docs/"); + Files.createDirectories(basePath); + Files.write(basePath.resolve("openapi.json"), formatted.getBytes()); + }); + } +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java new file mode 100644 index 00000000..f35005ba --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java @@ -0,0 +1,9 @@ +package it.pagopa.selfcare.user_group.config; + +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Import; + +@TestConfiguration +@Import(WebConfig.class) +public class WebTestConfig { +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java new file mode 100644 index 00000000..962bcfd7 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java @@ -0,0 +1,14 @@ +package it.pagopa.selfcare.user_group.controller; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class DummyController { + + public Object notVoidMethod() { + return new Object(); + } + + public void voidMethod() { + } +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java new file mode 100644 index 00000000..eafda1eb --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java @@ -0,0 +1,369 @@ +package it.pagopa.selfcare.user_group.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.model.*; +import it.pagopa.selfcare.user_group.service.UserGroupService; +import it.pagopa.selfcare.user_group.handler.UserGroupExceptionHandler; +import it.pagopa.selfcare.user_group.model.mapper.UserGroupMapperImpl; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.data.domain.Pageable; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import java.util.List; +import java.util.Set; +import java.util.UUID; + +import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; +import static java.util.UUID.randomUUID; +import static org.hamcrest.Matchers.*; +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; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + + +@WebMvcTest(value = {UserGroupV1Controller.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class) +@ContextConfiguration(classes = { + UserGroupV1Controller.class, + UserGroupExceptionHandler.class, + WebTestConfig.class, + UserGroupMapperImpl.class +}) +class UserGroupV1ControllerTest { + + private static final DummyCreateUserGroupDto CREATE_USER_GROUP_DTO = mockInstance(new DummyCreateUserGroupDto()); + private static final DummyUpdateUserGroupDto UPDATE_USER_GROUP_DTO = mockInstance(new DummyUpdateUserGroupDto()); + private static final String BASE_URL = "/v1/user-groups"; + + @MockBean + private UserGroupService groupServiceMock; + + @Autowired + protected MockMvc mvc; + + @Autowired + protected ObjectMapper mapper; + + @Captor + private ArgumentCaptor pageableCaptor; + + @Test + void createGroup() throws Exception { + //given + when(groupServiceMock.createGroup(any(UserGroupOperations.class))) + .thenAnswer(invocationOnMock -> invocationOnMock.getArgument(0, UserGroupOperations.class)); + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .post(BASE_URL) + .content(mapper.writeValueAsString(CREATE_USER_GROUP_DTO)) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isCreated()) + .andReturn(); + //then + UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); + assertNotNull(group); + assertEquals(CREATE_USER_GROUP_DTO.getDescription(), group.getDescription()); + assertEquals(CREATE_USER_GROUP_DTO.getName(), group.getName()); + assertEquals(CREATE_USER_GROUP_DTO.getInstitutionId(), group.getInstitutionId()); + assertEquals(CREATE_USER_GROUP_DTO.getProductId(), group.getProductId()); + assertEquals(CREATE_USER_GROUP_DTO.getStatus(), group.getStatus()); + assertEquals(CREATE_USER_GROUP_DTO.getMembers(), group.getMembers()); + } + + @Test + void deleteGroup_doesNotExists() throws Exception { + //given + Mockito.doThrow(ResourceNotFoundException.class) + .when(groupServiceMock).deleteGroup(Mockito.anyString()); + //when + mvc.perform(MockMvcRequestBuilders + .delete(BASE_URL + "/id") + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNotFound()) + .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) + .andExpect(content().string(not(emptyString()))); + //then + } + + @Test + void deleteGroup() throws Exception { + Mockito.doNothing() + .when(groupServiceMock).deleteGroup(Mockito.anyString()); + // when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .delete(BASE_URL + "/id") + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().is2xxSuccessful()) + .andReturn(); + // then + assertEquals("", result.getResponse().getContentAsString()); + verify(groupServiceMock, times(1)) + .deleteGroup(Mockito.anyString()); + Mockito.verifyNoMoreInteractions(groupServiceMock); + + } + + @Test + void activateGroup_doesNotExists() throws Exception { + //given + String groupId = "groupId"; + Mockito.doThrow(ResourceNotFoundException.class) + .when(groupServiceMock).activateGroup(Mockito.anyString()); + //when + mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/{id}/activate", groupId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNotFound()) + .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) + .andExpect(content().string(not(emptyString()))); + //then + } + + @Test + void activateGroup() throws Exception { + //given + String groupId = "groupId"; + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/{id}/activate", groupId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()) + .andReturn(); + //then + assertEquals(0, result.getResponse().getContentLength()); + verify(groupServiceMock, times(1)) + .activateGroup(groupId); + Mockito.verifyNoMoreInteractions(groupServiceMock); + } + + @Test + void suspendGroup_doesNotExists() throws Exception { + //given + String groupId = "groupId"; + Mockito.doThrow(ResourceNotFoundException.class) + .when(groupServiceMock).suspendGroup(Mockito.anyString()); + //when + mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/{id}/suspend", groupId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNotFound()) + .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) + .andExpect(content().string(not(emptyString()))); + //then + } + + @Test + void suspendGroup() throws Exception { + //given + String groupId = "groupId"; + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .post(BASE_URL + "/{id}/suspend", groupId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()) + .andReturn(); + //then + assertEquals(0, result.getResponse().getContentLength()); + verify(groupServiceMock, times(1)) + .suspendGroup(groupId); + Mockito.verifyNoMoreInteractions(groupServiceMock); + } + + @Test + void updateGroup_exists() throws Exception { + //given + when(groupServiceMock.updateGroup(Mockito.anyString(), any(UserGroupOperations.class))) + .thenAnswer(invocationOnMock -> { + String id = invocationOnMock.getArgument(0, String.class); + UserGroupOperations group = invocationOnMock.getArgument(1, UserGroupOperations.class); + group.setId(id); + group.setMembers(Set.of(randomUUID().toString(), randomUUID().toString())); + return group; + }); + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .put(BASE_URL + "/id") + .content(mapper.writeValueAsString(UPDATE_USER_GROUP_DTO)) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().is2xxSuccessful()) + .andReturn(); + //then + UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); + + assertNotNull(group); + assertEquals(UPDATE_USER_GROUP_DTO.getDescription(), group.getDescription()); + assertEquals(UPDATE_USER_GROUP_DTO.getName(), group.getName()); + assertNotEquals(UPDATE_USER_GROUP_DTO.getMembers().size(), group.getMembers().size()); + } + + @Test + void addMember() throws Exception { + //given + String groupId = "groupId"; + MemberUUID member = new MemberUUID(); + member.setMember(randomUUID()); + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .put(BASE_URL + "/groupId/members/" + member.getMember()) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().is2xxSuccessful()) + .andReturn(); + //then + assertEquals(0, result.getResponse().getContentLength()); + verify(groupServiceMock, times(1)) + .addMember(groupId, member.getMember()); + Mockito.verifyNoMoreInteractions(groupServiceMock); + } + + @Test + void deleteMember() throws Exception { + //given + String groupId = "groupId"; + UUID memberId = randomUUID(); + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .delete(BASE_URL + "/groupId/members/" + memberId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()) + .andReturn(); + //then + assertEquals(0, result.getResponse().getContentLength()); + verify(groupServiceMock, times(1)) + .deleteMember(groupId, memberId.toString()); + Mockito.verifyNoMoreInteractions(groupServiceMock); + } + + @Test + void getUserGroup() throws Exception { + //given + String InstitutionId = "institutionId"; + String productId = "productId"; + when(groupServiceMock.getUserGroup(Mockito.anyString())) + .thenAnswer(invocationOnMock -> { + String id = invocationOnMock.getArgument(0, String.class); + UserGroupOperations group = mockInstance(new GroupDto(), "setId"); + group.setId(id); + group.setMembers(Set.of(randomUUID().toString(), randomUUID().toString())); + return group; + }); + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .get(BASE_URL + "/groupId") + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().is2xxSuccessful()) + .andReturn(); + //then + UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); + assertNotNull(group); + } + + @Test + void getUserGroups() throws Exception { + //given + String institutionId = "institutionId"; + String productId = "productId"; + String userId = randomUUID().toString(); + UserGroupStatus allowedStatus = UserGroupStatus.ACTIVE; + final int page = 1; + final int size = 3; + UserGroupOperations groupOperations = mockInstance(new GroupDto()); + groupOperations.setMembers(Set.of(randomUUID().toString())); + when(groupServiceMock.getUserGroups(any(), any())) + .thenAnswer(invocation -> { + final Pageable pageable = invocation.getArgument(1, Pageable.class); + return getPage(List.of(groupOperations), pageable, () -> pageable.isPaged() + ? (long) pageable.getPageSize() * pageable.getPageNumber() + 1 + : 1); + }); + //when + mvc.perform(MockMvcRequestBuilders + .get(BASE_URL + "/") + .param("institutionId", institutionId) + .param("productId", productId) + .param("userId", userId) + .param("status", String.valueOf(allowedStatus)) + .param("page", String.valueOf(page)) + .param("size", String.valueOf(size)) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.number", notNullValue())) + .andExpect(jsonPath("$.size", notNullValue())) + .andExpect(jsonPath("$.totalElements", notNullValue())) + .andExpect(jsonPath("$.totalPages", notNullValue())) + .andExpect(jsonPath("$.content", notNullValue())) + .andExpect(jsonPath("$.content[0].id", notNullValue())) + .andExpect(jsonPath("$.content[0].institutionId", notNullValue())) + .andExpect(jsonPath("$.content[0].productId", notNullValue())) + .andExpect(jsonPath("$.content[0].name", notNullValue())) + .andExpect(jsonPath("$.content[0].description", notNullValue())) + .andExpect(jsonPath("$.content[0].status", notNullValue())) + .andExpect(jsonPath("$.content[0].members", not(emptyArray()))) + .andExpect(jsonPath("$.content[0].createdAt", notNullValue())) + .andExpect(jsonPath("$.content[0].createdBy", notNullValue())) + .andExpect(jsonPath("$.content[0].modifiedAt", notNullValue())) + .andExpect(jsonPath("$.content[0].modifiedBy", notNullValue())); + //then + ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(UserGroupFilter.class); + verify(groupServiceMock, times(1)) + .getUserGroups(filterCaptor.capture(), pageableCaptor.capture()); + UserGroupFilter capturedFilter = filterCaptor.getValue(); + assertEquals(capturedFilter.getProductId(), productId); + assertEquals(capturedFilter.getInstitutionId(), institutionId); + assertEquals(capturedFilter.getUserId(), userId); + Pageable capturedPageable = pageableCaptor.getValue(); + assertTrue(capturedPageable.getSort().isUnsorted()); + assertEquals(page, capturedPageable.getPageNumber()); + assertEquals(size, capturedPageable.getPageSize()); + } + + @Test + void deleteMembers() throws Exception { + //given + UUID memberId = randomUUID(); + String institutionId = "institutionId"; + String productId = "productId"; + //when + MvcResult result = mvc.perform(MockMvcRequestBuilders + .delete(BASE_URL + "/members/" + memberId) + .param("institutionId", institutionId) + .param("productId", productId) + .contentType(APPLICATION_JSON_VALUE) + .accept(APPLICATION_JSON_VALUE)) + .andExpect(status().isNoContent()) + .andReturn(); + //then + assertEquals(0, result.getResponse().getContentLength()); + verify(groupServiceMock, times(1)) + .deleteMembers(memberId.toString(), institutionId, productId); + Mockito.verifyNoMoreInteractions(groupServiceMock); + } + +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java new file mode 100644 index 00000000..0c4dd897 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java @@ -0,0 +1,375 @@ +package it.pagopa.selfcare.user_group.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.config.CoreConfig; +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 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, CoreConfig.class}) +class UserGroupRepositoryTest { + + @Autowired + private UserGroupRepository repository; + + @Autowired + private MongoTemplate mongoTemplate; + + @Autowired + private AuditorAware auditorAware; + + @AfterEach + void clear() { + repository.deleteAll(); + } + + + @Test + void create() { + //given + 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", + "setCreatedBy", + "setModifiedAt", + "setModifiedBy"); + group.setCreatedBy(selfCareUser.getId()); + //when + UserGroupEntity savedGroup = repository.insert(group); + //then + 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", + "setCreatedBy", + "setModifiedAt", + "setModifiedBy"); + group.setCreatedAt(now); + UserGroupEntity savedGroup = repository.insert(group); + + Optional groupMod = repository.findById(savedGroup.getId()); + groupMod.get().setId(savedGroup.getId()); + groupMod.get().setModifiedBy(selfCareUser.getId()); + groupMod.get().setModifiedAt(Instant.now()); + 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", + "setCreatedBy", + "setModifiedAt", + "setModifiedBy"); + group.setCreatedBy(selfCareUser.getId()); + 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", + "setCreatedBy", + "setModifiedAt", + "setModifiedBy"); + group.setCreatedBy(selfCareUser.getId()); + group.setModifiedBy(selfCareUser.getId()); + UserGroupEntity savedGroup = repository.insert(group); + 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-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java new file mode 100644 index 00000000..b73c859d --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java @@ -0,0 +1,68 @@ +package it.pagopa.selfcare.user_group.handler; + +import it.pagopa.selfcare.commons.web.model.Problem; +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 org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.http.ResponseEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.springframework.http.HttpStatus.*; + +class UserGroupExceptionHandlerTest { + private static final String DETAIL_MESSAGE = "detail message"; + private final UserGroupExceptionHandler handler = new UserGroupExceptionHandler(); + + + @Test + void resourceNotFoundException() { + //given + ResourceNotFoundException mockException = Mockito.mock(ResourceNotFoundException.class); + Mockito.when(mockException.getMessage()) + .thenReturn(DETAIL_MESSAGE); + //when + ResponseEntity responseEntity = handler.handleResourceNotFoundException(mockException); + //then + assertNotNull(responseEntity); + assertEquals(NOT_FOUND, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); + assertEquals(NOT_FOUND.value(), responseEntity.getBody().getStatus()); + } + + @Test + void resourceAlreadyExistsException() { + //given + ResourceAlreadyExistsException mockException = Mockito.mock(ResourceAlreadyExistsException.class); + Mockito.when(mockException.getMessage()) + .thenReturn(DETAIL_MESSAGE); + //when + ResponseEntity responseEntity = handler.handleResourceAlreadyExistsException(mockException); + //then + assertNotNull(responseEntity); + assertEquals(CONFLICT, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); + assertEquals(CONFLICT.value(), responseEntity.getBody().getStatus()); + } + + @Test + void resourceUpdateException() { + //given + ResourceUpdateException mockException = Mockito.mock(ResourceUpdateException.class); + Mockito.when(mockException.getMessage()) + .thenReturn(DETAIL_MESSAGE); + //when + ResponseEntity responseEntity = handler.handleResourceUpdateException(mockException); + //then + assertNotNull(responseEntity); + assertEquals(BAD_REQUEST, responseEntity.getStatusCode()); + assertNotNull(responseEntity.getBody()); + assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); + assertEquals(BAD_REQUEST.value(), responseEntity.getBody().getStatus()); + } + +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java new file mode 100644 index 00000000..24fb557d --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java @@ -0,0 +1,73 @@ +package it.pagopa.selfcare.user_group.model; + +import it.pagopa.selfcare.commons.utils.TestUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class CreateUserGroupDtoTest { + private Validator validator; + + @BeforeEach + void setUp() { + ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + validator = validatorFactory.getValidator(); + } + + @Test + void validateNullFields() { + // given + HashMap> toCheckMap = new HashMap<>(); + toCheckMap.put("institutionId", NotBlank.class); + toCheckMap.put("productId", NotBlank.class); + toCheckMap.put("name", NotBlank.class); + toCheckMap.put("description", NotBlank.class); + toCheckMap.put("status", NotNull.class); + toCheckMap.put("members", NotEmpty.class); + CreateUserGroupDto createUserGroupDto = new CreateUserGroupDto(); + createUserGroupDto.setDescription(null); + createUserGroupDto.setMembers(null); + createUserGroupDto.setName(null); + createUserGroupDto.setStatus(null); + createUserGroupDto.setProductId(null); + createUserGroupDto.setInstitutionId(null); + // when + Set> violations = validator.validate(createUserGroupDto); + // then + assertFalse(violations.isEmpty()); + List> filteredViolations = violations.stream() + .filter(violation -> { + Class annotationToCheck = toCheckMap.get(violation.getPropertyPath().toString()); + return !violation.getConstraintDescriptor().getAnnotation().annotationType().equals(annotationToCheck); + }) + .collect(Collectors.toList()); + assertTrue(filteredViolations.isEmpty()); + } + + @Test + void validateNotNullFields() { + // given + CreateUserGroupDto userGroupDto = TestUtils.mockInstance(new CreateUserGroupDto()); + userGroupDto.setMembers(Set.of(UUID.randomUUID())); + // when + Set> violations = validator.validate(userGroupDto); + // then + assertTrue(violations.isEmpty()); + } +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java new file mode 100644 index 00000000..e0ea7346 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java @@ -0,0 +1,17 @@ +package it.pagopa.selfcare.user_group.model; + +import lombok.Data; + +import java.util.List; +import java.util.UUID; + +@Data +public class DummyCreateUserGroupDto { + + private String institutionId; + private String productId; + private String name; + private String description; + private UserGroupStatus status; + private List members = List.of(UUID.randomUUID()); +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java new file mode 100644 index 00000000..7469d808 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java @@ -0,0 +1,24 @@ +package it.pagopa.selfcare.user_group.model; + +import it.pagopa.selfcare.user_group.api.UserGroupOperations; +import lombok.Data; + +import java.time.Instant; +import java.util.Set; + +@Data +public class DummyGroup implements UserGroupOperations { + + + private String id; + private String institutionId; + private String productId; + private String name; + private String description; + private UserGroupStatus status = UserGroupStatus.ACTIVE; + private Set members = Set.of("string1", "string2"); + private Instant createdAt; + private String createdBy; + private Instant modifiedAt; + private String modifiedBy; +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java new file mode 100644 index 00000000..c7f74db3 --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java @@ -0,0 +1,13 @@ +package it.pagopa.selfcare.user_group.model; + +import lombok.Data; + +import java.util.List; +import java.util.UUID; + +@Data +public class DummyUpdateUserGroupDto { + private String name; + private String description; + private List members = List.of(UUID.randomUUID()); +} diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java new file mode 100644 index 00000000..2d4bff0b --- /dev/null +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java @@ -0,0 +1,68 @@ +package it.pagopa.selfcare.user_group.model; + +import it.pagopa.selfcare.commons.utils.TestUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import javax.validation.ConstraintViolation; +import javax.validation.Validation; +import javax.validation.Validator; +import javax.validation.ValidatorFactory; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.lang.annotation.Annotation; +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class UpdateUserGroupDtoTest { + private Validator validator; + + @BeforeEach + void setUp() { + ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); + validator = validatorFactory.getValidator(); + } + + @Test + void validateNullFields() { + // given + HashMap> toCheckMap = new HashMap<>(); + toCheckMap.put("name", NotBlank.class); + toCheckMap.put("description", NotBlank.class); + toCheckMap.put("members", NotEmpty.class); + UpdateUserGroupDto updateUserGroupDto = new UpdateUserGroupDto(); + updateUserGroupDto.setDescription(null); + updateUserGroupDto.setMembers(null); + updateUserGroupDto.setName(null); + + // when + Set> violations = validator.validate(updateUserGroupDto); + // then + assertFalse(violations.isEmpty()); + List> filteredViolations = violations.stream() + .filter(violation -> { + Class annotationToCheck = toCheckMap.get(violation.getPropertyPath().toString()); + return !violation.getConstraintDescriptor().getAnnotation().annotationType().equals(annotationToCheck); + }) + .collect(Collectors.toList()); + assertTrue(filteredViolations.isEmpty()); + } + + @Test + void validateNotNullFields() { + // given + UpdateUserGroupDto userGroupDto = TestUtils.mockInstance(new UpdateUserGroupDto()); + userGroupDto.setMembers(Set.of(UUID.randomUUID())); + // when + Set> violations = validator.validate(userGroupDto); + // then + assertTrue(violations.isEmpty()); + } + +} \ No newline at end of file diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java new file mode 100644 index 00000000..9baac4cc --- /dev/null +++ b/apps/user-group-ms-2/app/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.commons.base.security.SelfCareUser; +import it.pagopa.selfcare.commons.utils.TestUtils; +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 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 + javax.validation.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-2/lombok.config b/apps/user-group-ms-2/lombok.config new file mode 100644 index 00000000..8f7e8aa1 --- /dev/null +++ b/apps/user-group-ms-2/lombok.config @@ -0,0 +1 @@ +lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/apps/user-group-ms-2/mvnw b/apps/user-group-ms-2/mvnw new file mode 100644 index 00000000..a16b5431 --- /dev/null +++ b/apps/user-group-ms-2/mvnw @@ -0,0 +1,310 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + PRG="$0" + + # need this for relative symlinks + while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG="`dirname "$PRG"`/$link" + fi + done + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/apps/user-group-ms-2/mvnw.cmd b/apps/user-group-ms-2/mvnw.cmd new file mode 100644 index 00000000..c8d43372 --- /dev/null +++ b/apps/user-group-ms-2/mvnw.cmd @@ -0,0 +1,182 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/apps/user-group-ms-2/pom.xml b/apps/user-group-ms-2/pom.xml new file mode 100644 index 00000000..3dba12ab --- /dev/null +++ b/apps/user-group-ms-2/pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + + + it.pagopa.selfcare + selc-starter-parent + 0.0.3-SNAPSHOT + + + + + user-group-ms-2 + pom + 1.0.0-SNAPSHOT + user-group-ms + Microservice to manage Self Care User Group + + + 2.5.1 + https://sonarcloud.io/ + true + + + + + it.pagopa.selfcare + selc-commons-base + ${selc-commons.version} + + + 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 + selc-commons-base + + + + org.owasp.encoder + encoder + 1.2.3 + + + + it.pagopa.selfcare + selc-commons-base + test-jar + test + + + + + app + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.10.0.2594 + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + + + + org.jacoco + jacoco-maven-plugin + + + default-prepare-agent + + prepare-agent + + + true + + + + + report + test + + report + + + + + + + + + + + selfcare-platform + + https://pkgs.dev.azure.com/pagopaspa/selfcare-platform-app-projects/_packaging/selfcare-platform/maven/v1 + + + + From e45cd684ce32598006096b51c67745344ce87daa Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Wed, 11 Dec 2024 22:57:27 +0100 Subject: [PATCH 2/8] [SELC-5969] First commit for cucumber --- apps/cucumber/pom.xml | 130 +++++++++ .../cucumber/SelfCareCucumberApplication.java | 17 ++ .../selfcare/cucumber/dao/CucumberConfig.java | 9 + .../cucumber/dao/UserGroupRepository.java | 8 + .../cucumber/model/UserGroupEntity.java | 24 ++ .../model/UserGroupEntityPageable.java | 14 + .../cucumber/model/UserGroupStatus.java | 7 + .../src/main/resources/application.properties | 3 + .../src/main/resources/application.yml | 31 +++ .../selfcare/cucumber/CucumberTest.java | 12 + .../cucumber/config/CucumberTestConfig.java | 11 + .../cucumber/steps/CreateUserGroupSteps.java | 164 +++++++++++ .../steps/RetrieveUserGroupSteps.java | 162 +++++++++++ .../cucumber/steps/UpdateUserGroupSteps.java | 258 ++++++++++++++++++ .../cucumber/steps/UserGroupMemberSteps.java | 116 ++++++++ .../cucumber/steps/UserGroupSteps.java | 35 +++ .../cucumber/utils/DataTypeConverter.java | 6 + .../resources/application.test.properties | 3 + .../src/test/resources/cucumber.properties | 3 + .../cucumber/scenarios/createGroup.feature | 91 ++++++ .../scenarios/retrieveUserGroup.feature | 56 ++++ .../scenarios/updateUserGroup.feature | 69 +++++ .../scenarios/userGroupMembers.feature | 66 +++++ .../test/resources/dataPopulation/data.yaml | 1 + .../dataPopulation/groupEntities.json | 41 +++ 25 files changed, 1337 insertions(+) create mode 100644 apps/cucumber/pom.xml create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java create mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java create mode 100644 apps/cucumber/src/main/resources/application.properties create mode 100644 apps/cucumber/src/main/resources/application.yml create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java create mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java create mode 100644 apps/cucumber/src/test/resources/application.test.properties create mode 100644 apps/cucumber/src/test/resources/cucumber.properties create mode 100644 apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature create mode 100644 apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature create mode 100644 apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature create mode 100644 apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature create mode 100644 apps/cucumber/src/test/resources/dataPopulation/data.yaml create mode 100644 apps/cucumber/src/test/resources/dataPopulation/groupEntities.json diff --git a/apps/cucumber/pom.xml b/apps/cucumber/pom.xml new file mode 100644 index 00000000..ff505c6a --- /dev/null +++ b/apps/cucumber/pom.xml @@ -0,0 +1,130 @@ + + + + selc-starter-parent + it.pagopa.selfcare + 0.0.3-SNAPSHOT + + 4.0.0 + + + 17 + 17 + UTF-8 + 2.5.1 + + + selfcare-cucumber + + + + io.cucumber + cucumber-java + 7.20.1 + + + + 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 + + + io.cucumber + cucumber-junit-platform-engine + 7.20.1 + test + + + + org.junit.platform + junit-platform-suite-api + 1.11.3 + test + + + io.cucumber + cucumber-spring + 7.19.0 + + + org.springframework.boot + spring-boot-starter + 3.4.0 + + + org.springframework.boot + spring-boot-starter-data-mongodb + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + 2.17.0 + test + + + + + + + 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 + + + + + + org.apache.maven.plugins + maven-jar-plugin + + true + + + + + test-jar + + + + + + + + diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java new file mode 100644 index 00000000..c96ddce9 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java @@ -0,0 +1,17 @@ +package it.pagopa.selfcare.cucumber; + +import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ApplicationContext; + +@SpringBootApplication +public class SelfCareCucumberApplication { + + + public static void main(String[] args) { + SpringApplication.run(SelfCareCucumberApplication.class, args); + } + +} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java new file mode 100644 index 00000000..d9a77568 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java @@ -0,0 +1,9 @@ +package it.pagopa.selfcare.cucumber.dao; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("classpath:application.properties") +public class CucumberConfig { +} \ No newline at end of file diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java new file mode 100644 index 00000000..784978f6 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java @@ -0,0 +1,8 @@ +package it.pagopa.selfcare.cucumber.dao; + +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import org.springframework.data.mongodb.repository.MongoRepository; + +public interface UserGroupRepository extends MongoRepository { + +} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java new file mode 100644 index 00000000..0af60294 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java @@ -0,0 +1,24 @@ +package it.pagopa.selfcare.cucumber.model; + +import lombok.Data; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.Instant; +import java.util.Set; + +@Data +@Document("UserGroups") +public class UserGroupEntity{ + + private String id; + private String institutionId; + private String productId; + private String name; + private String description; + private UserGroupStatus status; + private Set members; + private Instant createdAt; + private String createdBy; + private Instant modifiedAt; + private String modifiedBy; +} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java new file mode 100644 index 00000000..6ed80239 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java @@ -0,0 +1,14 @@ +package it.pagopa.selfcare.cucumber.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/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java new file mode 100644 index 00000000..5c5505f7 --- /dev/null +++ b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java @@ -0,0 +1,7 @@ +package it.pagopa.selfcare.cucumber.model; + +public enum UserGroupStatus { + ACTIVE, + SUSPENDED, + DELETED +} diff --git a/apps/cucumber/src/main/resources/application.properties b/apps/cucumber/src/main/resources/application.properties new file mode 100644 index 00000000..65e9fa5f --- /dev/null +++ b/apps/cucumber/src/main/resources/application.properties @@ -0,0 +1,3 @@ +user-group.allowed.sorting.parameters=name +spring.data.mongodb.uri=mongodb://localhost:27017 +spring.data.mongodb.database=selcUserGroup diff --git a/apps/cucumber/src/main/resources/application.yml b/apps/cucumber/src/main/resources/application.yml new file mode 100644 index 00000000..02599b30 --- /dev/null +++ b/apps/cucumber/src/main/resources/application.yml @@ -0,0 +1,31 @@ +server: + port: 8080 + +spring: + application: + name: "@project.parent.artifactId@" + version: "@project.version@" + profiles: + include: + # TO enable specific-language documentations + - swaggerEN + zipkin: + enabled: false + sleuth: + baggage: + remote-fields: X-Client-Ip + correlation-fields: X-Client-Ip + +info: + build: + artifact: "@project.parent.artifactId@" + name: "@project.parent.artifactId@" + description: "@project.description@" + version: "@project.version@" + + +logging: + level: + it.pagopa.selfcare: DEBUG + pattern: + additional-info: ",%X{X-Client-Ip:-}]" diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java new file mode 100644 index 00000000..98ef9532 --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java @@ -0,0 +1,12 @@ +package it.pagopa.selfcare.cucumber; + +import org.junit.platform.suite.api.IncludeEngines; +import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.Suite; + +@Suite +@IncludeEngines("cucumber") +@SelectClasspathResource("cucumber") +public class CucumberTest { +} + diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java new file mode 100644 index 00000000..44889c2e --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java @@ -0,0 +1,11 @@ +package it.pagopa.selfcare.cucumber.config; + +import io.cucumber.spring.CucumberContextConfiguration; +import it.pagopa.selfcare.cucumber.SelfCareCucumberApplication; +import org.springframework.boot.test.context.SpringBootTest; + +@CucumberContextConfiguration +@SpringBootTest(classes = SelfCareCucumberApplication.class) +public class CucumberTestConfig { + +} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java new file mode 100644 index 00000000..eec63e5d --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java @@ -0,0 +1,164 @@ +package it.pagopa.selfcare.cucumber.steps; + +import com.fasterxml.jackson.databind.ObjectMapper; +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 it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import it.pagopa.selfcare.cucumber.model.UserGroupStatus; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +public class CreateUserGroupSteps extends UserGroupSteps{ + + @Autowired + private UserGroupRepository userGroupRepository; + + @Autowired + private ObjectMapper objectMapper; + + List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + + @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") + public void iSendAPOSTRequestToWithTheGivenDetails(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .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(); + } + } + + @When("I send a POST request to {string} with the given details without authentication") + public void iSendAPOSTRequestToWithTheGivenDetailsWithoutAuthentication(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + null) + .body(userGroupDetails) + .when() + .post(url) + .then() + .extract(); + + status = response.statusCode(); + } + + @Given("the following user group details:") + public void givenUserGroupDetails(List userGroupEntityList) { + if (userGroupEntityList != null && userGroupEntityList.size() == 1) + this.userGroupDetails = userGroupEntityList.get(0); + } + + // Step per verificare lo stato della risposta + @Then("the response status should be {int}") + public void verifyResponseStatus(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); + } + + // Step per verificare che la risposta contenga un gruppo utente valido + @Then("the response should contain a valid user group resource with name {string}") + public void verifyUserGroupName(String expectedName) { + Assertions.assertEquals(expectedName, userGroupEntityResponse.getName()); + } + + // Step per verificare un messaggio di errore nella risposta + @Then("the response should contain an error message {string}") + public void verifyErrorMessage(String expectedErrorMessage) { + String[] errorMessageArray = expectedErrorMessage.split(","); + Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + } + + // Step per verificare che la risposta contenga un determinato campo + @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() { + Assertions.assertNotNull(userGroupEntityResponse.getCreatedAt()); + } + + + @And("the response should contain the modified data null") + public void theResponseShouldContainTheModifiedDataNull() { + Assertions.assertNull(userGroupEntityResponse.getModifiedAt()); + Assertions.assertNull(userGroupEntityResponse.getModifiedBy()); + } + + @And("the response should contain the description {string}") + public void theResponseShouldContainTheDescription(String expectedDescription) { + Assertions.assertEquals(expectedDescription, userGroupEntityResponse.getDescription()); + } + + @Before("@DuplicateGroupName") + public void beforeScenarioOfCreateDuplicatedGroup() 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("@DuplicateGroupName") + public void afterScenarioOfCreateDuplicatedGroup() { + userGroupRepository.deleteAllById(userGroupsIds); + } + + @After("@CreateNewGroup") + public void afterScenarioOfCreateGroup() { + userGroupRepository.deleteById(userGroupId); + } +} + diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java new file mode 100644 index 00000000..29bc5655 --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java @@ -0,0 +1,162 @@ +package it.pagopa.selfcare.cucumber.steps; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.response.Response; +import io.restassured.response.ResponseOptions; +import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + + +public class RetrieveUserGroupSteps extends UserGroupSteps{ + + @Autowired + private UserGroupRepository userGroupRepository; + + @Autowired + private ObjectMapper objectMapper; + + List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + + + @Given("I have an empty group ID") + public void i_have_an_empty_group_ID() { + userGroupId = ""; + } + + @Given("I have a suspended group ID {string}") + public void i_have_a_suspended_group_ID(String suspendedGroupId) { + userGroupId = suspendedGroupId; + } + + @When("I send a GET request to") + public void i_send_a_GET_request_to_with_the_group_id(String endpoint) { + ResponseOptions response = RestAssured.given() + .pathParam("id", userGroupId) + .when() + .get(endpoint); + status = response.statusCode(); + if(status == 200) { + userGroupEntityResponse = response.getBody().as(UserGroupEntity.class); + }else{ + errorMessage = response.getBody().asString(); + } + } + + @Then("the response should contain the group details") + public void the_response_should_contain_the_group_details() { + // Verifica che la risposta contenga i dettagli del gruppo, per esempio controllando un campo specifico + // assert(responseBody.contains("groupName")); // Supponiamo che la risposta contenga un campo "groupName" + } + + @When("I send a GET request to {string}") + public void iSendAGETRequestTo(String arg0) { + + } + + @And("the response should contain the suspended group details") + public void theResponseShouldContainTheSuspendedGroupDetails() { + + } + + @Given("I have valid filters institutionId {string} productId {string} and status {string}") + public void iHaveValidFiltersAndAnd(String institutionId, String productId, String status) { + + } + + @And("the response should contain user groups data") + public void theResponseShouldContainUserGroupsData() { + + } + + @Given("I have no filters") + public void iHaveNoFilters() { + + } + + @Given("I have invalid filters {string} and {string}") + public void iHaveInvalidFiltersAnd(String arg0, String arg1) { + + } + + @Given("I have a filter with sorting by {string} but no {string} or {string}") + public void iHaveAFilterWithSortingByButNoOr(String arg0, String arg1, String arg2) { + + } + + @Given("I have a filter with status {string} but no {string}, {string}, or {string}") + public void iHaveAFilterWithStatusButNoOr(String arg0, String arg1, String arg2, String arg3) { + + } + + @Given("I have valid filters {string} and {string}") + public void iHaveValidFiltersAnd(String arg0, String arg1) { + + } + + @And("I set the page number to {int} and page size to {int}") + public void iSetThePageNumberToAndPageSizeTo(int arg0, int arg1) { + + } + + @And("the response should contain a paginated list of user groups") + public void theResponseShouldContainAPaginatedListOfUserGroups() { + + } + + @Given("I have filters {string} and {string}") + public void iHaveFiltersAnd(String arg0, String arg1) { + + } + + @And("the response should contain an empty list") + public void theResponseShouldContainAnEmptyList() { + + } + + @Before("@FirstRetrieveUserGroupScenario") + 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("@LastRetrieveUserGroupScenario") + public void afterFeature() { + userGroupRepository.deleteAllById(userGroupsIds); + } + + @And("the response of retrieve operation should contain an error message {string}") + public void verifyErrorMessage(String expectedErrorMessage) { + String[] errorMessageArray = expectedErrorMessage.split(","); + Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + } + + @And("the response should contain {int} item") + public void theResponseShouldContainOneItem(int expectedItemsCount) { + + } + + @And("the response should contain valid data") + public void theResponseShouldContainValidData() { + } + + @Then("I should receive a response of retrieve user group operation with status code {int}") + public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); + } +} + diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java new file mode 100644 index 00000000..eb591be4 --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java @@ -0,0 +1,258 @@ +package it.pagopa.selfcare.cucumber.steps; + +import com.fasterxml.jackson.databind.ObjectMapper; +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 it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class UpdateUserGroupSteps extends UserGroupSteps { + + @Autowired + private UserGroupRepository userGroupRepository; + + @Autowired + private ObjectMapper objectMapper; + + List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + + @Given("I retrieve to update Group a group Id for product {string} and institution {string}") + public void iRetrieveAGroupIdForProductAndInstitution(String productId, String institutionId) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .queryParams("productId", productId, "institutionId", institutionId) + .when() + .get("/v1/user-groups") + .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("I should receive a response with status code {int}") + public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); + } + + // Step per verificare un messaggio di errore nella risposta + @Then("the response of update operation should contain an error message {string}") + public void verifyErrorMessage(String expectedErrorMessage) { + String[] errorMessageArray = expectedErrorMessage.split(","); + Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + } + + + @When("I send a POST request to suspendAPI with retrieved groupId") + public void iSendAPOSTRequestToSuspendAPIWithRetrieveGroupId() { + callSuspendApi(); + } + + + @When("I send a POST request to suspendAPI without groupId") + public void iSendAPOSTRequestToSuspendAPIWithoutGroupId() { + callSuspendApi(); + } + + + @When("I send a POST request to suspendAPI with not existent groupId") + public void iSendAPOSTRequestToSuspendAPIWithNonExistentGroupId() { + callSuspendApi(); + } + + private void callSuspendApi() { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .when() + .post("/v1/user-groups/" + this.userGroupId + "/suspend") + .then() + .extract(); + + this.status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } + } + + @When("I send a POST request to deleteAPI with retrieve groupId") + public void iSendAPOSTRequestToDeleteAPIWithRetrieveGroupId() { + callDeleteApi(); + } + + @When("I send a POST request to deleteAPI with not existent groupId") + public void iSendAPOSTRequestToDeleteAPIWithNonExistentGroupId() { + callDeleteApi(); + } + + private void callDeleteApi() { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .when() + .delete("/v1/user-groups/" + userGroupId) + .then() + .extract(); + + status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } + } + + + @When("I send a POST request to activateAPI with retrieve groupId") + public void iSendAPOSTRequestToActivateAPIWithRetrieveGroupId() { + callActivateApi(); + } + + @When("I send a POST request to activateAPI with not existent groupId") + public void iSendAPOSTRequestToActivateAPIWithNotExistentGroupId() { + callActivateApi(); + } + + @When("I send a POST request to activateAPI without groupId") + public void iSendAPOSTRequestToActivateAPIWithoutGroupId() { + callActivateApi(); + } + + private void callActivateApi() { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .when() + .post("/v1/user-groups/" + userGroupId + "/activate") + .then() + .extract(); + + status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } + } + + + @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 PUT request to updateAPI with the retrieved group data") + public void iSendAPUTRequestToUpdateAPIWithTheRetrievedGroupData() { + callUpdateApi(); + } + + @When("I send a PUT request to updateAPI with the group data") + public void iSendAPUTRequestToUpdateAPIWithTheGroupData() { + callUpdateApi(); + } + + private void callUpdateApi() { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .body(userGroupDetails) + .when() + .put("/v1/user-groups/" + userGroupId) + .then() + .extract(); + + status = response.statusCode(); + if(status == 201) { + userGroupEntityResponse = response.body().as(UserGroupEntity.class); + userGroupId = userGroupEntityResponse.getId(); + }else { + errorMessage = response.body().asString(); + } + } + + @Given("I have a valid group ID {string}") + public void i_have_a_valid_group_ID(String validGroupId) { + userGroupId = validGroupId; + } + + @Given("I have a non-existent group ID {string}") + public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { + userGroupId = nonExistentGroupId; + } + + @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) { + userGroupEntityResponse = response.body().as(new TypeRef<>() { + }); + Assertions.assertEquals(changedStatus, userGroupEntityResponse.getStatus().name()); + Assertions.assertNotNull(userGroupEntityResponse.getModifiedAt()); + Assertions.assertNotNull(userGroupEntityResponse.getModifiedBy()); + } + } + + @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(userGroupEntityResponse.getName(), updatedUserGroupEntity.getName()); + Assertions.assertNotEquals(userGroupEntityResponse.getDescription(), updatedUserGroupEntity.getDescription()); + Assertions.assertNotEquals(userGroupEntityResponse.getMembers(), updatedUserGroupEntity.getMembers()); + Assertions.assertNotNull(updatedUserGroupEntity.getModifiedAt()); + Assertions.assertNotNull(updatedUserGroupEntity.getModifiedBy()); + } + } + + @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); + } + +} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java new file mode 100644 index 00000000..5b16da52 --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java @@ -0,0 +1,116 @@ +package it.pagopa.selfcare.cucumber.steps; + +import com.fasterxml.jackson.databind.ObjectMapper; +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.response.Response; +import io.restassured.response.ResponseOptions; +import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class UserGroupMemberSteps extends UserGroupSteps { + + @Autowired + private UserGroupRepository userGroupRepository; + + @Autowired + private ObjectMapper objectMapper; + + List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + + @Given("I have a valid group ID {string} and a valid member ID {string}") + public void i_have_a_valid_group_ID_and_a_valid_member_ID(String groupId, String memberId) { + + } + + @Given("I have a non-existent group ID {string} and a valid member ID {string}") + public void i_have_a_non_existent_group_ID_and_a_valid_member_ID(String groupId, String memberId) { + + } + + @Given("I have a suspended group ID {string} and a valid member ID {string}") + public void i_have_a_suspended_group_ID_and_a_valid_member_ID(String groupId, String memberId) { + + } + + @Given("I have a valid group ID {string} and an invalid member ID {string}") + public void i_have_a_valid_group_ID_and_an_invalid_member_ID(String groupId, String 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) { + + } + + @Given("I have a valid group ID {string} and a missing member ID") + public void i_have_a_valid_group_ID_and_a_missing_member_ID(String groupId) { + + } + + @When("I send a PUT request to {string}") + public void i_send_a_PUT_request_to_with_the_group_and_member_ids(String groupId, String memberId) { + ResponseOptions response = RestAssured.given() + .pathParam("id", groupId) + .pathParam("memberId", memberId) + .when() + .put("/groups/{id}/members/{memberId}"); + + } + + @Given("I have a valid member ID {string}, institution ID {string}, and product ID {string}") + public void iHaveAValidMemberIDInstitutionIDAndProductID(String arg0, String arg1, String arg2) { + + } + + @Given("I have a valid member ID {string} and institution ID {string} and a missing product ID") + public void iHaveAValidMemberIDAndInstitutionIDAndAMissingProductID(String arg0, String arg1) { + + } + + @Given("I have a valid member ID {string} and a missing institution ID and product ID {string}") + public void iHaveAValidMemberIDAndAMissingInstitutionIDAndProductID(String arg0, String arg1) { + } + + @When("I send a DELETE request to {string}") + public void iSendADELETERequestTo(String arg0) { + } + + @Before("@FirstGroupMembersScenario") + 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("@LastGroupMembersScenario") + public void afterFeature() { + userGroupRepository.deleteAllById(userGroupsIds); + } + + @And("the response of operation on user group members should contain an error message {string}") + public void verifyErrorMessage(String expectedErrorMessage) { + String[] errorMessageArray = expectedErrorMessage.split(","); + Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + } + + @Then("I should receive a response of operation on user group members with status code {int}") + public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); + } +} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java new file mode 100644 index 00000000..94fd2bcc --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java @@ -0,0 +1,35 @@ +package it.pagopa.selfcare.cucumber.steps; + +import com.fasterxml.jackson.databind.ObjectMapper; +import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import it.pagopa.selfcare.cucumber.model.UserGroupEntityPageable; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +public class UserGroupSteps { + + protected String userGroupId; + protected UserGroupEntity userGroupDetails; + protected UserGroupEntity userGroupEntityResponse; + protected UserGroupEntity updatedUserGroupEntity; + protected UserGroupEntityPageable userGroupEntityResponsePage; + protected int status; + protected String errorMessage; + protected String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTIxMTg1LCJleHAiOjE3MzM5NTM1ODUsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8yMGM3YmY1OTdlY2UyNzYxOTUyNyJ9.pc65diXLGvMEJI1CmVZqtkJLu7QdPPkZ7B8xjbj8gkUEItShV-L25O5JBtexkTIm4YJM86rv4ORiIEISPY1oP9vv1CN6I1DUDJXWhh5uMuvK2_soKzhP5IlyxVGl6GtmpD38Q1YVr0faB7EABwrOVUVYEkufZF0WgzYdYQFgG_YPv5qNqEj9SReC0nWSPP8gM5Z1ARA3mzLccEvLy253uZ1-IBbNhFwf2m0xc97lVSqov0jxYaoudFLd8CHaP9SztrOdzMOTIriicasF7gzDgnhtjR7I9IDmkUVLrKFjpyjsV18XfH3UeHkvdtTdjr8kIdmkJgeh3u-CK_QZWiDy0g"; + + /* public Map readDataPopulation() { + ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); + TypeReference> typeReference = new TypeReference<>() { + }; + Map readValue = new HashMap<>(); + try { + return objectMapper.readValue(new File("src/test/resources/dataPopulation/data.yaml"), typeReference); + } catch (IOException e) { + e.printStackTrace(); + } + return readValue; + }*/ + +} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java new file mode 100644 index 00000000..15e950c7 --- /dev/null +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java @@ -0,0 +1,6 @@ +package it.pagopa.selfcare.cucumber.utils; + +public class DataTypeConverter { + + +} diff --git a/apps/cucumber/src/test/resources/application.test.properties b/apps/cucumber/src/test/resources/application.test.properties new file mode 100644 index 00000000..65e9fa5f --- /dev/null +++ b/apps/cucumber/src/test/resources/application.test.properties @@ -0,0 +1,3 @@ +user-group.allowed.sorting.parameters=name +spring.data.mongodb.uri=mongodb://localhost:27017 +spring.data.mongodb.database=selcUserGroup diff --git a/apps/cucumber/src/test/resources/cucumber.properties b/apps/cucumber/src/test/resources/cucumber.properties new file mode 100644 index 00000000..8c89c962 --- /dev/null +++ b/apps/cucumber/src/test/resources/cucumber.properties @@ -0,0 +1,3 @@ +cucumber.features=classpath:cucumber/scenarios +cucumber.glue=it.pagopa.selfcare.cucumber.steps +cucumber.plugin=pretty,html:target/cucumber-reports diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature new file mode 100644 index 00000000..6f210f1e --- /dev/null +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/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 + Then 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-io | 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 + Then the response status should be 409 + And 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 + Then the response status should be 400 + And 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 + Then the response status should be 400 + And 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 + Then the response status should be 400 + And 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 + Then the response status should be 400 + And 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 + Then the response status should be 400 + And 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 + Then the response status should be 400 + And 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 without authentication + Then the response status should be 401 diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature new file mode 100644 index 00000000..79b4f1f7 --- /dev/null +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature @@ -0,0 +1,56 @@ +Feature: Get User Group + + @FirstRetrieveGroupScenario + Scenario: Successfully retrieve a group with a valid ID + Given I have a valid group ID "6759f8df78b6af202b222d29" + When I send a GET request to "/v1/user-groups/6759f8df78b6af202b222d29" + Then I should receive a response of retrieve user group operation with status code 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 "99999" + When I send a GET request to "/v1/user-groups/99999" + Then I should receive a response of retrieve user group operation with status code 404 + And the response of retrieve operation should contain an error message "User group not found" + + Scenario: Successfully retrieve user groups with valid filters + Given I have valid filters institutionId "9c8ae123-d990-4400-b043-67a60aff31bc" productId "prod-io" and status "ACTIVE" + When I send a GET request to "/v1/user-groups" + Then I should receive a response of retrieve user group operation with status code 200 + And the response should contain 1 item + And the response should contain valid data + + Scenario: Successfully retrieve user groups without any filters + Given I have no filters + When I send a GET request to "/v1/user-groups" + Then I should receive a response of retrieve user group operation with status code 200 + And the response should contain user groups data + And the response should contain 3 item + And the response should contain valid data + + 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 "institutionId" or "productId" + When I send a GET request to "/v1/user-groups" + Then I should receive a response of retrieve user group operation with status code 400 + And the response of retrieve operation should contain an error message "Sorting not allowed without productId or institutionId" + + 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" + Then I should receive a response of retrieve user group operation with status code 400 + And the response of retrieve operation 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 valid filters "institutionId=123" and "productId=abc" + And I set the page number to 1 and page size to 10 + When I send a GET request to "/v1/user-groups" + Then I should receive a response of retrieve user group operation with status code 200 + And the response should contain a paginated list of user groups + + @LastFirstRetrieveGroupScenario + Scenario: No user groups found for the provided filters + Given I have filters "institutionId=9999" and "productId=xyz" + When I send a GET request to "/v1/user-groups" + Then I should receive a response of retrieve user group operation with status code 200 + And the response should contain an empty list + diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature new file mode 100644 index 00000000..706937a8 --- /dev/null +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature @@ -0,0 +1,69 @@ +Feature: Update User Group + + @FirstUpdateScenario + Scenario: Successfully suspend a group with a valid ID + Given I retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + When I send a POST request to suspendAPI with retrieved groupId + Then I should receive a response with status code 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 suspendAPI with not existent groupId + Then I should receive a response with status code 404 + And the response of update operation should contain an error message "Not Found" + + Scenario: Successfully activate a group with a valid ID + Given I retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + When I send a POST request to activateAPI with retrieve groupId + Then I should receive a response with status code 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 activateAPI with not existent groupId + Then I should receive a response with status code 404 + And the response of update operation should contain an error message "Not Found" + + Scenario: Successfully delete a group with a valid ID + Given I retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + When I send a POST request to deleteAPI with retrieve groupId + Then I should receive a response with status code 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 POST request to deleteAPI with not existent groupId + Then I should receive a response with status code 404 + And the response of update operation should contain an error message "Not Found" + + Scenario: Successfully update a group with a valid ID and valid data + Given I retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + 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 updateAPI with the retrieved group data + Then I should receive a response with status code 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 updateAPI with the group data + Then I should receive a response with status code 404 + And the response of update operation should contain an error message "Not Found" + + @LastUpdateScenario + Scenario: Attempt to update a suspended group + Given I retrieve to update Group a group Id for product "prod-interop" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + 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 updateAPI with the retrieved group data + Then I should receive a response with status code 400 + And the response of update operation should contain an error message "Trying to modify suspended group" + + + diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature new file mode 100644 index 00000000..2d00ac11 --- /dev/null +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature @@ -0,0 +1,66 @@ +Feature: User Group Members + + @FirstGroupMembersScenario + Scenario: Successfully add a member to a group + Given I have a valid group ID "12345" and a valid member ID "67890" + When I send a PUT request to "/groups/12345/members/67890" + Then I should receive a response of operation on user group members with status code 204 + + Scenario: Attempt to add a member to a non-existent group + Given I have a non-existent group ID "99999" and a valid member ID "67890" + When I send a PUT request to "/groups/99999/members/67890" + Then I should receive a response of operation on user group members with status code 404 + And the response of operation on user group members should contain an error message "Group not found" + + Scenario: Attempt to add a member to a suspended group + Given I have a suspended group ID "12345" and a valid member ID "67890" + When I send a PUT request to "/groups/12345/members/67890" + Then I should receive a response of operation on user group members with status code 409 + And the response of operation on user group members should contain an error message "Cannot modify a suspended group" + + Scenario: Successfully delete a member from a group + Given I have a valid group ID "12345" and a valid member ID "67890" + When I send a DELETE request to "/groups/12345/members/67890" + Then I should receive a response of operation on user group members with status code 204 + + Scenario: Attempt to delete a member from a non-existent group + Given I have a non-existent group ID "99999" and a valid member ID "67890" + When I send a DELETE request to "/groups/99999/members/67890" + Then I should receive a response of operation on user group members with status code 404 + And the response of operation on user group members should contain an error message "Group not found" + + Scenario: Attempt to delete a member from a suspended group + Given I have a suspended group ID "12345" and a valid member ID "67890" + When I send a DELETE request to "/groups/12345/members/67890" + Then I should receive a response of operation on user group members with status code 409 + And the response of operation on user group members should contain an error message "Cannot modify a suspended group" + + Scenario: Attempt to delete a member with non-existent member ID + Given I have a valid group ID "12345" and an invalid member ID "invalid-id" + When I send a DELETE request to "/groups/12345/members/invalid-id" + Then I should receive a response of operation on user group members with status code 400 + And the response of operation on user group members should contain an error message "Invalid member ID" + + Scenario: Successfully delete a member from all groups associated with institutionId and productId + Given I have a valid member ID "67890", institution ID "institution1", and product ID "product1" + When I send a DELETE request to "/members/67890?institutionId=institution1&productId=product1" + Then I should receive a response of operation on user group members with status code 204 + + Scenario: Attempt to delete a member with a missing institution ID + Given I have a valid member ID "67890" and a missing institution ID and product ID "product1" + When I send a DELETE request to "/members/67890?productId=product1" + Then I should receive a response of operation on user group members with status code 400 + And the response of operation on user group members should contain an error message "Institution ID is required" + + Scenario: Attempt to delete a member with a missing product ID + Given I have a valid member ID "67890" and institution ID "institution1" and a missing product ID + When I send a DELETE request to "/members/67890?institutionId=institution1" + Then I should receive a response of operation on user group members with status code 400 + And the response of operation on user group members should contain an error message "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 valid member ID "67890", institution ID "institution1", and product ID "product1" + When I send a DELETE request to "/members/67890?institutionId=institution1&productId=product1" + Then I should receive a response of operation on user group members with status code 204 + diff --git a/apps/cucumber/src/test/resources/dataPopulation/data.yaml b/apps/cucumber/src/test/resources/dataPopulation/data.yaml new file mode 100644 index 00000000..93994919 --- /dev/null +++ b/apps/cucumber/src/test/resources/dataPopulation/data.yaml @@ -0,0 +1 @@ +token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTIxMTg1LCJleHAiOjE3MzM5NTM1ODUsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8yMGM3YmY1OTdlY2UyNzYxOTUyNyJ9.pc65diXLGvMEJI1CmVZqtkJLu7QdPPkZ7B8xjbj8gkUEItShV-L25O5JBtexkTIm4YJM86rv4ORiIEISPY1oP9vv1CN6I1DUDJXWhh5uMuvK2_soKzhP5IlyxVGl6GtmpD38Q1YVr0faB7EABwrOVUVYEkufZF0WgzYdYQFgG_YPv5qNqEj9SReC0nWSPP8gM5Z1ARA3mzLccEvLy253uZ1-IBbNhFwf2m0xc97lVSqov0jxYaoudFLd8CHaP9SztrOdzMOTIriicasF7gzDgnhtjR7I9IDmkUVLrKFjpyjsV18XfH3UeHkvdtTdjr8kIdmkJgeh3u-CK_QZWiDy0g \ No newline at end of file diff --git a/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json b/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json new file mode 100644 index 00000000..f39a007d --- /dev/null +++ b/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json @@ -0,0 +1,41 @@ +[ + { + "id": "6759f8df78b6af202b222d29", + "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc", + "productId": "prod-io", + "name": "io group", + "description": "io group description", + "status": "ACTIVE", + "members": [ + "75003d64-7b8c-4768-b20c-cf66467d44c7" + ], + "createdAt": "2024-12-10T17:12:54.618Z", + "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + }, + { + "id": "6759f8df78b6af202b222d2a", + "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc", + "productId": "prod-pagopa", + "name": "pagopa group", + "description": "pagopa group description", + "status": "ACTIVE", + "members": [ + "75003d64-7b8c-4768-b20c-cf66467d44c7" + ], + "createdAt": "2024-12-10T17:12:54.618Z", + "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + }, + { + "id": "6759f8df78b6af202b222d2b", + "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc", + "productId": "prod-interop", + "name": "interop group", + "description": "interop group description", + "status": "SUSPENDED", + "members": [ + "75003d64-7b8c-4768-b20c-cf66467d44c7" + ], + "createdAt": "2024-12-10T17:12:54.618Z", + "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + } +] \ No newline at end of file From d0fe15c2a777b638d0e682842534c74fac2a25e7 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Thu, 12 Dec 2024 14:21:06 +0100 Subject: [PATCH 3/8] [SELC-5969] Added all scenarios for userGroup APIs --- .../steps/RetrieveUserGroupSteps.java | 260 +++++++++++++----- .../cucumber/steps/UpdateUserGroupSteps.java | 10 +- .../cucumber/steps/UserGroupMemberSteps.java | 137 +++++++-- .../cucumber/steps/UserGroupSteps.java | 14 +- .../scenarios/retrieveUserGroup.feature | 48 ++-- .../scenarios/userGroupMembers.feature | 63 +++-- .../dataPopulation/groupEntities.json | 6 +- .../user_group/config/CoreConfig.java | 2 + .../resources/config/core-config.properties | 2 +- .../resources/config/dao-config.properties | 2 +- 10 files changed, 373 insertions(+), 171 deletions(-) diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java index 29bc5655..51a44418 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java @@ -8,20 +8,26 @@ 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 it.pagopa.selfcare.cucumber.dao.UserGroupRepository; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import it.pagopa.selfcare.cucumber.model.UserGroupStatus; import org.junit.jupiter.api.Assertions; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.Objects; -public class RetrieveUserGroupSteps extends UserGroupSteps{ +public class RetrieveUserGroupSteps extends UserGroupSteps { @Autowired private UserGroupRepository userGroupRepository; @@ -29,114 +35,212 @@ public class RetrieveUserGroupSteps extends UserGroupSteps{ @Autowired private ObjectMapper objectMapper; - List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a", "6759f8df78b6af202b222d2b"); - - @Given("I have an empty group ID") - public void i_have_an_empty_group_ID() { - userGroupId = ""; + @Given("I have a valid group ID to retrieve: {string}") + public void i_have_a_valid_group_ID(String validGroupId) { + userGroupId = validGroupId; } - @Given("I have a suspended group ID {string}") - public void i_have_a_suspended_group_ID(String suspendedGroupId) { - userGroupId = suspendedGroupId; + @Given("I have a non-existent group ID to retrieve {string}") + public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { + userGroupId = nonExistentGroupId; } - @When("I send a GET request to") - public void i_send_a_GET_request_to_with_the_group_id(String endpoint) { + @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(endpoint); + .get(url); status = response.statusCode(); - if(status == 200) { + if (status == 200) { userGroupEntityResponse = response.getBody().as(UserGroupEntity.class); - }else{ + } else { errorMessage = response.getBody().asString(); } } - @Then("the response should contain the group details") - public void the_response_should_contain_the_group_details() { - // Verifica che la risposta contenga i dettagli del gruppo, per esempio controllando un campo specifico - // assert(responseBody.contains("groupName")); // Supponiamo che la risposta contenga un campo "groupName" - } - @When("I send a GET request to {string}") - public void iSendAGETRequestTo(String arg0) { - + @When("I send a GET request to {string} to retrieve filtered userGroups") + public void iSendAGETRequestToRetrieveFilteredUserGroups(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .queryParams("productId", userGroupEntityFilter.getProductId(), + "institutionId", userGroupEntityFilter.getInstitutionId(), + "status", userGroupEntityFilter.getStatus()) + .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(); + } } - @And("the response should contain the suspended group details") - public void theResponseShouldContainTheSuspendedGroupDetails() { - + @When("I send a GET request to {string} to filter userGroups by status") + public void iSendAGETRequestToToFilterUserGroupsByStatus(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .queryParams("status", userGroupEntityFilter.getStatus()) + .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(); + } } - @Given("I have valid filters institutionId {string} productId {string} and status {string}") - public void iHaveValidFiltersAndAnd(String institutionId, String productId, String status) { - + @When("I send a GET request to {string} to retrieve not filtered userGroups") + public void iSendAGETRequestToToRetrieveNotFilteredUserGroups(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .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(); + } } - @And("the response should contain user groups data") - public void theResponseShouldContainUserGroupsData() { - + @When("I send a GET request to {string} to retrieve sorted userGroups") + public void iSendAGETRequestToToRetrieveSortedUserGroups(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .queryParams("sort", sort) + .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(); + } } - @Given("I have no filters") - public void iHaveNoFilters() { - + @When("I send a GET request to {string} to pageable object") + public void iSendAGETRequestToToPageableObject(String url) { + ExtractableResponse response = RestAssured.given() + .contentType("application/json") + .header("Authorization", "Bearer " + token) + .queryParams("page", pageable.getPageNumber(), "size", pageable.getPageSize()) + .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(); + } } - @Given("I have invalid filters {string} and {string}") - public void iHaveInvalidFiltersAnd(String arg0, String arg1) { - + @Given("I have a filter with sorting by {string} but no filter") + public void iHaveAFilterWithSortingByButNoFilter(String sortBy) { + sort = sortBy; } - @Given("I have a filter with sorting by {string} but no {string} or {string}") - public void iHaveAFilterWithSortingByButNoOr(String arg0, String arg1, String arg2) { - + @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 a filter with status {string} but no {string}, {string}, or {string}") - public void iHaveAFilterWithStatusButNoOr(String arg0, String arg1, String arg2, String arg3) { - + @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-io", 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.assertNull(userGroupEntityResponse.getModifiedAt()); + Assertions.assertEquals("4ba2832d-9c4c-40f3-9126-e1c72905ef14", userGroupEntityResponse.getCreatedBy()); + Assertions.assertNull(userGroupEntityResponse.getModifiedBy()); } - @Given("I have valid filters {string} and {string}") - public void iHaveValidFiltersAnd(String arg0, String arg1) { - + @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()); } - @And("I set the page number to {int} and page size to {int}") - public void iSetThePageNumberToAndPageSizeTo(int arg0, int arg1) { - + @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 contain a paginated list of user groups") - public void theResponseShouldContainAPaginatedListOfUserGroups() { - + @Given("I have no filters") + public void iHaveNoFilters() { + userGroupEntityFilter = new UserGroupEntity(); } - @Given("I have filters {string} and {string}") - public void iHaveFiltersAnd(String arg0, String arg1) { - + @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() { - - } - - @Before("@FirstRetrieveUserGroupScenario") - 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); + Assertions.assertEquals(0, userGroupEntityResponsePage.getContent().size()); } - @After("@LastRetrieveUserGroupScenario") - public void afterFeature() { - userGroupRepository.deleteAllById(userGroupsIds); + @And("the response should contain {int} item") + public void theResponseShouldContainOneItem(int expectedItemsCount) { + Assertions.assertEquals(expectedItemsCount, userGroupEntityResponsePage.getContent().size()); } @And("the response of retrieve operation should contain an error message {string}") @@ -145,18 +249,28 @@ public void verifyErrorMessage(String expectedErrorMessage) { Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); } - @And("the response should contain {int} item") - public void theResponseShouldContainOneItem(int expectedItemsCount) { + @Then("I should receive a response of retrieve user group operation with status code {int}") + public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); + } + + @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)); } - @And("the response should contain valid data") - public void theResponseShouldContainValidData() { + @Before("@FirstRetrieveGroupScenario") + 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); } - @Then("I should receive a response of retrieve user group operation with status code {int}") - public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { - Assertions.assertEquals(expectedStatusCode, status); + @After("@LastRetrieveGroupScenario") + public void afterFeature() { + userGroupRepository.deleteAllById(userGroupsIds); } } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java index eb591be4..2129a48b 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java @@ -31,6 +31,11 @@ public class UpdateUserGroupSteps extends UserGroupSteps { List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + @Given("I have a valid group ID {string}") + public void i_have_a_valid_group_ID(String validGroupId) { + userGroupId = validGroupId; + } + @Given("I retrieve to update Group a group Id for product {string} and institution {string}") public void iRetrieveAGroupIdForProductAndInstitution(String productId, String institutionId) { ExtractableResponse response = RestAssured.given() @@ -191,11 +196,6 @@ private void callUpdateApi() { } } - @Given("I have a valid group ID {string}") - public void i_have_a_valid_group_ID(String validGroupId) { - userGroupId = validGroupId; - } - @Given("I have a non-existent group ID {string}") public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { userGroupId = nonExistentGroupId; diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java index 5b16da52..9f78d5c6 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java @@ -35,27 +35,107 @@ public class UserGroupMemberSteps extends UserGroupSteps { @Given("I have a valid group ID {string} and a valid member ID {string}") public void i_have_a_valid_group_ID_and_a_valid_member_ID(String groupId, String memberId) { - + userGroupId = groupId; + userGroupMemberId = UUID.fromString(memberId); } @Given("I have a non-existent group ID {string} and a valid member ID {string}") public void i_have_a_non_existent_group_ID_and_a_valid_member_ID(String groupId, String memberId) { + userGroupId = groupId; + userGroupMemberId = UUID.fromString(memberId); + } + + @When("I send a PUT request to {string}") + public void i_send_a_PUT_request_to_with_the_group_and_member_ids(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 institutionId and productId") + public void iSendADELETERequestToWithQueryParametersInstitutionIdAndProductId(String url) { + ResponseOptions response = RestAssured.given() + .header("Authorization", "Bearer " + token) + .pathParam("memberId", userGroupMemberId) + .queryParam("institutionId", userGroupEntityFilter.getInstitutionId()) + .queryParam("productId", userGroupEntityFilter.getProductId()) + .when() + .delete(url); + + status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } + } + + @When("I send a DELETE request to {string} with query parameters institutionId") + public void iSendADELETERequestToWithQueryParametersInstitutionId(String url) { + ResponseOptions response = RestAssured.given() + .header("Authorization", "Bearer " + token) + .pathParam("memberId", userGroupMemberId) + .queryParam("institutionId", userGroupEntityFilter.getInstitutionId()) + .when() + .delete(url); + + status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } + } + + @When("I send a DELETE request to {string} with query parameters productId") + public void iSendADELETERequestToWithQueryParametersProductId(String url) { + ResponseOptions response = RestAssured.given() + .header("Authorization", "Bearer " + token) + .pathParam("memberId", userGroupMemberId) + .queryParam("productId", userGroupEntityFilter.getProductId()) + .when() + .delete(url); + + status = response.statusCode(); + if(status != 204) { + errorMessage = response.body().asString(); + } } @Given("I have a suspended group ID {string} and a valid member ID {string}") public void i_have_a_suspended_group_ID_and_a_valid_member_ID(String groupId, String memberId) { - + userGroupId = groupId; + userGroupMemberId = UUID.fromString(memberId); } @Given("I have a valid group ID {string} and an invalid member ID {string}") public void i_have_a_valid_group_ID_and_an_invalid_member_ID(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 valid group ID {string} and a missing member ID") @@ -63,32 +143,39 @@ public void i_have_a_valid_group_ID_and_a_missing_member_ID(String groupId) { } - @When("I send a PUT request to {string}") - public void i_send_a_PUT_request_to_with_the_group_and_member_ids(String groupId, String memberId) { - ResponseOptions response = RestAssured.given() - .pathParam("id", groupId) - .pathParam("memberId", memberId) - .when() - .put("/groups/{id}/members/{memberId}"); - - } @Given("I have a valid member ID {string}, institution ID {string}, and product ID {string}") - public void iHaveAValidMemberIDInstitutionIDAndProductID(String arg0, String arg1, String arg2) { - + 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 valid member ID {string} and institution ID {string} and a missing product ID") - public void iHaveAValidMemberIDAndInstitutionIDAndAMissingProductID(String arg0, String arg1) { - + public void iHaveAValidMemberIDAndInstitutionIDAndAMissingProductID(String memberId, String institutionId) { + userGroupMemberId = UUID.fromString(memberId); + userGroupEntityFilter = new UserGroupEntity(); + userGroupEntityFilter.setInstitutionId(institutionId); } @Given("I have a valid member ID {string} and a missing institution ID and product ID {string}") - public void iHaveAValidMemberIDAndAMissingInstitutionIDAndProductID(String arg0, String arg1) { + public void iHaveAValidMemberIDAndAMissingInstitutionIDAndProductID(String memberId, String productId) { + userGroupMemberId = UUID.fromString(memberId); + userGroupEntityFilter = new UserGroupEntity(); + userGroupEntityFilter.setProductId(productId); } - @When("I send a DELETE request to {string}") - public void iSendADELETERequestTo(String arg0) { + + @And("the response of operation on user group members should contain an error message {string}") + public void verifyErrorMessage(String expectedErrorMessage) { + String[] errorMessageArray = expectedErrorMessage.split(","); + Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + } + + @Then("I should receive a response of operation on user group members with status code {int}") + public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + Assertions.assertEquals(expectedStatusCode, status); } @Before("@FirstGroupMembersScenario") @@ -103,14 +190,4 @@ public void afterFeature() { userGroupRepository.deleteAllById(userGroupsIds); } - @And("the response of operation on user group members should contain an error message {string}") - public void verifyErrorMessage(String expectedErrorMessage) { - String[] errorMessageArray = expectedErrorMessage.split(","); - Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); - } - - @Then("I should receive a response of operation on user group members with status code {int}") - public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { - Assertions.assertEquals(expectedStatusCode, status); - } } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java index 94fd2bcc..aeafaee5 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java @@ -1,23 +1,27 @@ package it.pagopa.selfcare.cucumber.steps; -import com.fasterxml.jackson.databind.ObjectMapper; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import it.pagopa.selfcare.cucumber.model.UserGroupEntityPageable; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Pageable; -import java.util.List; +import java.util.UUID; public class UserGroupSteps { protected String userGroupId; + protected UUID userGroupMemberId; protected UserGroupEntity userGroupDetails; protected UserGroupEntity userGroupEntityResponse; protected UserGroupEntity updatedUserGroupEntity; protected UserGroupEntityPageable userGroupEntityResponsePage; + protected Pageable pageable; + protected String sort; + + protected UserGroupEntity userGroupEntityFilter; protected int status; protected String errorMessage; - protected String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTIxMTg1LCJleHAiOjE3MzM5NTM1ODUsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8yMGM3YmY1OTdlY2UyNzYxOTUyNyJ9.pc65diXLGvMEJI1CmVZqtkJLu7QdPPkZ7B8xjbj8gkUEItShV-L25O5JBtexkTIm4YJM86rv4ORiIEISPY1oP9vv1CN6I1DUDJXWhh5uMuvK2_soKzhP5IlyxVGl6GtmpD38Q1YVr0faB7EABwrOVUVYEkufZF0WgzYdYQFgG_YPv5qNqEj9SReC0nWSPP8gM5Z1ARA3mzLccEvLy253uZ1-IBbNhFwf2m0xc97lVSqov0jxYaoudFLd8CHaP9SztrOdzMOTIriicasF7gzDgnhtjR7I9IDmkUVLrKFjpyjsV18XfH3UeHkvdtTdjr8kIdmkJgeh3u-CK_QZWiDy0g"; + + protected String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTk2MzQwLCJleHAiOjE3MzQwMjg3NDAsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8zZTg4NzkyNzRmODJlMGY5Yzk0MSJ9.myOhEFshQKu0agM9jIg0WakcQF0rNVRSrh9k2k5-LA3SkIUpN_Io6d9dLg9Rb7aTGqU50BxEk0OP4zGDJSUjT6pHfWJz0emGFL9UkVJ-w9Jc7WX2oMuj-E9ej9YuB7pXNYM9bKvg4PpE4ZMvnLVxvh_AuTmDVM9nK7K0uD1vvPWptmIwQSjlJhA68LWVxLMlfMVoCk7ysmtIdAkbD4QkqFsP1mQKCOSH2EQUyz_NQFgYWX70-9boSuwx8kOTOHturG1xAuLCGXqhk6yk_HgJShDkeDI6Q9C73dYBE_nNKeJ-yg10vNfiYV5MPjjFiW4eeqvKw5ATf8LhhJmIrjMDcw"; /* public Map readDataPopulation() { ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature index 79b4f1f7..9d62fe7d 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature @@ -2,55 +2,61 @@ Feature: Get User Group @FirstRetrieveGroupScenario Scenario: Successfully retrieve a group with a valid ID - Given I have a valid group ID "6759f8df78b6af202b222d29" - When I send a GET request to "/v1/user-groups/6759f8df78b6af202b222d29" + Given I have a valid group ID to retrieve: "6759f8df78b6af202b222d29" + When I send a GET request to "/v1/user-groups/{id}" Then I should receive a response of retrieve user group operation with status code 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 "99999" - When I send a GET request to "/v1/user-groups/99999" + Given I have a non-existent group ID to retrieve "99999" + When I send a GET request to "/v1/user-groups/{id}" Then I should receive a response of retrieve user group operation with status code 404 - And the response of retrieve operation should contain an error message "User group not found" + And the response of retrieve operation 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-io" and status "ACTIVE" - When I send a GET request to "/v1/user-groups" + When I send a GET request to "/v1/user-groups" to retrieve filtered userGroups Then I should receive a response of retrieve user group operation with status code 200 And the response should contain 1 item - And the response should contain valid data + 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" + When I send a GET request to "/v1/user-groups" to retrieve not filtered userGroups Then I should receive a response of retrieve user group operation with status code 200 - And the response should contain user groups data And the response should contain 3 item - And the response should contain valid data + 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 "institutionId" or "productId" - When I send a GET request to "/v1/user-groups" + Given I have a filter with sorting by "name" but no filter + When I send a GET request to "/v1/user-groups" to retrieve sorted userGroups Then I should receive a response of retrieve user group operation with status code 400 And the response of retrieve operation should contain an error message "Sorting not allowed without productId or institutionId" 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" + 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 filter userGroups by status Then I should receive a response of retrieve user group operation with status code 400 And the response of retrieve operation 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 valid filters "institutionId=123" and "productId=abc" - And I set the page number to 1 and page size to 10 - When I send a GET request to "/v1/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 pageable object + Then I should receive a response of retrieve user group operation with status code 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 pageable object Then I should receive a response of retrieve user group operation with status code 200 - And the response should contain a paginated list of user groups + And the response should contain a paginated list of user groups of 1 items on page 1 - @LastFirstRetrieveGroupScenario + @LastRetrieveGroupScenario Scenario: No user groups found for the provided filters - Given I have filters "institutionId=9999" and "productId=xyz" - When I send a GET request to "/v1/user-groups" + Given I have valid filters institutionId "9c8ae123-d990-4400-b043-67a60affabcd" productId "prod-io" and status "ACTIVE" + When I send a GET request to "/v1/user-groups" to retrieve filtered userGroups Then I should receive a response of retrieve user group operation with status code 200 And the response should contain an empty list diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature index 2d00ac11..af8b6fbf 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature @@ -2,65 +2,64 @@ Feature: User Group Members @FirstGroupMembersScenario Scenario: Successfully add a member to a group - Given I have a valid group ID "12345" and a valid member ID "67890" - When I send a PUT request to "/groups/12345/members/67890" + Given I have a valid group ID "6759f8df78b6af202b222d29" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}" Then I should receive a response of operation on user group members with status code 204 Scenario: Attempt to add a member to a non-existent group - Given I have a non-existent group ID "99999" and a valid member ID "67890" - When I send a PUT request to "/groups/99999/members/67890" + Given I have a non-existent group ID "99999" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}" Then I should receive a response of operation on user group members with status code 404 - And the response of operation on user group members should contain an error message "Group not found" + And the response of operation on user group members should contain an error message "Not Found" Scenario: Attempt to add a member to a suspended group - Given I have a suspended group ID "12345" and a valid member ID "67890" - When I send a PUT request to "/groups/12345/members/67890" - Then I should receive a response of operation on user group members with status code 409 - And the response of operation on user group members should contain an error message "Cannot modify a suspended group" + Given I have a suspended group ID "6759f8df78b6af202b222d2b" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a PUT request to "/v1/user-groups/{id}/members/{memberId}" + Then I should receive a response of operation on user group members with status code 400 + And the response of operation on user group members should contain an error message "Trying to modify suspended group" Scenario: Successfully delete a member from a group - Given I have a valid group ID "12345" and a valid member ID "67890" - When I send a DELETE request to "/groups/12345/members/67890" + Given I have a valid group ID "6759f8df78b6af202b222d29" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}" Then I should receive a response of operation on user group members with status code 204 Scenario: Attempt to delete a member from a non-existent group - Given I have a non-existent group ID "99999" and a valid member ID "67890" - When I send a DELETE request to "/groups/99999/members/67890" + Given I have a non-existent group ID "99999" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}" Then I should receive a response of operation on user group members with status code 404 - And the response of operation on user group members should contain an error message "Group not found" + And the response of operation on user group members should contain an error message "Not Found" Scenario: Attempt to delete a member from a suspended group - Given I have a suspended group ID "12345" and a valid member ID "67890" - When I send a DELETE request to "/groups/12345/members/67890" - Then I should receive a response of operation on user group members with status code 409 - And the response of operation on user group members should contain an error message "Cannot modify a suspended group" + Given I have a suspended group ID "6759f8df78b6af202b222d2b" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}" + Then I should receive a response of operation on user group members with status code 400 + And the response of operation on user group members should contain an error message "Trying to modify suspended group" Scenario: Attempt to delete a member with non-existent member ID - Given I have a valid group ID "12345" and an invalid member ID "invalid-id" - When I send a DELETE request to "/groups/12345/members/invalid-id" - Then I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Invalid member ID" + Given I have a valid group ID "6759f8df78b6af202b222d29" and an invalid member ID "f71dcad0-3374-4b51-91b8-75a9b36a5696" + When I send a DELETE request to "/v1/user-groups/{id}/members/{memberId}" + Then I should receive a response of operation on user group members with status code 204 Scenario: Successfully delete a member from all groups associated with institutionId and productId - Given I have a valid member ID "67890", institution ID "institution1", and product ID "product1" - When I send a DELETE request to "/members/67890?institutionId=institution1&productId=product1" + Given I have a valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7", institution ID "9c8ae123-d990-4400-b043-67a60aff31bc", and product ID "prod-io" + When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId and productId Then I should receive a response of operation on user group members with status code 204 Scenario: Attempt to delete a member with a missing institution ID - Given I have a valid member ID "67890" and a missing institution ID and product ID "product1" - When I send a DELETE request to "/members/67890?productId=product1" + Given I have a valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7" and a missing institution ID and product ID "prod-io" + When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters productId Then I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Institution ID is required" + And the response of operation on user group members should contain an error message "Required request parameter 'institutionId' for method parameter type String is not present" Scenario: Attempt to delete a member with a missing product ID - Given I have a valid member ID "67890" and institution ID "institution1" and a missing product ID - When I send a DELETE request to "/members/67890?institutionId=institution1" + Given I have a valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7" and institution ID "9c8ae123-d990-4400-b043-67a60aff31bc" and a missing product ID + When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId Then I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Product ID is required" + And the response of operation on user group members should contain an error message "Required request parameter 'productId' for method parameter type String is not present" @LastGroupMembersScenario Scenario: Attempt to delete a member who is not in any group associated with the given institutionId and productId - Given I have a valid member ID "67890", institution ID "institution1", and product ID "product1" - When I send a DELETE request to "/members/67890?institutionId=institution1&productId=product1" + Given I have a valid member ID "19017fde-142a-4e11-9498-a12a746d0f15", institution ID "9c8ae123-d990-4400-b043-67a60aff31bc", and product ID "prod-io" + When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId and productId Then I should receive a response of operation on user group members with status code 204 diff --git a/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json b/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json index f39a007d..4a725c2c 100644 --- a/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json +++ b/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json @@ -15,10 +15,10 @@ { "id": "6759f8df78b6af202b222d2a", "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc", - "productId": "prod-pagopa", - "name": "pagopa group", + "productId": "prod-io", + "name": "io group 2", "description": "pagopa group description", - "status": "ACTIVE", + "status": "SUSPENDED", "members": [ "75003d64-7b8c-4768-b20c-cf66467d44c7" ], diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java index 2c649212..f02e02ea 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java +++ b/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java @@ -5,8 +5,10 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.data.domain.AuditorAware; +import org.springframework.data.mongodb.config.EnableMongoAuditing; @Configuration +@EnableMongoAuditing(modifyOnCreate = false) @PropertySource("classpath:config/core-config.properties") public class CoreConfig { @Bean diff --git a/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties b/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties index 7f702443..a8f9b74e 100644 --- a/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties +++ b/apps/user-group-ms-2/app/src/main/resources/config/core-config.properties @@ -1,3 +1,3 @@ user-group.allowed.sorting.parameters=${ALLOWED_SORTING_PARAMETERS:name} -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.uri=${MONGODB_CONNECTION_URI:mongodb://localhost:27017} spring.data.mongodb.database=${MONGODB_NAME:selcUserGroup} \ No newline at end of file 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 index 1d25e708..5b30716c 100644 --- 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 @@ -1,2 +1,2 @@ -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.uri=${MONGODB_CONNECTION_URI:mongodb://localhost:27017} spring.data.mongodb.database=${MONGODB_NAME:selcUserGroup} \ No newline at end of file From 3d6123b030c5758a5200a891fbfc7dee6452f444 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Thu, 12 Dec 2024 18:23:50 +0100 Subject: [PATCH 4/8] [SELC-5969] Clean all user-group module --- .../cucumber/steps/CreateUserGroupSteps.java | 107 +- .../steps/RetrieveUserGroupSteps.java | 219 ++-- .../cucumber/steps/UpdateUserGroupSteps.java | 230 ++--- .../cucumber/steps/UserGroupMemberSteps.java | 184 ++-- .../cucumber/steps/UserGroupSteps.java | 31 + .../cucumber/scenarios/createGroup.feature | 50 +- .../scenarios/retrieveUserGroup.feature | 44 +- .../scenarios/updateUserGroup.feature | 56 +- .../scenarios/userGroupMembers.feature | 64 +- apps/pom.xml | 4 +- apps/user-group-ms-2/app/pom.xml | 2 +- .../app/src/main/docs/openapi.json | 2 +- .../user_group/config/SwaggerConfigTest.java | 3 +- apps/user-group-ms-2/pom.xml | 2 +- apps/user-group-ms/Dockerfile | 48 - apps/user-group-ms/Dockerfile.dockerignore | 117 --- apps/user-group-ms/README.md | 39 - apps/user-group-ms/app/pom.xml | 45 - .../app/src/main/docs/openapi.json | 977 ------------------ .../SelfCareUserGroupApplication.java | 13 - .../src/main/resources/config/application.yml | 31 - .../web/config/SwaggerConfigTest.java | 68 -- apps/user-group-ms/connector-api/pom.xml | 39 - .../connector/api/UserGroupConnector.java | 29 - .../connector/api/UserGroupOperations.java | 54 - .../ResourceAlreadyExistsException.java | 12 - .../exception/ResourceNotFoundException.java | 4 - .../exception/ResourceUpdateException.java | 7 - .../connector/model/UserGroupFilter.java | 30 - .../connector/model/UserGroupStatus.java | 7 - .../user_group/connector/DummyGroup.java | 25 - apps/user-group-ms/connector/dao/pom.xml | 25 - .../connector/dao/UserGroupConnectorImpl.java | 219 ---- .../connector/dao/UserGroupRepository.java | 8 - .../auditing/SpringSecurityAuditorAware.java | 25 - .../connector/dao/config/DaoConfig.java | 20 - .../connector/dao/model/CriteriaBuilder.java | 50 - .../connector/dao/model/UserGroupEntity.java | 66 -- .../resources/config/dao-config.properties | 2 - .../dao/UserGroupConnectorImplTest.java | 894 ---------------- .../dao/UserGroupRepositoryTest.java | 372 ------- .../connector/dao/config/DaoTestConfig.java | 9 - apps/user-group-ms/connector/pom.xml | 23 - apps/user-group-ms/core/pom.xml | 26 - .../user_group/core/UserGroupService.java | 31 - .../user_group/core/UserGroupServiceImpl.java | 191 ---- .../user_group/core/config/CoreConfig.java | 10 - .../resources/config/core-config.properties | 1 - .../core/UserGroupServiceImplTest.java | 700 ------------- .../core/config/CoreTestConfig.java | 9 - apps/user-group-ms/lombok.config | 1 - apps/user-group-ms/mvnw | 310 ------ apps/user-group-ms/mvnw.cmd | 182 ---- apps/user-group-ms/pom.xml | 175 ---- apps/user-group-ms/web/pom.xml | 34 - .../user_group/web/config/SwaggerConfig.java | 93 -- .../web/config/UserGroupSecurityConfig.java | 14 - .../user_group/web/config/WebConfig.java | 10 - .../web/controller/UserGroupV1Controller.java | 231 ----- .../handler/UserGroupExceptionHandler.java | 37 - .../web/model/CreateUserGroupDto.java | 48 - .../user_group/web/model/GroupDto.java | 23 - .../user_group/web/model/MemberUUID.java | 16 - .../web/model/UpdateUserGroupDto.java | 28 - .../web/model/UserGroupResource.java | 55 - .../web/model/mapper/UserGroupMapper.java | 53 - .../UserGroupControllerResponseValidator.java | 26 - .../resources/swagger/swagger_en.properties | 29 - .../user_group/web/config/WebTestConfig.java | 9 - .../web/controller/DummyController.java | 14 - .../controller/UserGroupV1ControllerTest.java | 371 ------- .../UserGroupExceptionHandlerTest.java | 68 -- .../web/model/CreateUserGroupDtoTest.java | 73 -- .../web/model/DummyCreateUserGroupDto.java | 18 - .../web/model/DummyUpdateUserGroupDto.java | 13 - .../web/model/UpdateUserGroupDtoTest.java | 68 -- ...rGroupControllerResponseValidatorTest.java | 39 - 77 files changed, 398 insertions(+), 6864 deletions(-) delete mode 100644 apps/user-group-ms/Dockerfile delete mode 100644 apps/user-group-ms/Dockerfile.dockerignore delete mode 100644 apps/user-group-ms/README.md delete mode 100644 apps/user-group-ms/app/pom.xml delete mode 100644 apps/user-group-ms/app/src/main/docs/openapi.json delete mode 100644 apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java delete mode 100644 apps/user-group-ms/app/src/main/resources/config/application.yml delete mode 100644 apps/user-group-ms/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java delete mode 100644 apps/user-group-ms/connector-api/pom.xml delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupConnector.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java delete mode 100644 apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java delete mode 100644 apps/user-group-ms/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java delete mode 100644 apps/user-group-ms/connector/dao/pom.xml delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImpl.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java delete mode 100644 apps/user-group-ms/connector/dao/src/main/resources/config/dao-config.properties delete mode 100644 apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupConnectorImplTest.java delete mode 100644 apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepositoryTest.java delete mode 100644 apps/user-group-ms/connector/dao/src/test/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoTestConfig.java delete mode 100644 apps/user-group-ms/connector/pom.xml delete mode 100644 apps/user-group-ms/core/pom.xml delete mode 100644 apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java delete mode 100644 apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImpl.java delete mode 100644 apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/config/CoreConfig.java delete mode 100644 apps/user-group-ms/core/src/main/resources/config/core-config.properties delete mode 100644 apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/UserGroupServiceImplTest.java delete mode 100644 apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java delete mode 100644 apps/user-group-ms/lombok.config delete mode 100644 apps/user-group-ms/mvnw delete mode 100644 apps/user-group-ms/mvnw.cmd delete mode 100644 apps/user-group-ms/pom.xml delete mode 100644 apps/user-group-ms/web/pom.xml delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java delete mode 100644 apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java delete mode 100644 apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java delete mode 100644 apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidatorTest.java diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java index eec63e5d..bbec1684 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.cucumber.steps; -import com.fasterxml.jackson.databind.ObjectMapper; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.DataTableType; @@ -10,25 +9,48 @@ import io.cucumber.java.en.When; import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import io.restassured.specification.RequestSpecification; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import it.pagopa.selfcare.cucumber.model.UserGroupStatus; import org.junit.jupiter.api.Assertions; -import org.springframework.beans.factory.annotation.Autowired; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; public class CreateUserGroupSteps extends UserGroupSteps{ - @Autowired - private UserGroupRepository userGroupRepository; + @Before("@DuplicateGroupName") + public void beforeScenarioOfCreateDuplicatedGroup() 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("@DuplicateGroupName") + public void afterScenarioOfCreateDuplicatedGroup() { + userGroupRepository.deleteAllById(userGroupsIds); + } + + @After("@CreateNewGroup") + public void afterScenarioOfCreateGroup() { + userGroupRepository.deleteById(userGroupId); + } - @Autowired - private ObjectMapper objectMapper; + @Override + @Then("[CREATE] the response status should be {int}") + public void verifyResponseStatus(int expectedStatusCode) { + super.verifyResponseStatus(expectedStatusCode); + } - List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + @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) { @@ -42,11 +64,16 @@ public UserGroupEntity convertRequest(Map entry) { return userGroupEntity; } - @When("I send a POST request to {string} with the given details") - public void iSendAPOSTRequestToWithTheGivenDetails(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) + @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) @@ -62,46 +89,17 @@ public void iSendAPOSTRequestToWithTheGivenDetails(String url) { } } - @When("I send a POST request to {string} with the given details without authentication") - public void iSendAPOSTRequestToWithTheGivenDetailsWithoutAuthentication(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + null) - .body(userGroupDetails) - .when() - .post(url) - .then() - .extract(); - - status = response.statusCode(); - } - @Given("the following user group details:") public void givenUserGroupDetails(List userGroupEntityList) { if (userGroupEntityList != null && userGroupEntityList.size() == 1) this.userGroupDetails = userGroupEntityList.get(0); } - // Step per verificare lo stato della risposta - @Then("the response status should be {int}") - public void verifyResponseStatus(int expectedStatusCode) { - Assertions.assertEquals(expectedStatusCode, status); - } - - // Step per verificare che la risposta contenga un gruppo utente valido @Then("the response should contain a valid user group resource with name {string}") public void verifyUserGroupName(String expectedName) { Assertions.assertEquals(expectedName, userGroupEntityResponse.getName()); } - // Step per verificare un messaggio di errore nella risposta - @Then("the response should contain an error message {string}") - public void verifyErrorMessage(String expectedErrorMessage) { - String[] errorMessageArray = expectedErrorMessage.split(","); - Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); - } - - // Step per verificare che la risposta contenga un determinato campo @Then("the response should contain the productId {string}") public void verifyProductId(String expectedProductId) { Assertions.assertEquals(expectedProductId, userGroupEntityResponse.getProductId()); @@ -129,36 +127,17 @@ public void theResponseShouldContainTheCreatedBy(String expectedCreatedBy) { @And("the response should contain the createdAt notNull") public void theResponseShouldContainTheCreatedAtNotNull() { - Assertions.assertNotNull(userGroupEntityResponse.getCreatedAt()); + verifyNotNull(userGroupEntityResponse.getCreatedAt()); } - @And("the response should contain the modified data null") public void theResponseShouldContainTheModifiedDataNull() { - Assertions.assertNull(userGroupEntityResponse.getModifiedAt()); - Assertions.assertNull(userGroupEntityResponse.getModifiedBy()); + verifyNull(userGroupEntityResponse.getModifiedAt(), userGroupEntityResponse.getModifiedBy()); } @And("the response should contain the description {string}") public void theResponseShouldContainTheDescription(String expectedDescription) { Assertions.assertEquals(expectedDescription, userGroupEntityResponse.getDescription()); } - - @Before("@DuplicateGroupName") - public void beforeScenarioOfCreateDuplicatedGroup() 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("@DuplicateGroupName") - public void afterScenarioOfCreateDuplicatedGroup() { - userGroupRepository.deleteAllById(userGroupsIds); - } - - @After("@CreateNewGroup") - public void afterScenarioOfCreateGroup() { - userGroupRepository.deleteById(userGroupId); - } } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java index 51a44418..38ef1d50 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.cucumber.steps; -import com.fasterxml.jackson.databind.ObjectMapper; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.en.And; @@ -12,11 +11,11 @@ import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; import io.restassured.response.ResponseOptions; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import io.restassured.specification.RequestSpecification; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import it.pagopa.selfcare.cucumber.model.UserGroupStatus; import org.junit.jupiter.api.Assertions; -import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; @@ -29,24 +28,63 @@ public class RetrieveUserGroupSteps extends UserGroupSteps { - @Autowired - private UserGroupRepository userGroupRepository; + @Before("@FirstRetrieveGroupScenario") + 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); + } - @Autowired - private ObjectMapper objectMapper; + @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); + } - List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a", "6759f8df78b6af202b222d2b"); @Given("I have a valid group ID to retrieve: {string}") - public void i_have_a_valid_group_ID(String validGroupId) { + public void iHaveAValidGroupId(String validGroupId) { userGroupId = validGroupId; } @Given("I have a non-existent group ID to retrieve {string}") - public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { + 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() @@ -62,106 +100,33 @@ public void iSendAGETRequestTo(String url) { } } - - @When("I send a GET request to {string} to retrieve filtered userGroups") - public void iSendAGETRequestToRetrieveFilteredUserGroups(String url) { - ExtractableResponse response = RestAssured.given() + @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) - .queryParams("productId", userGroupEntityFilter.getProductId(), - "institutionId", userGroupEntityFilter.getInstitutionId(), - "status", userGroupEntityFilter.getStatus()) - .when() - .get(url) - .then() - .extract(); + .header("Authorization", "Bearer " + token); - 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(); + if (Objects.nonNull(userGroupEntityFilter)) { + if (Objects.nonNull(userGroupEntityFilter.getProductId())) { + requestSpecification.queryParam("productId", userGroupEntityFilter.getProductId()); } - } else { - errorMessage = response.body().asString(); - } - } - - @When("I send a GET request to {string} to filter userGroups by status") - public void iSendAGETRequestToToFilterUserGroupsByStatus(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .queryParams("status", userGroupEntityFilter.getStatus()) - .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); + if (Objects.nonNull(userGroupEntityFilter.getInstitutionId())) { + requestSpecification.queryParam("institutionId", userGroupEntityFilter.getInstitutionId()); } - userGroupId = userGroupEntityResponse.getId(); - } else { - errorMessage = response.body().asString(); - } - } - - @When("I send a GET request to {string} to retrieve not filtered userGroups") - public void iSendAGETRequestToToRetrieveNotFilteredUserGroups(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .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); + if (Objects.nonNull(userGroupEntityFilter.getStatus())) { + requestSpecification.queryParam("status", userGroupEntityFilter.getStatus()); } - userGroupId = userGroupEntityResponse.getId(); - } else { - errorMessage = response.body().asString(); } - } - - @When("I send a GET request to {string} to retrieve sorted userGroups") - public void iSendAGETRequestToToRetrieveSortedUserGroups(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .queryParams("sort", sort) - .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); + if (Objects.nonNull(pageable)) { + requestSpecification.queryParam("size",pageable.getPageSize()); + requestSpecification.queryParam("page",pageable.getPageNumber()); + if(pageable.getSort().isSorted()){ + requestSpecification.queryParam("sort", pageable.getSort().toString()); } - userGroupId = userGroupEntityResponse.getId(); - } else { - errorMessage = response.body().asString(); } - } - @When("I send a GET request to {string} to pageable object") - public void iSendAGETRequestToToPageableObject(String url) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .queryParams("page", pageable.getPageNumber(), "size", pageable.getPageSize()) + ExtractableResponse response = requestSpecification .when() .get(url) .then() @@ -169,26 +134,17 @@ public void iSendAGETRequestToToPageableObject(String url) { status = response.statusCode(); if (status == 200) { - userGroupEntityResponsePage = response.body().as(new TypeRef<>() {}); + userGroupEntityResponsePage = response.body().as(new TypeRef<>() { + }); if (Objects.nonNull(userGroupEntityResponsePage) && !userGroupEntityResponsePage.getContent().isEmpty()) { userGroupEntityResponse = userGroupEntityResponsePage.getContent().get(0); + userGroupId = userGroupEntityResponse.getId(); } - userGroupId = userGroupEntityResponse.getId(); } else { errorMessage = response.body().asString(); } } - @Given("I have a filter with sorting by {string} but no filter") - public void iHaveAFilterWithSortingByButNoFilter(String sortBy) { - sort = sortBy; - } - - @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); - } - @Then("the response should contain the group details") public void the_response_should_contain_the_group_details() { Assertions.assertEquals(userGroupId, userGroupEntityResponse.getId()); @@ -200,13 +156,12 @@ public void the_response_should_contain_the_group_details() { Assertions.assertEquals(1, userGroupEntityResponse.getMembers().size()); Assertions.assertEquals("75003d64-7b8c-4768-b20c-cf66467d44c7", userGroupEntityResponse.getMembers().iterator().next()); Assertions.assertNotNull(userGroupEntityResponse.getCreatedAt()); - Assertions.assertNull(userGroupEntityResponse.getModifiedAt()); Assertions.assertEquals("4ba2832d-9c4c-40f3-9126-e1c72905ef14", userGroupEntityResponse.getCreatedBy()); - Assertions.assertNull(userGroupEntityResponse.getModifiedBy()); + Assertions.assertNull(userGroupEntityResponse.getModifiedAt(), 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) { + public void theResponseShouldContainAPaginatedListOfUserGroups(int count, int page) { Assertions.assertEquals(count, userGroupEntityResponsePage.getContent().size()); Assertions.assertEquals(3, userGroupEntityResponsePage.getTotalElements()); Assertions.assertEquals(2, userGroupEntityResponsePage.getTotalPages()); @@ -222,13 +177,8 @@ public void iHaveValidFiltersAndAnd(String institutionId, String productId, Stri userGroupEntityFilter.setStatus(UserGroupStatus.valueOf(status)); } - @Given("I have no filters") - public void iHaveNoFilters() { - userGroupEntityFilter = new UserGroupEntity(); - } - @And("the response should contains groupIds {string}") - public void theResponseShouldContainGroupIds( String ids) { + public void theResponseShouldContainGroupIds(String ids) { List idsList = Arrays.asList(ids.split(",")); Assertions.assertEquals(idsList, userGroupEntityResponsePage.getContent().stream().map(UserGroupEntity::getId).toList()); } @@ -243,34 +193,9 @@ public void theResponseShouldContainOneItem(int expectedItemsCount) { Assertions.assertEquals(expectedItemsCount, userGroupEntityResponsePage.getContent().size()); } - @And("the response of retrieve operation should contain an error message {string}") - public void verifyErrorMessage(String expectedErrorMessage) { - String[] errorMessageArray = expectedErrorMessage.split(","); - Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); - } - @Then("I should receive a response of retrieve user group operation with status code {int}") - public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { + public void iShouldReceiveAResponseWithStatusCode(int expectedStatusCode) { Assertions.assertEquals(expectedStatusCode, status); } - - - @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)); - } - - @Before("@FirstRetrieveGroupScenario") - 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("@LastRetrieveGroupScenario") - public void afterFeature() { - userGroupRepository.deleteAllById(userGroupsIds); - } } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java index 2129a48b..873fbe39 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.cucumber.steps; -import com.fasterxml.jackson.databind.ObjectMapper; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.en.And; @@ -10,199 +9,126 @@ import io.restassured.RestAssured; import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import io.restassured.specification.RequestSpecification; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import org.junit.jupiter.api.Assertions; -import org.springframework.beans.factory.annotation.Autowired; import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.List; -import java.util.Objects; +import java.util.Set; public class UpdateUserGroupSteps extends UserGroupSteps { - @Autowired - private UserGroupRepository userGroupRepository; - - @Autowired - private ObjectMapper objectMapper; - - List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); - - @Given("I have a valid group ID {string}") - public void i_have_a_valid_group_ID(String validGroupId) { - userGroupId = validGroupId; + @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); } - @Given("I retrieve to update Group a group Id for product {string} and institution {string}") - public void iRetrieveAGroupIdForProductAndInstitution(String productId, String institutionId) { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .queryParams("productId", productId, "institutionId", institutionId) - .when() - .get("/v1/user-groups") - .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(); - } + @After("@LastUpdateScenario") + public void afterFeature() { + userGroupRepository.deleteAllById(userGroupsIds); } - @Then("I should receive a response with status code {int}") - public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { - Assertions.assertEquals(expectedStatusCode, status); + @Override + @Then("[UPDATE] the response status should be {int}") + public void verifyResponseStatus(int status) { + super.verifyResponseStatus(status); } - // Step per verificare un messaggio di errore nella risposta - @Then("the response of update operation should contain an error message {string}") + @Override + @Then("[UPDATE] the response should contain an error message {string}") public void verifyErrorMessage(String expectedErrorMessage) { - String[] errorMessageArray = expectedErrorMessage.split(","); - Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); + super.verifyErrorMessage(expectedErrorMessage); } - - @When("I send a POST request to suspendAPI with retrieved groupId") - public void iSendAPOSTRequestToSuspendAPIWithRetrieveGroupId() { - callSuspendApi(); + @Given("I have a valid group ID to update: {string}") + public void iHaveAValidGroupIDToUpdate(String groupId) { + userGroupId = groupId; } - - @When("I send a POST request to suspendAPI without groupId") - public void iSendAPOSTRequestToSuspendAPIWithoutGroupId() { - callSuspendApi(); + @Given("I have a non-existent group ID {string}") + public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { + userGroupId = nonExistentGroupId; } - - @When("I send a POST request to suspendAPI with not existent groupId") - public void iSendAPOSTRequestToSuspendAPIWithNonExistentGroupId() { - callSuspendApi(); + @And("I have data to update:") + public void iHaveDataToUpdate(List userGroupEntityList) { + if (userGroupEntityList != null && userGroupEntityList.size() == 1) + this.userGroupDetails = userGroupEntityList.get(0); } - private void callSuspendApi() { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .when() - .post("/v1/user-groups/" + this.userGroupId + "/suspend") - .then() - .extract(); + @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"); - this.status = response.statusCode(); - if(status != 204) { - errorMessage = response.body().asString(); + if(Boolean.parseBoolean(isAuthenticated)){ + requestSpecification.header("Authorization", "Bearer " + token); } - } - @When("I send a POST request to deleteAPI with retrieve groupId") - public void iSendAPOSTRequestToDeleteAPIWithRetrieveGroupId() { - callDeleteApi(); - } - - @When("I send a POST request to deleteAPI with not existent groupId") - public void iSendAPOSTRequestToDeleteAPIWithNonExistentGroupId() { - callDeleteApi(); - } - - private void callDeleteApi() { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) + ExtractableResponse response = requestSpecification + .pathParam("groupId", userGroupId) .when() - .delete("/v1/user-groups/" + userGroupId) + .post(url) .then() .extract(); - status = response.statusCode(); + 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"); - @When("I send a POST request to activateAPI with retrieve groupId") - public void iSendAPOSTRequestToActivateAPIWithRetrieveGroupId() { - callActivateApi(); - } - - @When("I send a POST request to activateAPI with not existent groupId") - public void iSendAPOSTRequestToActivateAPIWithNotExistentGroupId() { - callActivateApi(); - } - - @When("I send a POST request to activateAPI without groupId") - public void iSendAPOSTRequestToActivateAPIWithoutGroupId() { - callActivateApi(); - } + if(Boolean.parseBoolean(isAuthenticated)){ + requestSpecification.header("Authorization", "Bearer " + token); + } - private void callActivateApi() { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) + ExtractableResponse response = requestSpecification + .pathParam("groupId", userGroupId) .when() - .post("/v1/user-groups/" + userGroupId + "/activate") + .body(userGroupDetails) + .put(url) .then() .extract(); - status = response.statusCode(); + 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"); - @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 PUT request to updateAPI with the retrieved group data") - public void iSendAPUTRequestToUpdateAPIWithTheRetrievedGroupData() { - callUpdateApi(); - } - - @When("I send a PUT request to updateAPI with the group data") - public void iSendAPUTRequestToUpdateAPIWithTheGroupData() { - callUpdateApi(); - } + if(Boolean.parseBoolean(isAuthenticated)){ + requestSpecification.header("Authorization", "Bearer " + token); + } - private void callUpdateApi() { - ExtractableResponse response = RestAssured.given() - .contentType("application/json") - .header("Authorization", "Bearer " + token) - .body(userGroupDetails) + ExtractableResponse response = requestSpecification + .pathParam("groupId", userGroupId) .when() - .put("/v1/user-groups/" + userGroupId) + .delete(url) .then() .extract(); - status = response.statusCode(); - if(status == 201) { - userGroupEntityResponse = response.body().as(UserGroupEntity.class); - userGroupId = userGroupEntityResponse.getId(); - }else { + this.status = response.statusCode(); + if(status != 204) { errorMessage = response.body().asString(); } } - @Given("I have a non-existent group ID {string}") - public void i_have_a_non_existent_group_ID(String nonExistentGroupId) { - userGroupId = nonExistentGroupId; - } - - @And("the retrieved group should be changed status to {string}") - public void theRetrievedGroupShouldBeChangedStatusTo(String changedStatus) { + @And("the retrieved group should be updated") + public void theRetrievedGroupShouldBeUpdated() { ExtractableResponse response = RestAssured.given() .contentType("application/json") .header("Authorization", "Bearer " + token) @@ -213,16 +139,18 @@ public void theRetrievedGroupShouldBeChangedStatusTo(String changedStatus) { status = response.statusCode(); if (status == 200) { - userGroupEntityResponse = response.body().as(new TypeRef<>() { + updatedUserGroupEntity = response.body().as(new TypeRef<>() { }); - Assertions.assertEquals(changedStatus, userGroupEntityResponse.getStatus().name()); - Assertions.assertNotNull(userGroupEntityResponse.getModifiedAt()); - Assertions.assertNotNull(userGroupEntityResponse.getModifiedBy()); + 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 updated") - public void theRetrievedGroupShouldBeUpdated() { + @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) @@ -235,24 +163,10 @@ public void theRetrievedGroupShouldBeUpdated() { if (status == 200) { updatedUserGroupEntity = response.body().as(new TypeRef<>() { }); - Assertions.assertNotEquals(userGroupEntityResponse.getName(), updatedUserGroupEntity.getName()); - Assertions.assertNotEquals(userGroupEntityResponse.getDescription(), updatedUserGroupEntity.getDescription()); - Assertions.assertNotEquals(userGroupEntityResponse.getMembers(), updatedUserGroupEntity.getMembers()); + Assertions.assertEquals(changedStatus, updatedUserGroupEntity.getStatus().name()); Assertions.assertNotNull(updatedUserGroupEntity.getModifiedAt()); Assertions.assertNotNull(updatedUserGroupEntity.getModifiedBy()); } } - @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); - } - } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java index 9f78d5c6..e4562201 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.cucumber.steps; -import com.fasterxml.jackson.databind.ObjectMapper; import io.cucumber.java.After; import io.cucumber.java.Before; import io.cucumber.java.en.And; @@ -10,12 +9,9 @@ import io.restassured.RestAssured; import io.restassured.response.Response; import io.restassured.response.ResponseOptions; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; +import io.restassured.specification.RequestSpecification; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import org.junit.jupiter.api.Assertions; -import org.springframework.beans.factory.annotation.Autowired; - -import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; import java.io.IOException; @@ -25,28 +21,67 @@ public class UserGroupMemberSteps extends UserGroupSteps { - @Autowired - private UserGroupRepository userGroupRepository; + @Before("@FirstGroupMembersScenario") + 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); + } - @Autowired - private ObjectMapper objectMapper; + @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); + } - List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); - @Given("I have a valid group ID {string} and a valid member ID {string}") - public void i_have_a_valid_group_ID_and_a_valid_member_ID(String groupId, String memberId) { + @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 non-existent group ID {string} and a valid member ID {string}") - public void i_have_a_non_existent_group_ID_and_a_valid_member_ID(String groupId, String memberId) { - userGroupId = groupId; + @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 i_send_a_PUT_request_to_with_the_group_and_member_ids(String url) { + public void iSendAPutRequestTo(String url) { ResponseOptions response = RestAssured.given() .header("Authorization", "Bearer " + token) .pathParam("id", userGroupId) @@ -55,7 +90,7 @@ public void i_send_a_PUT_request_to_with_the_group_and_member_ids(String url) { .put(url); status = response.statusCode(); - if(status != 204) { + if (status != 204) { errorMessage = response.body().asString(); } } @@ -70,124 +105,33 @@ public void iSendADELETERequestTo(String url) { .delete(url); status = response.statusCode(); - if(status != 204) { + if (status != 204) { errorMessage = response.body().asString(); } } - @When("I send a DELETE request to {string} with query parameters institutionId and productId") - public void iSendADELETERequestToWithQueryParametersInstitutionIdAndProductId(String url) { - ResponseOptions response = RestAssured.given() + @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) - .queryParam("institutionId", userGroupEntityFilter.getInstitutionId()) - .queryParam("productId", userGroupEntityFilter.getProductId()) - .when() - .delete(url); + .pathParam("memberId", userGroupMemberId); - status = response.statusCode(); - if(status != 204) { - errorMessage = response.body().asString(); + if (userGroupEntityFilter.getInstitutionId() != null) { + requestSpecification.queryParam("institutionId", userGroupEntityFilter.getInstitutionId()); } - } - - @When("I send a DELETE request to {string} with query parameters institutionId") - public void iSendADELETERequestToWithQueryParametersInstitutionId(String url) { - ResponseOptions response = RestAssured.given() - .header("Authorization", "Bearer " + token) - .pathParam("memberId", userGroupMemberId) - .queryParam("institutionId", userGroupEntityFilter.getInstitutionId()) - .when() - .delete(url); - - status = response.statusCode(); - if(status != 204) { - errorMessage = response.body().asString(); + if (userGroupEntityFilter.getProductId() != null) { + requestSpecification.queryParam("productId", userGroupEntityFilter.getProductId()); } - } - @When("I send a DELETE request to {string} with query parameters productId") - public void iSendADELETERequestToWithQueryParametersProductId(String url) { - ResponseOptions response = RestAssured.given() - .header("Authorization", "Bearer " + token) - .pathParam("memberId", userGroupMemberId) + ResponseOptions response = requestSpecification + .queryParam("institutionId", userGroupEntityFilter.getInstitutionId()) .queryParam("productId", userGroupEntityFilter.getProductId()) .when() .delete(url); status = response.statusCode(); - if(status != 204) { + if (status != 204) { errorMessage = response.body().asString(); } } - - @Given("I have a suspended group ID {string} and a valid member ID {string}") - public void i_have_a_suspended_group_ID_and_a_valid_member_ID(String groupId, String memberId) { - userGroupId = groupId; - userGroupMemberId = UUID.fromString(memberId); - } - - @Given("I have a valid group ID {string} and an invalid member ID {string}") - public void i_have_a_valid_group_ID_and_an_invalid_member_ID(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 valid group ID {string} and a missing member ID") - public void i_have_a_valid_group_ID_and_a_missing_member_ID(String groupId) { - - } - - - @Given("I have a valid 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 valid member ID {string} and institution ID {string} and a missing product ID") - public void iHaveAValidMemberIDAndInstitutionIDAndAMissingProductID(String memberId, String institutionId) { - userGroupMemberId = UUID.fromString(memberId); - userGroupEntityFilter = new UserGroupEntity(); - userGroupEntityFilter.setInstitutionId(institutionId); - } - - @Given("I have a valid member ID {string} and a missing institution ID and product ID {string}") - public void iHaveAValidMemberIDAndAMissingInstitutionIDAndProductID(String memberId, String productId) { - userGroupMemberId = UUID.fromString(memberId); - userGroupEntityFilter = new UserGroupEntity(); - userGroupEntityFilter.setProductId(productId); - } - - - @And("the response of operation on user group members should contain an error message {string}") - public void verifyErrorMessage(String expectedErrorMessage) { - String[] errorMessageArray = expectedErrorMessage.split(","); - Arrays.stream(errorMessageArray).forEach(s -> Assertions.assertTrue(errorMessage.contains(s))); - } - - @Then("I should receive a response of operation on user group members with status code {int}") - public void i_should_receive_a_response_with_status_code(int expectedStatusCode) { - Assertions.assertEquals(expectedStatusCode, status); - } - - @Before("@FirstGroupMembersScenario") - 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("@LastGroupMembersScenario") - public void afterFeature() { - userGroupRepository.deleteAllById(userGroupsIds); - } - } diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java index aeafaee5..6844882e 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java +++ b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java @@ -1,9 +1,15 @@ package it.pagopa.selfcare.cucumber.steps; +import com.fasterxml.jackson.databind.ObjectMapper; +import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; import it.pagopa.selfcare.cucumber.model.UserGroupEntity; import it.pagopa.selfcare.cucumber.model.UserGroupEntityPageable; +import org.junit.jupiter.api.Assertions; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Pageable; +import java.util.Arrays; +import java.util.List; import java.util.UUID; public class UserGroupSteps { @@ -21,6 +27,14 @@ public class UserGroupSteps { protected int status; protected String errorMessage; + @Autowired + protected UserGroupRepository userGroupRepository; + + @Autowired + protected ObjectMapper objectMapper; + + protected List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); + protected String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTk2MzQwLCJleHAiOjE3MzQwMjg3NDAsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8zZTg4NzkyNzRmODJlMGY5Yzk0MSJ9.myOhEFshQKu0agM9jIg0WakcQF0rNVRSrh9k2k5-LA3SkIUpN_Io6d9dLg9Rb7aTGqU50BxEk0OP4zGDJSUjT6pHfWJz0emGFL9UkVJ-w9Jc7WX2oMuj-E9ej9YuB7pXNYM9bKvg4PpE4ZMvnLVxvh_AuTmDVM9nK7K0uD1vvPWptmIwQSjlJhA68LWVxLMlfMVoCk7ysmtIdAkbD4QkqFsP1mQKCOSH2EQUyz_NQFgYWX70-9boSuwx8kOTOHturG1xAuLCGXqhk6yk_HgJShDkeDI6Q9C73dYBE_nNKeJ-yg10vNfiYV5MPjjFiW4eeqvKw5ATf8LhhJmIrjMDcw"; /* public Map readDataPopulation() { @@ -36,4 +50,21 @@ public class UserGroupSteps { return readValue; }*/ + 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); + } + } diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature index 6f210f1e..76f37158 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature @@ -6,8 +6,8 @@ Feature: Create 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 - Then the response status should be 201 + 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" @@ -24,68 +24,68 @@ Feature: Create User Group Given the following user group details: | name | description | productId | institutionId | status | members | | io group | TestGroup | prod-io | 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 - Then the response status should be 409 - And the response should contain an error message "A group with the same name already exists in ACTIVE or SUSPENDED state" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.name,must not be blank" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.institutionId,must not be blank" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.productId,must not be blank" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.description,must not be blank" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.status,must not be null" + 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 - Then the response status should be 400 - And the response should contain an error message "createUserGroupDto.members,must not be empty" + 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 without authentication - Then the response status should be 401 + 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/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature index 9d62fe7d..ab28f98b 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature @@ -4,59 +4,65 @@ Feature: Get User Group 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 I should receive a response of retrieve user group operation with status code 200 + 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 I should receive a response of retrieve user group operation with status code 404 - And the response of retrieve operation should contain an error message "Not Found" + 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-io" and status "ACTIVE" - When I send a GET request to "/v1/user-groups" to retrieve filtered userGroups - Then I should receive a response of retrieve user group operation with status code 200 + 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 not filtered userGroups - Then I should receive a response of retrieve user group operation with status code 200 + 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 sorted userGroups - Then I should receive a response of retrieve user group operation with status code 400 - And the response of retrieve operation should contain an error message "Sorting not allowed without productId or institutionId" + 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 filter userGroups by status - Then I should receive a response of retrieve user group operation with status code 400 - And the response of retrieve operation should contain an error message "At least one of productId, institutionId and userId must be provided with status 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 "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 pageable object - Then I should receive a response of retrieve user group operation with status code 200 + 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 pageable object - Then I should receive a response of retrieve user group operation with status code 200 + 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-io" and status "ACTIVE" - When I send a GET request to "/v1/user-groups" to retrieve filtered userGroups - Then I should receive a response of retrieve user group operation with status code 200 + 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/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature index 706937a8..a53aa8eb 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature @@ -2,48 +2,48 @@ Feature: Update User Group @FirstUpdateScenario Scenario: Successfully suspend a group with a valid ID - Given I retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" - When I send a POST request to suspendAPI with retrieved groupId - Then I should receive a response with status code 204 + 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 suspendAPI with not existent groupId - Then I should receive a response with status code 404 - And the response of update operation should contain an error message "Not Found" + 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 retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" - When I send a POST request to activateAPI with retrieve groupId - Then I should receive a response with status code 204 + 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 activateAPI with not existent groupId - Then I should receive a response with status code 404 - And the response of update operation should contain an error message "Not Found" + 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 retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" - When I send a POST request to deleteAPI with retrieve groupId - Then I should receive a response with status code 204 + 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 POST request to deleteAPI with not existent groupId - Then I should receive a response with status code 404 - And the response of update operation should contain an error message "Not Found" + 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 retrieve to update Group a group Id for product "prod-io" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + 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 updateAPI with the retrieved group data - Then I should receive a response with status code 200 + 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 @@ -51,19 +51,19 @@ Feature: Update User Group 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 updateAPI with the group data - Then I should receive a response with status code 404 - And the response of update operation should contain an error message "Not Found" + 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 retrieve to update Group a group Id for product "prod-interop" and institution "9c8ae123-d990-4400-b043-67a60aff31bc" + 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 updateAPI with the retrieved group data - Then I should receive a response with status code 400 - And the response of update operation should contain an error message "Trying to modify suspended group" + 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/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature index af8b6fbf..37a07f12 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature +++ b/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature @@ -2,64 +2,64 @@ Feature: User Group Members @FirstGroupMembersScenario Scenario: Successfully add a member to a group - Given I have a valid group ID "6759f8df78b6af202b222d29" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 204 + Then [MEMBERS] the response status should be 204 Scenario: Attempt to add a member to a non-existent group - Given I have a non-existent group ID "99999" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 404 - And the response of operation on user group members should contain an error message "Not Found" + 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 a suspended group ID "6759f8df78b6af202b222d2b" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Trying to modify suspended group" + 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 a valid group ID "6759f8df78b6af202b222d29" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 204 + Then [MEMBERS] the response status should be 204 Scenario: Attempt to delete a member from a non-existent group - Given I have a non-existent group ID "99999" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 404 - And the response of operation on user group members should contain an error message "Not Found" + 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 a suspended group ID "6759f8df78b6af202b222d2b" and a valid member ID "78bb7f07-0464-4ff9-a0ee-82568902b7bf" + 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 I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Trying to modify suspended group" + 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 a valid group ID "6759f8df78b6af202b222d29" and an invalid member ID "f71dcad0-3374-4b51-91b8-75a9b36a5696" + 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 I should receive a response of operation on user group members with status code 204 + 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 valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7", institution ID "9c8ae123-d990-4400-b043-67a60aff31bc", and product ID "prod-io" - When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId and productId - Then I should receive a response of operation on user group members with status code 204 + Given I have a member id "75003d64-7b8c-4768-b20c-cf66467d44c7", institution id "9c8ae123-d990-4400-b043-67a60aff31bc" and product id "prod-io" + 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 valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7" and a missing institution ID and product ID "prod-io" - When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters productId - Then I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Required request parameter 'institutionId' for method parameter type String is not present" + Given I have a member id "75003d64-7b8c-4768-b20c-cf66467d44c7" and product id "prod-io" + 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 valid member ID "75003d64-7b8c-4768-b20c-cf66467d44c7" and institution ID "9c8ae123-d990-4400-b043-67a60aff31bc" and a missing product ID - When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId - Then I should receive a response of operation on user group members with status code 400 - And the response of operation on user group members should contain an error message "Required request parameter 'productId' for method parameter type String is not present" + 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 valid member ID "19017fde-142a-4e11-9498-a12a746d0f15", institution ID "9c8ae123-d990-4400-b043-67a60aff31bc", and product ID "prod-io" - When I send a DELETE request to "/v1/user-groups/members/{memberId}" with query parameters institutionId and productId - Then I should receive a response of operation on user group members with status code 204 + Given I have a member id "19017fde-142a-4e11-9498-a12a746d0f15", institution id "9c8ae123-d990-4400-b043-67a60aff31bc" and product id "prod-io" + 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/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-2/app/pom.xml b/apps/user-group-ms-2/app/pom.xml index 1a6c160e..3c8ef58a 100644 --- a/apps/user-group-ms-2/app/pom.xml +++ b/apps/user-group-ms-2/app/pom.xml @@ -2,7 +2,7 @@ - user-group-ms-2 + user-group-ms it.pagopa.selfcare 1.0.0-SNAPSHOT diff --git a/apps/user-group-ms-2/app/src/main/docs/openapi.json b/apps/user-group-ms-2/app/src/main/docs/openapi.json index 587bf75c..abf1f2f9 100644 --- a/apps/user-group-ms-2/app/src/main/docs/openapi.json +++ b/apps/user-group-ms-2/app/src/main/docs/openapi.json @@ -1,7 +1,7 @@ { "openapi" : "3.0.3", "info" : { - "title" : "user-group-ms-2", + "title" : "user-group-ms", "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-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java index 1bc8b101..463e8d37 100644 --- a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java +++ b/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java @@ -27,12 +27,11 @@ @SpringBootTest(classes = { SwaggerConfig.class, - CoreConfig.class, WebConfig.class, }) @EnableOpenApi @EnableWebMvc -@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.controller") +@ComponentScan(basePackages = {"it.pagopa.selfcare.user_group.controller","it.pagopa.selfcare.user_group.model"}) @TestPropertySource(locations = "classpath:config/application.yml") class SwaggerConfigTest { diff --git a/apps/user-group-ms-2/pom.xml b/apps/user-group-ms-2/pom.xml index 3dba12ab..beecf6f8 100644 --- a/apps/user-group-ms-2/pom.xml +++ b/apps/user-group-ms-2/pom.xml @@ -11,7 +11,7 @@ - user-group-ms-2 + user-group-ms pom 1.0.0-SNAPSHOT user-group-ms diff --git a/apps/user-group-ms/Dockerfile b/apps/user-group-ms/Dockerfile deleted file mode 100644 index 3b15bfa1..00000000 --- a/apps/user-group-ms/Dockerfile +++ /dev/null @@ -1,48 +0,0 @@ -# syntax=docker/dockerfile:1.6@sha256:ac85f380a63b13dfcefa89046420e1781752bab202122f8f50032edf31be0021 -FROM maven:3-eclipse-temurin-17@sha256:0d328fa6843bb26b60cf44d69833f241ffe96218fb29fa19df7a6603863eaae7 AS builder - -WORKDIR /src -COPY --link pom.xml . - -WORKDIR /src/test-coverage -COPY --link ./test-coverage/pom.xml . - -WORKDIR /src/apps -COPY --link ./apps/pom.xml . - -WORKDIR /src/apps/user-group-ms -COPY --link ./apps/user-group-ms/pom.xml . -COPY ./apps/user-group-ms/ ./ - -RUN echo "\n" \ - "\n" \ - "\n" \ - "\${repositoryId}\n" \ - "\${repoLogin}\n" \ - "\${repoPwd}\n" \ - "\n" \ - "\n" \ - "\n" > settings.xml - -ARG REPO_ONBOARDING -ARG REPO_USERNAME -ARG REPO_PASSWORD - -RUN mvn --global-settings settings.xml --projects :user-group-ms -DrepositoryId=${REPO_ONBOARDING} -DrepoLogin=${REPO_USERNAME} -DrepoPwd=${REPO_PASSWORD} --also-make-dependents clean package -DskipTests - - -FROM openjdk:17-jdk@sha256:528707081fdb9562eb819128a9f85ae7fe000e2fbaeaf9f87662e7b3f38cb7d8 AS runtime - -ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' - -WORKDIR /app - -COPY --from=builder /src/apps/user-group-ms/target/*.jar ./app.jar - -ADD https://github.com/microsoft/ApplicationInsights-Java/releases/download/3.2.11/applicationinsights-agent-3.2.11.jar ./applicationinsights-agent.jar -RUN chmod 755 ./applicationinsights-agent.jar - -EXPOSE 8080 -USER 1001 - -ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/apps/user-group-ms/Dockerfile.dockerignore b/apps/user-group-ms/Dockerfile.dockerignore deleted file mode 100644 index 427b8ce4..00000000 --- a/apps/user-group-ms/Dockerfile.dockerignore +++ /dev/null @@ -1,117 +0,0 @@ -**/.dockerignore -**/.git -**/bin -**/docker-compose* -**/Dockerfile* -**/node_modules -**/npm-debug.log -**/obj -**/secrets.dev.yaml -**/values.dev.yaml -LICENSE -README.md - -**/.idea -.idea -**/.mvn -.mvn - -**/target - -# Created by .ignore support plugin (hsz.mobi) -### Maven template -target/ -pom.xml.tag -pom.xml.releaseBackup -pom.xml.versionsBackup -pom.xml.next -release.properties -dependency-reduced-pom.xml -buildNumber.properties -.mvn/timing.properties -.mvn/wrapper/maven-wrapper.jar -### Java template -# Compiled class file -*.class - -# Log file -*.log - -# BlueJ files -*.ctxt - -# Mobile Tools for Java (J2ME) -.mtj.tmp/ - -# Package Files # -*.jar -*.war -*.nar -*.ear -*.zip -*.tar.gz -*.rar - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* -### JetBrains template -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Gradle and Maven with auto-import -# When using Gradle or Maven with auto-import, you should exclude module files, -# since they will be recreated, and may cause churn. Uncomment if using -# auto-import. -# .idea/modules.xml -# .idea/*.iml -# .idea/modules - -# CMake -cmake-build-*/ - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties - -# Editor-based Rest Client -.idea/httpRequests \ No newline at end of file diff --git a/apps/user-group-ms/README.md b/apps/user-group-ms/README.md deleted file mode 100644 index 89ace93d..00000000 --- a/apps/user-group-ms/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# selfcare-ms-user-group -microservice to manage group of users - -## Description -This Spring Boot-based microservice is designed to handle several key functionalities in the selfcare user-group operations domain and business logic for CRUD groups. - -## Prerequisites -Before running the microservice, ensure you have installed: - -- Java JDK 17 or higher -- Maven 3.6 or higher -- Connection to VPN selc-d-vnet - -## Configuration -Look at app/src/main/resources/`application.yml` file to set up environment-specific settings, such as database details. - -## Installation and Local Startup -To run the microservice locally, follow these steps: - -1. **Build the Project** - -```shell script -mvn clean install -``` - -2. **Start the Application** - -```shell script -mvn spring-boot:run -pl app -``` - -Remember to set environment-specific settings (look above). - -## Usage -After starting, the microservice will be available at `http://localhost:8080/`. - -To use the API, refer to the Swagger UI documentation (if available) at `http://localhost:8080/swagger-ui.html`. - - 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/app/src/main/docs/openapi.json b/apps/user-group-ms/app/src/main/docs/openapi.json deleted file mode 100644 index c9875eb7..00000000 --- a/apps/user-group-ms/app/src/main/docs/openapi.json +++ /dev/null @@ -1,977 +0,0 @@ -{ - "openapi" : "3.0.3", - "info" : { - "title" : "user-group-ms", - "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" - }, - "servers" : [ { - "url" : "{url}:{port}{basePath}", - "variables" : { - "url" : { - "default" : "http://localhost" - }, - "port" : { - "default" : "80" - }, - "basePath" : { - "default" : "" - } - } - } ], - "tags" : [ { - "name" : "UserGroup", - "description" : "User group endpoint CRUD operations" - } ], - "paths" : { - "/v1/user-groups" : { - "get" : { - "tags" : [ "UserGroup", "external-pnpg", "external-v2", "support", "support-pnpg" ], - "summary" : "getUserGroups", - "description" : "Service that allows to get a list of UserGroup entities", - "operationId" : "getUserGroupsUsingGET", - "parameters" : [ { - "name" : "institutionId", - "in" : "query", - "description" : "Users group's institutionId", - "required" : false, - "style" : "form", - "schema" : { - "type" : "string" - } - }, { - "name" : "page", - "in" : "query", - "description" : "The page number to access (0 indexed, defaults to 0)", - "required" : false, - "style" : "form", - "allowReserved" : true, - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, { - "name" : "size", - "in" : "query", - "description" : "Number of records per page (defaults to 20, max 2000)", - "required" : false, - "style" : "form", - "allowReserved" : true, - "schema" : { - "type" : "integer", - "format" : "int32" - } - }, { - "name" : "sort", - "in" : "query", - "description" : "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", - "required" : false, - "style" : "form", - "allowReserved" : true, - "schema" : { - "type" : "array", - "items" : { - "type" : "string" - } - } - }, { - "name" : "productId", - "in" : "query", - "description" : "Users group's productId", - "required" : false, - "style" : "form", - "schema" : { - "type" : "string" - } - }, { - "name" : "userId", - "in" : "query", - "description" : "Member's unique identifier", - "required" : false, - "style" : "form", - "schema" : { - "type" : "string", - "format" : "uuid" - } - }, { - "name" : "status", - "in" : "query", - "description" : "If filter on status is present, it must be used with at least one of the other filters", - "required" : false, - "style" : "form", - "explode" : true, - "schema" : { - "type" : "string", - "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] - } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/PageOfUserGroupResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "post" : { - "tags" : [ "UserGroup" ], - "summary" : "createGroup", - "description" : "Service that allows the insert of a new occurrence for the UserGroup entity", - "operationId" : "createGroupUsingPOST", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/CreateUserGroupDto" - } - } - } - }, - "responses" : { - "201" : { - "description" : "Created", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserGroupResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "409" : { - "description" : "Conflict", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/v1/user-groups/members/{memberId}" : { - "delete" : { - "tags" : [ "UserGroup" ], - "summary" : "deleteMemberFromUserGroups", - "description" : "Service to delete a member from a specific UserGroup entity", - "operationId" : "deleteMemberFromUserGroupsUsingDELETE", - "parameters" : [ { - "name" : "memberId", - "in" : "path", - "description" : "Member's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string", - "format" : "uuid" - } - }, { - "name" : "institutionId", - "in" : "query", - "description" : "institutionId", - "required" : true, - "style" : "form", - "schema" : { - "type" : "string" - } - }, { - "name" : "productId", - "in" : "query", - "description" : "productId", - "required" : true, - "style" : "form", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/v1/user-groups/{id}" : { - "get" : { - "tags" : [ "UserGroup", "external-v2" ], - "summary" : "getUserGroup", - "description" : "Service to get a specific UserGroup entity", - "operationId" : "getUserGroupUsingGET", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserGroupResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "404" : { - "description" : "Not Found", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "put" : { - "tags" : [ "UserGroup" ], - "summary" : "updateUserGroup", - "description" : "Service that allows the modification of a specific occurrence for the UserGroup entity by an Admin user", - "operationId" : "updateUserGroupUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UpdateUserGroupDto" - } - } - } - }, - "responses" : { - "200" : { - "description" : "OK", - "content" : { - "application/json" : { - "schema" : { - "$ref" : "#/components/schemas/UserGroupResource" - } - } - } - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "409" : { - "description" : "Conflict", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "delete" : { - "tags" : [ "UserGroup" ], - "summary" : "deleteGroup", - "description" : "Service that allows the deletion of a specific occurrence for the UserGroup entity by an Admin user", - "operationId" : "deleteGroupUsingDELETE", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/v1/user-groups/{id}/activate" : { - "post" : { - "tags" : [ "UserGroup" ], - "summary" : "activateGroup", - "description" : "Service that allows the activation of a specific occurrence for the UserGroup entity by an Admin user", - "operationId" : "activateGroupUsingPOST", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/v1/user-groups/{id}/members/{memberId}" : { - "put" : { - "tags" : [ "UserGroup" ], - "summary" : "addMemberToUserGroup", - "description" : "Service to add a member to a specific UserGroup entity", - "operationId" : "addMemberToUserGroupUsingPUT", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - }, { - "name" : "memberId", - "in" : "path", - "description" : "Member's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string", - "format" : "uuid" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - }, - "delete" : { - "tags" : [ "UserGroup" ], - "summary" : "deleteMemberFromUserGroup", - "description" : "Service to delete a member from a specific UserGroup entity", - "operationId" : "deleteMemberFromUserGroupUsingDELETE", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - }, { - "name" : "memberId", - "in" : "path", - "description" : "Member's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string", - "format" : "uuid" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - }, - "/v1/user-groups/{id}/suspend" : { - "post" : { - "tags" : [ "UserGroup" ], - "summary" : "suspendGroup", - "description" : "Service that allows the suspension of a specific occurrence for the UserGroup entity by an Admin user", - "operationId" : "suspendGroupUsingPOST", - "parameters" : [ { - "name" : "id", - "in" : "path", - "description" : "Users group's unique identifier", - "required" : true, - "style" : "simple", - "schema" : { - "type" : "string" - } - } ], - "responses" : { - "204" : { - "description" : "No Content" - }, - "400" : { - "description" : "Bad Request", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "401" : { - "description" : "Unauthorized", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - }, - "500" : { - "description" : "Internal Server Error", - "content" : { - "application/problem+json" : { - "schema" : { - "$ref" : "#/components/schemas/Problem" - } - } - } - } - }, - "security" : [ { - "bearerAuth" : [ "global" ] - } ] - } - } - }, - "components" : { - "schemas" : { - "CreateUserGroupDto" : { - "title" : "CreateUserGroupDto", - "required" : [ "description", "institutionId", "members", "name", "productId", "status" ], - "type" : "object", - "properties" : { - "description" : { - "type" : "string", - "description" : "Users group's description" - }, - "institutionId" : { - "type" : "string", - "description" : "Users group's institutionId" - }, - "members" : { - "uniqueItems" : true, - "type" : "array", - "description" : "List of all the members of the group", - "items" : { - "type" : "string", - "format" : "uuid" - } - }, - "name" : { - "type" : "string", - "description" : "Users group's name" - }, - "productId" : { - "type" : "string", - "description" : "Users group's productId" - }, - "status" : { - "type" : "string", - "description" : "Users group's status", - "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] - } - } - }, - "InvalidParam" : { - "title" : "InvalidParam", - "required" : [ "name", "reason" ], - "type" : "object", - "properties" : { - "name" : { - "type" : "string", - "description" : "Invalid parameter name." - }, - "reason" : { - "type" : "string", - "description" : "Invalid parameter reason." - } - } - }, - "PageOfUserGroupResource" : { - "title" : "PageOfUserGroupResource", - "required" : [ "content", "number", "size", "totalElements", "totalPages" ], - "type" : "object", - "properties" : { - "content" : { - "type" : "array", - "description" : "The page content", - "items" : { - "$ref" : "#/components/schemas/UserGroupResource" - } - }, - "number" : { - "type" : "integer", - "description" : "The number of the current page", - "format" : "int32" - }, - "size" : { - "type" : "integer", - "description" : "The size of the page", - "format" : "int32" - }, - "totalElements" : { - "type" : "integer", - "description" : "The total amount of elements", - "format" : "int64" - }, - "totalPages" : { - "type" : "integer", - "description" : "The number of total pages", - "format" : "int32" - } - } - }, - "Problem" : { - "title" : "Problem", - "required" : [ "status", "title" ], - "type" : "object", - "properties" : { - "detail" : { - "type" : "string", - "description" : "Human-readable description of this specific problem." - }, - "instance" : { - "type" : "string", - "description" : "A URI that describes where the problem occurred." - }, - "invalidParams" : { - "type" : "array", - "description" : "A list of invalid parameters details.", - "items" : { - "$ref" : "#/components/schemas/InvalidParam" - } - }, - "status" : { - "type" : "integer", - "description" : "The HTTP status code.", - "format" : "int32", - "example" : 500 - }, - "title" : { - "type" : "string", - "description" : "Short human-readable summary of the problem." - }, - "type" : { - "type" : "string", - "description" : "A URL to a page with more details regarding the problem." - } - }, - "description" : "A \"problem detail\" as a way to carry machine-readable details of errors (https://datatracker.ietf.org/doc/html/rfc7807)" - }, - "UpdateUserGroupDto" : { - "title" : "UpdateUserGroupDto", - "required" : [ "description", "members", "name" ], - "type" : "object", - "properties" : { - "description" : { - "type" : "string", - "description" : "Users group's description" - }, - "members" : { - "uniqueItems" : true, - "type" : "array", - "description" : "List of all the members of the group", - "items" : { - "type" : "string", - "format" : "uuid" - } - }, - "name" : { - "type" : "string", - "description" : "Users group's name" - } - } - }, - "UserGroupResource" : { - "title" : "UserGroupResource", - "required" : [ "description", "id", "institutionId", "name", "productId", "status" ], - "type" : "object", - "properties" : { - "createdAt" : { - "type" : "string", - "description" : "Date on which the group was created", - "format" : "date-time" - }, - "createdBy" : { - "type" : "string", - "description" : "User by which the group was created" - }, - "description" : { - "type" : "string", - "description" : "Users group's description" - }, - "id" : { - "type" : "string", - "description" : "Users group's unique identifier" - }, - "institutionId" : { - "type" : "string", - "description" : "Users group's institutionId" - }, - "members" : { - "type" : "array", - "description" : "List of all the members of the group", - "items" : { - "type" : "string", - "format" : "uuid" - } - }, - "modifiedAt" : { - "type" : "string", - "description" : "Date on which the group was modified", - "format" : "date-time" - }, - "modifiedBy" : { - "type" : "string", - "description" : "User by which the group was modified" - }, - "name" : { - "type" : "string", - "description" : "Users group's name" - }, - "productId" : { - "type" : "string", - "description" : "Users group's productId" - }, - "status" : { - "type" : "string", - "description" : "Users group's status", - "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] - } - } - } - }, - "securitySchemes" : { - "bearerAuth" : { - "type" : "http", - "description" : "A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725)", - "scheme" : "bearer", - "bearerFormat" : "JWT" - } - } - } -} \ No newline at end of file diff --git a/apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java b/apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java deleted file mode 100644 index b1f71755..00000000 --- a/apps/user-group-ms/app/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java +++ /dev/null @@ -1,13 +0,0 @@ -package it.pagopa.selfcare.user_group; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SelfCareUserGroupApplication { - - public static void main(String[] args) { - SpringApplication.run(SelfCareUserGroupApplication.class, args); - } - -} diff --git a/apps/user-group-ms/app/src/main/resources/config/application.yml b/apps/user-group-ms/app/src/main/resources/config/application.yml deleted file mode 100644 index e7eff680..00000000 --- a/apps/user-group-ms/app/src/main/resources/config/application.yml +++ /dev/null @@ -1,31 +0,0 @@ -server: - port: ${MS_USER_GROUP_SERVER_PORT:8080} - -spring: - application: - name: "@project.parent.artifactId@" - version: "@project.version@" - profiles: - include: - # TO enable specific-language documentations - - swaggerEN - zipkin: - enabled: false - sleuth: - baggage: - remote-fields: X-Client-Ip - correlation-fields: X-Client-Ip - -info: - build: - artifact: "@project.parent.artifactId@" - name: "@project.parent.artifactId@" - description: "@project.description@" - version: "@project.version@" - - -logging: - level: - it.pagopa.selfcare: ${MS_USER_GROUP_LOG_LEVEL:DEBUG} - pattern: - additional-info: ",%X{X-Client-Ip:-}]" 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/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java deleted file mode 100644 index 112eeef6..00000000 --- a/apps/user-group-ms/app/src/test/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfigTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package it.pagopa.selfcare.user_group.web.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 org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.http.MediaType; -import org.springframework.test.context.TestPropertySource; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; -import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import springfox.documentation.oas.annotations.EnableOpenApi; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -@SpringBootTest(classes = { - SwaggerConfig.class, - WebConfig.class -}) -@EnableOpenApi -@EnableWebMvc -@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.web.controller") -@TestPropertySource(locations = "classpath:config/application.yml") -class SwaggerConfigTest { - - @MockBean - private UserGroupService userGroupService; - - @Autowired - WebApplicationContext context; - - @MockBean - private UserGroupMapper userGroupMapper; - - @Autowired - private ObjectMapper objectMapper; - - @Test - void swaggerSpringPlugin() throws Exception { - MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); - mockMvc.perform(MockMvcRequestBuilders.get("/v3/api-docs").accept(MediaType.APPLICATION_JSON)) - .andExpect(MockMvcResultMatchers.status().is2xxSuccessful()) - .andDo((result) -> { - assertNotNull(result); - assertNotNull(result.getResponse()); - final String content = result.getResponse().getContentAsString(); - assertFalse(content.isBlank()); - assertFalse(content.contains("${"), "Generated swagger contains placeholders"); - Object swagger = objectMapper.readValue(result.getResponse().getContentAsString(), Object.class); - String formatted = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(swagger); - Path basePath = Paths.get("src/main/docs/"); - Files.createDirectories(basePath); - Files.write(basePath.resolve("openapi.json"), formatted.getBytes()); - }); - } -} 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-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java b/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java deleted file mode 100644 index 48b47821..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/api/UserGroupOperations.java +++ /dev/null @@ -1,54 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.api; - -import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus; - -import java.time.Instant; -import java.util.Set; - -public interface UserGroupOperations { - - String getId(); - - void setId(String id); - - String getInstitutionId(); - - void setInstitutionId(String institutionId); - - String getProductId(); - - void setProductId(String productId); - - String getName(); - - void setName(String name); - - String getDescription(); - - void setDescription(String description); - - UserGroupStatus getStatus(); - - void setStatus(UserGroupStatus status); - - Set getMembers(); - - void setMembers(Set members); - - Instant getCreatedAt(); - - void setCreatedAt(Instant createdAt); - - String getCreatedBy(); - - void setCreatedBy(String createdBy); - - Instant getModifiedAt(); - - void setModifiedAt(Instant modifiedAt); - - String getModifiedBy(); - - void setModifiedBy(String modifiedBy); - -} 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/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java deleted file mode 100644 index 89623f06..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceAlreadyExistsException.java +++ /dev/null @@ -1,12 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.exception; - -public class ResourceAlreadyExistsException extends RuntimeException { - - public ResourceAlreadyExistsException(String msg, Throwable cause) { - super(msg, cause); - } - - public ResourceAlreadyExistsException(String msg) { - super(msg); - } -} 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/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java deleted file mode 100644 index f3351e83..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceNotFoundException.java +++ /dev/null @@ -1,4 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.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/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java deleted file mode 100644 index 1fbab29f..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/exception/ResourceUpdateException.java +++ /dev/null @@ -1,7 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.exception; - -public class ResourceUpdateException extends RuntimeException { - public ResourceUpdateException(String msg) { - super(msg); - } -} 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/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java deleted file mode 100644 index 28f6132d..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupFilter.java +++ /dev/null @@ -1,30 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.model; - -import lombok.AllArgsConstructor; -import lombok.Data; -import org.springframework.util.CollectionUtils; - -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -@Data -@AllArgsConstructor -public class UserGroupFilter { - private String institutionId; - private String productId; - private String userId; - private List status; - - public UserGroupFilter(String institutionId, String productId, UUID userId, List status) { - this.institutionId = institutionId; - this.productId = productId; - this.userId = userId != null ? userId.toString() : null; - this.status = CollectionUtils.isEmpty(status) ? Collections.emptyList() : status; - } - - public UserGroupFilter(){ - this.status = Collections.emptyList(); - } - -} 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/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java deleted file mode 100644 index 5cea8344..00000000 --- a/apps/user-group-ms/connector-api/src/main/java/it/pagopa/selfcare/user_group/connector/model/UserGroupStatus.java +++ /dev/null @@ -1,7 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.model; - -public enum UserGroupStatus { - ACTIVE, - SUSPENDED, - DELETED -} 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/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java deleted file mode 100644 index d1b18345..00000000 --- a/apps/user-group-ms/connector-api/src/test/java/it/pagopa/selfcare/user_group/connector/DummyGroup.java +++ /dev/null @@ -1,25 +0,0 @@ -package it.pagopa.selfcare.user_group.connector; - -import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations; -import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus; -import lombok.Data; - -import java.time.Instant; -import java.util.Set; - -@Data -public class DummyGroup implements UserGroupOperations { - - - private String id; - private String institutionId; - private String productId; - private String name; - private String description; - private UserGroupStatus status = UserGroupStatus.ACTIVE; - private Set members = Set.of("string1", "string2"); - private Instant createdAt; - private String createdBy; - private Instant modifiedAt; - private String modifiedBy; -} 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/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java b/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java deleted file mode 100644 index 75742161..00000000 --- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/UserGroupRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.dao; - -import it.pagopa.selfcare.user_group.connector.dao.model.UserGroupEntity; -import org.springframework.data.mongodb.repository.MongoRepository; - -public interface UserGroupRepository extends MongoRepository { - -} 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/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java deleted file mode 100644 index 726d4248..00000000 --- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/auditing/SpringSecurityAuditorAware.java +++ /dev/null @@ -1,25 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.dao.auditing; - -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.AuditorAware; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; - -import java.util.Optional; - -@Slf4j -public class SpringSecurityAuditorAware implements AuditorAware { - - @Override - public Optional getCurrentAuditor() { - log.trace("getCurrentAuditor start"); - Optional result = Optional.ofNullable(SecurityContextHolder.getContext()) - .map(SecurityContext::getAuthentication) - .map(Authentication::getName); - log.debug("getCurrentAuditor result = {}", result); - log.trace("getCurrentAuditor end"); - return result; - } - -} \ No newline at end of file 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/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java deleted file mode 100644 index bf61e6f8..00000000 --- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/config/DaoConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.dao.config; - -import it.pagopa.selfcare.user_group.connector.dao.auditing.SpringSecurityAuditorAware; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.mongodb.config.EnableMongoAuditing; - -@Configuration -@EnableMongoAuditing(modifyOnCreate = false) -@PropertySource("classpath:config/dao-config.properties") -class DaoConfig { - - @Bean - public AuditorAware myAuditorProvider() { - return new SpringSecurityAuditorAware(); - } - -} 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/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java deleted file mode 100644 index 81db9ee5..00000000 --- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/CriteriaBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.dao.model; - -import org.springframework.data.mongodb.core.query.Criteria; -import org.springframework.lang.NonNull; -import org.springframework.lang.Nullable; - -import java.util.List; - -public class CriteriaBuilder { - - private Criteria criteria; - private boolean first; - - private CriteriaBuilder() { - criteria = new Criteria(); - first = true; - } - - public static CriteriaBuilder builder() { - return new CriteriaBuilder(); - } - - public Criteria build() { - return criteria; - } - - public CriteriaBuilder inIfNotEmpty(@NonNull String key, @Nullable List value) { - if (value != null && !value.isEmpty()) { - if (first) { - criteria = Criteria.where(key).in(value); - first = false; - } else { - criteria = criteria.and(key).in(value); - } - } - return this; - } - - public CriteriaBuilder isIfNotNull(@NonNull String key, @Nullable Object value) { - if (value != null) { - if (first) { - criteria = Criteria.where(key).is(value); - first = false; - } else { - criteria = criteria.and(key).is(value); - } - } - return this; - } -} 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/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java deleted file mode 100644 index 327b2114..00000000 --- a/apps/user-group-ms/connector/dao/src/main/java/it/pagopa/selfcare/user_group/connector/dao/model/UserGroupEntity.java +++ /dev/null @@ -1,66 +0,0 @@ -package it.pagopa.selfcare.user_group.connector.dao.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 lombok.experimental.FieldNameConstants; -import org.springframework.data.annotation.*; -import org.springframework.data.mongodb.core.mapping.Document; - -import java.time.Instant; -import java.util.Set; - -@Data -@NoArgsConstructor -@EqualsAndHashCode(of = "id") -@Document("UserGroups") -@FieldNameConstants(onlyExplicitlyIncluded = true) -public class UserGroupEntity implements UserGroupOperations { - - public UserGroupEntity(UserGroupOperations userGroup) { - this(); - id = userGroup.getId(); - institutionId = userGroup.getInstitutionId(); - productId = userGroup.getProductId(); - name = userGroup.getName(); - description = userGroup.getDescription(); - status = userGroup.getStatus(); - members = userGroup.getMembers(); - createdAt = userGroup.getCreatedAt(); - createdBy = userGroup.getCreatedBy(); - modifiedAt = userGroup.getModifiedAt(); - modifiedBy = userGroup.getModifiedBy(); - } - - @Id - private String id; - @FieldNameConstants.Include - private String institutionId; - @FieldNameConstants.Include - private String productId; - private String name; - private String description; - @FieldNameConstants.Include - private UserGroupStatus status; - @FieldNameConstants.Include - private Set members; - @CreatedDate - private Instant createdAt; - @CreatedBy - private String createdBy; - @LastModifiedDate - @FieldNameConstants.Include - private Instant modifiedAt; - @LastModifiedBy - @FieldNameConstants.Include - private String modifiedBy; - - - public static class Fields { - public static String id = org.springframework.data.mongodb.core.aggregation.Fields.UNDERSCORE_ID; - } - -} 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 5b30716c..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} -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/UserGroupService.java b/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java deleted file mode 100644 index cc6661c2..00000000 --- a/apps/user-group-ms/core/src/main/java/it/pagopa/selfcare/user_group/core/UserGroupService.java +++ /dev/null @@ -1,31 +0,0 @@ -package it.pagopa.selfcare.user_group.core; - -import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations; -import it.pagopa.selfcare.user_group.connector.model.UserGroupFilter; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.UUID; - -public interface UserGroupService { - - UserGroupOperations createGroup(UserGroupOperations group); - - void addMember(String id, UUID memberId); - - void deleteMember(String groupId, String memberId); - - void deleteMembers(String userId, String institutionId, String memberId); - - UserGroupOperations getUserGroup(String id); - - Page getUserGroups(UserGroupFilter filter, Pageable pageable); - - void deleteGroup(String id); - - void suspendGroup(String id); - - void activateGroup(String id); - - UserGroupOperations updateGroup(String id, UserGroupOperations group); -} 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/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java b/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java deleted file mode 100644 index 9b294139..00000000 --- a/apps/user-group-ms/core/src/test/java/it/pagopa/selfcare/user_group/core/config/CoreTestConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package it.pagopa.selfcare.user_group.core.config; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Import; - -@TestConfiguration -@Import(CoreConfig.class) -public class CoreTestConfig { -} diff --git a/apps/user-group-ms/lombok.config b/apps/user-group-ms/lombok.config deleted file mode 100644 index 8f7e8aa1..00000000 --- a/apps/user-group-ms/lombok.config +++ /dev/null @@ -1 +0,0 @@ -lombok.addLombokGeneratedAnnotation = true \ No newline at end of file diff --git a/apps/user-group-ms/mvnw b/apps/user-group-ms/mvnw deleted file mode 100644 index a16b5431..00000000 --- a/apps/user-group-ms/mvnw +++ /dev/null @@ -1,310 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - export JAVA_HOME="`/usr/libexec/java_home`" - else - export JAVA_HOME="/Library/Java/Home" - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=`cd "$wdir/.."; pwd` - fi - # end of workaround - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -BASE_DIR=`find_maven_basedir "$(pwd)"` -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found .mvn/wrapper/maven-wrapper.jar" - fi -else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." - fi - if [ -n "$MVNW_REPOURL" ]; then - jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - else - jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - fi - while IFS="=" read key value; do - case "$key" in (wrapperUrl) jarUrl="$value"; break ;; - esac - done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" - if [ "$MVNW_VERBOSE" = true ]; then - echo "Downloading from: $jarUrl" - fi - wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" - if $cygwin; then - wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` - fi - - if command -v wget > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found wget ... using wget" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget "$jarUrl" -O "$wrapperJarPath" - else - wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - if [ "$MVNW_VERBOSE" = true ]; then - echo "Found curl ... using curl" - fi - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl -o "$wrapperJarPath" "$jarUrl" -f - else - curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f - fi - - else - if [ "$MVNW_VERBOSE" = true ]; then - echo "Falling back to using Java to download" - fi - javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaClass=`cygpath --path --windows "$javaClass"` - fi - if [ -e "$javaClass" ]; then - if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Compiling MavenWrapperDownloader.java ..." - fi - # Compiling the Java class - ("$JAVA_HOME/bin/javac" "$javaClass") - fi - if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then - # Running the downloader - if [ "$MVNW_VERBOSE" = true ]; then - echo " - Running MavenWrapperDownloader.java ..." - fi - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} -if [ "$MVNW_VERBOSE" = true ]; then - echo $MAVEN_PROJECTBASEDIR -fi -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/apps/user-group-ms/mvnw.cmd b/apps/user-group-ms/mvnw.cmd deleted file mode 100644 index c8d43372..00000000 --- a/apps/user-group-ms/mvnw.cmd +++ /dev/null @@ -1,182 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - -FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %DOWNLOAD_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/apps/user-group-ms/pom.xml b/apps/user-group-ms/pom.xml deleted file mode 100644 index b6345be3..00000000 --- a/apps/user-group-ms/pom.xml +++ /dev/null @@ -1,175 +0,0 @@ - - - 4.0.0 - - - it.pagopa.selfcare - selc-starter-parent - 0.0.3-SNAPSHOT - - - - - user-group-ms - pom - 1.0.0-SNAPSHOT - user-group-ms - Microservice to manage Self Care User Group - - - 2.5.1 - https://sonarcloud.io/ - true - - - - - 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 - - - - it.pagopa.selfcare - selc-commons-base - ${selc-commons.version} - - - - 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 - - - - - - - - it.pagopa.selfcare - selc-commons-base - - - - org.owasp.encoder - encoder - 1.2.3 - - - - it.pagopa.selfcare - selc-commons-base - test-jar - test - - - - - core - web - app - connector-api - connector - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - org.sonarsource.scanner.maven - sonar-maven-plugin - 3.10.0.2594 - - - org.jacoco - jacoco-maven-plugin - 0.8.11 - - - - - - - org.jacoco - jacoco-maven-plugin - - - default-prepare-agent - - prepare-agent - - - true - - - - - report - test - - report - - - - - - - - - - - selfcare-platform - - https://pkgs.dev.azure.com/pagopaspa/selfcare-platform-app-projects/_packaging/selfcare-platform/maven/v1 - - - - 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/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java b/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java deleted file mode 100644 index 24bf6715..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/SwaggerConfig.java +++ /dev/null @@ -1,93 +0,0 @@ -package it.pagopa.selfcare.user_group.web.config; - -import com.fasterxml.classmate.TypeResolver; -import it.pagopa.selfcare.commons.web.model.Problem; -import it.pagopa.selfcare.commons.web.swagger.BaseSwaggerConfig; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.*; -import org.springframework.core.env.Environment; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpMethod; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.AuthorizationScope; -import springfox.documentation.service.HttpAuthenticationScheme; -import springfox.documentation.service.SecurityReference; -import springfox.documentation.service.Tag; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spi.service.contexts.SecurityContext; -import springfox.documentation.spring.web.plugins.Docket; - -import java.time.LocalTime; -import java.util.Collections; -import java.util.List; - -import static it.pagopa.selfcare.commons.web.swagger.BaseSwaggerConfig.*; - -/** - * The Class SwaggerConfig. - */ -@Configuration -@Import(BaseSwaggerConfig.class) -class SwaggerConfig { - - private static final String AUTH_SCHEMA_NAME = "bearerAuth"; - - @Configuration - @Profile("swaggerIT") - @PropertySource("classpath:/swagger/swagger_it.properties") - public static class itConfig { - } - - @Configuration - @Profile("swaggerEN") - @PropertySource("classpath:/swagger/swagger_en.properties") - public static class enConfig { - } - - private final Environment environment; - - - @Autowired - SwaggerConfig(Environment environment) { - this.environment = environment; - } - - @Bean - public Docket swaggerSpringPlugin(@Autowired TypeResolver typeResolver) { - return new Docket(DocumentationType.OAS_30) - .apiInfo(new ApiInfoBuilder() - .title(environment.getProperty("swagger.title", environment.getProperty("spring.application.name"))) - .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() - .tags(new Tag("UserGroup", environment.getProperty("swagger.user-group.api.description"))) - .directModelSubstitute(LocalTime.class, String.class) - .ignoredParameterTypes(Pageable.class) - .forCodeGeneration(true) - .useDefaultResponseMessages(false) - .globalResponses(HttpMethod.GET, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE, NOT_FOUND_RESPONSE)) - .globalResponses(HttpMethod.DELETE, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) - .globalResponses(HttpMethod.POST, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) - .globalResponses(HttpMethod.PUT, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) - .globalResponses(HttpMethod.PATCH, List.of(INTERNAL_SERVER_ERROR_RESPONSE, UNAUTHORIZED_RESPONSE, BAD_REQUEST_RESPONSE)) - .additionalModels(typeResolver.resolve(Problem.class)) - .securityContexts(Collections.singletonList(SecurityContext.builder() - .securityReferences(defaultAuth()) - .build())) - .securitySchemes(Collections.singletonList(HttpAuthenticationScheme.JWT_BEARER_BUILDER - .name(AUTH_SCHEMA_NAME) - .description(environment.getProperty("swagger.security.schema.bearer.description")) - .build())); - } - - - private List defaultAuth() { - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - return Collections.singletonList(new SecurityReference(AUTH_SCHEMA_NAME, authorizationScopes)); - } - -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java deleted file mode 100644 index a6e76d05..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/UserGroupSecurityConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package it.pagopa.selfcare.user_group.web.config; - -import it.pagopa.selfcare.commons.web.config.SecurityConfig; -import lombok.extern.slf4j.Slf4j; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; - -@Slf4j -@Configuration -@EnableWebSecurity -@Import(SecurityConfig.class) -class UserGroupSecurityConfig { -} \ No newline at end of file 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/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java deleted file mode 100644 index 0b81dc86..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/config/WebConfig.java +++ /dev/null @@ -1,10 +0,0 @@ -package it.pagopa.selfcare.user_group.web.config; - -import it.pagopa.selfcare.commons.web.config.BaseWebConfig; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -@Configuration -@Import(BaseWebConfig.class) -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/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java deleted file mode 100644 index d21c5cc5..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1Controller.java +++ /dev/null @@ -1,231 +0,0 @@ -package it.pagopa.selfcare.user_group.web.controller; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import io.swagger.annotations.ApiParam; -import io.swagger.v3.oas.annotations.media.Content; -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; -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 lombok.extern.slf4j.Slf4j; -import org.owasp.encoder.Encode; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.web.bind.annotation.*; - -import javax.validation.Valid; -import java.util.List; -import java.util.UUID; - -@Slf4j -@RestController -@RequestMapping(value = "/v1/user-groups", produces = MediaType.APPLICATION_JSON_VALUE) -@Api(tags = "UserGroup") -public class UserGroupV1Controller { - - private final UserGroupService groupService; - private final UserGroupMapper userGroupMapper; - - @Autowired - public UserGroupV1Controller(UserGroupService groupService, - UserGroupMapper userGroupMapper) { - this.groupService = groupService; - this.userGroupMapper = userGroupMapper; - } - - @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) - @ResponseStatus(HttpStatus.CREATED) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.createUserGroup}") - @ApiResponse(responseCode = "409", - description = "Conflict", - content = { - @Content(mediaType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, - schema = @Schema(implementation = Problem.class)) - }) - public UserGroupResource createGroup(@RequestBody - @Valid - CreateUserGroupDto group) { - log.trace("createGroup start"); - log.debug("createGroup group = {}", group); - UserGroupOperations groupOperations = groupService.createGroup(userGroupMapper.fromDto(group)); - UserGroupResource result = userGroupMapper.toResource(groupOperations); - log.debug("createGroup result = {}", result); - log.trace("createGroup end"); - return result; - } - - - @DeleteMapping("/{id}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteUserGroup}") - public void deleteGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id) { - log.trace("deteleGroup start"); - log.debug("deleteGroup id = {}", Encode.forJava(id)); - groupService.deleteGroup(id); - log.trace("deteleGroup end"); - - } - - - @PostMapping("/{id}/activate") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.activateUserGroup}") - public void activateGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id) { - log.trace("activateGroup start"); - log.debug("activateGroup id = {}", Encode.forJava(id)); - groupService.activateGroup(id); - log.trace("activateGroup end"); - } - - - @PostMapping("/{id}/suspend") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.suspendUserGroup}") - public void suspendGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id) { - log.trace("suspendGroup start"); - log.debug("suspendGroup id = {}", Encode.forJava(id)); - groupService.suspendGroup(id); - log.trace("suspendGroup end"); - } - - - @PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE) - @ResponseStatus(HttpStatus.OK) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.updateUserGroup}") - @ApiResponse(responseCode = "409", - description = "Conflict", - content = { - @Content(mediaType = MediaType.APPLICATION_PROBLEM_JSON_VALUE, - schema = @Schema(implementation = Problem.class)) - }) - public UserGroupResource updateUserGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id, - @RequestBody - @Valid - UpdateUserGroupDto groupDto) { - log.trace("updateUserGroup start"); - log.debug("updateUserGroup id = {}", Encode.forJava(id)); - UserGroupOperations updatedGroup = groupService.updateGroup(id, userGroupMapper.toUserGroupOperations(groupDto)); - UserGroupResource result = userGroupMapper.toResource(updatedGroup); - log.debug("updateUserGroup result = {}", result); - log.trace("updateUserGroup end"); - return result; - } - - - @PutMapping(value = "/{id}/members/{memberId}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.addMember}") - public void addMemberToUserGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id, - @ApiParam("${swagger.user-group.model.memberId}") - @PathVariable("memberId") - UUID userId) { - log.trace("addMemberToUserGroup start"); - log.debug("addMemberToUserGroup id = {}", Encode.forJava(id)); - groupService.addMember(id, userId); - log.trace("addMemberToUserGroup end"); - } - - - @Tag(name = "UserGroup") - @Tag(name = "external-v2") - @GetMapping(value = "/{id}") - @ResponseStatus(HttpStatus.OK) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.getUserGroup}") - public UserGroupResource getUserGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String id) { - log.trace("getUserGroup start"); - log.debug("getUserGroup id = {}", Encode.forJava(id)); - UserGroupOperations group = groupService.getUserGroup(id); - UserGroupResource groupResource = userGroupMapper.toResource(group); - log.debug("getUserGroup result = {}", groupResource); - log.trace("getUserGroup end"); - return groupResource; - } - - - @Tag(name = "support") - @Tag(name = "external-v2") - @Tag(name = "UserGroup") - @Tag(name = "support-pnpg") - @Tag(name = "external-pnpg") - @GetMapping() - @ResponseStatus(HttpStatus.OK) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.getUserGroups}") - public Page getUserGroups(@ApiParam("${swagger.user-group.model.institutionId}") - @RequestParam(value = "institutionId", required = false) - String institutionId, - @ApiParam("${swagger.user-group.model.productId}") - @RequestParam(value = "productId", required = false) - String productId, - @ApiParam("${swagger.user-group.model.memberId}") - @RequestParam(value = "userId", required = false) - UUID memberId, - @ApiParam("${swagger.user-group.model.statusFilter}") - @RequestParam(value = "status", required = false) - List status, - Pageable pageable) { - log.trace("getUserGroups start"); - log.debug("getUserGroups institutionId = {}, productId = {}, pageable = {}, status = {}", Encode.forJava(institutionId), Encode.forJava(productId), pageable, status); - UserGroupFilter filter = new UserGroupFilter(institutionId, productId, memberId, status); - Page result = PageMapper.map(groupService.getUserGroups(filter, pageable) - .map(userGroupMapper::toResource)); - log.debug("getUserGroups result = {}", result); - log.trace("getUserGroups end"); - return result; - } - - @DeleteMapping(value = "/{id}/members/{memberId}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteMember}") - public void deleteMemberFromUserGroup(@ApiParam("${swagger.user-group.model.id}") - @PathVariable("id") - String userGroupId, - @ApiParam("${swagger.user-group.model.memberId}") - @PathVariable("memberId") - UUID memberId) { - log.trace("deleteMemberFromUserGroup start"); - log.debug("deleteMemberFromUserGroup userGroupId = {}, memberId = {}", Encode.forJava(userGroupId), memberId); - groupService.deleteMember(userGroupId, memberId.toString()); - log.trace("deleteMemberFromUserGroup end"); - } - - - @DeleteMapping(value = "/members/{memberId}") - @ResponseStatus(HttpStatus.NO_CONTENT) - @ApiOperation(value = "", notes = "${swagger.user-group.groups.api.deleteMember}") - public void deleteMemberFromUserGroups(@ApiParam("${swagger.user-group.model.memberId}") - @PathVariable("memberId") - UUID memberId, - @RequestParam(value = "institutionId") String institutionId, - @RequestParam(value = "productId") String productId) { - log.trace("deleteMemberFromUserGroups start"); - log.debug("deleteMemberFromUserGroups memberId = {}, institutionId = {}, productId = {}", memberId, Encode.forJava(institutionId), Encode.forJava(productId)); - groupService.deleteMembers(memberId.toString(), institutionId, productId); - log.trace("deleteMemberFromUserGroups end"); - } - -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java deleted file mode 100644 index 23ca627b..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandler.java +++ /dev/null @@ -1,37 +0,0 @@ -package it.pagopa.selfcare.user_group.web.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 lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; - -import static org.springframework.http.HttpStatus.*; - -@ControllerAdvice(assignableTypes = {UserGroupV1Controller.class}) -@Slf4j -public class UserGroupExceptionHandler { - - @ExceptionHandler({ResourceAlreadyExistsException.class}) - ResponseEntity handleResourceAlreadyExistsException(ResourceAlreadyExistsException e) { - log.warn(e.toString()); - return ProblemMapper.toResponseEntity(new Problem(CONFLICT, e.getMessage())); - } - - @ExceptionHandler({ResourceUpdateException.class}) - ResponseEntity handleResourceUpdateException(ResourceUpdateException e) { - log.warn(e.toString()); - return ProblemMapper.toResponseEntity(new Problem(BAD_REQUEST, e.getMessage())); - } - - @ExceptionHandler({ResourceNotFoundException.class}) - ResponseEntity handleResourceNotFoundException(ResourceNotFoundException e) { - log.warn(e.toString()); - return ProblemMapper.toResponseEntity(new Problem(NOT_FOUND, e.getMessage())); - } -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java deleted file mode 100644 index 265f720d..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDto.java +++ /dev/null @@ -1,48 +0,0 @@ -package it.pagopa.selfcare.user_group.web.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; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.util.Set; -import java.util.UUID; - -@Data -public class CreateUserGroupDto { - - - @ApiModelProperty(value = "${swagger.user-group.model.institutionId}", required = true) - @JsonProperty(required = true) - @NotBlank - private String institutionId; - - @ApiModelProperty(value = "${swagger.user-group.model.productId}", required = true) - @JsonProperty(required = true) - @NotBlank - private String productId; - - @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) - @JsonProperty(required = true) - @NotBlank - private String name; - - @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) - @JsonProperty(required = true) - @NotBlank - private String description; - - @ApiModelProperty(value = "${swagger.user-group.model.status}", required = true) - @JsonProperty(required = true) - @NotNull - private UserGroupStatus status; - - @ApiModelProperty(value = "${swagger.user-group.model.members}", required = true) - @JsonProperty(required = true) - @NotEmpty - private Set members; - -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java deleted file mode 100644 index 9c047c18..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/GroupDto.java +++ /dev/null @@ -1,23 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import it.pagopa.selfcare.user_group.connector.api.UserGroupOperations; -import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus; -import lombok.Data; - -import java.time.Instant; -import java.util.Set; - -@Data -public class GroupDto implements UserGroupOperations { - private String id; - private String institutionId; - private String productId; - private String name; - private String description; - private UserGroupStatus status; - private Set members; - private Instant createdAt; - private String createdBy; - private Instant modifiedAt; - private String modifiedBy; -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java deleted file mode 100644 index c2229031..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/MemberUUID.java +++ /dev/null @@ -1,16 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; -import java.util.UUID; - -@Data -public class MemberUUID { - @ApiModelProperty(value = "${swagger.user-group.model.memberId}", required = true) - @JsonProperty(required = true) - @NotNull - private UUID member; -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java deleted file mode 100644 index b6932fd2..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDto.java +++ /dev/null @@ -1,28 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import com.fasterxml.jackson.annotation.JsonProperty; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import java.util.Set; -import java.util.UUID; - -@Data -public class UpdateUserGroupDto { - @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) - @JsonProperty(required = true) - @NotBlank - private String name; - - @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) - @JsonProperty(required = true) - @NotBlank - private String description; - - @ApiModelProperty(value = "${swagger.user-group.model.members}", required = true) - @JsonProperty(required = true) - @NotEmpty - private Set members; -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java deleted file mode 100644 index 30fe95b8..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/UserGroupResource.java +++ /dev/null @@ -1,55 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import io.swagger.annotations.ApiModelProperty; -import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus; -import lombok.Data; - -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotNull; -import java.time.Instant; -import java.util.List; -import java.util.UUID; - -@Data -public class UserGroupResource { - - @ApiModelProperty(value = "${swagger.user-group.model.id}", required = true) - @NotBlank - private String id; - - @ApiModelProperty(value = "${swagger.user-group.model.institutionId}", required = true) - @NotBlank - private String institutionId; - - @ApiModelProperty(value = "${swagger.user-group.model.productId}", required = true) - @NotBlank - private String productId; - - @ApiModelProperty(value = "${swagger.user-group.model.name}", required = true) - @NotBlank - private String name; - - @ApiModelProperty(value = "${swagger.user-group.model.description}", required = true) - @NotBlank - private String description; - - @ApiModelProperty(value = "${swagger.user-group.model.status}", required = true) - @NotNull - private UserGroupStatus status; - - @ApiModelProperty(value = "${swagger.user-group.model.members}") - private List members; - - @ApiModelProperty(value = "${swagger.user-group.model.createdAt}") - private Instant createdAt; - - @ApiModelProperty(value = "${swagger.user-group.model.createdBy}") - private String createdBy; - - @ApiModelProperty(value = "${swagger.user-group.model.modifiedAt}") - private Instant modifiedAt; - - @ApiModelProperty(value = "${swagger.user-group.model.modifiedBy}") - private String modifiedBy; - -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java deleted file mode 100644 index 01f6e6af..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/model/mapper/UserGroupMapper.java +++ /dev/null @@ -1,53 +0,0 @@ -package it.pagopa.selfcare.user_group.web.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 org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Named; - -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -@Mapper(componentModel = "spring") -public interface UserGroupMapper { - - @Mapping(source = ".", target = "members", qualifiedByName = "getMembersUUID") - UserGroupResource toResource(UserGroupOperations entity); - - @Mapping(source = ".", target = "members", qualifiedByName = "getMembers") - GroupDto fromDto(CreateUserGroupDto dto); - - @Mapping(source = ".", target = "members", qualifiedByName = "getOperationMembers") - GroupDto toUserGroupOperations(UpdateUserGroupDto dto); - - @Named("getMembersUUID") - default List getMembersUUID(UserGroupOperations entity) { - return entity.getMembers() - .stream() - .map(UUID::fromString) - .collect(Collectors.toList()); - } - - @Named("getMembers") - default Set getMembers(CreateUserGroupDto entity) { - return entity.getMembers() - .stream() - .map(UUID::toString) - .collect(Collectors.toSet()); - } - - @Named("getOperationMembers") - default Set getOperationMembers(UpdateUserGroupDto entity) { - return entity.getMembers() - .stream() - .map(UUID::toString) - .collect(Collectors.toSet()); - } - -} 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/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java deleted file mode 100644 index d461704e..00000000 --- a/apps/user-group-ms/web/src/main/java/it/pagopa/selfcare/user_group/web/validator/UserGroupControllerResponseValidator.java +++ /dev/null @@ -1,26 +0,0 @@ -package it.pagopa.selfcare.user_group.web.validator; - -import it.pagopa.selfcare.commons.web.validator.ControllerResponseValidator; -import org.aspectj.lang.annotation.Aspect; -import org.aspectj.lang.annotation.Pointcut; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.validation.Validator; - -@Aspect -@Component -public class UserGroupControllerResponseValidator extends ControllerResponseValidator { - - @Autowired - public UserGroupControllerResponseValidator(Validator validator) { - super(validator); - } - - @Override - @Pointcut("execution(* it.pagopa.selfcare.user_group.web.controller.*.*(..))") - public void controllersPointcut() { - // Do nothing because is a pointcut - } - -} diff --git a/apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties b/apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties deleted file mode 100644 index 0d6de28b..00000000 --- a/apps/user-group-ms/web/src/main/resources/swagger/swagger_en.properties +++ /dev/null @@ -1,29 +0,0 @@ -swagger.description=The services described in this section deal with the management of UserGroup entity, providing the necessary methods for its creation, consultation and activation. -swagger.security.schema.bearer.description=A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725) -swagger.pageable.page=Results page you want to retrieve (0..N) -swagger.pageable.size=Number of records per page. Default page size is 20 -swagger.pageable.sort=Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported. -swagger.user-group.api.description=User group endpoint CRUD operations -swagger.user-group.groups.api.createUserGroup=Service that allows the insert of a new occurrence for the UserGroup entity -swagger.user-group.groups.api.deleteUserGroup=Service that allows the deletion of a specific occurrence for the UserGroup entity by an Admin user -swagger.user-group.groups.api.activateUserGroup=Service that allows the activation of a specific occurrence for the UserGroup entity by an Admin user -swagger.user-group.groups.api.suspendUserGroup=Service that allows the suspension of a specific occurrence for the UserGroup entity by an Admin user -swagger.user-group.groups.api.updateUserGroup=Service that allows the modification of a specific occurrence for the UserGroup entity by an Admin user -swagger.user-group.groups.api.getUserGroups=Service that allows to get a list of UserGroup entities -swagger.user-group.groups.api.getUserGroup=Service to get a specific UserGroup entity -swagger.user-group.groups.api.addMember=Service to add a member to a specific UserGroup entity -swagger.user-group.groups.api.deleteMember=Service to delete a member from a specific UserGroup entity -swagger.user-group.model.id=Users group's unique identifier -swagger.user-group.model.institutionId=Users group's institutionId -swagger.user-group.model.productId=Users group's productId -swagger.user-group.model.name=Users group's name -swagger.user-group.model.description=Users group's description -swagger.user-group.model.status=Users group's status -swagger.user-group.model.members=List of all the members of the group -swagger.user-group.model.pageable=Details for retrieving usergroups based on size and index -swagger.user-group.model.memberId=Member's unique identifier -swagger.user-group.model.createdAt=Date on which the group was created -swagger.user-group.model.createdBy=User by which the group was created -swagger.user-group.model.modifiedAt=Date on which the group was modified -swagger.user-group.model.modifiedBy=User by which the group was modified -swagger.user-group.model.statusFilter=If filter on status is present, it must be used with at least one of the other filters \ No newline at end of file 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/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java deleted file mode 100644 index f7ce419c..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/config/WebTestConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package it.pagopa.selfcare.user_group.web.config; - -import org.springframework.boot.test.context.TestConfiguration; -import org.springframework.context.annotation.Import; - -@TestConfiguration -@Import(WebConfig.class) -public class WebTestConfig { -} 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/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java deleted file mode 100644 index 5cdeb06c..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/DummyController.java +++ /dev/null @@ -1,14 +0,0 @@ -package it.pagopa.selfcare.user_group.web.controller; - -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class DummyController { - - public Object notVoidMethod() { - return new Object(); - } - - public void voidMethod() { - } -} 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/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java deleted file mode 100644 index 03d67b17..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/controller/UserGroupV1ControllerTest.java +++ /dev/null @@ -1,371 +0,0 @@ -package it.pagopa.selfcare.user_group.web.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 org.junit.jupiter.api.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.Captor; -import org.mockito.Mockito; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.data.domain.Pageable; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.MvcResult; -import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; - -import java.util.List; -import java.util.Set; -import java.util.UUID; - -import static it.pagopa.selfcare.commons.utils.TestUtils.mockInstance; -import static java.util.UUID.randomUUID; -import static org.hamcrest.Matchers.*; -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; -import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; -import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - - -@WebMvcTest(value = {UserGroupV1Controller.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class) -@ContextConfiguration(classes = { - UserGroupV1Controller.class, - UserGroupExceptionHandler.class, - WebTestConfig.class, - UserGroupMapperImpl.class -}) -class UserGroupV1ControllerTest { - - private static final DummyCreateUserGroupDto CREATE_USER_GROUP_DTO = mockInstance(new DummyCreateUserGroupDto()); - private static final DummyUpdateUserGroupDto UPDATE_USER_GROUP_DTO = mockInstance(new DummyUpdateUserGroupDto()); - private static final String BASE_URL = "/v1/user-groups"; - - @MockBean - private UserGroupService groupServiceMock; - - @Autowired - protected MockMvc mvc; - - @Autowired - protected ObjectMapper mapper; - - @Captor - private ArgumentCaptor pageableCaptor; - - @Test - void createGroup() throws Exception { - //given - when(groupServiceMock.createGroup(any(UserGroupOperations.class))) - .thenAnswer(invocationOnMock -> invocationOnMock.getArgument(0, UserGroupOperations.class)); - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .post(BASE_URL) - .content(mapper.writeValueAsString(CREATE_USER_GROUP_DTO)) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isCreated()) - .andReturn(); - //then - UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); - assertNotNull(group); - assertEquals(CREATE_USER_GROUP_DTO.getDescription(), group.getDescription()); - assertEquals(CREATE_USER_GROUP_DTO.getName(), group.getName()); - assertEquals(CREATE_USER_GROUP_DTO.getInstitutionId(), group.getInstitutionId()); - assertEquals(CREATE_USER_GROUP_DTO.getProductId(), group.getProductId()); - assertEquals(CREATE_USER_GROUP_DTO.getStatus(), group.getStatus()); - assertEquals(CREATE_USER_GROUP_DTO.getMembers(), group.getMembers()); - } - - @Test - void deleteGroup_doesNotExists() throws Exception { - //given - Mockito.doThrow(ResourceNotFoundException.class) - .when(groupServiceMock).deleteGroup(Mockito.anyString()); - //when - mvc.perform(MockMvcRequestBuilders - .delete(BASE_URL + "/id") - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNotFound()) - .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) - .andExpect(content().string(not(emptyString()))); - //then - } - - @Test - void deleteGroup() throws Exception { - Mockito.doNothing() - .when(groupServiceMock).deleteGroup(Mockito.anyString()); - // when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .delete(BASE_URL + "/id") - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().is2xxSuccessful()) - .andReturn(); - // then - assertEquals("", result.getResponse().getContentAsString()); - verify(groupServiceMock, times(1)) - .deleteGroup(Mockito.anyString()); - Mockito.verifyNoMoreInteractions(groupServiceMock); - - } - - @Test - void activateGroup_doesNotExists() throws Exception { - //given - String groupId = "groupId"; - Mockito.doThrow(ResourceNotFoundException.class) - .when(groupServiceMock).activateGroup(Mockito.anyString()); - //when - mvc.perform(MockMvcRequestBuilders - .post(BASE_URL + "/{id}/activate", groupId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNotFound()) - .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) - .andExpect(content().string(not(emptyString()))); - //then - } - - @Test - void activateGroup() throws Exception { - //given - String groupId = "groupId"; - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .post(BASE_URL + "/{id}/activate", groupId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNoContent()) - .andReturn(); - //then - assertEquals(0, result.getResponse().getContentLength()); - verify(groupServiceMock, times(1)) - .activateGroup(groupId); - Mockito.verifyNoMoreInteractions(groupServiceMock); - } - - @Test - void suspendGroup_doesNotExists() throws Exception { - //given - String groupId = "groupId"; - Mockito.doThrow(ResourceNotFoundException.class) - .when(groupServiceMock).suspendGroup(Mockito.anyString()); - //when - mvc.perform(MockMvcRequestBuilders - .post(BASE_URL + "/{id}/suspend", groupId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNotFound()) - .andExpect(content().contentType(APPLICATION_PROBLEM_JSON)) - .andExpect(content().string(not(emptyString()))); - //then - } - - @Test - void suspendGroup() throws Exception { - //given - String groupId = "groupId"; - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .post(BASE_URL + "/{id}/suspend", groupId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNoContent()) - .andReturn(); - //then - assertEquals(0, result.getResponse().getContentLength()); - verify(groupServiceMock, times(1)) - .suspendGroup(groupId); - Mockito.verifyNoMoreInteractions(groupServiceMock); - } - - @Test - void updateGroup_exists() throws Exception { - //given - when(groupServiceMock.updateGroup(Mockito.anyString(), any(UserGroupOperations.class))) - .thenAnswer(invocationOnMock -> { - String id = invocationOnMock.getArgument(0, String.class); - UserGroupOperations group = invocationOnMock.getArgument(1, UserGroupOperations.class); - group.setId(id); - group.setMembers(Set.of(randomUUID().toString(), randomUUID().toString())); - return group; - }); - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .put(BASE_URL + "/id") - .content(mapper.writeValueAsString(UPDATE_USER_GROUP_DTO)) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().is2xxSuccessful()) - .andReturn(); - //then - UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); - - assertNotNull(group); - assertEquals(UPDATE_USER_GROUP_DTO.getDescription(), group.getDescription()); - assertEquals(UPDATE_USER_GROUP_DTO.getName(), group.getName()); - assertNotEquals(UPDATE_USER_GROUP_DTO.getMembers().size(), group.getMembers().size()); - } - - @Test - void addMember() throws Exception { - //given - String groupId = "groupId"; - MemberUUID member = new MemberUUID(); - member.setMember(randomUUID()); - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .put(BASE_URL + "/groupId/members/" + member.getMember()) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().is2xxSuccessful()) - .andReturn(); - //then - assertEquals(0, result.getResponse().getContentLength()); - verify(groupServiceMock, times(1)) - .addMember(groupId, member.getMember()); - Mockito.verifyNoMoreInteractions(groupServiceMock); - } - - @Test - void deleteMember() throws Exception { - //given - String groupId = "groupId"; - UUID memberId = randomUUID(); - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .delete(BASE_URL + "/groupId/members/" + memberId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNoContent()) - .andReturn(); - //then - assertEquals(0, result.getResponse().getContentLength()); - verify(groupServiceMock, times(1)) - .deleteMember(groupId, memberId.toString()); - Mockito.verifyNoMoreInteractions(groupServiceMock); - } - - @Test - void getUserGroup() throws Exception { - //given - String InstitutionId = "institutionId"; - String productId = "productId"; - when(groupServiceMock.getUserGroup(Mockito.anyString())) - .thenAnswer(invocationOnMock -> { - String id = invocationOnMock.getArgument(0, String.class); - UserGroupOperations group = mockInstance(new GroupDto(), "setId"); - group.setId(id); - group.setMembers(Set.of(randomUUID().toString(), randomUUID().toString())); - return group; - }); - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .get(BASE_URL + "/groupId") - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().is2xxSuccessful()) - .andReturn(); - //then - UserGroupResource group = mapper.readValue(result.getResponse().getContentAsString(), UserGroupResource.class); - assertNotNull(group); - } - - @Test - void getUserGroups() throws Exception { - //given - String institutionId = "institutionId"; - String productId = "productId"; - String userId = randomUUID().toString(); - UserGroupStatus allowedStatus = UserGroupStatus.ACTIVE; - final int page = 1; - final int size = 3; - UserGroupOperations groupOperations = mockInstance(new GroupDto()); - groupOperations.setMembers(Set.of(randomUUID().toString())); - when(groupServiceMock.getUserGroups(any(), any())) - .thenAnswer(invocation -> { - final Pageable pageable = invocation.getArgument(1, Pageable.class); - return getPage(List.of(groupOperations), pageable, () -> pageable.isPaged() - ? (long) pageable.getPageSize() * pageable.getPageNumber() + 1 - : 1); - }); - //when - mvc.perform(MockMvcRequestBuilders - .get(BASE_URL + "/") - .param("institutionId", institutionId) - .param("productId", productId) - .param("userId", userId) - .param("status", String.valueOf(allowedStatus)) - .param("page", String.valueOf(page)) - .param("size", String.valueOf(size)) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.number", notNullValue())) - .andExpect(jsonPath("$.size", notNullValue())) - .andExpect(jsonPath("$.totalElements", notNullValue())) - .andExpect(jsonPath("$.totalPages", notNullValue())) - .andExpect(jsonPath("$.content", notNullValue())) - .andExpect(jsonPath("$.content[0].id", notNullValue())) - .andExpect(jsonPath("$.content[0].institutionId", notNullValue())) - .andExpect(jsonPath("$.content[0].productId", notNullValue())) - .andExpect(jsonPath("$.content[0].name", notNullValue())) - .andExpect(jsonPath("$.content[0].description", notNullValue())) - .andExpect(jsonPath("$.content[0].status", notNullValue())) - .andExpect(jsonPath("$.content[0].members", not(emptyArray()))) - .andExpect(jsonPath("$.content[0].createdAt", notNullValue())) - .andExpect(jsonPath("$.content[0].createdBy", notNullValue())) - .andExpect(jsonPath("$.content[0].modifiedAt", notNullValue())) - .andExpect(jsonPath("$.content[0].modifiedBy", notNullValue())); - //then - ArgumentCaptor filterCaptor = ArgumentCaptor.forClass(UserGroupFilter.class); - verify(groupServiceMock, times(1)) - .getUserGroups(filterCaptor.capture(), pageableCaptor.capture()); - UserGroupFilter capturedFilter = filterCaptor.getValue(); - assertEquals(capturedFilter.getProductId(), productId); - assertEquals(capturedFilter.getInstitutionId(), institutionId); - assertEquals(capturedFilter.getUserId(), userId); - Pageable capturedPageable = pageableCaptor.getValue(); - assertTrue(capturedPageable.getSort().isUnsorted()); - assertEquals(page, capturedPageable.getPageNumber()); - assertEquals(size, capturedPageable.getPageSize()); - } - - @Test - void deleteMembers() throws Exception { - //given - UUID memberId = randomUUID(); - String institutionId = "institutionId"; - String productId = "productId"; - //when - MvcResult result = mvc.perform(MockMvcRequestBuilders - .delete(BASE_URL + "/members/" + memberId) - .param("institutionId", institutionId) - .param("productId", productId) - .contentType(APPLICATION_JSON_VALUE) - .accept(APPLICATION_JSON_VALUE)) - .andExpect(status().isNoContent()) - .andReturn(); - //then - assertEquals(0, result.getResponse().getContentLength()); - verify(groupServiceMock, times(1)) - .deleteMembers(memberId.toString(), institutionId, productId); - Mockito.verifyNoMoreInteractions(groupServiceMock); - } - -} \ No newline at end of file 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/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java deleted file mode 100644 index 1bc2ebdd..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/handler/UserGroupExceptionHandlerTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package it.pagopa.selfcare.user_group.web.handler; - -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; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.springframework.http.HttpStatus.*; - -class UserGroupExceptionHandlerTest { - private static final String DETAIL_MESSAGE = "detail message"; - private final UserGroupExceptionHandler handler = new UserGroupExceptionHandler(); - - - @Test - void resourceNotFoundException() { - //given - ResourceNotFoundException mockException = Mockito.mock(ResourceNotFoundException.class); - Mockito.when(mockException.getMessage()) - .thenReturn(DETAIL_MESSAGE); - //when - ResponseEntity responseEntity = handler.handleResourceNotFoundException(mockException); - //then - assertNotNull(responseEntity); - assertEquals(NOT_FOUND, responseEntity.getStatusCode()); - assertNotNull(responseEntity.getBody()); - assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); - assertEquals(NOT_FOUND.value(), responseEntity.getBody().getStatus()); - } - - @Test - void resourceAlreadyExistsException() { - //given - ResourceAlreadyExistsException mockException = Mockito.mock(ResourceAlreadyExistsException.class); - Mockito.when(mockException.getMessage()) - .thenReturn(DETAIL_MESSAGE); - //when - ResponseEntity responseEntity = handler.handleResourceAlreadyExistsException(mockException); - //then - assertNotNull(responseEntity); - assertEquals(CONFLICT, responseEntity.getStatusCode()); - assertNotNull(responseEntity.getBody()); - assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); - assertEquals(CONFLICT.value(), responseEntity.getBody().getStatus()); - } - - @Test - void resourceUpdateException() { - //given - ResourceUpdateException mockException = Mockito.mock(ResourceUpdateException.class); - Mockito.when(mockException.getMessage()) - .thenReturn(DETAIL_MESSAGE); - //when - ResponseEntity responseEntity = handler.handleResourceUpdateException(mockException); - //then - assertNotNull(responseEntity); - assertEquals(BAD_REQUEST, responseEntity.getStatusCode()); - assertNotNull(responseEntity.getBody()); - assertEquals(DETAIL_MESSAGE, responseEntity.getBody().getDetail()); - assertEquals(BAD_REQUEST.value(), responseEntity.getBody().getStatus()); - } - -} \ No newline at end of file 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/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java deleted file mode 100644 index 51828516..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/CreateUserGroupDtoTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import it.pagopa.selfcare.commons.utils.TestUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class CreateUserGroupDtoTest { - private Validator validator; - - @BeforeEach - void setUp() { - ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - validator = validatorFactory.getValidator(); - } - - @Test - void validateNullFields() { - // given - HashMap> toCheckMap = new HashMap<>(); - toCheckMap.put("institutionId", NotBlank.class); - toCheckMap.put("productId", NotBlank.class); - toCheckMap.put("name", NotBlank.class); - toCheckMap.put("description", NotBlank.class); - toCheckMap.put("status", NotNull.class); - toCheckMap.put("members", NotEmpty.class); - CreateUserGroupDto createUserGroupDto = new CreateUserGroupDto(); - createUserGroupDto.setDescription(null); - createUserGroupDto.setMembers(null); - createUserGroupDto.setName(null); - createUserGroupDto.setStatus(null); - createUserGroupDto.setProductId(null); - createUserGroupDto.setInstitutionId(null); - // when - Set> violations = validator.validate(createUserGroupDto); - // then - assertFalse(violations.isEmpty()); - List> filteredViolations = violations.stream() - .filter(violation -> { - Class annotationToCheck = toCheckMap.get(violation.getPropertyPath().toString()); - return !violation.getConstraintDescriptor().getAnnotation().annotationType().equals(annotationToCheck); - }) - .collect(Collectors.toList()); - assertTrue(filteredViolations.isEmpty()); - } - - @Test - void validateNotNullFields() { - // given - CreateUserGroupDto userGroupDto = TestUtils.mockInstance(new CreateUserGroupDto()); - userGroupDto.setMembers(Set.of(UUID.randomUUID())); - // when - Set> violations = validator.validate(userGroupDto); - // then - assertTrue(violations.isEmpty()); - } -} \ No newline at end of file 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/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java deleted file mode 100644 index 0c88bc5c..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyCreateUserGroupDto.java +++ /dev/null @@ -1,18 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import it.pagopa.selfcare.user_group.connector.model.UserGroupStatus; -import lombok.Data; - -import java.util.List; -import java.util.UUID; - -@Data -public class DummyCreateUserGroupDto { - - private String institutionId; - private String productId; - private String name; - private String description; - private UserGroupStatus status; - private List members = List.of(UUID.randomUUID()); -} 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/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java deleted file mode 100644 index 4ec3d794..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/DummyUpdateUserGroupDto.java +++ /dev/null @@ -1,13 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import lombok.Data; - -import java.util.List; -import java.util.UUID; - -@Data -public class DummyUpdateUserGroupDto { - private String name; - private String description; - private List members = List.of(UUID.randomUUID()); -} 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/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java deleted file mode 100644 index 2afd0828..00000000 --- a/apps/user-group-ms/web/src/test/java/it/pagopa/selfcare/user_group/web/model/UpdateUserGroupDtoTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package it.pagopa.selfcare.user_group.web.model; - -import it.pagopa.selfcare.commons.utils.TestUtils; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import javax.validation.ConstraintViolation; -import javax.validation.Validation; -import javax.validation.Validator; -import javax.validation.ValidatorFactory; -import javax.validation.constraints.NotBlank; -import javax.validation.constraints.NotEmpty; -import java.lang.annotation.Annotation; -import java.util.HashMap; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import java.util.stream.Collectors; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class UpdateUserGroupDtoTest { - private Validator validator; - - @BeforeEach - void setUp() { - ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); - validator = validatorFactory.getValidator(); - } - - @Test - void validateNullFields() { - // given - HashMap> toCheckMap = new HashMap<>(); - toCheckMap.put("name", NotBlank.class); - toCheckMap.put("description", NotBlank.class); - toCheckMap.put("members", NotEmpty.class); - UpdateUserGroupDto updateUserGroupDto = new UpdateUserGroupDto(); - updateUserGroupDto.setDescription(null); - updateUserGroupDto.setMembers(null); - updateUserGroupDto.setName(null); - - // when - Set> violations = validator.validate(updateUserGroupDto); - // then - assertFalse(violations.isEmpty()); - List> filteredViolations = violations.stream() - .filter(violation -> { - Class annotationToCheck = toCheckMap.get(violation.getPropertyPath().toString()); - return !violation.getConstraintDescriptor().getAnnotation().annotationType().equals(annotationToCheck); - }) - .collect(Collectors.toList()); - assertTrue(filteredViolations.isEmpty()); - } - - @Test - void validateNotNullFields() { - // given - UpdateUserGroupDto userGroupDto = TestUtils.mockInstance(new UpdateUserGroupDto()); - userGroupDto.setMembers(Set.of(UUID.randomUUID())); - // when - Set> violations = validator.validate(userGroupDto); - // then - assertTrue(violations.isEmpty()); - } - -} \ No newline at end of file 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 From 9c3bb35f7e8e54ddc8171882364b1f1542fef627 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Fri, 13 Dec 2024 17:43:42 +0100 Subject: [PATCH 5/8] [SELC-5969] completed refactpr user-group-ms, added all cucumber scenarios --- apps/cucumber/pom.xml | 130 --- .../cucumber/SelfCareCucumberApplication.java | 17 - .../selfcare/cucumber/dao/CucumberConfig.java | 9 - .../cucumber/dao/UserGroupRepository.java | 8 - .../cucumber/model/UserGroupEntity.java | 24 - .../cucumber/model/UserGroupStatus.java | 7 - .../src/main/resources/application.yml | 31 - .../selfcare/cucumber/CucumberTest.java | 12 - .../cucumber/config/CucumberTestConfig.java | 11 - .../cucumber/steps/UserGroupSteps.java | 70 -- .../cucumber/utils/DataTypeConverter.java | 6 - .../resources/application.test.properties | 3 - .../src/test/resources/cucumber.properties | 3 - .../test/resources/dataPopulation/data.yaml | 1 - apps/pom.xml | 11 + apps/user-group-ms-2/app/pom.xml | 90 -- .../app/src/main/docs/openapi.json | 36 - apps/user-group-ms-2/pom.xml | 136 --- .../Dockerfile | 0 .../Dockerfile.dockerignore | 0 .../README.md | 0 .../lombok.config | 0 apps/{user-group-ms-2 => user-group-ms}/mvnw | 0 .../mvnw.cmd | 0 apps/user-group-ms/pom.xml | 241 +++++ apps/user-group-ms/src/main/docs/openapi.json | 977 ++++++++++++++++++ .../SelfCareUserGroupApplication.java | 0 .../user_group/api/UserGroupOperations.java | 1 + .../auditing/SpringSecurityAuditorAware.java | 0 .../user_group/config/CoreConfig.java | 0 .../user_group/config/SwaggerConfig.java | 4 +- .../config/UserGroupSecurityConfig.java | 0 .../selfcare/user_group/config/WebConfig.java | 2 +- .../controller/UserGroupV1Controller.java | 12 +- .../user_group/dao/UserGroupRepository.java | 0 .../ResourceAlreadyExistsException.java | 0 .../exception/ResourceNotFoundException.java | 0 .../exception/ResourceUpdateException.java | 0 .../handler/UserGroupExceptionHandler.java | 2 +- .../user_group/model/CreateUserGroupDto.java | 0 .../user_group/model/CriteriaBuilder.java | 0 .../selfcare/user_group/model/GroupDto.java | 0 .../selfcare/user_group/model/MemberUUID.java | 0 .../user_group/model/UpdateUserGroupDto.java | 0 .../user_group/model/UserGroupEntity.java | 1 - .../user_group/model/UserGroupFilter.java | 0 .../user_group/model/UserGroupResource.java | 0 .../user_group/model/UserGroupStatus.java | 0 .../model/mapper/UserGroupMapper.java | 0 .../user_group/service/UserGroupService.java | 0 .../service/UserGroupServiceImpl.java | 2 +- .../UserGroupControllerResponseValidator.java | 0 .../src/main/resources/config/application.yml | 0 .../resources/config/core-config.properties | 0 .../resources/swagger/swagger_en.properties | 0 .../user_group/config/CoreTestConfig.java | 0 .../user_group/config/SwaggerConfigTest.java | 4 +- .../user_group/config/WebTestConfig.java | 0 .../controller/DummyController.java | 0 .../controller/UserGroupV1ControllerTest.java | 6 +- .../dao/UserGroupRepositoryTest.java | 4 +- .../UserGroupExceptionHandlerTest.java | 2 +- .../integration_test/CucumberConfig.java | 15 + .../integration_test/CucumberSuite.java | 18 + .../steps/CreateUserGroupSteps.java | 13 +- .../steps/RetrieveUserGroupSteps.java | 15 +- .../steps/UpdateUserGroupSteps.java | 4 +- .../steps/UserGroupMemberSteps.java | 13 +- .../steps/UserGroupSteps.java | 77 ++ .../model/CreateUserGroupDtoTest.java | 0 .../model/DummyCreateUserGroupDto.java | 0 .../selfcare/user_group/model/DummyGroup.java | 0 .../model/DummyUpdateUserGroupDto.java | 0 .../user_group/model/TestProperties.java | 8 + .../model/UpdateUserGroupDtoTest.java | 0 .../model/UserGroupEntityPageable.java | 2 +- .../service/UserGroupServiceImplTest.java | 6 +- .../resources/application-test.properties} | 2 + .../test/resources/dataPopulation/data.json | 3 + .../dataPopulation/groupEntities.json | 21 +- .../resources/features}/createGroup.feature | 4 +- .../features}/retrieveUserGroup.feature | 4 +- .../features}/updateUserGroup.feature | 0 .../features}/userGroupMembers.feature | 6 +- pom.xml | 1 + 85 files changed, 1411 insertions(+), 664 deletions(-) delete mode 100644 apps/cucumber/pom.xml delete mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java delete mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java delete mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java delete mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java delete mode 100644 apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java delete mode 100644 apps/cucumber/src/main/resources/application.yml delete mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java delete mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java delete mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java delete mode 100644 apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java delete mode 100644 apps/cucumber/src/test/resources/application.test.properties delete mode 100644 apps/cucumber/src/test/resources/cucumber.properties delete mode 100644 apps/cucumber/src/test/resources/dataPopulation/data.yaml delete mode 100644 apps/user-group-ms-2/app/pom.xml delete mode 100644 apps/user-group-ms-2/app/src/main/docs/openapi.json delete mode 100644 apps/user-group-ms-2/pom.xml rename apps/{user-group-ms-2 => user-group-ms}/Dockerfile (100%) rename apps/{user-group-ms-2 => user-group-ms}/Dockerfile.dockerignore (100%) rename apps/{user-group-ms-2 => user-group-ms}/README.md (100%) rename apps/{user-group-ms-2 => user-group-ms}/lombok.config (100%) rename apps/{user-group-ms-2 => user-group-ms}/mvnw (100%) rename apps/{user-group-ms-2 => user-group-ms}/mvnw.cmd (100%) create mode 100644 apps/user-group-ms/pom.xml create mode 100644 apps/user-group-ms/src/main/docs/openapi.json rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/SelfCareUserGroupApplication.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java (99%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java (98%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java (91%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java (95%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java (99%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java (99%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/resources/config/application.yml (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/resources/config/core-config.properties (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/main/resources/swagger/swagger_en.properties (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java (95%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java (99%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java (100%) create mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberConfig.java create mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberSuite.java rename apps/{cucumber/src/test/java/it/pagopa/selfcare/cucumber => user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test}/steps/CreateUserGroupSteps.java (91%) rename apps/{cucumber/src/test/java/it/pagopa/selfcare/cucumber => user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test}/steps/RetrieveUserGroupSteps.java (93%) rename apps/{cucumber/src/test/java/it/pagopa/selfcare/cucumber => user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test}/steps/UpdateUserGroupSteps.java (98%) rename apps/{cucumber/src/test/java/it/pagopa/selfcare/cucumber => user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test}/steps/UserGroupMemberSteps.java (90%) create mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupSteps.java rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java (100%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java (100%) create mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/TestProperties.java rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java (100%) rename apps/{cucumber/src/main/java/it/pagopa/selfcare/cucumber => user-group-ms/src/test/java/it/pagopa/selfcare/user_group}/model/UserGroupEntityPageable.java (85%) rename apps/{user-group-ms-2/app => user-group-ms}/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java (99%) rename apps/{cucumber/src/main/resources/application.properties => user-group-ms/src/test/resources/application-test.properties} (68%) create mode 100644 apps/user-group-ms/src/test/resources/dataPopulation/data.json rename apps/{cucumber => user-group-ms}/src/test/resources/dataPopulation/groupEntities.json (63%) rename apps/{cucumber/src/test/resources/cucumber/scenarios => user-group-ms/src/test/resources/features}/createGroup.feature (94%) rename apps/{cucumber/src/test/resources/cucumber/scenarios => user-group-ms/src/test/resources/features}/retrieveUserGroup.feature (96%) rename apps/{cucumber/src/test/resources/cucumber/scenarios => user-group-ms/src/test/resources/features}/updateUserGroup.feature (100%) rename apps/{cucumber/src/test/resources/cucumber/scenarios => user-group-ms/src/test/resources/features}/userGroupMembers.feature (98%) diff --git a/apps/cucumber/pom.xml b/apps/cucumber/pom.xml deleted file mode 100644 index ff505c6a..00000000 --- a/apps/cucumber/pom.xml +++ /dev/null @@ -1,130 +0,0 @@ - - - - selc-starter-parent - it.pagopa.selfcare - 0.0.3-SNAPSHOT - - 4.0.0 - - - 17 - 17 - UTF-8 - 2.5.1 - - - selfcare-cucumber - - - - io.cucumber - cucumber-java - 7.20.1 - - - - 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 - - - io.cucumber - cucumber-junit-platform-engine - 7.20.1 - test - - - - org.junit.platform - junit-platform-suite-api - 1.11.3 - test - - - io.cucumber - cucumber-spring - 7.19.0 - - - org.springframework.boot - spring-boot-starter - 3.4.0 - - - org.springframework.boot - spring-boot-starter-data-mongodb - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.17.0 - test - - - - - - - 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 - - - - - - org.apache.maven.plugins - maven-jar-plugin - - true - - - - - test-jar - - - - - - - - diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java deleted file mode 100644 index c96ddce9..00000000 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/SelfCareCucumberApplication.java +++ /dev/null @@ -1,17 +0,0 @@ -package it.pagopa.selfcare.cucumber; - -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.ApplicationContext; - -@SpringBootApplication -public class SelfCareCucumberApplication { - - - public static void main(String[] args) { - SpringApplication.run(SelfCareCucumberApplication.class, args); - } - -} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java deleted file mode 100644 index d9a77568..00000000 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/CucumberConfig.java +++ /dev/null @@ -1,9 +0,0 @@ -package it.pagopa.selfcare.cucumber.dao; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.PropertySource; - -@Configuration -@PropertySource("classpath:application.properties") -public class CucumberConfig { -} \ No newline at end of file diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java deleted file mode 100644 index 784978f6..00000000 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/dao/UserGroupRepository.java +++ /dev/null @@ -1,8 +0,0 @@ -package it.pagopa.selfcare.cucumber.dao; - -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import org.springframework.data.mongodb.repository.MongoRepository; - -public interface UserGroupRepository extends MongoRepository { - -} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java deleted file mode 100644 index 0af60294..00000000 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntity.java +++ /dev/null @@ -1,24 +0,0 @@ -package it.pagopa.selfcare.cucumber.model; - -import lombok.Data; -import org.springframework.data.mongodb.core.mapping.Document; - -import java.time.Instant; -import java.util.Set; - -@Data -@Document("UserGroups") -public class UserGroupEntity{ - - private String id; - private String institutionId; - private String productId; - private String name; - private String description; - private UserGroupStatus status; - private Set members; - private Instant createdAt; - private String createdBy; - private Instant modifiedAt; - private String modifiedBy; -} diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java b/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java deleted file mode 100644 index 5c5505f7..00000000 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupStatus.java +++ /dev/null @@ -1,7 +0,0 @@ -package it.pagopa.selfcare.cucumber.model; - -public enum UserGroupStatus { - ACTIVE, - SUSPENDED, - DELETED -} diff --git a/apps/cucumber/src/main/resources/application.yml b/apps/cucumber/src/main/resources/application.yml deleted file mode 100644 index 02599b30..00000000 --- a/apps/cucumber/src/main/resources/application.yml +++ /dev/null @@ -1,31 +0,0 @@ -server: - port: 8080 - -spring: - application: - name: "@project.parent.artifactId@" - version: "@project.version@" - profiles: - include: - # TO enable specific-language documentations - - swaggerEN - zipkin: - enabled: false - sleuth: - baggage: - remote-fields: X-Client-Ip - correlation-fields: X-Client-Ip - -info: - build: - artifact: "@project.parent.artifactId@" - name: "@project.parent.artifactId@" - description: "@project.description@" - version: "@project.version@" - - -logging: - level: - it.pagopa.selfcare: DEBUG - pattern: - additional-info: ",%X{X-Client-Ip:-}]" diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java deleted file mode 100644 index 98ef9532..00000000 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/CucumberTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package it.pagopa.selfcare.cucumber; - -import org.junit.platform.suite.api.IncludeEngines; -import org.junit.platform.suite.api.SelectClasspathResource; -import org.junit.platform.suite.api.Suite; - -@Suite -@IncludeEngines("cucumber") -@SelectClasspathResource("cucumber") -public class CucumberTest { -} - diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java deleted file mode 100644 index 44889c2e..00000000 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/config/CucumberTestConfig.java +++ /dev/null @@ -1,11 +0,0 @@ -package it.pagopa.selfcare.cucumber.config; - -import io.cucumber.spring.CucumberContextConfiguration; -import it.pagopa.selfcare.cucumber.SelfCareCucumberApplication; -import org.springframework.boot.test.context.SpringBootTest; - -@CucumberContextConfiguration -@SpringBootTest(classes = SelfCareCucumberApplication.class) -public class CucumberTestConfig { - -} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java deleted file mode 100644 index 6844882e..00000000 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupSteps.java +++ /dev/null @@ -1,70 +0,0 @@ -package it.pagopa.selfcare.cucumber.steps; - -import com.fasterxml.jackson.databind.ObjectMapper; -import it.pagopa.selfcare.cucumber.dao.UserGroupRepository; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import it.pagopa.selfcare.cucumber.model.UserGroupEntityPageable; -import org.junit.jupiter.api.Assertions; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Pageable; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -public class UserGroupSteps { - - protected String userGroupId; - protected UUID userGroupMemberId; - protected UserGroupEntity userGroupDetails; - protected UserGroupEntity userGroupEntityResponse; - protected UserGroupEntity updatedUserGroupEntity; - protected UserGroupEntityPageable userGroupEntityResponsePage; - protected Pageable pageable; - protected String sort; - - protected UserGroupEntity userGroupEntityFilter; - protected int status; - protected String errorMessage; - - @Autowired - protected UserGroupRepository userGroupRepository; - - @Autowired - protected ObjectMapper objectMapper; - - protected List userGroupsIds = List.of("6759f8df78b6af202b222d29", "6759f8df78b6af202b222d2a","6759f8df78b6af202b222d2b"); - - protected String token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTk2MzQwLCJleHAiOjE3MzQwMjg3NDAsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8zZTg4NzkyNzRmODJlMGY5Yzk0MSJ9.myOhEFshQKu0agM9jIg0WakcQF0rNVRSrh9k2k5-LA3SkIUpN_Io6d9dLg9Rb7aTGqU50BxEk0OP4zGDJSUjT6pHfWJz0emGFL9UkVJ-w9Jc7WX2oMuj-E9ej9YuB7pXNYM9bKvg4PpE4ZMvnLVxvh_AuTmDVM9nK7K0uD1vvPWptmIwQSjlJhA68LWVxLMlfMVoCk7ysmtIdAkbD4QkqFsP1mQKCOSH2EQUyz_NQFgYWX70-9boSuwx8kOTOHturG1xAuLCGXqhk6yk_HgJShDkeDI6Q9C73dYBE_nNKeJ-yg10vNfiYV5MPjjFiW4eeqvKw5ATf8LhhJmIrjMDcw"; - - /* public Map readDataPopulation() { - ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory()); - TypeReference> typeReference = new TypeReference<>() { - }; - Map readValue = new HashMap<>(); - try { - return objectMapper.readValue(new File("src/test/resources/dataPopulation/data.yaml"), typeReference); - } catch (IOException e) { - e.printStackTrace(); - } - return readValue; - }*/ - - 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); - } - -} diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java b/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java deleted file mode 100644 index 15e950c7..00000000 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/utils/DataTypeConverter.java +++ /dev/null @@ -1,6 +0,0 @@ -package it.pagopa.selfcare.cucumber.utils; - -public class DataTypeConverter { - - -} diff --git a/apps/cucumber/src/test/resources/application.test.properties b/apps/cucumber/src/test/resources/application.test.properties deleted file mode 100644 index 65e9fa5f..00000000 --- a/apps/cucumber/src/test/resources/application.test.properties +++ /dev/null @@ -1,3 +0,0 @@ -user-group.allowed.sorting.parameters=name -spring.data.mongodb.uri=mongodb://localhost:27017 -spring.data.mongodb.database=selcUserGroup diff --git a/apps/cucumber/src/test/resources/cucumber.properties b/apps/cucumber/src/test/resources/cucumber.properties deleted file mode 100644 index 8c89c962..00000000 --- a/apps/cucumber/src/test/resources/cucumber.properties +++ /dev/null @@ -1,3 +0,0 @@ -cucumber.features=classpath:cucumber/scenarios -cucumber.glue=it.pagopa.selfcare.cucumber.steps -cucumber.plugin=pretty,html:target/cucumber-reports diff --git a/apps/cucumber/src/test/resources/dataPopulation/data.yaml b/apps/cucumber/src/test/resources/dataPopulation/data.yaml deleted file mode 100644 index 93994919..00000000 --- a/apps/cucumber/src/test/resources/dataPopulation/data.yaml +++ /dev/null @@ -1 +0,0 @@ -token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Imp3dF9hMjo3YTo0NjozYjoyYTo2MDo1Njo0MDo4ODphMDo1ZDphNDpmODowMToxZTozZSJ9.eyJmYW1pbHlfbmFtZSI6IkJhbGJvYSIsImZpc2NhbF9udW1iZXIiOiJCTEJSS1k2N0MzMEg1MDFCIiwibmFtZSI6IlJvY2t5Iiwic3BpZF9sZXZlbCI6Imh0dHBzOi8vd3d3LnNwaWQuZ292Lml0L1NwaWRMMiIsImZyb21fYWEiOmZhbHNlLCJ1aWQiOiI0YmEyODMyZC05YzRjLTQwZjMtOTEyNi1lMWM3MjkwNWVmMTQiLCJsZXZlbCI6IkwyIiwiaWF0IjoxNzMzOTIxMTg1LCJleHAiOjE3MzM5NTM1ODUsImF1ZCI6ImFwaS5kZXYuc2VsZmNhcmUucGFnb3BhLml0IiwiaXNzIjoiU1BJRCIsImp0aSI6Il8yMGM3YmY1OTdlY2UyNzYxOTUyNyJ9.pc65diXLGvMEJI1CmVZqtkJLu7QdPPkZ7B8xjbj8gkUEItShV-L25O5JBtexkTIm4YJM86rv4ORiIEISPY1oP9vv1CN6I1DUDJXWhh5uMuvK2_soKzhP5IlyxVGl6GtmpD38Q1YVr0faB7EABwrOVUVYEkufZF0WgzYdYQFgG_YPv5qNqEj9SReC0nWSPP8gM5Z1ARA3mzLccEvLy253uZ1-IBbNhFwf2m0xc97lVSqov0jxYaoudFLd8CHaP9SztrOdzMOTIriicasF7gzDgnhtjR7I9IDmkUVLrKFjpyjsV18XfH3UeHkvdtTdjr8kIdmkJgeh3u-CK_QZWiDy0g \ No newline at end of file diff --git a/apps/pom.xml b/apps/pom.xml index ca693ae0..c3a9175b 100644 --- a/apps/pom.xml +++ b/apps/pom.xml @@ -73,6 +73,17 @@ user-group-ms + + user-group-ms2 + + + user-group-ms2/pom.xml + + + + user-group-ms2 + + user-group-cdc diff --git a/apps/user-group-ms-2/app/pom.xml b/apps/user-group-ms-2/app/pom.xml deleted file mode 100644 index 3c8ef58a..00000000 --- a/apps/user-group-ms-2/app/pom.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - user-group-ms - it.pagopa.selfcare - 1.0.0-SNAPSHOT - - 4.0.0 - - user-group-ms-app - - - - org.springframework.boot - spring-boot-starter-data-mongodb - - - de.flapdoodle.embed - de.flapdoodle.embed.mongo - test - - - org.springframework.data - spring-data-commons - - - it.pagopa.selfcare - selc-commons-web - - - it.pagopa.selfcare - selc-commons-web - test-jar - test - - - io.springfox - springfox-boot-starter - - - - - - - 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 - - - - - - org.apache.maven.plugins - maven-jar-plugin - - true - - - - - test-jar - - - - - - - - diff --git a/apps/user-group-ms-2/app/src/main/docs/openapi.json b/apps/user-group-ms-2/app/src/main/docs/openapi.json deleted file mode 100644 index abf1f2f9..00000000 --- a/apps/user-group-ms-2/app/src/main/docs/openapi.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "openapi" : "3.0.3", - "info" : { - "title" : "user-group-ms", - "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" - }, - "servers" : [ { - "url" : "{url}:{port}{basePath}", - "variables" : { - "url" : { - "default" : "http://localhost" - }, - "port" : { - "default" : "80" - }, - "basePath" : { - "default" : "" - } - } - } ], - "tags" : [ { - "name" : "UserGroup", - "description" : "User group endpoint CRUD operations" - } ], - "components" : { - "securitySchemes" : { - "bearerAuth" : { - "type" : "http", - "description" : "A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725)", - "scheme" : "bearer", - "bearerFormat" : "JWT" - } - } - } -} \ No newline at end of file diff --git a/apps/user-group-ms-2/pom.xml b/apps/user-group-ms-2/pom.xml deleted file mode 100644 index beecf6f8..00000000 --- a/apps/user-group-ms-2/pom.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - 4.0.0 - - - it.pagopa.selfcare - selc-starter-parent - 0.0.3-SNAPSHOT - - - - - user-group-ms - pom - 1.0.0-SNAPSHOT - user-group-ms - Microservice to manage Self Care User Group - - - 2.5.1 - https://sonarcloud.io/ - true - - - - - it.pagopa.selfcare - selc-commons-base - ${selc-commons.version} - - - 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 - selc-commons-base - - - - org.owasp.encoder - encoder - 1.2.3 - - - - it.pagopa.selfcare - selc-commons-base - test-jar - test - - - - - app - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.1 - - - org.sonarsource.scanner.maven - sonar-maven-plugin - 3.10.0.2594 - - - org.jacoco - jacoco-maven-plugin - 0.8.11 - - - - - - - org.jacoco - jacoco-maven-plugin - - - default-prepare-agent - - prepare-agent - - - true - - - - - report - test - - report - - - - - - - - - - - selfcare-platform - - https://pkgs.dev.azure.com/pagopaspa/selfcare-platform-app-projects/_packaging/selfcare-platform/maven/v1 - - - - diff --git a/apps/user-group-ms-2/Dockerfile b/apps/user-group-ms/Dockerfile similarity index 100% rename from apps/user-group-ms-2/Dockerfile rename to apps/user-group-ms/Dockerfile diff --git a/apps/user-group-ms-2/Dockerfile.dockerignore b/apps/user-group-ms/Dockerfile.dockerignore similarity index 100% rename from apps/user-group-ms-2/Dockerfile.dockerignore rename to apps/user-group-ms/Dockerfile.dockerignore diff --git a/apps/user-group-ms-2/README.md b/apps/user-group-ms/README.md similarity index 100% rename from apps/user-group-ms-2/README.md rename to apps/user-group-ms/README.md diff --git a/apps/user-group-ms-2/lombok.config b/apps/user-group-ms/lombok.config similarity index 100% rename from apps/user-group-ms-2/lombok.config rename to apps/user-group-ms/lombok.config diff --git a/apps/user-group-ms-2/mvnw b/apps/user-group-ms/mvnw similarity index 100% rename from apps/user-group-ms-2/mvnw rename to apps/user-group-ms/mvnw diff --git a/apps/user-group-ms-2/mvnw.cmd b/apps/user-group-ms/mvnw.cmd similarity index 100% rename from apps/user-group-ms-2/mvnw.cmd rename to apps/user-group-ms/mvnw.cmd diff --git a/apps/user-group-ms/pom.xml b/apps/user-group-ms/pom.xml new file mode 100644 index 00000000..03e249fc --- /dev/null +++ b/apps/user-group-ms/pom.xml @@ -0,0 +1,241 @@ + + + 4.0.0 + + it.pagopa.selfcare + selc-starter-parent + 0.0.3-SNAPSHOT + + + + + user-group-ms + + + 17 + 17 + UTF-8 + + + + + + io.cucumber + cucumber-bom + 7.20.1 + pom + import + + + org.junit + junit-bom + 5.10.1 + pom + import + + + + + + + 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 + + + + org.owasp.encoder + encoder + 1.2.3 + + + + org.springframework.data + spring-data-commons + + + io.springfox + springfox-boot-starter + + + io.cucumber + cucumber-java + 7.20.1 + test + + + 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 + test + + + org.springframework + spring-webmvc + 5.3.24 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + + org.sonarsource.scanner.maven + sonar-maven-plugin + 3.10.0.2594 + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + + + + org.jacoco + jacoco-maven-plugin + + + default-prepare-agent + + prepare-agent + + + true + + + + + report + test + + report + + + + + + 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 + + + + + + + + + + selfcare-platform + + https://pkgs.dev.azure.com/pagopaspa/selfcare-platform-app-projects/_packaging/selfcare-platform/maven/v1 + + + + \ No newline at end of file diff --git a/apps/user-group-ms/src/main/docs/openapi.json b/apps/user-group-ms/src/main/docs/openapi.json new file mode 100644 index 00000000..013a6b8d --- /dev/null +++ b/apps/user-group-ms/src/main/docs/openapi.json @@ -0,0 +1,977 @@ +{ + "openapi" : "3.0.3", + "info" : { + "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" : "0.0.3-SNAPSHOT" + }, + "servers" : [ { + "url" : "{url}:{port}{basePath}", + "variables" : { + "url" : { + "default" : "http://localhost" + }, + "port" : { + "default" : "80" + }, + "basePath" : { + "default" : "" + } + } + } ], + "tags" : [ { + "name" : "UserGroup", + "description" : "User group endpoint CRUD operations" + } ], + "paths" : { + "/v1/user-groups" : { + "get" : { + "tags" : [ "UserGroup", "external-pnpg", "external-v2", "support", "support-pnpg" ], + "summary" : "getUserGroups", + "description" : "Service that allows to get a list of UserGroup entities", + "operationId" : "getUserGroupsUsingGET", + "parameters" : [ { + "name" : "institutionId", + "in" : "query", + "description" : "Users group's institutionId", + "required" : false, + "style" : "form", + "schema" : { + "type" : "string" + } + }, { + "name" : "page", + "in" : "query", + "description" : "The page number to access (0 indexed, defaults to 0)", + "required" : false, + "style" : "form", + "allowReserved" : true, + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "size", + "in" : "query", + "description" : "Number of records per page (defaults to 20, max 2000)", + "required" : false, + "style" : "form", + "allowReserved" : true, + "schema" : { + "type" : "integer", + "format" : "int32" + } + }, { + "name" : "sort", + "in" : "query", + "description" : "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "required" : false, + "style" : "form", + "allowReserved" : true, + "schema" : { + "type" : "array", + "items" : { + "type" : "string" + } + } + }, { + "name" : "productId", + "in" : "query", + "description" : "Users group's productId", + "required" : false, + "style" : "form", + "schema" : { + "type" : "string" + } + }, { + "name" : "userId", + "in" : "query", + "description" : "Member's unique identifier", + "required" : false, + "style" : "form", + "schema" : { + "type" : "string", + "format" : "uuid" + } + }, { + "name" : "status", + "in" : "query", + "description" : "If filter on status is present, it must be used with at least one of the other filters", + "required" : false, + "style" : "form", + "explode" : true, + "schema" : { + "type" : "string", + "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/PageOfUserGroupResource" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "404" : { + "description" : "Not Found", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + }, + "post" : { + "tags" : [ "UserGroup" ], + "summary" : "createGroup", + "description" : "Service that allows the insert of a new occurrence for the UserGroup entity", + "operationId" : "createGroupUsingPOST", + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/CreateUserGroupDto" + } + } + } + }, + "responses" : { + "201" : { + "description" : "Created", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserGroupResource" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "409" : { + "description" : "Conflict", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v1/user-groups/members/{memberId}" : { + "delete" : { + "tags" : [ "UserGroup" ], + "summary" : "deleteMemberFromUserGroups", + "description" : "Service to delete a member from a specific UserGroup entity", + "operationId" : "deleteMemberFromUserGroupsUsingDELETE", + "parameters" : [ { + "name" : "memberId", + "in" : "path", + "description" : "Member's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string", + "format" : "uuid" + } + }, { + "name" : "institutionId", + "in" : "query", + "description" : "institutionId", + "required" : true, + "style" : "form", + "schema" : { + "type" : "string" + } + }, { + "name" : "productId", + "in" : "query", + "description" : "productId", + "required" : true, + "style" : "form", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v1/user-groups/{id}" : { + "get" : { + "tags" : [ "UserGroup", "external-v2" ], + "summary" : "getUserGroup", + "description" : "Service to get a specific UserGroup entity", + "operationId" : "getUserGroupUsingGET", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserGroupResource" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "404" : { + "description" : "Not Found", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + }, + "put" : { + "tags" : [ "UserGroup" ], + "summary" : "updateUserGroup", + "description" : "Service that allows the modification of a specific occurrence for the UserGroup entity by an Admin user", + "operationId" : "updateUserGroupUsingPUT", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + } ], + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UpdateUserGroupDto" + } + } + } + }, + "responses" : { + "200" : { + "description" : "OK", + "content" : { + "application/json" : { + "schema" : { + "$ref" : "#/components/schemas/UserGroupResource" + } + } + } + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "409" : { + "description" : "Conflict", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + }, + "delete" : { + "tags" : [ "UserGroup" ], + "summary" : "deleteGroup", + "description" : "Service that allows the deletion of a specific occurrence for the UserGroup entity by an Admin user", + "operationId" : "deleteGroupUsingDELETE", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v1/user-groups/{id}/activate" : { + "post" : { + "tags" : [ "UserGroup" ], + "summary" : "activateGroup", + "description" : "Service that allows the activation of a specific occurrence for the UserGroup entity by an Admin user", + "operationId" : "activateGroupUsingPOST", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v1/user-groups/{id}/members/{memberId}" : { + "put" : { + "tags" : [ "UserGroup" ], + "summary" : "addMemberToUserGroup", + "description" : "Service to add a member to a specific UserGroup entity", + "operationId" : "addMemberToUserGroupUsingPUT", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + }, { + "name" : "memberId", + "in" : "path", + "description" : "Member's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string", + "format" : "uuid" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + }, + "delete" : { + "tags" : [ "UserGroup" ], + "summary" : "deleteMemberFromUserGroup", + "description" : "Service to delete a member from a specific UserGroup entity", + "operationId" : "deleteMemberFromUserGroupUsingDELETE", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + }, { + "name" : "memberId", + "in" : "path", + "description" : "Member's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string", + "format" : "uuid" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + }, + "/v1/user-groups/{id}/suspend" : { + "post" : { + "tags" : [ "UserGroup" ], + "summary" : "suspendGroup", + "description" : "Service that allows the suspension of a specific occurrence for the UserGroup entity by an Admin user", + "operationId" : "suspendGroupUsingPOST", + "parameters" : [ { + "name" : "id", + "in" : "path", + "description" : "Users group's unique identifier", + "required" : true, + "style" : "simple", + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "204" : { + "description" : "No Content" + }, + "400" : { + "description" : "Bad Request", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "401" : { + "description" : "Unauthorized", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + }, + "500" : { + "description" : "Internal Server Error", + "content" : { + "application/problem+json" : { + "schema" : { + "$ref" : "#/components/schemas/Problem" + } + } + } + } + }, + "security" : [ { + "bearerAuth" : [ "global" ] + } ] + } + } + }, + "components" : { + "schemas" : { + "CreateUserGroupDto" : { + "title" : "CreateUserGroupDto", + "required" : [ "description", "institutionId", "members", "name", "productId", "status" ], + "type" : "object", + "properties" : { + "description" : { + "type" : "string", + "description" : "Users group's description" + }, + "institutionId" : { + "type" : "string", + "description" : "Users group's institutionId" + }, + "members" : { + "uniqueItems" : true, + "type" : "array", + "description" : "List of all the members of the group", + "items" : { + "type" : "string", + "format" : "uuid" + } + }, + "name" : { + "type" : "string", + "description" : "Users group's name" + }, + "productId" : { + "type" : "string", + "description" : "Users group's productId" + }, + "status" : { + "type" : "string", + "description" : "Users group's status", + "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] + } + } + }, + "InvalidParam" : { + "title" : "InvalidParam", + "required" : [ "name", "reason" ], + "type" : "object", + "properties" : { + "name" : { + "type" : "string", + "description" : "Invalid parameter name." + }, + "reason" : { + "type" : "string", + "description" : "Invalid parameter reason." + } + } + }, + "PageOfUserGroupResource" : { + "title" : "PageOfUserGroupResource", + "required" : [ "content", "number", "size", "totalElements", "totalPages" ], + "type" : "object", + "properties" : { + "content" : { + "type" : "array", + "description" : "The page content", + "items" : { + "$ref" : "#/components/schemas/UserGroupResource" + } + }, + "number" : { + "type" : "integer", + "description" : "The number of the current page", + "format" : "int32" + }, + "size" : { + "type" : "integer", + "description" : "The size of the page", + "format" : "int32" + }, + "totalElements" : { + "type" : "integer", + "description" : "The total amount of elements", + "format" : "int64" + }, + "totalPages" : { + "type" : "integer", + "description" : "The number of total pages", + "format" : "int32" + } + } + }, + "Problem" : { + "title" : "Problem", + "required" : [ "status", "title" ], + "type" : "object", + "properties" : { + "detail" : { + "type" : "string", + "description" : "Human-readable description of this specific problem." + }, + "instance" : { + "type" : "string", + "description" : "A URI that describes where the problem occurred." + }, + "invalidParams" : { + "type" : "array", + "description" : "A list of invalid parameters details.", + "items" : { + "$ref" : "#/components/schemas/InvalidParam" + } + }, + "status" : { + "type" : "integer", + "description" : "The HTTP status code.", + "format" : "int32", + "example" : 500 + }, + "title" : { + "type" : "string", + "description" : "Short human-readable summary of the problem." + }, + "type" : { + "type" : "string", + "description" : "A URL to a page with more details regarding the problem." + } + }, + "description" : "A \"problem detail\" as a way to carry machine-readable details of errors (https://datatracker.ietf.org/doc/html/rfc7807)" + }, + "UpdateUserGroupDto" : { + "title" : "UpdateUserGroupDto", + "required" : [ "description", "members", "name" ], + "type" : "object", + "properties" : { + "description" : { + "type" : "string", + "description" : "Users group's description" + }, + "members" : { + "uniqueItems" : true, + "type" : "array", + "description" : "List of all the members of the group", + "items" : { + "type" : "string", + "format" : "uuid" + } + }, + "name" : { + "type" : "string", + "description" : "Users group's name" + } + } + }, + "UserGroupResource" : { + "title" : "UserGroupResource", + "required" : [ "description", "id", "institutionId", "name", "productId", "status" ], + "type" : "object", + "properties" : { + "createdAt" : { + "type" : "string", + "description" : "Date on which the group was created", + "format" : "date-time" + }, + "createdBy" : { + "type" : "string", + "description" : "User by which the group was created" + }, + "description" : { + "type" : "string", + "description" : "Users group's description" + }, + "id" : { + "type" : "string", + "description" : "Users group's unique identifier" + }, + "institutionId" : { + "type" : "string", + "description" : "Users group's institutionId" + }, + "members" : { + "type" : "array", + "description" : "List of all the members of the group", + "items" : { + "type" : "string", + "format" : "uuid" + } + }, + "modifiedAt" : { + "type" : "string", + "description" : "Date on which the group was modified", + "format" : "date-time" + }, + "modifiedBy" : { + "type" : "string", + "description" : "User by which the group was modified" + }, + "name" : { + "type" : "string", + "description" : "Users group's name" + }, + "productId" : { + "type" : "string", + "description" : "Users group's productId" + }, + "status" : { + "type" : "string", + "description" : "Users group's status", + "enum" : [ "ACTIVE", "DELETED", "SUSPENDED" ] + } + } + } + }, + "securitySchemes" : { + "bearerAuth" : { + "type" : "http", + "description" : "A bearer token in the format of a JWS and conformed to the specifications included in [RFC8725](https://tools.ietf.org/html/RFC8725)", + "scheme" : "bearer", + "bearerFormat" : "JWT" + } + } + } +} \ No newline at end of file diff --git a/apps/user-group-ms-2/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-2/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-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java similarity index 99% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java index e9721504..cc7956b8 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/api/UserGroupOperations.java @@ -1,5 +1,6 @@ package it.pagopa.selfcare.user_group.api; + import it.pagopa.selfcare.user_group.model.UserGroupStatus; import java.time.Instant; diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/auditing/SpringSecurityAuditorAware.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/CoreConfig.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java similarity index 98% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java index 31579c4a..ca3d3b81 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/SwaggerConfig.java @@ -29,7 +29,7 @@ */ @Configuration @Import(BaseSwaggerConfig.class) -class SwaggerConfig { +public class SwaggerConfig { private static final String AUTH_SCHEMA_NAME = "bearerAuth"; @@ -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-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/UserGroupSecurityConfig.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java similarity index 91% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java index ebf46036..ebdb3a28 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/config/WebConfig.java @@ -6,5 +6,5 @@ @Configuration @Import(BaseWebConfig.class) -class WebConfig { +public class WebConfig { } diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java similarity index 95% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java index f8342c15..75e033b8 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/controller/UserGroupV1Controller.java @@ -11,13 +11,9 @@ import it.pagopa.selfcare.commons.web.model.Problem; import it.pagopa.selfcare.commons.web.model.mapper.PageMapper; import it.pagopa.selfcare.user_group.api.UserGroupOperations; -import it.pagopa.selfcare.user_group.model.UserGroupFilter; -import it.pagopa.selfcare.user_group.model.UserGroupStatus; -import it.pagopa.selfcare.user_group.service.UserGroupService; -import it.pagopa.selfcare.user_group.model.CreateUserGroupDto; -import it.pagopa.selfcare.user_group.model.UpdateUserGroupDto; -import it.pagopa.selfcare.user_group.model.UserGroupResource; +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-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/dao/UserGroupRepository.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceAlreadyExistsException.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceNotFoundException.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/exception/ResourceUpdateException.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java index 2a745add..f2d78377 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandler.java @@ -2,10 +2,10 @@ import it.pagopa.selfcare.commons.web.model.Problem; import it.pagopa.selfcare.commons.web.model.mapper.ProblemMapper; +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 it.pagopa.selfcare.user_group.controller.UserGroupV1Controller; import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ControllerAdvice; diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDto.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/CriteriaBuilder.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/GroupDto.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/MemberUUID.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDto.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java similarity index 99% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java index cc5e5e0d..1b9328b0 100644 --- a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java +++ b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupEntity.java @@ -1,6 +1,5 @@ package it.pagopa.selfcare.user_group.model; - import it.pagopa.selfcare.user_group.api.UserGroupOperations; import lombok.*; import lombok.experimental.FieldNameConstants; diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupFilter.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupResource.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/UserGroupStatus.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/model/mapper/UserGroupMapper.java diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupService.java diff --git a/apps/user-group-ms-2/app/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 similarity index 99% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImpl.java index dcde818c..28ece021 100644 --- a/apps/user-group-ms-2/app/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 @@ -36,7 +36,7 @@ @Slf4j @Service -class UserGroupServiceImpl implements UserGroupService { +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"; diff --git a/apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java b/apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java similarity index 100% rename from apps/user-group-ms-2/app/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java rename to apps/user-group-ms/src/main/java/it/pagopa/selfcare/user_group/validator/UserGroupControllerResponseValidator.java diff --git a/apps/user-group-ms-2/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-2/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-2/app/src/main/resources/config/core-config.properties b/apps/user-group-ms/src/main/resources/config/core-config.properties similarity index 100% rename from apps/user-group-ms-2/app/src/main/resources/config/core-config.properties rename to apps/user-group-ms/src/main/resources/config/core-config.properties diff --git a/apps/user-group-ms-2/app/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-2/app/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-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/CoreTestConfig.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java similarity index 95% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java index 463e8d37..01c31f58 100644 --- a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/SwaggerConfigTest.java @@ -27,11 +27,11 @@ @SpringBootTest(classes = { SwaggerConfig.class, - WebConfig.class, + WebConfig.class }) @EnableOpenApi @EnableWebMvc -@ComponentScan(basePackages = {"it.pagopa.selfcare.user_group.controller","it.pagopa.selfcare.user_group.model"}) +@ComponentScan(basePackages = "it.pagopa.selfcare.user_group.controller") @TestPropertySource(locations = "classpath:config/application.yml") class SwaggerConfigTest { diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/config/WebTestConfig.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/DummyController.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java similarity index 99% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java index eafda1eb..d9578e0a 100644 --- a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/controller/UserGroupV1ControllerTest.java @@ -4,10 +4,10 @@ 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.model.*; -import it.pagopa.selfcare.user_group.service.UserGroupService; 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; @@ -21,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-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java index 0c4dd897..b04be9f9 100644 --- a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java @@ -1,12 +1,12 @@ package it.pagopa.selfcare.user_group.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.config.CoreConfig; 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.AfterEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/handler/UserGroupExceptionHandlerTest.java index b73c859d..e0299198 100644 --- a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/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.handler; -import it.pagopa.selfcare.commons.web.model.Problem; 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 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..5ef71334 --- /dev/null +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/CucumberSuite.java @@ -0,0 +1,18 @@ +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}) +public class CucumberSuite { +} + diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java similarity index 91% rename from apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java index bbec1684..2fefe49b 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/CreateUserGroupSteps.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/CreateUserGroupSteps.java @@ -1,4 +1,4 @@ -package it.pagopa.selfcare.cucumber.steps; +package it.pagopa.selfcare.user_group.integration_test.steps; import io.cucumber.java.After; import io.cucumber.java.Before; @@ -10,24 +10,21 @@ import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.specification.RequestSpecification; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import it.pagopa.selfcare.cucumber.model.UserGroupStatus; +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.File; 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{ +public class CreateUserGroupSteps extends UserGroupSteps { @Before("@DuplicateGroupName") public void beforeScenarioOfCreateDuplicatedGroup() throws IOException { - List groupsToInsert = objectMapper.readValue(new File("src/test/resources/dataPopulation/groupEntities.json"), - objectMapper.getTypeFactory().constructCollectionType(List.class, UserGroupEntity.class)); - userGroupRepository.insert(groupsToInsert); + initializeCollection(); } @After("@DuplicateGroupName") diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java similarity index 93% rename from apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java index 38ef1d50..92349197 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/RetrieveUserGroupSteps.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/RetrieveUserGroupSteps.java @@ -1,4 +1,4 @@ -package it.pagopa.selfcare.cucumber.steps; +package it.pagopa.selfcare.user_group.integration_test.steps; import io.cucumber.java.After; import io.cucumber.java.Before; @@ -12,14 +12,13 @@ import io.restassured.response.Response; import io.restassured.response.ResponseOptions; import io.restassured.specification.RequestSpecification; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import it.pagopa.selfcare.cucumber.model.UserGroupStatus; +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.File; import java.io.IOException; import java.util.Arrays; import java.util.List; @@ -30,9 +29,7 @@ public class RetrieveUserGroupSteps extends UserGroupSteps { @Before("@FirstRetrieveGroupScenario") 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); + initializeCollection(); } @After("@LastRetrieveGroupScenario") @@ -151,13 +148,13 @@ public void the_response_should_contain_the_group_details() { 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-io", userGroupEntityResponse.getProductId()); + 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.getModifiedAt(), userGroupEntityResponse.getModifiedBy()); + Assertions.assertNull(userGroupEntityResponse.getModifiedBy()); } @And("the response should contain a paginated list of user groups of {int} items on page {int}") diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java similarity index 98% rename from apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java index 873fbe39..4bfbd9be 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UpdateUserGroupSteps.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UpdateUserGroupSteps.java @@ -1,4 +1,4 @@ -package it.pagopa.selfcare.cucumber.steps; +package it.pagopa.selfcare.user_group.integration_test.steps; import io.cucumber.java.After; import io.cucumber.java.Before; @@ -10,7 +10,7 @@ import io.restassured.common.mapper.TypeRef; import io.restassured.response.ExtractableResponse; import io.restassured.specification.RequestSpecification; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; +import it.pagopa.selfcare.user_group.model.UserGroupEntity; import org.junit.jupiter.api.Assertions; import java.io.File; diff --git a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java similarity index 90% rename from apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java index e4562201..a4b36aef 100644 --- a/apps/cucumber/src/test/java/it/pagopa/selfcare/cucumber/steps/UserGroupMemberSteps.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/UserGroupMemberSteps.java @@ -1,8 +1,7 @@ -package it.pagopa.selfcare.cucumber.steps; +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; @@ -10,22 +9,16 @@ import io.restassured.response.Response; import io.restassured.response.ResponseOptions; import io.restassured.specification.RequestSpecification; -import it.pagopa.selfcare.cucumber.model.UserGroupEntity; -import org.junit.jupiter.api.Assertions; +import it.pagopa.selfcare.user_group.model.UserGroupEntity; -import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.List; import java.util.UUID; public class UserGroupMemberSteps extends UserGroupSteps { @Before("@FirstGroupMembersScenario") 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); + initializeCollection(); } @After("@LastGroupMembersScenario") 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-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/CreateUserGroupDtoTest.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyCreateUserGroupDto.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyGroup.java diff --git a/apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/DummyUpdateUserGroupDto.java 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-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java similarity index 100% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UpdateUserGroupDtoTest.java diff --git a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java similarity index 85% rename from apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java index 6ed80239..818fc961 100644 --- a/apps/cucumber/src/main/java/it/pagopa/selfcare/cucumber/model/UserGroupEntityPageable.java +++ b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/model/UserGroupEntityPageable.java @@ -1,4 +1,4 @@ -package it.pagopa.selfcare.cucumber.model; +package it.pagopa.selfcare.user_group.model; import lombok.Data; diff --git a/apps/user-group-ms-2/app/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 similarity index 99% rename from apps/user-group-ms-2/app/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java rename to apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/service/UserGroupServiceImplTest.java index 9baac4cc..3607458d 100644 --- a/apps/user-group-ms-2/app/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 @@ -1,8 +1,6 @@ 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.commons.utils.TestUtils; import it.pagopa.selfcare.user_group.api.UserGroupOperations; import it.pagopa.selfcare.user_group.config.CoreTestConfig; import it.pagopa.selfcare.user_group.dao.UserGroupRepository; @@ -13,6 +11,8 @@ 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; @@ -484,7 +484,7 @@ void getUserGroups_invalidSortParameter() { //when Executable executable = () -> groupService.getUserGroups(filter, pageable); //then - javax.validation.ValidationException exception = assertThrows(ValidationException.class, executable); + ValidationException exception = assertThrows(ValidationException.class, executable); assertEquals("Given sort parameters aren't valid", exception.getMessage()); verifyNoInteractions(mongoTemplateMock, userGroupRepository); } diff --git a/apps/cucumber/src/main/resources/application.properties b/apps/user-group-ms/src/test/resources/application-test.properties similarity index 68% rename from apps/cucumber/src/main/resources/application.properties rename to apps/user-group-ms/src/test/resources/application-test.properties index 65e9fa5f..a94cfa2a 100644 --- a/apps/cucumber/src/main/resources/application.properties +++ b/apps/user-group-ms/src/test/resources/application-test.properties @@ -1,3 +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/cucumber/src/test/resources/dataPopulation/groupEntities.json b/apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json similarity index 63% rename from apps/cucumber/src/test/resources/dataPopulation/groupEntities.json rename to apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json index 4a725c2c..4867ac7c 100644 --- a/apps/cucumber/src/test/resources/dataPopulation/groupEntities.json +++ b/apps/user-group-ms/src/test/resources/dataPopulation/groupEntities.json @@ -2,40 +2,43 @@ { "id": "6759f8df78b6af202b222d29", "institutionId": "9c8ae123-d990-4400-b043-67a60aff31bc", - "productId": "prod-io", + "productId": "prod-test", "name": "io group", "description": "io group description", "status": "ACTIVE", "members": [ "75003d64-7b8c-4768-b20c-cf66467d44c7" ], - "createdAt": "2024-12-10T17:12:54.618Z", - "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + "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-io", + "productId": "prod-test", "name": "io group 2", "description": "pagopa group description", "status": "SUSPENDED", "members": [ "75003d64-7b8c-4768-b20c-cf66467d44c7" ], - "createdAt": "2024-12-10T17:12:54.618Z", - "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + "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-interop", + "productId": "prod-test2", "name": "interop group", "description": "interop group description", "status": "SUSPENDED", "members": [ "75003d64-7b8c-4768-b20c-cf66467d44c7" ], - "createdAt": "2024-12-10T17:12:54.618Z", - "createdBy": "4ba2832d-9c4c-40f3-9126-e1c72905ef14" + "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/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature b/apps/user-group-ms/src/test/resources/features/createGroup.feature similarity index 94% rename from apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature rename to apps/user-group-ms/src/test/resources/features/createGroup.feature index 76f37158..0e02b65d 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/createGroup.feature +++ b/apps/user-group-ms/src/test/resources/features/createGroup.feature @@ -22,8 +22,8 @@ Feature: Create User Group @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-io | 9c8ae123-d990-4400-b043-67a60aff31bc | ACTIVE | 525db33f-967f-4a82-8984-c606225e714a,a1b7c86b-d195-41d8-8291-7c3467abfd30 | + | 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" diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature b/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature similarity index 96% rename from apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature rename to apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature index ab28f98b..80f0c424 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/retrieveUserGroup.feature +++ b/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature @@ -14,7 +14,7 @@ Feature: Get User Group 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-io" and status "ACTIVE" + 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 @@ -61,7 +61,7 @@ Feature: Get User Group @LastRetrieveGroupScenario Scenario: No user groups found for the provided filters - Given I have valid filters institutionId "9c8ae123-d990-4400-b043-67a60affabcd" productId "prod-io" and status "ACTIVE" + 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/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature b/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature similarity index 100% rename from apps/cucumber/src/test/resources/cucumber/scenarios/updateUserGroup.feature rename to apps/user-group-ms/src/test/resources/features/updateUserGroup.feature diff --git a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature similarity index 98% rename from apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature rename to apps/user-group-ms/src/test/resources/features/userGroupMembers.feature index 37a07f12..a362ed5e 100644 --- a/apps/cucumber/src/test/resources/cucumber/scenarios/userGroupMembers.feature +++ b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature @@ -41,12 +41,12 @@ Feature: User Group Members 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-io" + 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-io" + 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" @@ -59,7 +59,7 @@ Feature: User Group Members @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-io" + 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/pom.xml b/pom.xml index 182a1616..32afd7a5 100644 --- a/pom.xml +++ b/pom.xml @@ -15,6 +15,7 @@ apps libs test-coverage + apps/user-group-ms From 5718949c4bf191a715358172e153b41c56f0f16f Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Tue, 17 Dec 2024 18:19:15 +0100 Subject: [PATCH 6/8] [SELC-5969] Added fake test to cucumber suite --- .../resources/config/core-config.properties | 4 +++- .../integration_test/CucumberSuite.java | 1 + .../integration_test/steps/FakeSteps.java | 20 +++++++++++++++++++ .../src/test/resources/features/fake.feature | 5 +++++ .../features/retrieveUserGroup.feature | 1 + .../features/updateUserGroup.feature | 1 + .../features/userGroupMembers.feature | 1 + 7 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/integration_test/steps/FakeSteps.java create mode 100644 apps/user-group-ms/src/test/resources/features/fake.feature 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 index a8f9b74e..6e45af83 100644 --- a/apps/user-group-ms/src/main/resources/config/core-config.properties +++ b/apps/user-group-ms/src/main/resources/config/core-config.properties @@ -1,3 +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} \ No newline at end of file +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/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 index 5ef71334..5ef02773 100644 --- 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 @@ -13,6 +13,7 @@ @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/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/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 index 80f0c424..7211fe6d 100644 --- a/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature +++ b/apps/user-group-ms/src/test/resources/features/retrieveUserGroup.feature @@ -1,3 +1,4 @@ +@FeatureRetrieve Feature: Get User Group @FirstRetrieveGroupScenario diff --git a/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature b/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature index a53aa8eb..8cc540d1 100644 --- a/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature +++ b/apps/user-group-ms/src/test/resources/features/updateUserGroup.feature @@ -1,3 +1,4 @@ +@FeatureUpdate Feature: Update User Group @FirstUpdateScenario diff --git a/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature index a362ed5e..090af0e8 100644 --- a/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature +++ b/apps/user-group-ms/src/test/resources/features/userGroupMembers.feature @@ -1,3 +1,4 @@ +@FeatureMembers Feature: User Group Members @FirstGroupMembersScenario From 2a3f22654b85f85f9676ab81a8deda4793b66a3a Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Fri, 20 Dec 2024 10:23:02 +0100 Subject: [PATCH 7/8] [SELC-5969] updated pom for apps module and user-group-ms module --- apps/pom.xml | 11 ----------- apps/user-group-ms/pom.xml | 1 + 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/apps/pom.xml b/apps/pom.xml index c3a9175b..ca693ae0 100644 --- a/apps/pom.xml +++ b/apps/pom.xml @@ -73,17 +73,6 @@ user-group-ms - - user-group-ms2 - - - user-group-ms2/pom.xml - - - - user-group-ms2 - - user-group-cdc diff --git a/apps/user-group-ms/pom.xml b/apps/user-group-ms/pom.xml index 03e249fc..e0f170e7 100644 --- a/apps/user-group-ms/pom.xml +++ b/apps/user-group-ms/pom.xml @@ -12,6 +12,7 @@ user-group-ms + 1.0.0-SNAPSHOT 17 From f636c1d22ca7570f4d80c8c1ac8eba3db0bde1c1 Mon Sep 17 00:00:00 2001 From: flaminiaScarciofolo Date: Fri, 20 Dec 2024 11:16:13 +0100 Subject: [PATCH 8/8] clean pom in test-coverage module --- apps/user-group-ms/pom.xml | 7 + apps/user-group-ms/src/main/docs/openapi.json | 2 +- .../dao/UserGroupRepositoryTest.java | 375 ------------------ pom.xml | 1 - test-coverage/pom.xml | 22 +- 5 files changed, 9 insertions(+), 398 deletions(-) delete mode 100644 apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java diff --git a/apps/user-group-ms/pom.xml b/apps/user-group-ms/pom.xml index 0b2ee055..760a8cfb 100644 --- a/apps/user-group-ms/pom.xml +++ b/apps/user-group-ms/pom.xml @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + it.pagopa.selfcare selc-starter-parent @@ -12,9 +13,15 @@ user-group-ms + jar 1.0.0-SNAPSHOT + user-group-ms + Microservice to manage Self Care User Group + 2.5.1 + https://sonarcloud.io/ + true 17 17 UTF-8 diff --git a/apps/user-group-ms/src/main/docs/openapi.json b/apps/user-group-ms/src/main/docs/openapi.json index 013a6b8d..17fdef00 100644 --- a/apps/user-group-ms/src/main/docs/openapi.json +++ b/apps/user-group-ms/src/main/docs/openapi.json @@ -3,7 +3,7 @@ "info" : { "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" : "0.0.3-SNAPSHOT" + "version" : "1.0.0-SNAPSHOT" }, "servers" : [ { "url" : "{url}:{port}{basePath}", diff --git a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java b/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java deleted file mode 100644 index b04be9f9..00000000 --- a/apps/user-group-ms/src/test/java/it/pagopa/selfcare/user_group/dao/UserGroupRepositoryTest.java +++ /dev/null @@ -1,375 +0,0 @@ -package it.pagopa.selfcare.user_group.dao; - -import com.mongodb.client.result.UpdateResult; -import it.pagopa.selfcare.user_group.config.CoreConfig; -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.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, CoreConfig.class}) -class UserGroupRepositoryTest { - - @Autowired - private UserGroupRepository repository; - - @Autowired - private MongoTemplate mongoTemplate; - - @Autowired - private AuditorAware auditorAware; - - @AfterEach - void clear() { - repository.deleteAll(); - } - - - @Test - void create() { - //given - 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", - "setCreatedBy", - "setModifiedAt", - "setModifiedBy"); - group.setCreatedBy(selfCareUser.getId()); - //when - UserGroupEntity savedGroup = repository.insert(group); - //then - 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", - "setCreatedBy", - "setModifiedAt", - "setModifiedBy"); - group.setCreatedAt(now); - UserGroupEntity savedGroup = repository.insert(group); - - Optional groupMod = repository.findById(savedGroup.getId()); - groupMod.get().setId(savedGroup.getId()); - groupMod.get().setModifiedBy(selfCareUser.getId()); - groupMod.get().setModifiedAt(Instant.now()); - 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", - "setCreatedBy", - "setModifiedAt", - "setModifiedBy"); - group.setCreatedBy(selfCareUser.getId()); - 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", - "setCreatedBy", - "setModifiedAt", - "setModifiedBy"); - group.setCreatedBy(selfCareUser.getId()); - group.setModifiedBy(selfCareUser.getId()); - UserGroupEntity savedGroup = repository.insert(group); - 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/pom.xml b/pom.xml index 32afd7a5..182a1616 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,6 @@ apps libs test-coverage - apps/user-group-ms 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