From 25b84e59f15addaace74146f803eb1b3b03ce08e Mon Sep 17 00:00:00 2001 From: Raja Kolli Date: Fri, 10 Nov 2023 18:12:58 +0000 Subject: [PATCH] feat: adds comments to post request and response --- .../graphql/querydsl/mapper/PostMapper.java | 19 ++++++++--- .../model/request/CreatePostRequest.java | 4 ++- ...ostRequest.java => UpdatePostRequest.java} | 2 +- .../querydsl/model/response/PostResponse.java | 8 ++++- .../querydsl/services/PostService.java | 6 ++-- .../web/controllers/PostController.java | 5 +-- .../querydsl/services/PostServiceTest.java | 3 +- .../web/controllers/PostControllerIT.java | 19 +++++++---- .../web/controllers/PostControllerTest.java | 32 +++++++++++-------- 9 files changed, 64 insertions(+), 34 deletions(-) rename graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/{PostRequest.java => UpdatePostRequest.java} (89%) diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/mapper/PostMapper.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/mapper/PostMapper.java index 048e37f79..b87be03dc 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/mapper/PostMapper.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/mapper/PostMapper.java @@ -1,23 +1,30 @@ package com.example.graphql.querydsl.mapper; import com.example.graphql.querydsl.entities.Post; +import com.example.graphql.querydsl.entities.PostComment; import com.example.graphql.querydsl.entities.PostDetails; import com.example.graphql.querydsl.model.request.CreatePostRequest; -import com.example.graphql.querydsl.model.request.PostRequest; +import com.example.graphql.querydsl.model.request.UpdatePostRequest; import com.example.graphql.querydsl.model.response.PostResponse; import java.time.LocalDateTime; import java.util.List; -import org.mapstruct.*; +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; @Mapper public interface PostMapper { + @Mapping(target = "details", ignore = true) + @Mapping(target = "comments", ignore = true) @Mapping(target = "id", ignore = true) Post toEntity(CreatePostRequest createPostRequest); + @Mapping(target = "details", ignore = true) + @Mapping(target = "comments", ignore = true) @Mapping(target = "id", ignore = true) - // @Mapping(target = "createdOn", ignore = true) - void mapPostWithRequest(PostRequest postRequest, @MappingTarget Post post); + void mapPostWithRequest(UpdatePostRequest updatePostRequest, @MappingTarget Post post); @Mapping(target = "createdOn", source = "details.createdOn") PostResponse toResponse(Post post); @@ -28,5 +35,9 @@ public interface PostMapper { default void setAfterMappingToPost(CreatePostRequest createPostRequest, @MappingTarget Post post) { post.addDetails( new PostDetails().setCreatedBy(createPostRequest.createdBy()).setCreatedOn(LocalDateTime.now())); + createPostRequest + .postCommentRequests() + .forEach(postCommentRequest -> post.addComment( + new PostComment().setReview(postCommentRequest.review()).setCreatedOn(LocalDateTime.now()))); } } diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/CreatePostRequest.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/CreatePostRequest.java index d9bb0a8c3..38f1c48e4 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/CreatePostRequest.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/CreatePostRequest.java @@ -2,8 +2,10 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; +import java.util.List; public record CreatePostRequest( @NotEmpty(message = "Title cannot be empty") String title, @NotBlank(message = "Content cannot be blank") String content, - @NotBlank(message = "CreatedBy cannot be blank") String createdBy) {} + @NotBlank(message = "CreatedBy cannot be blank") String createdBy, + List postCommentRequests) {} diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/PostRequest.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/UpdatePostRequest.java similarity index 89% rename from graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/PostRequest.java rename to graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/UpdatePostRequest.java index 086f49708..f5bcbd0c7 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/PostRequest.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/request/UpdatePostRequest.java @@ -3,6 +3,6 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; -public record PostRequest( +public record UpdatePostRequest( @NotEmpty(message = "Title cannot be empty") String title, @NotBlank(message = "Content cannot be blank") String content) {} diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/response/PostResponse.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/response/PostResponse.java index 5e4141c28..8a6a3acd9 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/response/PostResponse.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/model/response/PostResponse.java @@ -1,5 +1,11 @@ package com.example.graphql.querydsl.model.response; import java.time.LocalDateTime; +import java.util.List; -public record PostResponse(Long id, String title, String content, LocalDateTime createdOn) {} +public record PostResponse( + Long id, + String title, + String content, + LocalDateTime createdOn, + List postCommentResponses) {} diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/services/PostService.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/services/PostService.java index aef279f4c..b76f61c18 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/services/PostService.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/services/PostService.java @@ -5,7 +5,7 @@ import com.example.graphql.querydsl.mapper.PostMapper; import com.example.graphql.querydsl.model.query.FindPostsQuery; import com.example.graphql.querydsl.model.request.CreatePostRequest; -import com.example.graphql.querydsl.model.request.PostRequest; +import com.example.graphql.querydsl.model.request.UpdatePostRequest; import com.example.graphql.querydsl.model.response.PagedResult; import com.example.graphql.querydsl.model.response.PostResponse; import com.example.graphql.querydsl.repositories.PostRepository; @@ -60,11 +60,11 @@ public PostResponse savePost(CreatePostRequest createPostRequest) { } @Transactional - public PostResponse updatePost(Long id, PostRequest postRequest) { + public PostResponse updatePost(Long id, UpdatePostRequest updatePostRequest) { Post post = postRepository.findById(id).orElseThrow(() -> new PostNotFoundException(id)); // Update the post object with data from postRequest - postMapper.mapPostWithRequest(postRequest, post); + postMapper.mapPostWithRequest(updatePostRequest, post); // Save the updated post object Post updatedPost = postRepository.save(post); diff --git a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/web/controllers/PostController.java b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/web/controllers/PostController.java index 32e15b924..72e16a690 100644 --- a/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/web/controllers/PostController.java +++ b/graphql/boot-graphql-querydsl/src/main/java/com/example/graphql/querydsl/web/controllers/PostController.java @@ -3,7 +3,7 @@ import com.example.graphql.querydsl.exception.PostNotFoundException; import com.example.graphql.querydsl.model.query.FindPostsQuery; import com.example.graphql.querydsl.model.request.CreatePostRequest; -import com.example.graphql.querydsl.model.request.PostRequest; +import com.example.graphql.querydsl.model.request.UpdatePostRequest; import com.example.graphql.querydsl.model.response.PagedResult; import com.example.graphql.querydsl.model.response.PostResponse; import com.example.graphql.querydsl.services.PostService; @@ -63,7 +63,8 @@ public ResponseEntity createPost(@RequestBody @Validated CreatePos } @PutMapping("/{id}") - public ResponseEntity updatePost(@PathVariable Long id, @RequestBody @Valid PostRequest postRequest) { + public ResponseEntity updatePost( + @PathVariable Long id, @RequestBody @Valid UpdatePostRequest postRequest) { return ResponseEntity.ok(postService.updatePost(id, postRequest)); } diff --git a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/services/PostServiceTest.java b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/services/PostServiceTest.java index 1c3ff427d..740fef504 100644 --- a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/services/PostServiceTest.java +++ b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/services/PostServiceTest.java @@ -12,6 +12,7 @@ import com.example.graphql.querydsl.model.response.PostResponse; import com.example.graphql.querydsl.repositories.PostRepository; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -63,6 +64,6 @@ private Post getPost() { } private PostResponse getPostResponse() { - return new PostResponse(1L, "junitTest", "junitContent", LocalDateTime.now()); + return new PostResponse(1L, "junitTest", "junitContent", LocalDateTime.now(), new ArrayList<>()); } } diff --git a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerIT.java b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerIT.java index 4050d2c13..5903b1d7f 100644 --- a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerIT.java +++ b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerIT.java @@ -15,7 +15,8 @@ import com.example.graphql.querydsl.entities.Post; import com.example.graphql.querydsl.entities.PostDetails; import com.example.graphql.querydsl.model.request.CreatePostRequest; -import com.example.graphql.querydsl.model.request.PostRequest; +import com.example.graphql.querydsl.model.request.PostCommentRequest; +import com.example.graphql.querydsl.model.request.UpdatePostRequest; import com.example.graphql.querydsl.repositories.PostRepository; import java.time.LocalDateTime; import java.util.ArrayList; @@ -75,7 +76,11 @@ void shouldFindPostById() throws Exception { @Test void shouldCreateNewPost() throws Exception { - CreatePostRequest postRequest = new CreatePostRequest("New Post", "New Content", "Junit"); + CreatePostRequest postRequest = new CreatePostRequest( + "New Post", + "New Content", + "Junit", + List.of(new PostCommentRequest("New Review"), new PostCommentRequest("Second Review"))); this.mockMvc .perform(post("/api/posts") .contentType(MediaType.APPLICATION_JSON) @@ -89,7 +94,7 @@ void shouldCreateNewPost() throws Exception { @Test void shouldReturn400WhenCreateNewPostWithoutTitleAndContent() throws Exception { - CreatePostRequest createPostRequest = new CreatePostRequest(null, null, null); + CreatePostRequest createPostRequest = new CreatePostRequest(null, null, null, new ArrayList<>()); this.mockMvc .perform(post("/api/posts") @@ -115,16 +120,16 @@ void shouldReturn400WhenCreateNewPostWithoutTitleAndContent() throws Exception { @Test void shouldUpdatePost() throws Exception { Long postId = postList.get(0).getId(); - PostRequest postRequest = new PostRequest("Updated Post", "New Content"); + UpdatePostRequest updatePostRequest = new UpdatePostRequest("Updated Post", "New Content"); this.mockMvc .perform(put("/api/posts/{id}", postId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(postRequest))) + .content(objectMapper.writeValueAsString(updatePostRequest))) .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(postId), Long.class)) - .andExpect(jsonPath("$.title", is(postRequest.title()))) - .andExpect(jsonPath("$.content", is(postRequest.content()))); + .andExpect(jsonPath("$.title", is(updatePostRequest.title()))) + .andExpect(jsonPath("$.content", is(updatePostRequest.content()))); } @Test diff --git a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerTest.java b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerTest.java index 0eeb97e7e..a36aa6932 100644 --- a/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerTest.java +++ b/graphql/boot-graphql-querydsl/src/test/java/com/example/graphql/querydsl/web/controllers/PostControllerTest.java @@ -22,7 +22,7 @@ import com.example.graphql.querydsl.exception.PostNotFoundException; import com.example.graphql.querydsl.model.query.FindPostsQuery; import com.example.graphql.querydsl.model.request.CreatePostRequest; -import com.example.graphql.querydsl.model.request.PostRequest; +import com.example.graphql.querydsl.model.request.UpdatePostRequest; import com.example.graphql.querydsl.model.response.PagedResult; import com.example.graphql.querydsl.model.response.PostResponse; import com.example.graphql.querydsl.services.PostService; @@ -104,7 +104,7 @@ void shouldFetchAllPosts() throws Exception { @Test void shouldFindPostById() throws Exception { Long postId = 1L; - PostResponse post = new PostResponse(postId, "text 1", "content 1", getCreatedOn()); + PostResponse post = new PostResponse(postId, "text 1", "content 1", getCreatedOn(), new ArrayList<>()); given(postService.findPostById(postId)).willReturn(Optional.of(post)); this.mockMvc @@ -134,8 +134,9 @@ void shouldReturn404WhenFetchingNonExistingPost() throws Exception { @Test void shouldCreateNewPost() throws Exception { - PostResponse post = new PostResponse(1L, "some text", "some content", getCreatedOn()); - CreatePostRequest postRequest = new CreatePostRequest("some title", "some content", "appUser"); + PostResponse post = new PostResponse(1L, "some text", "some content", getCreatedOn(), new ArrayList<>()); + CreatePostRequest postRequest = + new CreatePostRequest("some title", "some content", "appUser", new ArrayList<>()); given(postService.savePost(any(CreatePostRequest.class))).willReturn(post); this.mockMvc @@ -153,7 +154,7 @@ void shouldCreateNewPost() throws Exception { @Test void shouldReturn400WhenCreateNewPostWithoutTitleAndContent() throws Exception { - CreatePostRequest createPostRequest = new CreatePostRequest(null, null, null); + CreatePostRequest createPostRequest = new CreatePostRequest(null, null, null, null); this.mockMvc .perform(post("/api/posts") @@ -182,13 +183,15 @@ class Update { @Test void shouldUpdatePost() throws Exception { Long postId = 1L; - PostResponse post = new PostResponse(postId, "Updated text", "some content", getCreatedOn()); - PostRequest postRequest = new PostRequest("Updated text", "some content"); - given(postService.updatePost(eq(postId), any(PostRequest.class))).willReturn(post); + PostResponse post = + new PostResponse(postId, "Updated text", "some content", getCreatedOn(), new ArrayList<>()); + UpdatePostRequest updatePostRequest = new UpdatePostRequest("Updated text", "some content"); + given(postService.updatePost(eq(postId), any(UpdatePostRequest.class))) + .willReturn(post); mockMvc.perform(put("/api/posts/{id}", postId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(postRequest))) + .content(objectMapper.writeValueAsString(updatePostRequest))) .andExpect(status().isOk()) .andExpect(jsonPath("$.id", is(postId), Long.class)) .andExpect(jsonPath("$.title", is(post.title()))) @@ -200,13 +203,13 @@ void shouldUpdatePost() throws Exception { @Test void shouldReturn404WhenUpdatingNonExistingPost() throws Exception { Long postId = 1L; - PostRequest postRequest = new PostRequest("Updated text", "some content"); - given(postService.updatePost(eq(postId), any(PostRequest.class))) + UpdatePostRequest updatePostRequest = new UpdatePostRequest("Updated text", "some content"); + given(postService.updatePost(eq(postId), any(UpdatePostRequest.class))) .willThrow(new PostNotFoundException(postId)); mockMvc.perform(put("/api/posts/{id}", postId) .contentType(MediaType.APPLICATION_JSON) - .content(objectMapper.writeValueAsString(postRequest))) + .content(objectMapper.writeValueAsString(updatePostRequest))) .andExpect(status().isNotFound()) .andExpect(header().string("Content-Type", is(MediaType.APPLICATION_PROBLEM_JSON_VALUE))) .andExpect(jsonPath("$.type", is("http://api.boot-graphql-querydsl.com/errors/not-found"))) @@ -219,7 +222,7 @@ void shouldReturn404WhenUpdatingNonExistingPost() throws Exception { @Test void shouldDeletePost() throws Exception { Long postId = 1L; - PostResponse post = new PostResponse(postId, "Some text", "some content", getCreatedOn()); + PostResponse post = new PostResponse(postId, "Some text", "some content", getCreatedOn(), new ArrayList<>()); given(postService.findPostById(postId)).willReturn(Optional.of(post)); doNothing().when(postService).deletePostById(postId); @@ -252,7 +255,8 @@ List getPostResponseList() { post.getId(), post.getTitle(), post.getContent(), - post.getDetails().getCreatedOn())) + post.getDetails().getCreatedOn(), + new ArrayList<>())) .toList(); }