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..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 @@ -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; @@ -18,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; @@ -127,11 +131,45 @@ public void testPOSTCreateAReviewPeriod() { assertEquals(String.format("%s/%s", request.getPath(), body.getId()), response.getHeaders().get("location")); } + @Test + public void testReviewPeriodCreateDTOSerialization() 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(); - 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"); @@ -218,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();