diff --git a/pom.xml b/pom.xml
index 3427391..45deb9c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,10 +9,10 @@
3.3.3
- it.gov.pagopa.onboarding.citizen
- emd-onboarding-citizen
- emd-onboarding-citizen
- Onboarding Citizen Microservice
+ it.gov.pagopa.citizen
+ emd-citizen
+ emd-citizen
+ Citizen Microservice
0.0.1-SNAPSHOT
@@ -24,18 +24,10 @@
org.springframework.boot
spring-boot-starter
-
- org.springframework.boot
- spring-boot-starter-web
-
org.springframework.boot
spring-boot-starter-webflux
-
- org.springframework.boot
- spring-boot-starter-data-mongodb
-
org.springframework.boot
spring-boot-starter-data-mongodb-reactive
@@ -48,27 +40,12 @@
org.springframework.boot
spring-boot-starter-validation
-
- org.springframework.cloud
- spring-cloud-starter-openfeign
-
-
- org.springframework.boot
- spring-boot-starter-data-redis
-
-
- com.azure.spring
- spring-cloud-azure-stream-binder-servicebus
-
+
com.azure.spring
spring-cloud-azure-starter-data-cosmos
-
- org.springframework.boot
- spring-boot-starter-cache
-
org.springframework.cloud
spring-cloud-stream-test-support
@@ -83,17 +60,6 @@
lombok
1.18.30
-
-
- io.github.openfeign
- feign-okhttp
- 13.1
-
-
- org.codehaus.janino
- janino
- 3.1.11
-
@@ -108,14 +74,8 @@
- org.springframework.cloud
- spring-cloud-contract-wiremock
- test
-
-
- de.flapdoodle.embed
- de.flapdoodle.embed.mongo.spring30x
- 4.11.0
+ io.projectreactor
+ reactor-test
test
@@ -136,6 +96,12 @@
pom
import
+
+ org.xmlunit
+ xmlunit-core
+ 2.10.0
+ test
+
diff --git a/src/main/java/it/gov/pagopa/common/configuration/CustomReactiveMongoHealthIndicator.java b/src/main/java/it/gov/pagopa/common/configuration/CustomReactiveMongoHealthIndicator.java
new file mode 100644
index 0000000..d713e4e
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/common/configuration/CustomReactiveMongoHealthIndicator.java
@@ -0,0 +1,28 @@
+package it.gov.pagopa.common.configuration;
+
+import org.bson.Document;
+import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
+import org.springframework.util.Assert;
+import reactor.core.publisher.Mono;
+
+public class CustomReactiveMongoHealthIndicator extends AbstractReactiveHealthIndicator {
+
+ private final ReactiveMongoTemplate reactiveMongoTemplate;
+
+ public CustomReactiveMongoHealthIndicator(ReactiveMongoTemplate reactiveMongoTemplate) {
+ super("Mongo health check failed");
+ Assert.notNull(reactiveMongoTemplate, "ReactiveMongoTemplate must not be null");
+ this.reactiveMongoTemplate = reactiveMongoTemplate;
+ }
+
+ @Override
+ protected Mono doHealthCheck(Health.Builder builder) {
+ Mono buildInfo = this.reactiveMongoTemplate.executeCommand("{ isMaster: 1 }");
+ return buildInfo.map(document -> builderUp(builder, document));
+ }
+ private Health builderUp(Health.Builder builder, Document document) {
+ return builder.up().withDetail("maxWireVersion", document.getInteger("maxWireVersion")).build();
+ }
+}
diff --git a/src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java b/src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java
new file mode 100644
index 0000000..aa906e0
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java
@@ -0,0 +1,104 @@
+package it.gov.pagopa.common.configuration;
+
+import com.mongodb.lang.NonNull;
+import it.gov.pagopa.common.utils.CommonConstants;
+import lombok.Setter;
+import org.bson.types.Decimal128;
+import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.data.convert.ReadingConverter;
+import org.springframework.data.convert.WritingConverter;
+import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
+
+import java.math.BigDecimal;
+import java.time.OffsetDateTime;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@Configuration
+public class MongoConfig {
+
+ @Configuration
+ @ConfigurationProperties(prefix = "spring.data.mongodb.config")
+ public static class MongoDbCustomProperties {
+ @Setter
+ ConnectionPoolSettings connectionPool;
+
+ @Setter
+ static class ConnectionPoolSettings {
+ int maxSize;
+ int minSize;
+ long maxWaitTimeMS;
+ long maxConnectionLifeTimeMS;
+ long maxConnectionIdleTimeMS;
+ int maxConnecting;
+ }
+
+ }
+
+ @Bean
+ public MongoClientSettingsBuilderCustomizer customizer(MongoDbCustomProperties mongoDbCustomProperties) {
+ return builder -> builder.applyToConnectionPoolSettings(
+ connectionPool -> {
+ connectionPool.maxSize(mongoDbCustomProperties.connectionPool.maxSize);
+ connectionPool.minSize(mongoDbCustomProperties.connectionPool.minSize);
+ connectionPool.maxWaitTime(mongoDbCustomProperties.connectionPool.maxWaitTimeMS, TimeUnit.MILLISECONDS);
+ connectionPool.maxConnectionLifeTime(mongoDbCustomProperties.connectionPool.maxConnectionLifeTimeMS, TimeUnit.MILLISECONDS);
+ connectionPool.maxConnectionIdleTime(mongoDbCustomProperties.connectionPool.maxConnectionIdleTimeMS, TimeUnit.MILLISECONDS);
+ connectionPool.maxConnecting(mongoDbCustomProperties.connectionPool.maxConnecting);
+ });
+ }
+
+ @Bean
+ public MongoCustomConversions mongoCustomConversions() {
+ return new MongoCustomConversions(Arrays.asList(
+ // BigDecimal support
+ new BigDecimalDecimal128Converter(),
+ new Decimal128BigDecimalConverter(),
+
+ // OffsetDateTime support
+ new OffsetDateTimeWriteConverter(),
+ new OffsetDateTimeReadConverter()
+ ));
+ }
+
+ @WritingConverter
+ private static class BigDecimalDecimal128Converter implements Converter {
+
+ @Override
+ public Decimal128 convert(@NonNull BigDecimal source) {
+ return new Decimal128(source);
+ }
+ }
+
+ @ReadingConverter
+ private static class Decimal128BigDecimalConverter implements Converter {
+
+ @Override
+ public BigDecimal convert(@NonNull Decimal128 source) {
+ return source.bigDecimalValue();
+ }
+
+ }
+
+ @WritingConverter
+ public static class OffsetDateTimeWriteConverter implements Converter {
+ @Override
+ public Date convert(OffsetDateTime offsetDateTime) {
+ return Date.from(offsetDateTime.toInstant());
+ }
+ }
+
+ @ReadingConverter
+ public static class OffsetDateTimeReadConverter implements Converter {
+ @Override
+ public OffsetDateTime convert(Date date) {
+ return date.toInstant().atZone(CommonConstants.ZONEID).toOffsetDateTime();
+ }
+ }
+}
+
diff --git a/src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java b/src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java
new file mode 100644
index 0000000..d046ec2
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java
@@ -0,0 +1,14 @@
+package it.gov.pagopa.common.configuration;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
+
+@Configuration
+public class MongoHealthConfig {
+ @Bean
+ public CustomReactiveMongoHealthIndicator customMongoHealthIndicator(ReactiveMongoTemplate reactiveMongoTemplate) {
+ return new CustomReactiveMongoHealthIndicator(reactiveMongoTemplate);
+ }
+}
+
diff --git a/src/main/java/it/gov/pagopa/common/utils/CommonConstants.java b/src/main/java/it/gov/pagopa/common/utils/CommonConstants.java
new file mode 100644
index 0000000..79440b2
--- /dev/null
+++ b/src/main/java/it/gov/pagopa/common/utils/CommonConstants.java
@@ -0,0 +1,16 @@
+package it.gov.pagopa.common.utils;
+
+import java.time.ZoneId;
+
+public class CommonConstants {
+
+
+ public static final class ExceptionCode {
+ public static final String GENERIC_ERROR = "GENERIC_ERROR";
+ private ExceptionCode() {}
+ }
+
+ public static final ZoneId ZONEID = ZoneId.of("Europe/Rome");
+
+ private CommonConstants(){}
+}
diff --git a/src/main/java/it/gov/pagopa/common/utils/Utils.java b/src/main/java/it/gov/pagopa/common/utils/Utils.java
index 704b8e7..28bfd53 100644
--- a/src/main/java/it/gov/pagopa/common/utils/Utils.java
+++ b/src/main/java/it/gov/pagopa/common/utils/Utils.java
@@ -1,5 +1,5 @@
package it.gov.pagopa.common.utils;
-import it.gov.pagopa.onboarding.citizen.exception.custom.EmdEncryptionException;
+import it.gov.pagopa.common.web.exception.EmdEncryptionException;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
@@ -30,10 +30,7 @@ public static String createSHA256(String fiscalCode) {
}
}
- public static void logInfo(String message){
- log.info(inputSanify(message));
- }
- private static String inputSanify(String message){
+ public static String inputSanify(String message){
if (message != null)
return message.replaceAll("[\\r\\n]", "");
return "[EMD][WARNING] Null log";
diff --git a/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionNoBody.java b/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionNoBody.java
index e7d8182..f330ec2 100644
--- a/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionNoBody.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionNoBody.java
@@ -2,7 +2,7 @@
import org.springframework.http.HttpStatus;
-public class ClientExceptionNoBody extends ClientException{
+public class ClientExceptionNoBody extends ClientException {
public ClientExceptionNoBody(HttpStatus httpStatus, String message) {
super(httpStatus, message);
diff --git a/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionWithBody.java b/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionWithBody.java
index 06bfb81..7faac1c 100644
--- a/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionWithBody.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/ClientExceptionWithBody.java
@@ -4,7 +4,7 @@
import org.springframework.http.HttpStatus;
@Getter
-public class ClientExceptionWithBody extends ClientException{
+public class ClientExceptionWithBody extends ClientException {
private final String code;
public ClientExceptionWithBody(HttpStatus httpStatus, String code, String message){
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/EmdEncryptionException.java b/src/main/java/it/gov/pagopa/common/web/exception/EmdEncryptionException.java
similarity index 64%
rename from src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/EmdEncryptionException.java
rename to src/main/java/it/gov/pagopa/common/web/exception/EmdEncryptionException.java
index 9994924..c846862 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/EmdEncryptionException.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/EmdEncryptionException.java
@@ -1,8 +1,7 @@
-package it.gov.pagopa.onboarding.citizen.exception.custom;
+package it.gov.pagopa.common.web.exception;
-import it.gov.pagopa.common.web.exception.ServiceException;
-import it.gov.pagopa.onboarding.citizen.constants.OnboardingCitizenConstants.ExceptionCode;
+import it.gov.pagopa.common.utils.CommonConstants.ExceptionCode;
public class EmdEncryptionException extends ServiceException {
diff --git a/src/main/java/it/gov/pagopa/common/web/exception/ErrorManager.java b/src/main/java/it/gov/pagopa/common/web/exception/ErrorManager.java
index cead9f8..7b37f7a 100644
--- a/src/main/java/it/gov/pagopa/common/web/exception/ErrorManager.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/ErrorManager.java
@@ -1,11 +1,11 @@
package it.gov.pagopa.common.web.exception;
import it.gov.pagopa.common.web.dto.ErrorDTO;
-import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -23,7 +23,7 @@ public ErrorManager(@Nullable ErrorDTO defaultErrorDTO) {
}
@ExceptionHandler(RuntimeException.class)
- protected ResponseEntity handleException(RuntimeException error, HttpServletRequest request) {
+ protected ResponseEntity handleException(RuntimeException error, ServerHttpRequest request) {
logClientException(error, request);
@@ -46,7 +46,7 @@ protected ResponseEntity handleException(RuntimeException error, HttpS
.body(errorDTO);
}
}
- public static void logClientException(RuntimeException error, HttpServletRequest request) {
+ public static void logClientException(RuntimeException error, ServerHttpRequest request) {
Throwable unwrappedException = error.getCause() instanceof ServiceException
? error.getCause()
: error;
@@ -71,7 +71,7 @@ public static void logClientException(RuntimeException error, HttpServletRequest
}
}
- public static String getRequestDetails(HttpServletRequest request) {
- return "%s %s".formatted(request.getMethod(), request.getRequestURI());
+ public static String getRequestDetails(ServerHttpRequest request) {
+ return "%s %s".formatted(request.getMethod(), request.getURI());
}
}
diff --git a/src/main/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandler.java b/src/main/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandler.java
index ccd1014..4763292 100644
--- a/src/main/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandler.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandler.java
@@ -1,13 +1,13 @@
package it.gov.pagopa.common.web.exception;
-import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
+import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@@ -27,7 +27,7 @@ public ServiceExceptionHandler(ErrorManager errorManager, Map handleException(ServiceException error, HttpServletRequest request) {
+ protected ResponseEntity extends ServiceExceptionPayload> handleException(ServiceException error, ServerHttpRequest request) {
if (null != error.getPayload()) {
return handleBodyProvidedException(error, request);
}
@@ -45,7 +45,7 @@ private ClientException transcodeException(ServiceException error) {
return new ClientExceptionWithBody(httpStatus, error.getCode(), error.getMessage(), error.isPrintStackTrace(), error);
}
- private ResponseEntity extends ServiceExceptionPayload> handleBodyProvidedException(ServiceException error, HttpServletRequest request) {
+ private ResponseEntity extends ServiceExceptionPayload> handleBodyProvidedException(ServiceException error, ServerHttpRequest request) {
ClientException clientException = transcodeException(error);
ErrorManager.logClientException(clientException, request);
diff --git a/src/main/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandler.java b/src/main/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandler.java
index 96688c3..b7873ff 100644
--- a/src/main/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandler.java
+++ b/src/main/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandler.java
@@ -1,18 +1,19 @@
package it.gov.pagopa.common.web.exception;
import it.gov.pagopa.common.web.dto.ErrorDTO;
-import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
+import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.lang.Nullable;
import org.springframework.validation.FieldError;
-import org.springframework.web.bind.MethodArgumentNotValidException;
-import org.springframework.web.bind.MissingRequestHeaderException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.bind.support.WebExchangeBindException;
+import org.springframework.web.reactive.resource.NoResourceFoundException;
+import org.springframework.web.server.MissingRequestValueException;
import java.util.Optional;
import java.util.stream.Collectors;
@@ -29,10 +30,10 @@ public ValidationExceptionHandler(@Nullable ErrorDTO templateValidationErrorDTO)
.orElse(new ErrorDTO("INVALID_REQUEST", "Invalid request"));
}
- @ExceptionHandler(MethodArgumentNotValidException.class)
+ @ExceptionHandler(WebExchangeBindException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
- public ErrorDTO handleValidationExceptions(
- MethodArgumentNotValidException ex, HttpServletRequest request) {
+ public ErrorDTO handleWebExchangeBindException(
+ WebExchangeBindException ex, ServerHttpRequest request) {
String message = ex.getBindingResult().getAllErrors().stream()
.map(error -> {
@@ -41,24 +42,34 @@ public ErrorDTO handleValidationExceptions(
return String.format("[%s]: %s", fieldName, errorMessage);
}).collect(Collectors.joining("; "));
- log.info("A MethodArgumentNotValidException occurred handling request {}: HttpStatus 400 - {}",
+ log.info("A WebExchangeBindException occurred handling request {}: HttpStatus 400 - {}",
ErrorManager.getRequestDetails(request), message);
log.debug("Something went wrong while validating http request", ex);
return new ErrorDTO(templateValidationErrorDTO.getCode(), message);
}
- @ExceptionHandler(MissingRequestHeaderException.class)
+ @ExceptionHandler(MissingRequestValueException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
- public ErrorDTO handleMissingRequestHeaderExceptions(
- MissingRequestHeaderException ex, HttpServletRequest request) {
+ public ErrorDTO handleMissingRequestValueException(MissingRequestValueException e, ServerHttpRequest request) {
- String message = ex.getMessage();
+ log.info("A MissingRequestValueException occurred handling request {}: HttpStatus 400 - {}",
+ ErrorManager.getRequestDetails(request), e.getMessage());
+ log.debug("Something went wrong due to a missing request value", e);
- log.info("A MissingRequestHeaderException occurred handling request {}: HttpStatus 400 - {}",
- ErrorManager.getRequestDetails(request), message);
- log.debug("Something went wrong handling request", ex);
+ return new ErrorDTO(templateValidationErrorDTO.getCode(), templateValidationErrorDTO.getMessage());
+ }
- return new ErrorDTO(templateValidationErrorDTO.getCode(), message);
+ @ExceptionHandler(NoResourceFoundException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public ErrorDTO handleNoResourceFoundException(NoResourceFoundException e, ServerHttpRequest request) {
+
+ log.info("A NoResourceFoundException occurred handling request {}: HttpStatus 400 - {}",
+ ErrorManager.getRequestDetails(request), e.getMessage());
+ log.debug("Something went wrong due to a missing request value", e);
+
+ return new ErrorDTO(templateValidationErrorDTO.getCode(), templateValidationErrorDTO.getMessage());
}
+
+
}
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/EmdOnboardingCitizen.java b/src/main/java/it/gov/pagopa/onboarding/citizen/EmdCitizen.java
similarity index 74%
rename from src/main/java/it/gov/pagopa/onboarding/citizen/EmdOnboardingCitizen.java
rename to src/main/java/it/gov/pagopa/onboarding/citizen/EmdCitizen.java
index 92908d5..94b6308 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/EmdOnboardingCitizen.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/EmdCitizen.java
@@ -4,10 +4,10 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication(scanBasePackages = "it.gov.pagopa")
-public class EmdOnboardingCitizen {
+public class EmdCitizen {
public static void main(String[] args) {
- SpringApplication.run(EmdOnboardingCitizen.class, args);
+ SpringApplication.run(EmdCitizen.class, args);
}
}
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/ExceptionMap.java b/src/main/java/it/gov/pagopa/onboarding/citizen/configuration/ExceptionMap.java
similarity index 95%
rename from src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/ExceptionMap.java
rename to src/main/java/it/gov/pagopa/onboarding/citizen/configuration/ExceptionMap.java
index 33b3c81..141f65f 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/exception/custom/ExceptionMap.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/configuration/ExceptionMap.java
@@ -1,4 +1,4 @@
-package it.gov.pagopa.onboarding.citizen.exception.custom;
+package it.gov.pagopa.onboarding.citizen.configuration;
import it.gov.pagopa.common.web.exception.ClientExceptionWithBody;
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerImpl.java b/src/main/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerImpl.java
index a3b86c3..668325d 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerImpl.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerImpl.java
@@ -3,7 +3,6 @@
import it.gov.pagopa.onboarding.citizen.dto.CitizenConsentDTO;
import it.gov.pagopa.onboarding.citizen.service.CitizenServiceImpl;
import jakarta.validation.Valid;
-import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@@ -22,35 +21,33 @@ public CitizenControllerImpl(CitizenServiceImpl citizenService) {
@Override
public Mono> saveCitizenConsent(@Valid CitizenConsentDTO citizenConsentDTO) {
return citizenService.createCitizenConsent(citizenConsentDTO)
- .map(consent -> new ResponseEntity<>(consent, HttpStatus.CREATED));
+ .map(ResponseEntity::ok);
}
@Override
public Mono> stateUpdate(@Valid CitizenConsentDTO citizenConsentDTO) {
return citizenService.updateChannelState(
- citizenConsentDTO.getHashedFiscalCode(),
+ citizenConsentDTO.getHashedFiscalCode(), //at this stage the fiscalCode has not yet been hashed
citizenConsentDTO.getTppId(),
citizenConsentDTO.getTppState())
- .map(consent -> new ResponseEntity<>(consent, HttpStatus.OK));
+ .map(ResponseEntity::ok);
}
@Override
public Mono> getConsentStatus(String fiscalCode, String tppId) {
return citizenService.getConsentStatus(fiscalCode, tppId)
- .map(consent -> new ResponseEntity<>(consent, HttpStatus.OK));
+ .map(ResponseEntity::ok);
}
@Override
public Mono>> getCitizenConsentsEnabled(String fiscalCode) {
return citizenService.getListEnabledConsents(fiscalCode)
- .collectList()
- .map(consents -> new ResponseEntity<>(consents, HttpStatus.OK));
+ .map(ResponseEntity::ok);
}
@Override
public Mono>> getCitizenConsents(String fiscalCode) {
return citizenService.getListAllConsents(fiscalCode)
- .collectList()
- .map(consents -> new ResponseEntity<>(consents, HttpStatus.OK));
+ .map(ResponseEntity::ok);
}
}
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/dto/CitizenConsentDTO.java b/src/main/java/it/gov/pagopa/onboarding/citizen/dto/CitizenConsentDTO.java
index 8957ef4..9151702 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/dto/CitizenConsentDTO.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/dto/CitizenConsentDTO.java
@@ -1,5 +1,6 @@
package it.gov.pagopa.onboarding.citizen.dto;
+import com.fasterxml.jackson.annotation.JsonAlias;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -12,6 +13,7 @@
@AllArgsConstructor
@NoArgsConstructor
public class CitizenConsentDTO {
+ @JsonAlias("fiscalCode")
private String hashedFiscalCode;
private String tppId;
private Boolean tppState;
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentMapperToDTO.java b/src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentObjectToDTOMapper.java
similarity index 81%
rename from src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentMapperToDTO.java
rename to src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentObjectToDTOMapper.java
index cb4a462..885bf6f 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentMapperToDTO.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/dto/mapper/CitizenConsentObjectToDTOMapper.java
@@ -6,9 +6,9 @@
import org.springframework.stereotype.Service;
@Service
-public class CitizenConsentMapperToDTO {
+public class CitizenConsentObjectToDTOMapper {
- public CitizenConsentDTO citizenConsentMapper(CitizenConsent citizenConsent){
+ public CitizenConsentDTO map(CitizenConsent citizenConsent){
return CitizenConsentDTO.builder()
.tppState(citizenConsent.getTppState())
.tppId(citizenConsent.getTppId())
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/model/CitizenConsent.java b/src/main/java/it/gov/pagopa/onboarding/citizen/model/CitizenConsent.java
index d717c4a..4c8657e 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/model/CitizenConsent.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/model/CitizenConsent.java
@@ -1,7 +1,5 @@
package it.gov.pagopa.onboarding.citizen.model;
-import com.fasterxml.jackson.annotation.JsonAlias;
-import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@@ -15,19 +13,12 @@
@NoArgsConstructor
public class CitizenConsent {
- @JsonAlias("_id")
private String id;
- @JsonProperty("hashed_fiscal_code")
private String hashedFiscalCode;
- @JsonProperty("tpp_id")
private String tppId;
- @JsonProperty("tpp_state")
private Boolean tppState;
- @JsonProperty("user_id")
private String userId;
- @JsonProperty("creation_date")
private LocalDateTime creationDate;
- @JsonProperty("last_update_date")
private LocalDateTime lastUpdateDate;
}
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentMapperToObject.java b/src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentDTOToObjectMapper.java
similarity index 80%
rename from src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentMapperToObject.java
rename to src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentDTOToObjectMapper.java
index bbd2f55..195aebe 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentMapperToObject.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/model/mapper/CitizenConsentDTOToObjectMapper.java
@@ -6,9 +6,9 @@
import org.springframework.stereotype.Service;
@Service
-public class CitizenConsentMapperToObject{
+public class CitizenConsentDTOToObjectMapper {
- public CitizenConsent citizenConsentDTOMapper(CitizenConsentDTO citizenConsentDTO){
+ public CitizenConsent map(CitizenConsentDTO citizenConsentDTO){
return CitizenConsent.builder()
.tppState(true)
.tppId(citizenConsentDTO.getTppId())
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenService.java b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenService.java
index a1846b5..ae98fcd 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenService.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenService.java
@@ -1,14 +1,15 @@
package it.gov.pagopa.onboarding.citizen.service;
import it.gov.pagopa.onboarding.citizen.dto.CitizenConsentDTO;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
+import java.util.List;
+
public interface CitizenService {
Mono createCitizenConsent(CitizenConsentDTO citizenConsent);
- Mono updateChannelState(String hashedFiscalCode, String tppId, boolean tppState);
+ Mono updateChannelState(String fiscalCode, String tppId, boolean tppState);
Mono getConsentStatus(String fiscalCode, String tppId);
- Flux getListEnabledConsents(String fiscalCode);
- Flux getListAllConsents(String fiscalCode);
+ Mono> getListEnabledConsents(String fiscalCode);
+ Mono> getListAllConsents(String fiscalCode);
}
diff --git a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java
index 5c06e25..14e9875 100644
--- a/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java
+++ b/src/main/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceImpl.java
@@ -3,28 +3,30 @@
import it.gov.pagopa.common.utils.Utils;
import it.gov.pagopa.onboarding.citizen.constants.OnboardingCitizenConstants.ExceptionName;
import it.gov.pagopa.onboarding.citizen.dto.CitizenConsentDTO;
-import it.gov.pagopa.onboarding.citizen.dto.mapper.CitizenConsentMapperToDTO;
-import it.gov.pagopa.onboarding.citizen.exception.custom.ExceptionMap;
+import it.gov.pagopa.onboarding.citizen.dto.mapper.CitizenConsentObjectToDTOMapper;
+import it.gov.pagopa.onboarding.citizen.configuration.ExceptionMap;
import it.gov.pagopa.onboarding.citizen.model.CitizenConsent;
-import it.gov.pagopa.onboarding.citizen.model.mapper.CitizenConsentMapperToObject;
+import it.gov.pagopa.onboarding.citizen.model.mapper.CitizenConsentDTOToObjectMapper;
import it.gov.pagopa.onboarding.citizen.repository.CitizenRepository;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.LocalDateTime;
+import java.util.List;
-import static it.gov.pagopa.common.utils.Utils.logInfo;
+import static it.gov.pagopa.common.utils.Utils.inputSanify;
@Service
+@Slf4j
public class CitizenServiceImpl implements CitizenService {
private final CitizenRepository citizenRepository;
- private final CitizenConsentMapperToDTO mapperToDTO;
- private final CitizenConsentMapperToObject mapperToObject;
+ private final CitizenConsentObjectToDTOMapper mapperToDTO;
+ private final CitizenConsentDTOToObjectMapper mapperToObject;
private final ExceptionMap exceptionMap;
- public CitizenServiceImpl(CitizenRepository citizenRepository, CitizenConsentMapperToDTO mapperToDTO, CitizenConsentMapperToObject mapperToObject, ExceptionMap exceptionMap) {
+ public CitizenServiceImpl(CitizenRepository citizenRepository, CitizenConsentObjectToDTOMapper mapperToDTO, CitizenConsentDTOToObjectMapper mapperToObject, ExceptionMap exceptionMap) {
this.citizenRepository = citizenRepository;
this.mapperToDTO = mapperToDTO;
this.mapperToObject = mapperToObject;
@@ -33,22 +35,23 @@ public CitizenServiceImpl(CitizenRepository citizenRepository, CitizenConsentMap
@Override
public Mono createCitizenConsent(CitizenConsentDTO citizenConsentDTO) {
- logInfo("[EMD][CREATE-CITIZEN-CONSENT] Received message: %s".formatted(citizenConsentDTO.toString()));
- CitizenConsent citizenConsent = mapperToObject.citizenConsentDTOMapper(citizenConsentDTO);
+ log.info("[EMD][CITIZEN][CREATE] Received message: {}",inputSanify(citizenConsentDTO.toString()));
+ CitizenConsent citizenConsent = mapperToObject.map(citizenConsentDTO);
String hashedFiscalCode = Utils.createSHA256(citizenConsent.getHashedFiscalCode());
citizenConsent.setHashedFiscalCode(hashedFiscalCode);
citizenConsent.setCreationDate(LocalDateTime.now());
citizenConsent.setLastUpdateDate(LocalDateTime.now());
-
return citizenRepository.save(citizenConsent)
- .doOnSuccess(savedConsent -> logInfo("[EMD][CREATE-CITIZEN-CONSENT] Created"))
- .map(mapperToDTO::citizenConsentMapper);
+ .map(mapperToDTO::map)
+ .doOnSuccess(savedConsent -> log.info("[EMD][CREATE-CITIZEN-CONSENT] Created"));
+
}
@Override
- public Mono updateChannelState(String hashedFiscalCode, String tppId, boolean tppState) {
- logInfo("[EMD][UPDATE-CHANNEL-STATE] Received hashedFiscalCode: %s and tppId: %s with state: %s".formatted(hashedFiscalCode, tppId, tppState));
-
+ public Mono updateChannelState(String fiscalCode, String tppId, boolean tppState) {
+ String hashedFiscalCode = Utils.createSHA256(fiscalCode);
+ log.info("[EMD][[CITIZEN][UPDATE-CHANNEL-STATE] Received hashedFiscalCode: {} and tppId: {} with state: {}"
+ ,hashedFiscalCode, inputSanify(tppId), tppState);
return citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId)
.switchIfEmpty(Mono.error(exceptionMap.getException(ExceptionName.CITIZEN_NOT_ONBOARDED)))
.flatMap(citizenConsent -> {
@@ -56,37 +59,45 @@ public Mono updateChannelState(String hashedFiscalCode, Strin
citizenConsent.setLastUpdateDate(LocalDateTime.now());
return citizenRepository.save(citizenConsent);
})
- .doOnSuccess(savedConsent -> logInfo("[EMD][UPDATE-CHANNEL-STATE] Updated state"))
- .map(mapperToDTO::citizenConsentMapper);
+ .map(mapperToDTO::map)
+ .doOnSuccess(savedConsent -> log.info("[EMD][[CITIZEN][UPDATE-CHANNEL-STATE] Updated state"));
}
@Override
public Mono getConsentStatus(String fiscalCode, String tppId) {
- logInfo("[EMD][GET-CONSENT-STATUS] Received fiscalCode: %s and tppId: %s".formatted(fiscalCode, tppId));
String hashedFiscalCode = Utils.createSHA256(fiscalCode);
-
+ log.info("[EMD][CITIZEN][GET-CONSENT-STATUS] Received hashedFiscalCode: {} and tppId: {}",hashedFiscalCode,inputSanify(tppId));
return citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId)
.switchIfEmpty(Mono.error(exceptionMap.getException(ExceptionName.CITIZEN_NOT_ONBOARDED)))
- .map(mapperToDTO::citizenConsentMapper);
+ .map(mapperToDTO::map)
+ .doOnSuccess(consent -> log.info("[EMD][CITIZEN][GET-CONSENT-STATUS] Consent found:: {}",consent));
+
}
@Override
- public Flux getListEnabledConsents(String fiscalCode) {
- logInfo("[EMD][FIND-CITIZEN-CONSENTS-ENABLED] Received fiscalCode: %s".formatted(fiscalCode));
+ public Mono> getListEnabledConsents(String fiscalCode) {
String hashedFiscalCode = Utils.createSHA256(fiscalCode);
-
+ log.info("[EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Received hashedFiscalCode: {}",hashedFiscalCode);
return citizenRepository.findByHashedFiscalCodeAndTppStateTrue(hashedFiscalCode)
- .map(mapperToDTO::citizenConsentMapper)
- .doOnNext(citizenConsentDTO -> logInfo("[EMD][FIND-CITIZEN-CONSENT-ENABLED] Consents enabled found: %s".formatted(citizenConsentDTO)));
+ .collectList()
+ .map(consentList -> consentList.stream()
+ .map(mapperToDTO::map)
+ .toList()
+ )
+ .doOnSuccess(consentList -> log.info("EMD][CITIZEN][FIND-CITIZEN-CONSENTS-ENABLED] Consents founded: {}",(consentList.size())));
+
}
@Override
- public Flux getListAllConsents(String fiscalCode) {
- logInfo("[EMD][FIND-ALL-CITIZEN-CONSENTS] Received fiscalCode: %s".formatted(fiscalCode));
+ public Mono> getListAllConsents(String fiscalCode) {
String hashedFiscalCode = Utils.createSHA256(fiscalCode);
-
+ log.info("[EMD][CITIZEN][FIND-ALL-CITIZEN-CONSENTS] Received hashedFiscalCode: {}",(hashedFiscalCode));
return citizenRepository.findByHashedFiscalCode(hashedFiscalCode)
- .map(mapperToDTO::citizenConsentMapper)
- .doOnNext(citizenConsentDTO -> logInfo("[EMD][FIND-ALL-CITIZEN-CONSENTS] Consents found: %s".formatted(citizenConsentDTO)));
+ .collectList()
+ .map(consentList -> consentList.stream()
+ .map(mapperToDTO::map)
+ .toList()
+ )
+ .doOnSuccess(consentList -> log.info("[EMD][CITIZEN][FIND-ALL-CITIZEN-CONSENTS] Consents found:: {}",consentList));
}
}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 9c501d8..9dc143c 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -6,13 +6,6 @@ spring:
name: "@project.artifactId@"
version: "@project.version@"
jmx.enabled: true
- resources:
- static-locations: classpath:/static/
- cache:
- cachecontrol:
- max-age: 3600
- no-transform: true
- must-revalidate: true
config:
activate:
on-profile: default
@@ -20,19 +13,30 @@ spring:
mongodb:
database: ${MONGODB_DBNAME:mil}
uri: ${MONGODB_URI:mongodb://localhost:27017}
+ config:
+ connectionPool:
+ maxSize: ${MONGODB_CONNECTIONPOOL_MAX_SIZE:100}
+ minSize: ${MONGODB_CONNECTIONPOOL_MIN_SIZE:5}
+ maxWaitTimeMS: ${MONGODB_CONNECTIONPOOL_MAX_WAIT_MS:120000}
+ maxConnectionLifeTimeMS: ${MONGODB_CONNECTIONPOOL_MAX_CONNECTION_LIFE_MS:0}
+ maxConnectionIdleTimeMS: ${MONGODB_CONNECTIONPOOL_MAX_CONNECTION_IDLE_MS:120000}
+ maxConnecting: ${MONGODB_CONNECTIONPOOL_MAX_CONNECTING:2}
+
+server:
+ port: ${CITIZEN_PORT:8084}
management:
health:
- redis.enabled: ${REDIS_CACHE_ENABLED:false}
- mongo.enabled: ${HEALTH_MONGO_ENABLED:true}
+ mongo.enabled: ${HEALTH_MONGO_ENABLED:false}
endpoint:
health:
+ show-details: always
probes.enabled: true
group:
readiness.include: "*"
- liveness.include: livenessState,diskSpace,ping,binders
+ liveness.include: livenessState,diskSpace,ping
endpoints:
jmx:
exposure.include: "*"
web:
- exposure.include: info, health
\ No newline at end of file
+ exposure.include: info, health
diff --git a/src/test/java/it/gov/pagopa/common/configuration/CustomMongoHealthIndicatorTest.java b/src/test/java/it/gov/pagopa/common/configuration/CustomMongoHealthIndicatorTest.java
new file mode 100644
index 0000000..8b0b8c5
--- /dev/null
+++ b/src/test/java/it/gov/pagopa/common/configuration/CustomMongoHealthIndicatorTest.java
@@ -0,0 +1,50 @@
+package it.gov.pagopa.common.configuration;
+
+import com.mongodb.MongoException;
+import org.bson.Document;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.actuate.health.Health;
+import org.springframework.boot.actuate.health.Status;
+import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
+import reactor.core.publisher.Mono;
+import reactor.test.StepVerifier;
+
+import java.time.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+
+class CustomMongoHealthIndicatorTest {
+ @Test
+ void testMongoIsUp() {
+ Document buildInfo = mock(Document.class);
+ given(buildInfo.getInteger("maxWireVersion")).willReturn(10);
+ ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class);
+ given(reactiveMongoTemplate.executeCommand("{ isMaster: 1 }")).willReturn(Mono.just(buildInfo));
+ CustomReactiveMongoHealthIndicator customReactiveMongoHealthIndicator = new CustomReactiveMongoHealthIndicator(
+ reactiveMongoTemplate);
+ Mono health = customReactiveMongoHealthIndicator.health();
+ StepVerifier.create(health).consumeNextWith(h -> {
+ assertThat(h.getStatus()).isEqualTo(Status.UP);
+ assertThat(h.getDetails()).containsOnlyKeys("maxWireVersion");
+ assertThat(h.getDetails()).containsEntry("maxWireVersion", 10);
+ }).expectComplete().verify(Duration.ofSeconds(30));
+ }
+
+ @Test
+ void testMongoIsDown() {
+ ReactiveMongoTemplate reactiveMongoTemplate = mock(ReactiveMongoTemplate.class);
+ given(reactiveMongoTemplate.executeCommand("{ isMaster: 1 }")).willThrow(new MongoException("Connection failed"));
+ CustomReactiveMongoHealthIndicator customReactiveMongoHealthIndicator = new CustomReactiveMongoHealthIndicator(
+ reactiveMongoTemplate);
+ Mono health = customReactiveMongoHealthIndicator.health();
+ StepVerifier.create(health).consumeNextWith(h -> {
+ assertThat(h.getStatus()).isEqualTo(Status.DOWN);
+ assertThat(h.getDetails()).containsOnlyKeys("error");
+ assertThat(h.getDetails()).containsEntry("error", MongoException.class.getName() + ": Connection failed");
+ }).expectComplete().verify(Duration.ofSeconds(30));
+ }
+
+}
diff --git a/src/test/java/it/gov/pagopa/common/utils/UtilsTest.java b/src/test/java/it/gov/pagopa/common/utils/UtilsTest.java
index 52ebf02..3fa89a3 100644
--- a/src/test/java/it/gov/pagopa/common/utils/UtilsTest.java
+++ b/src/test/java/it/gov/pagopa/common/utils/UtilsTest.java
@@ -1,7 +1,7 @@
package it.gov.pagopa.common.utils;
-import it.gov.pagopa.onboarding.citizen.exception.custom.EmdEncryptionException;
+import it.gov.pagopa.common.web.exception.EmdEncryptionException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
@@ -20,15 +20,16 @@ class UtilsTest {
@Test
- void createSHA256_Ko_NoSuchAlgorithm() throws NoSuchAlgorithmException {
+ void createSHA256_Ko_NoSuchAlgorithm() {
try (MockedStatic mockedStatic = Mockito.mockStatic(MessageDigest.class)) {
mockedStatic.when(() -> MessageDigest.getInstance(any()))
- .thenThrow(NoSuchAlgorithmException.class);
+ .thenThrow(new NoSuchAlgorithmException("SHA-256 not available"));
EmdEncryptionException exception = assertThrows(EmdEncryptionException.class, () -> Utils.createSHA256(""));
+
+ assertEquals("SHA-256 not available", exception.getCause().getMessage());
}
}
-
@Test
void createSHA256_Ok(){
String toHash = "RSSMRA98B18L049O";
diff --git a/src/test/java/it/gov/pagopa/common/web/exception/ErrorManagerTest.java b/src/test/java/it/gov/pagopa/common/web/exception/ErrorManagerTest.java
index 832e8c7..078708d 100644
--- a/src/test/java/it/gov/pagopa/common/web/exception/ErrorManagerTest.java
+++ b/src/test/java/it/gov/pagopa/common/web/exception/ErrorManagerTest.java
@@ -10,43 +10,37 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.slf4j.LoggerFactory;
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.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-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.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.regex.Pattern;
-@ExtendWith(SpringExtension.class)
-@WebMvcTest(value = {
- ErrorManagerTest.TestController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
+@WebFluxTest(value = {
+ ErrorManagerTest.TestController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
@ContextConfiguration(classes = {ErrorManagerTest.TestController.class, ErrorManager.class})
+@Slf4j
class ErrorManagerTest {
private static final String EXPECTED_GENERIC_ERROR = "{\"code\":\"Error\",\"message\":\"Something gone wrong\"}";
@Autowired
- private MockMvc mockMvc;
-
+ private WebTestClient webTestClient;
@SpyBean
private TestController testControllerSpy;
+
private static MemoryAppender memoryAppender;
@RestController
- @Slf4j
static class TestController {
-
@GetMapping("/test")
String testEndpoint() {
return "OK";
@@ -54,98 +48,106 @@ String testEndpoint() {
}
@BeforeAll
- static void configureMemoryAppender(){
+ static void configureMemoryAppender() {
memoryAppender = new MemoryAppender();
memoryAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory());
memoryAppender.start();
}
@BeforeEach
- void clearMemoryAppender(){
+ void clearMemoryAppender() {
memoryAppender.reset();
-
ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ErrorManager.class.getName());
logger.setLevel(ch.qos.logback.classic.Level.INFO);
logger.addAppender(memoryAppender);
}
@Test
- void handleExceptionClientExceptionNoBody() throws Exception {
+ void handleExceptionClientExceptionNoBody() {
Mockito.doThrow(
- new ClientExceptionNoBody(HttpStatus.BAD_REQUEST, "NOTFOUND ClientExceptionNoBody"))
- .when(testControllerSpy).testEndpoint();
+ new ClientExceptionNoBody(HttpStatus.BAD_REQUEST, "NOTFOUND ClientExceptionNoBody"))
+ .when(testControllerSpy).testEndpoint();
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isBadRequest());
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().isBadRequest();
checkStackTraceSuppressedLog(memoryAppender,
"A ClientExceptionNoBody occurred handling request GET /test: HttpStatus 400 BAD_REQUEST - NOTFOUND ClientExceptionNoBody at it.gov.pagopa.common.web.exception.ErrorManagerTest\\$TestController.testEndpoint\\(ErrorManagerTest.java:[0-9]+\\)");
-
}
@Test
- void handleExceptionClientExceptionWithBody() throws Exception {
+ void handleExceptionClientExceptionWithBody() {
Mockito.doThrow(
- new ClientExceptionWithBody(HttpStatus.BAD_REQUEST, "Error", "Error ClientExceptionWithBody"))
- .when(testControllerSpy).testEndpoint();
+ new ClientExceptionWithBody(HttpStatus.BAD_REQUEST, "Error", "Error ClientExceptionWithBody"))
+ .when(testControllerSpy).testEndpoint();
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isBadRequest())
- .andExpect(MockMvcResultMatchers.content()
- .json("{\"code\":\"Error\",\"message\":\"Error ClientExceptionWithBody\"}"));
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody()
+ .json("{\"code\":\"Error\",\"message\":\"Error ClientExceptionWithBody\"}");
Mockito.doThrow(
- new ClientExceptionWithBody(HttpStatus.BAD_REQUEST, "Error", "Error ClientExceptionWithBody",
- new Exception()))
- .when(testControllerSpy).testEndpoint();
-
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isBadRequest())
- .andExpect(MockMvcResultMatchers.content()
- .json("{\"code\":\"Error\",\"message\":\"Error ClientExceptionWithBody\"}"));
+ new ClientExceptionWithBody(HttpStatus.BAD_REQUEST, "Error", "Error ClientExceptionWithBody",
+ new Exception()))
+ .when(testControllerSpy).testEndpoint();
+
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody()
+ .json("{\"code\":\"Error\",\"message\":\"Error ClientExceptionWithBody\"}");
}
@Test
- void handleExceptionClientExceptionTest() throws Exception {
-
+ void handleExceptionClientExceptionTest() {
Mockito.doThrow(ClientException.class)
- .when(testControllerSpy).testEndpoint();
+ .when(testControllerSpy).testEndpoint();
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content()
- .json(EXPECTED_GENERIC_ERROR));
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json(EXPECTED_GENERIC_ERROR);
checkStackTraceSuppressedLog(memoryAppender, "A ClientException occurred handling request GET /test: HttpStatus null - null at UNKNOWN");
memoryAppender.reset();
Mockito.doThrow(
- new ClientException(HttpStatus.BAD_REQUEST, "ClientException with httpStatus and message"))
- .when(testControllerSpy).testEndpoint();
+ new ClientException(HttpStatus.BAD_REQUEST, "ClientException with httpStatus and message"))
+ .when(testControllerSpy).testEndpoint();
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content()
- .json(EXPECTED_GENERIC_ERROR));
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json(EXPECTED_GENERIC_ERROR);
checkStackTraceSuppressedLog(memoryAppender, "A ClientException occurred handling request GET /test: HttpStatus 400 BAD_REQUEST - ClientException with httpStatus and message at it.gov.pagopa.common.web.exception.ErrorManagerTest\\$TestController.testEndpoint\\(ErrorManagerTest.java:[0-9]+\\)");
memoryAppender.reset();
-
Mockito.doThrow(new ClientException(HttpStatus.BAD_REQUEST,
- "ClientException with httpStatus, message and throwable", new Throwable()))
- .when(testControllerSpy).testEndpoint();
+ "ClientException with httpStatus, message and throwable", new Throwable()))
+ .when(testControllerSpy).testEndpoint();
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content()
- .json(EXPECTED_GENERIC_ERROR));
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json(EXPECTED_GENERIC_ERROR);
checkLog(memoryAppender,
"Something went wrong handling request GET /test: HttpStatus 400 BAD_REQUEST - ClientException with httpStatus, message and throwable",
@@ -155,15 +157,17 @@ void handleExceptionClientExceptionTest() throws Exception {
}
@Test
- void handleExceptionRuntimeException() throws Exception {
+ void handleExceptionRuntimeException() {
Mockito.doThrow(RuntimeException.class)
- .when(testControllerSpy).testEndpoint();
-
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content()
- .json(EXPECTED_GENERIC_ERROR));
+ .when(testControllerSpy).testEndpoint();
+
+ webTestClient.get()
+ .uri("/test")
+ .accept(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json(EXPECTED_GENERIC_ERROR);
}
public static void checkStackTraceSuppressedLog(MemoryAppender memoryAppender, String expectedLoggedMessage) {
diff --git a/src/test/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandlerTest.java b/src/test/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandlerTest.java
index 43397a1..0896c70 100644
--- a/src/test/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandlerTest.java
+++ b/src/test/java/it/gov/pagopa/common/web/exception/ServiceExceptionHandlerTest.java
@@ -9,28 +9,24 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.LoggerFactory;
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.autoconfigure.web.reactive.WebFluxTest;
+import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-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.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
-@ExtendWith(SpringExtension.class)
-@WebMvcTest(value = {
+@WebFluxTest(value = {
ServiceExceptionHandlerTest.TestController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
@ContextConfiguration(classes = {ServiceExceptionHandler.class,
ServiceExceptionHandlerTest.TestController.class, ErrorManager.class})
class ServiceExceptionHandlerTest {
@Autowired
- private MockMvc mockMvc;
+ private WebTestClient webTestClient;
private static MemoryAppender memoryAppender;
@@ -74,22 +70,29 @@ static class ErrorPayloadTest implements ServiceExceptionPayload {
}
@Test
- void testSimpleException() throws Exception{
- mockMvc.perform(MockMvcRequestBuilders.get("/test")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content().json("{\"code\":\"DUMMY_CODE\",\"message\":\"DUMMY_MESSAGE\"}", false));
+ void testSimpleException(){
+ webTestClient.method(HttpMethod.GET)
+ .uri("/test")
+ .contentType(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json("{\"code\":\"DUMMY_CODE\",\"message\":\"DUMMY_MESSAGE\"}", false);
ErrorManagerTest.checkStackTraceSuppressedLog(memoryAppender, "A ServiceException occurred handling request GET /test: HttpStatus 500 INTERNAL_SERVER_ERROR - DUMMY_CODE: DUMMY_MESSAGE at it.gov.pagopa.common.web.exception.ServiceExceptionHandlerTest\\$TestController.test\\(ServiceExceptionHandlerTest.java:[0-9]+\\)");
}
@Test
- void testCustomBodyException() throws Exception{
- mockMvc.perform(MockMvcRequestBuilders.get("/test/customBody")
- .contentType(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isInternalServerError())
- .andExpect(MockMvcResultMatchers.content().json("{\"stringCode\":\"RESPONSE\",\"longCode\":0}", false));
+ void testCustomBodyException(){
+
+ webTestClient.method(HttpMethod.GET)
+ .uri("/test/customBody")
+ .contentType(MediaType.APPLICATION_JSON)
+ .exchange()
+ .expectStatus().is5xxServerError()
+ .expectBody()
+ .json("{\"stringCode\":\"RESPONSE\",\"longCode\":0}", false);
ErrorManagerTest.checkLog(memoryAppender,
"Something went wrong handling request GET /test/customBody: HttpStatus 500 INTERNAL_SERVER_ERROR - DUMMY_CODE: DUMMY_MESSAGE",
diff --git a/src/test/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandlerTest.java b/src/test/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandlerTest.java
index d87f430..3236568 100644
--- a/src/test/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandlerTest.java
+++ b/src/test/java/it/gov/pagopa/common/web/exception/ValidationExceptionHandlerTest.java
@@ -1,48 +1,37 @@
package it.gov.pagopa.common.web.exception;
-import com.fasterxml.jackson.databind.ObjectMapper;
+
+import it.gov.pagopa.common.web.dto.ErrorDTO;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.junit.jupiter.MockitoExtension;
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.SpyBean;
+import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-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.reactive.server.WebTestClient;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
-@ExtendWith({SpringExtension.class, MockitoExtension.class})
-@WebMvcTest(value = {ValidationExceptionHandlerTest.TestController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
+import static org.assertj.core.api.Assertions.assertThat;
+
+@WebFluxTest(value = {ValidationExceptionHandlerTest.TestController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
@ContextConfiguration(classes = {
ValidationExceptionHandlerTest.TestController.class,
ValidationExceptionHandler.class})
class ValidationExceptionHandlerTest {
@Autowired
- private MockMvc mockMvc;
-
- @Autowired
- ObjectMapper objectMapper;
+ private WebTestClient webTestClient;
- @SpyBean
- private TestController testControllerSpy;
@RestController
- @Slf4j
static class TestController {
@PutMapping("/test")
@@ -59,31 +48,43 @@ static class ValidationDTO {
private String data;
}
- private final ValidationDTO VALIDATION_DTO = new ValidationDTO("data");
-
@Test
- void handleMethodArgumentNotValidException() throws Exception {
+ void testHandleValueNotValidException() {
+ String invalidJson = "{}";
- mockMvc.perform(MockMvcRequestBuilders.put("/test")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(new ValidationDTO("")))
- .header("data", "data")
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isBadRequest())
- .andExpect(MockMvcResultMatchers.jsonPath("$.code").value("INVALID_REQUEST"))
- .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("[data]: The field is mandatory!"));
+ webTestClient.put()
+ .uri("/test")
+ .contentType(MediaType.APPLICATION_JSON)
+ .header("data", "someValue")
+ .bodyValue(invalidJson)
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody(ErrorDTO.class)
+ .consumeWith(response -> {
+ ErrorDTO errorDTO = response.getResponseBody();
+ assertThat(errorDTO).isNotNull();
+ assertThat(errorDTO.getCode()).isEqualTo("INVALID_REQUEST");
+ assertThat(errorDTO.getMessage()).isEqualTo("[data]: The field is mandatory!");
+ });
}
-
@Test
- void handleMissingRequestHeaderException() throws Exception {
+ void testHandleHeaderNotValidException() {
+ String invalidJson = "{}";
+
+ webTestClient.put()
+ .uri("/test")
+ .contentType(MediaType.APPLICATION_JSON)
+ .bodyValue(new ValidationDTO("data"))
+ .exchange()
+ .expectStatus().isBadRequest()
+ .expectBody(ErrorDTO.class)
- mockMvc.perform(MockMvcRequestBuilders.put("/test")
- .contentType(MediaType.APPLICATION_JSON)
- .content(objectMapper.writeValueAsString(VALIDATION_DTO))
- .accept(MediaType.APPLICATION_JSON))
- .andExpect(MockMvcResultMatchers.status().isBadRequest())
- .andExpect(MockMvcResultMatchers.jsonPath("$.code").value("INVALID_REQUEST"))
- .andExpect(MockMvcResultMatchers.jsonPath("$.message").value("Required request header 'data' for method parameter type String is not present"));
+ .consumeWith(response -> {
+ ErrorDTO errorDTO = response.getResponseBody();
+ assertThat(errorDTO).isNotNull();
+ assertThat(errorDTO.getCode()).isEqualTo("INVALID_REQUEST");
+ assertThat(errorDTO.getMessage()).isEqualTo("Invalid request");
+ });
}
}
diff --git a/src/test/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerTest.java b/src/test/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerTest.java
index 1dfe4ee..d19116e 100644
--- a/src/test/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerTest.java
+++ b/src/test/java/it/gov/pagopa/onboarding/citizen/controller/CitizenControllerTest.java
@@ -2,7 +2,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import it.gov.pagopa.onboarding.citizen.dto.CitizenConsentDTO;
-import it.gov.pagopa.onboarding.citizen.model.mapper.CitizenConsentMapperToObject;
+import it.gov.pagopa.onboarding.citizen.faker.CitizenConsentDTOFaker;
import it.gov.pagopa.onboarding.citizen.service.CitizenServiceImpl;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -12,10 +12,8 @@
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
-import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import java.util.Collections;
import java.util.List;
@WebFluxTest(CitizenControllerImpl.class)
@@ -30,12 +28,13 @@ class CitizenControllerTest {
@Autowired
private ObjectMapper objectMapper;
- @MockBean
- CitizenConsentMapperToObject mapperToObject;
+ private static final String FISCAL_CODE = "fiscalCode";
+ private static final String TPP_ID = "tppId";
+
@Test
void saveCitizenConsent_Ok() {
- CitizenConsentDTO citizenConsentDTO = new CitizenConsentDTO();
+ CitizenConsentDTO citizenConsentDTO = CitizenConsentDTOFaker.mockInstance(true);
Mockito.when(citizenService.createCitizenConsent(citizenConsentDTO)).thenReturn(Mono.just(citizenConsentDTO));
@@ -44,7 +43,7 @@ void saveCitizenConsent_Ok() {
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(citizenConsentDTO)
.exchange()
- .expectStatus().isCreated()
+ .expectStatus().isOk()
.expectBody(CitizenConsentDTO.class)
.consumeWith(response -> {
CitizenConsentDTO resultResponse = response.getResponseBody();
@@ -55,10 +54,7 @@ void saveCitizenConsent_Ok() {
@Test
void stateUpdate_Ok() {
- CitizenConsentDTO citizenConsentDTO = new CitizenConsentDTO();
- citizenConsentDTO.setHashedFiscalCode("hashedFiscalCode");
- citizenConsentDTO.setTppId("tppId");
- citizenConsentDTO.setTppState(true);
+ CitizenConsentDTO citizenConsentDTO = CitizenConsentDTOFaker.mockInstance(true);
Mockito.when(citizenService.updateChannelState(
citizenConsentDTO.getHashedFiscalCode(),
@@ -82,15 +78,14 @@ void stateUpdate_Ok() {
@Test
void getConsentStatus_Ok() {
- String fiscalCode = "fiscalCode";
- String tppId = "tppId";
- CitizenConsentDTO citizenConsentDTO = new CitizenConsentDTO();
- Mockito.when(citizenService.getConsentStatus(fiscalCode, tppId))
+ CitizenConsentDTO citizenConsentDTO = CitizenConsentDTOFaker.mockInstance(true);
+
+ Mockito.when(citizenService.getConsentStatus(FISCAL_CODE, TPP_ID))
.thenReturn(Mono.just(citizenConsentDTO));
webClient.get()
- .uri("/emd/citizen/{fiscalCode}/{tppId}", fiscalCode, tppId)
+ .uri("/emd/citizen/{fiscalCode}/{tppId}", FISCAL_CODE, TPP_ID)
.exchange()
.expectStatus().isOk()
.expectBody(CitizenConsentDTO.class)
@@ -103,14 +98,13 @@ void getConsentStatus_Ok() {
@Test
void getCitizenConsentsEnabled_Ok() {
- String fiscalCode = "fiscalCode";
- List citizenConsentDTOList = Collections.singletonList(new CitizenConsentDTO());
+ List citizenConsentDTOList = List.of(CitizenConsentDTOFaker.mockInstance(true));
- Mockito.when(citizenService.getListEnabledConsents(fiscalCode))
- .thenReturn(Flux.fromIterable(citizenConsentDTOList));
+ Mockito.when(citizenService.getListEnabledConsents(FISCAL_CODE))
+ .thenReturn(Mono.just(citizenConsentDTOList));
webClient.get()
- .uri("/emd/citizen/list/{fiscalCode}/enabled", fiscalCode)
+ .uri("/emd/citizen/list/{fiscalCode}/enabled", FISCAL_CODE)
.exchange()
.expectStatus().isOk()
.expectBodyList(CitizenConsentDTO.class)
@@ -123,14 +117,13 @@ void getCitizenConsentsEnabled_Ok() {
@Test
void getCitizenConsents_Ok() {
- String fiscalCode = "fiscalCode";
- List citizenConsentDTOList = Collections.singletonList(new CitizenConsentDTO());
+ List citizenConsentDTOList = List.of(CitizenConsentDTOFaker.mockInstance(true));
- Mockito.when(citizenService.getListAllConsents(fiscalCode))
- .thenReturn(Flux.fromIterable(citizenConsentDTOList));
+ Mockito.when(citizenService.getListAllConsents(FISCAL_CODE))
+ .thenReturn(Mono.just(citizenConsentDTOList));
webClient.get()
- .uri("/emd/citizen/list/{fiscalCode}", fiscalCode)
+ .uri("/emd/citizen/list/{fiscalCode}", FISCAL_CODE)
.exchange()
.expectStatus().isOk()
.expectBodyList(CitizenConsentDTO.class)
diff --git a/src/test/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceTest.java b/src/test/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceTest.java
index 4c56166..f6ee817 100644
--- a/src/test/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceTest.java
+++ b/src/test/java/it/gov/pagopa/onboarding/citizen/service/CitizenServiceTest.java
@@ -3,12 +3,13 @@
import it.gov.pagopa.common.utils.Utils;
import it.gov.pagopa.common.web.exception.ClientExceptionWithBody;
import it.gov.pagopa.onboarding.citizen.dto.CitizenConsentDTO;
-import it.gov.pagopa.onboarding.citizen.dto.mapper.CitizenConsentMapperToDTO;
-import it.gov.pagopa.onboarding.citizen.exception.custom.EmdEncryptionException;
-import it.gov.pagopa.onboarding.citizen.exception.custom.ExceptionMap;
+import it.gov.pagopa.onboarding.citizen.dto.mapper.CitizenConsentObjectToDTOMapper;
+import it.gov.pagopa.common.web.exception.EmdEncryptionException;
+import it.gov.pagopa.onboarding.citizen.configuration.ExceptionMap;
import it.gov.pagopa.onboarding.citizen.faker.CitizenConsentDTOFaker;
+import it.gov.pagopa.onboarding.citizen.faker.CitizenConsentFaker;
import it.gov.pagopa.onboarding.citizen.model.CitizenConsent;
-import it.gov.pagopa.onboarding.citizen.model.mapper.CitizenConsentMapperToObject;
+import it.gov.pagopa.onboarding.citizen.model.mapper.CitizenConsentDTOToObjectMapper;
import it.gov.pagopa.onboarding.citizen.repository.CitizenRepository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -23,15 +24,16 @@
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
@ExtendWith({SpringExtension.class, MockitoExtension.class})
@ContextConfiguration(classes = {
CitizenServiceImpl.class,
- CitizenConsentMapperToDTO.class,
- CitizenConsentMapperToObject.class,
+ CitizenConsentObjectToDTOMapper.class,
+ CitizenConsentDTOToObjectMapper.class,
ExceptionMap.class
})
class CitizenServiceTest {
@@ -43,21 +45,25 @@ class CitizenServiceTest {
CitizenRepository citizenRepository;
@Autowired
- CitizenConsentMapperToObject mapperToObject;
- @Autowired
- ExceptionMap exceptionMap;
+ CitizenConsentDTOToObjectMapper mapperToObject;
+
+ private static final String FISCAL_CODE = "fiscalCode";
+ private static final String HASHED_FISCAL_CODE = Utils.createSHA256(FISCAL_CODE);
+ private static final String TPP_ID = "tppId";
+ private static final boolean TPP_STATE = true;
+ private static final CitizenConsent CITIZEN_CONSENT = CitizenConsentFaker.mockInstance(true);
@Test
void createCitizenConsent_Ok() {
CitizenConsentDTO citizenConsentDTO = CitizenConsentDTOFaker.mockInstance(true);
- CitizenConsent citizenConsent = mapperToObject.citizenConsentDTOMapper(citizenConsentDTO);
+ CitizenConsent citizenConsent = mapperToObject.map(citizenConsentDTO);
Mockito.when(citizenRepository.save(Mockito.any()))
.thenReturn(Mono.just(citizenConsent));
CitizenConsentDTO response = citizenService.createCitizenConsent(citizenConsentDTO).block();
- assert response != null;
+ assertNotNull(response);
citizenConsentDTO.setLastUpdateDate(response.getLastUpdateDate());
citizenConsentDTO.setCreationDate(response.getCreationDate());
@@ -78,30 +84,27 @@ void createCitizenConsent_Ko_EmdEncryptError() {
@Test
void updateChannelState_Ok() {
- String hashedFiscalCode = "hashedFiscalCode";
- String tppId = "tppId";
- boolean tppState = true;
- CitizenConsent citizenConsent = new CitizenConsent();
- Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId))
- .thenReturn(Mono.just(citizenConsent));
+
+
+ Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(HASHED_FISCAL_CODE, TPP_ID))
+ .thenReturn(Mono.just(CITIZEN_CONSENT));
Mockito.when(citizenRepository.save(Mockito.any()))
- .thenReturn(Mono.just(citizenConsent));
+ .thenReturn(Mono.just(CITIZEN_CONSENT));
- CitizenConsentDTO response = citizenService.updateChannelState(hashedFiscalCode, tppId, tppState).block();
- assert response != null;
- assertEquals(tppState, response.getTppState());
+ CitizenConsentDTO response = citizenService.updateChannelState(FISCAL_CODE, TPP_ID, TPP_STATE).block();
+ assertNotNull(response);
+ assertEquals(TPP_STATE, response.getTppState());
}
@Test
void updateChannelState_Ko_CitizenNotOnboarded() {
- String hashedFiscalCode = "hashedFiscalCode";
- String tppId = "tppId";
- Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId))
+
+ Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(HASHED_FISCAL_CODE, TPP_ID))
.thenReturn(Mono.empty());
- Executable executable = () -> citizenService.updateChannelState(hashedFiscalCode, tppId, true).block();
+ Executable executable = () -> citizenService.updateChannelState(FISCAL_CODE, TPP_ID, true).block();
ClientExceptionWithBody exception = assertThrows(ClientExceptionWithBody.class, executable);
assertEquals("CITIZEN_NOT_ONBOARDED", exception.getMessage());
@@ -109,28 +112,22 @@ void updateChannelState_Ko_CitizenNotOnboarded() {
@Test
void getConsentStatus_Ok() {
- String fiscalCode = "fiscalCode";
- String tppId = "tppId";
- String hashedFiscalCode = Utils.createSHA256(fiscalCode);
- CitizenConsent citizenConsent = new CitizenConsent();
+
- Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId))
- .thenReturn(Mono.just(citizenConsent));
+ Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(HASHED_FISCAL_CODE, TPP_ID))
+ .thenReturn(Mono.just(CITIZEN_CONSENT));
- CitizenConsentDTO response = citizenService.getConsentStatus(fiscalCode, tppId).block();
- assert response != null;
+ CitizenConsentDTO response = citizenService.getConsentStatus(FISCAL_CODE, TPP_ID).block();
+ assertNotNull(response);
}
@Test
void getConsentStatus_Ko_CitizenNotOnboarded() {
- String fiscalCode = "fiscalCode";
- String tppId = "tppId";
- String hashedFiscalCode = Utils.createSHA256(fiscalCode);
- Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(hashedFiscalCode, tppId))
+ Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppId(HASHED_FISCAL_CODE, TPP_ID))
.thenReturn(Mono.empty());
- Executable executable = () -> citizenService.getConsentStatus(fiscalCode, tppId).block();
+ Executable executable = () -> citizenService.getConsentStatus(FISCAL_CODE, TPP_ID).block();
ClientExceptionWithBody exception = assertThrows(ClientExceptionWithBody.class, executable);
assertEquals("CITIZEN_NOT_ONBOARDED", exception.getMessage());
@@ -138,27 +135,25 @@ void getConsentStatus_Ko_CitizenNotOnboarded() {
@Test
void getListEnabledConsents_Ok() {
- String fiscalCode = "fiscalCode";
- String hashedFiscalCode = Utils.createSHA256(fiscalCode);
- CitizenConsent citizenConsent = new CitizenConsent();
+
- Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppStateTrue(hashedFiscalCode))
- .thenReturn(Flux.just(citizenConsent));
+ Mockito.when(citizenRepository.findByHashedFiscalCodeAndTppStateTrue(HASHED_FISCAL_CODE))
+ .thenReturn(Flux.just(CITIZEN_CONSENT));
- Flux response = citizenService.getListEnabledConsents(fiscalCode);
- assertEquals(1, response.count().block());
+ List response = citizenService.getListEnabledConsents(FISCAL_CODE).block();
+ assertNotNull(response);
+ assertEquals(1, response.size());
}
@Test
void getListAllConsents_Ok() {
- String fiscalCode = "fiscalCode";
- String hashedFiscalCode = Utils.createSHA256(fiscalCode);
- CitizenConsent citizenConsent = new CitizenConsent();
+
- Mockito.when(citizenRepository.findByHashedFiscalCode(hashedFiscalCode))
- .thenReturn(Flux.just(citizenConsent));
+ Mockito.when(citizenRepository.findByHashedFiscalCode(HASHED_FISCAL_CODE))
+ .thenReturn(Flux.just(CITIZEN_CONSENT));
- Flux response = citizenService.getListAllConsents(fiscalCode);
- assertEquals(1, response.count().block());
+ List response = citizenService.getListAllConsents(FISCAL_CODE).block();
+ assertNotNull(response);
+ assertEquals(1, response.size());
}
}