From f107e1fdf20ea0f81d245786119ab9de3015a9cb Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 3 May 2024 11:43:26 -0500 Subject: [PATCH 1/2] 2227 Fixing issue where jackson wasn't serializing dates in correct format --- .../services/reviews/ReviewPeriod.java | 9 +++++ .../reviews/ReviewPeriodCreateDTO.java | 9 +++++ .../reviews/ReviewPeriodControllerTest.java | 37 +++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriod.java b/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriod.java index 6270c5622f..bcf9ae831c 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriod.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriod.java @@ -1,5 +1,8 @@ package com.objectcomputing.checkins.services.reviews; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import io.micronaut.core.annotation.Introspected; import io.micronaut.core.annotation.Nullable; import io.micronaut.data.annotation.AutoPopulated; @@ -57,14 +60,20 @@ public class ReviewPeriod { @Nullable @Column(name = "launch_date") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime launchDate; @Nullable @Column(name = "self_review_close_date") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime selfReviewCloseDate; @Nullable @Column(name = "close_date") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime closeDate; public ReviewPeriod(String name, ReviewStatus reviewStatus, @Nullable UUID reviewTemplateId, diff --git a/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodCreateDTO.java b/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodCreateDTO.java index 2d9ef8df87..cb1177c13d 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodCreateDTO.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodCreateDTO.java @@ -1,5 +1,8 @@ package com.objectcomputing.checkins.services.reviews; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import io.micronaut.core.annotation.Introspected; import io.micronaut.core.annotation.Nullable; import io.swagger.v3.oas.annotations.media.Schema; @@ -32,12 +35,18 @@ public class ReviewPeriodCreateDTO { private UUID selfReviewTemplateId; @Nullable + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime launchDate; @Nullable + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime selfReviewCloseDate; @Nullable + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private LocalDateTime closeDate; public ReviewPeriod convertToEntity(){ diff --git a/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java index f16ab914c8..055751ec4a 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java @@ -1,5 +1,8 @@ package com.objectcomputing.checkins.services.reviews; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.objectcomputing.checkins.services.TestContainersSuite; import com.objectcomputing.checkins.services.fixture.MemberProfileFixture; import com.objectcomputing.checkins.services.fixture.ReviewPeriodFixture; @@ -127,6 +130,40 @@ public void testPOSTCreateAReviewPeriod() { assertEquals(String.format("%s/%s", request.getPath(), body.getId()), response.getHeaders().get("location")); } + @Test + public void mattExampleJsonSerialization() throws JsonProcessingException { + ReviewPeriodCreateDTO reviewPeriodCreateDTO = new ReviewPeriodCreateDTO(); + reviewPeriodCreateDTO.setName("reincarnation"); + reviewPeriodCreateDTO.setReviewStatus(ReviewStatus.OPEN); + reviewPeriodCreateDTO.setLaunchDate(LocalDateTime.now()); + reviewPeriodCreateDTO.setSelfReviewCloseDate(LocalDateTime.now()); + reviewPeriodCreateDTO.setCloseDate(LocalDateTime.now()); + + final HttpRequest request = HttpRequest. + POST("/", reviewPeriodCreateDTO).basicAuth(MEMBER_ROLE, MEMBER_ROLE); + final HttpResponse response = client.toBlocking().exchange(request, String.class); + + assertNotNull(response); + var actualJson = response.body(); + assertNotNull(actualJson); + assertEquals(HttpStatus.CREATED, response.getStatus()); + + ObjectMapper objectMapper = new ObjectMapper(); + String expectedJson = objectMapper.writeValueAsString(reviewPeriodCreateDTO); + + String expectedLaunchDateFormat = objectMapper.readTree(expectedJson).get("launchDate").asText(); + String actualLaunchDateFormat = objectMapper.readTree(actualJson).get("launchDate").asText(); + assertEquals(expectedLaunchDateFormat, actualLaunchDateFormat); + + String expectedSelfReviewCloseDateFormat = objectMapper.readTree(expectedJson).get("selfReviewCloseDate").asText(); + String actualSelfReviewCloseDateFormat = objectMapper.readTree(actualJson).get("selfReviewCloseDate").asText(); + assertEquals(expectedSelfReviewCloseDateFormat, actualSelfReviewCloseDateFormat); + + String expectedCloseDateFormat = objectMapper.readTree(expectedJson).get("closeDate").asText(); + String actualCloseDateFormat = objectMapper.readTree(actualJson).get("closeDate").asText(); + assertEquals(expectedCloseDateFormat, actualCloseDateFormat); + } + @Test public void testPOSTCreateAReviewPeriodWithTimelines() { LocalDateTime launchDate = LocalDateTime.now(); From b46f6e9555d6350c5bb318ea1c643f6c1bf9b961 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Fri, 3 May 2024 12:33:53 -0500 Subject: [PATCH 2/2] 2227 Adding serialization tests --- .../reviews/ReviewPeriodControllerTest.java | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java b/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java index 055751ec4a..a40371cd7c 100644 --- a/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java +++ b/server/src/test/java/com/objectcomputing/checkins/services/reviews/ReviewPeriodControllerTest.java @@ -21,6 +21,7 @@ import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -131,7 +132,7 @@ public void testPOSTCreateAReviewPeriod() { } @Test - public void mattExampleJsonSerialization() throws JsonProcessingException { + public void testReviewPeriodCreateDTOSerialization() throws JsonProcessingException { ReviewPeriodCreateDTO reviewPeriodCreateDTO = new ReviewPeriodCreateDTO(); reviewPeriodCreateDTO.setName("reincarnation"); reviewPeriodCreateDTO.setReviewStatus(ReviewStatus.OPEN); @@ -166,9 +167,9 @@ public void mattExampleJsonSerialization() throws JsonProcessingException { @Test public void testPOSTCreateAReviewPeriodWithTimelines() { - LocalDateTime launchDate = LocalDateTime.now(); - LocalDateTime selfReviewCloseDate = LocalDateTime.now().plusDays(1); - LocalDateTime closeDate = LocalDateTime.now().plusDays(2); + LocalDateTime launchDate = LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS); + LocalDateTime selfReviewCloseDate = LocalDateTime.now().plusDays(1).truncatedTo(ChronoUnit.MILLIS); + LocalDateTime closeDate = LocalDateTime.now().plusDays(2).truncatedTo(ChronoUnit.MILLIS); ReviewPeriodCreateDTO reviewPeriodCreateDTO = new ReviewPeriodCreateDTO(); reviewPeriodCreateDTO.setName("reincarnation"); @@ -255,6 +256,38 @@ void testUpdateReviewPeriodAsAdmin() { assertEquals(HttpStatus.OK, response.getStatus()); } + @Test + void testReviewPeriodSerialization() throws JsonProcessingException { + MemberProfile memberProfileOfAdmin = createAnUnrelatedUser(); + createAndAssignAdminRole(memberProfileOfAdmin); + + ReviewPeriod reviewPeriod = createADefaultReviewPeriod(); + reviewPeriod.setReviewStatus(ReviewStatus.OPEN); + + final HttpRequest request = HttpRequest. + PUT("/", reviewPeriod).basicAuth(memberProfileOfAdmin.getWorkEmail(), ADMIN_ROLE); + + final HttpResponse response = client.toBlocking().exchange(request, String.class); + + String actualJson = response.body(); + assertEquals(HttpStatus.OK, response.getStatus()); + + ObjectMapper objectMapper = new ObjectMapper(); + String expectedJson = objectMapper.writeValueAsString(reviewPeriod); + + String expectedLaunchDateFormat = objectMapper.readTree(expectedJson).get("launchDate").asText(); + String actualLaunchDateFormat = objectMapper.readTree(actualJson).get("launchDate").asText(); + assertEquals(expectedLaunchDateFormat, actualLaunchDateFormat); + + String expectedSelfReviewCloseDateFormat = objectMapper.readTree(expectedJson).get("selfReviewCloseDate").asText(); + String actualSelfReviewCloseDateFormat = objectMapper.readTree(actualJson).get("selfReviewCloseDate").asText(); + assertEquals(expectedSelfReviewCloseDateFormat, actualSelfReviewCloseDateFormat); + + String expectedCloseDateFormat = objectMapper.readTree(expectedJson).get("closeDate").asText(); + String actualCloseDateFormat = objectMapper.readTree(actualJson).get("closeDate").asText(); + assertEquals(expectedCloseDateFormat, actualCloseDateFormat); + } + @Test public void testPUTUpdateReviewPeriodNonAdmin() { ReviewPeriod reviewPeriod = createADefaultReviewPeriod();