diff --git a/src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java b/src/main/java/it/gov/pagopa/common/mongo/MongoConfig.java similarity index 98% rename from src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java rename to src/main/java/it/gov/pagopa/common/mongo/MongoConfig.java index aa906e0..1fa7efb 100644 --- a/src/main/java/it/gov/pagopa/common/configuration/MongoConfig.java +++ b/src/main/java/it/gov/pagopa/common/mongo/MongoConfig.java @@ -1,4 +1,4 @@ -package it.gov.pagopa.common.configuration; +package it.gov.pagopa.common.mongo; import com.mongodb.lang.NonNull; import it.gov.pagopa.common.utils.CommonConstants; diff --git a/src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java b/src/main/java/it/gov/pagopa/common/mongo/MongoHealthConfig.java similarity index 79% rename from src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java rename to src/main/java/it/gov/pagopa/common/mongo/MongoHealthConfig.java index d046ec2..1630aa3 100644 --- a/src/main/java/it/gov/pagopa/common/configuration/MongoHealthConfig.java +++ b/src/main/java/it/gov/pagopa/common/mongo/MongoHealthConfig.java @@ -1,5 +1,6 @@ -package it.gov.pagopa.common.configuration; +package it.gov.pagopa.common.mongo; +import it.gov.pagopa.common.configuration.CustomReactiveMongoHealthIndicator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.mongodb.core.ReactiveMongoTemplate; diff --git a/src/main/java/it/gov/pagopa/common/web/dto/ErrorDTO.java b/src/main/java/it/gov/pagopa/common/web/dto/ErrorDTO.java index 3e4622d..98a1b67 100644 --- a/src/main/java/it/gov/pagopa/common/web/dto/ErrorDTO.java +++ b/src/main/java/it/gov/pagopa/common/web/dto/ErrorDTO.java @@ -5,14 +5,12 @@ import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; @JsonInclude(JsonInclude.Include.NON_NULL) @AllArgsConstructor @NoArgsConstructor @Data -@EqualsAndHashCode public class ErrorDTO implements ServiceExceptionPayload { @NotBlank diff --git a/src/main/java/it/gov/pagopa/message/dto/MessageDTO.java b/src/main/java/it/gov/pagopa/message/dto/MessageDTO.java index 5bd790b..b83e76f 100644 --- a/src/main/java/it/gov/pagopa/message/dto/MessageDTO.java +++ b/src/main/java/it/gov/pagopa/message/dto/MessageDTO.java @@ -20,8 +20,8 @@ public class MessageDTO { private String originId; @JsonAlias("message") private String content; - private String entityId; private Boolean associatedPayment; + private String idPsp; @Override public String toString() { diff --git a/src/main/java/it/gov/pagopa/message/event/producer/MessageProducer.java b/src/main/java/it/gov/pagopa/message/event/producer/MessageProducer.java index c2fa5bd..efb3073 100644 --- a/src/main/java/it/gov/pagopa/message/event/producer/MessageProducer.java +++ b/src/main/java/it/gov/pagopa/message/event/producer/MessageProducer.java @@ -26,7 +26,6 @@ public MessageProducer(StreamBridge streamBridge, public void scheduleMessage(Message message) { String messageId = message.getPayload().getMessageId(); log.info("[MESSAGE-CORE][SCHEDULE-MESSAGE] Scheduling message ID: {} to messageSenderQueue", messageId); - streamBridge.send("messageSender-out-0", binder, message); } } diff --git a/src/main/java/it/gov/pagopa/message/service/MessageProducerServiceImpl.java b/src/main/java/it/gov/pagopa/message/service/MessageProducerServiceImpl.java index 75c713c..5932314 100644 --- a/src/main/java/it/gov/pagopa/message/service/MessageProducerServiceImpl.java +++ b/src/main/java/it/gov/pagopa/message/service/MessageProducerServiceImpl.java @@ -27,13 +27,9 @@ public Mono enqueueMessage(MessageDTO messageDTO) { log.info("[MESSAGE-PRODUCER][ENQUEUE] Enqueuing message with ID: {}", messageDTO.getMessageId()); return Mono.fromRunnable(() -> { - try { Message message = createMessage(messageDTO); log.info("[MESSAGE-PRODUCER][ENQUEUE] Message with ID: {} successfully created. Sending to message queue.", messageDTO.getMessageId()); messageProducer.scheduleMessage(message); - } catch (Exception e) { - log.error("[MESSAGE-PRODUCER][ENQUEUE] Error while creating or sending message with ID: {}. Error: {}", messageDTO.getMessageId(), e.getMessage()); - } }); } diff --git a/src/test/java/it/gov/pagopa/common/reactive/utils/PerformanceLoggerTest.java b/src/test/java/it/gov/pagopa/common/reactive/utils/PerformanceLoggerTest.java index 70dee30..7e64831 100644 --- a/src/test/java/it/gov/pagopa/common/reactive/utils/PerformanceLoggerTest.java +++ b/src/test/java/it/gov/pagopa/common/reactive/utils/PerformanceLoggerTest.java @@ -10,6 +10,7 @@ class PerformanceLoggerTest { //region mono ops + @Test void testMonoLogTimingOnNext(){ testMonoLogTimingOnNext(null); testMonoLogTimingOnNext(Object::toString); diff --git a/src/test/java/it/gov/pagopa/common/utils/CommonUtilitiesTest.java b/src/test/java/it/gov/pagopa/common/utils/CommonUtilitiesTest.java index dc96b58..624d754 100644 --- a/src/test/java/it/gov/pagopa/common/utils/CommonUtilitiesTest.java +++ b/src/test/java/it/gov/pagopa/common/utils/CommonUtilitiesTest.java @@ -1,24 +1,37 @@ package it.gov.pagopa.common.utils; - - +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectReader; import it.gov.pagopa.common.web.exception.EmdEncryptionException; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; import org.mockito.MockedStatic; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.function.Consumer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; @ExtendWith(MockitoExtension.class) class CommonUtilitiesTest { + @Mock + private Message messageMock; + @Mock + private ObjectReader objectReaderMock; + @Test void createSHA256_Ko_NoSuchAlgorithm() { try (MockedStatic mockedStatic = Mockito.mockStatic(MessageDigest.class)) { @@ -30,12 +43,86 @@ void createSHA256_Ko_NoSuchAlgorithm() { assertEquals("SHA-256 not available", exception.getCause().getMessage()); } } + @Test - void createSHA256_Ok(){ + void createSHA256_Ok() { String toHash = "RSSMRA98B18L049O"; String hashedExpected = "0b393cbe68a39f26b90c80a8dc95abc0fe4c21821195b4671a374c1443f9a1bb"; String actualHash = CommonUtilities.createSHA256(toHash); - assertEquals(actualHash,hashedExpected); + assertEquals(hashedExpected, actualHash); } + @Test + void deserializeMessage_Ko_JsonProcessingException() { + Consumer errorHandler = e -> Assertions.assertTrue(e instanceof JsonProcessingException); + when(messageMock.getPayload()).thenReturn("invalid payload"); + + try { + when(objectReaderMock.readValue("invalid payload")).thenThrow(new JsonProcessingException("Invalid JSON") {}); + + // Act + Object result = CommonUtilities.deserializeMessage(messageMock, objectReaderMock, errorHandler); + + // Assert + Assertions.assertNull(result); + } catch (JsonProcessingException e) { + Assertions.fail("Exception should be handled in the method"); + } + } + + @Test + void deserializeMessage_Ok() { + // Setup + String validJson = "{\"name\":\"John\"}"; + MyObject expectedObject = new MyObject("John"); + Consumer errorHandler = e -> Assertions.fail("Should not have thrown an error"); + + when(messageMock.getPayload()).thenReturn(validJson); + try { + when(objectReaderMock.readValue(validJson)).thenReturn(expectedObject); + + MyObject result = CommonUtilities.deserializeMessage(messageMock, objectReaderMock, errorHandler); + + Assertions.assertNotNull(result); + assertEquals(expectedObject.name(), result.name()); + } catch (JsonProcessingException e) { + Assertions.fail("Exception should not be thrown"); + } + } + + @Test + void readMessagePayload_StringPayload() { + String expectedPayload = "test message"; + when(messageMock.getPayload()).thenReturn(expectedPayload); + + String actualPayload = CommonUtilities.readMessagePayload(messageMock); + + assertEquals(expectedPayload, actualPayload); + } + + @Test + void getHeaderValue_Test() { + String headerName = "testHeader"; + String headerValue = "headerValue"; + MessageHeaders headers = new MessageHeaders(Map.of(headerName, headerValue)); + + when(messageMock.getHeaders()).thenReturn(headers); + + Object result = CommonUtilities.getHeaderValue(messageMock, headerName); + + assertEquals(headerValue, result); + } + + @Test + void getByteArrayHeaderValue_Test() { + String headerName = "byteArrayHeader"; + String headerValue = "headerValue"; + MessageHeaders headers = new MessageHeaders(Map.of(headerName, headerValue.getBytes(StandardCharsets.UTF_8))); + when(messageMock.getHeaders()).thenReturn(headers); + + String result = CommonUtilities.getByteArrayHeaderValue(messageMock, headerName); + + assertEquals(headerValue, result); + } + record MyObject(String name) { } } 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 078708d..03247b9 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 @@ -76,6 +76,39 @@ void handleExceptionClientExceptionNoBody() { 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]+\\)"); + + memoryAppender.reset(); + + Throwable throwable = new Exception("Cause of the exception"); + + Mockito.doThrow( + new ClientExceptionNoBody(HttpStatus.BAD_REQUEST, "ClientExceptionNoBody with Throwable", throwable)) + .when(testControllerSpy).testEndpoint(); + + webTestClient.get() + .uri("/test") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isBadRequest(); + + checkStackTraceSuppressedLog(memoryAppender, + "Something went wrong handling request GET /test: HttpStatus 400 BAD_REQUEST - ClientExceptionNoBody with Throwable"); + + memoryAppender.reset(); + + Mockito.doThrow( + new ClientExceptionNoBody(HttpStatus.BAD_REQUEST, "ClientExceptionNoBody", true, throwable)) + .when(testControllerSpy).testEndpoint(); + + webTestClient.get() + .uri("/test") + .accept(MediaType.APPLICATION_JSON) + .exchange() + .expectStatus().isBadRequest(); + + checkStackTraceSuppressedLog(memoryAppender, + "Something went wrong handling request GET /test: HttpStatus 400 BAD_REQUEST - ClientExceptionNoBody"); + } @Test 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 3236568..7e95f91 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 @@ -51,7 +51,6 @@ static class ValidationDTO { @Test void testHandleValueNotValidException() { String invalidJson = "{}"; - webTestClient.put() .uri("/test") .contentType(MediaType.APPLICATION_JSON) @@ -69,8 +68,6 @@ void testHandleValueNotValidException() { } @Test void testHandleHeaderNotValidException() { - String invalidJson = "{}"; - webTestClient.put() .uri("/test") .contentType(MediaType.APPLICATION_JSON) @@ -78,7 +75,6 @@ void testHandleHeaderNotValidException() { .exchange() .expectStatus().isBadRequest() .expectBody(ErrorDTO.class) - .consumeWith(response -> { ErrorDTO errorDTO = response.getResponseBody(); assertThat(errorDTO).isNotNull(); @@ -87,4 +83,21 @@ void testHandleHeaderNotValidException() { }); } + + @Test + void testHandleNoResourceFoundException() { + webTestClient.put() + .uri("/test/missing") + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(new ValidationDTO("someData")) + .exchange() + .expectStatus().isNotFound() // Expect 404 Not Found + .expectBody(ErrorDTO.class) + .consumeWith(response -> { + ErrorDTO errorDTO = response.getResponseBody(); + assertThat(errorDTO).isNotNull(); + assertThat(errorDTO.getCode()).isEqualTo("INVALID_REQUEST"); // Check the code from ErrorDTO + assertThat(errorDTO.getMessage()).isEqualTo("Invalid request"); // Check the message from ErrorDTO + }); + } } diff --git a/src/test/java/it/gov/pagopa/message/connector/citizen/CitizenConnectorImplTest.java b/src/test/java/it/gov/pagopa/message/connector/citizen/CitizenConnectorImplTest.java index 2db9d4d..f9af1fd 100644 --- a/src/test/java/it/gov/pagopa/message/connector/citizen/CitizenConnectorImplTest.java +++ b/src/test/java/it/gov/pagopa/message/connector/citizen/CitizenConnectorImplTest.java @@ -9,13 +9,12 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; -import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; import java.io.IOException; import static it.gov.pagopa.message.utils.TestUtils.FISCAL_CODE; import static it.gov.pagopa.message.utils.TestUtils.RESPONSE; -import static org.assertj.core.api.Assertions.assertThat; @ExtendWith(MockitoExtension.class) class CitizenConnectorImplTest { @@ -42,10 +41,10 @@ void testCheckFiscalCode() { .setBody(RESPONSE) .addHeader("Content-Type", "application/json")); - Mono resultMono = citizenConnector.checkFiscalCode(FISCAL_CODE); - String result = resultMono.block(); - assertThat(result).isEqualTo(RESPONSE); + StepVerifier.create(citizenConnector.checkFiscalCode(FISCAL_CODE)) + .expectNext(RESPONSE) + .verifyComplete(); } } diff --git a/src/test/java/it/gov/pagopa/message/event/producer/MessageProducerTest.java b/src/test/java/it/gov/pagopa/message/event/producer/MessageProducerTest.java index 1304044..8a38026 100644 --- a/src/test/java/it/gov/pagopa/message/event/producer/MessageProducerTest.java +++ b/src/test/java/it/gov/pagopa/message/event/producer/MessageProducerTest.java @@ -20,13 +20,10 @@ class MessageProducerTest { @InjectMocks private MessageProducer messageProducer; - - @Test void testStreamBridgeSendCalled() { messageProducer.scheduleMessage(QUEUE_MESSAGE); verify(streamBridge, times(1)).send(eq("messageSender-out-0"), any(), eq(QUEUE_MESSAGE)); - } } diff --git a/src/test/java/it/gov/pagopa/message/service/MessageCoreServiceTest.java b/src/test/java/it/gov/pagopa/message/service/MessageCoreServiceTest.java index 149415c..0b6ea7b 100644 --- a/src/test/java/it/gov/pagopa/message/service/MessageCoreServiceTest.java +++ b/src/test/java/it/gov/pagopa/message/service/MessageCoreServiceTest.java @@ -1,8 +1,6 @@ package it.gov.pagopa.message.service; import it.gov.pagopa.message.connector.CitizenConnectorImpl; - -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; @@ -11,6 +9,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; import static it.gov.pagopa.message.utils.TestUtils.FISCAL_CODE; import static it.gov.pagopa.message.utils.TestUtils.MESSAGE_DTO; @@ -35,8 +34,10 @@ void sendMessage_Ok() { when(citizenConnector.checkFiscalCode(FISCAL_CODE)).thenReturn(Mono.just("OK")); when(messageProducerService.enqueueMessage(MESSAGE_DTO)).thenReturn(Mono.empty()); - Boolean result = messageCoreService.send(MESSAGE_DTO).block(); - Assertions.assertEquals(true, result); + + StepVerifier.create(messageCoreService.send(MESSAGE_DTO)) + .expectNext(true) + .verifyComplete(); } @@ -44,8 +45,9 @@ void sendMessage_Ok() { void sendMessage_Ko() { when(citizenConnector.checkFiscalCode(FISCAL_CODE)).thenReturn(Mono.just("NO CHANNEL ENABLED")); - Boolean result = messageCoreService.send(MESSAGE_DTO).block(); - Assertions.assertEquals(false,result); + StepVerifier.create(messageCoreService.send(MESSAGE_DTO)) + .expectNext(false) + .verifyComplete(); } } diff --git a/src/test/java/it/gov/pagopa/message/service/MessageProducerServiceTest.java b/src/test/java/it/gov/pagopa/message/service/MessageProducerServiceTest.java index b46396a..309dd2f 100644 --- a/src/test/java/it/gov/pagopa/message/service/MessageProducerServiceTest.java +++ b/src/test/java/it/gov/pagopa/message/service/MessageProducerServiceTest.java @@ -9,6 +9,7 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; +import reactor.test.StepVerifier; import static it.gov.pagopa.message.utils.TestUtils.MESSAGE_DTO; import static org.mockito.ArgumentMatchers.any; @@ -27,7 +28,8 @@ class MessageProducerServiceTest { @Test void sendMessage_OK(){ - messageProducerService.enqueueMessage(MESSAGE_DTO).block(); + StepVerifier.create(messageProducerService.enqueueMessage(MESSAGE_DTO)) + .verifyComplete(); Mockito.verify(messageProducer,times(1)).scheduleMessage(any()); }