From b74f1c0666849f9b57e6803ec1788608cd8662db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EA=B2=BD=ED=9B=88?= Date: Fri, 19 Apr 2024 19:04:30 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EA=B3=BC=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 + .../assignment/AssignmentApplication.java | 16 ++- .../application/CreateCommentService.java | 14 ++ .../application/CreatePostService.java | 13 ++ .../application/DeletePostService.java | 11 ++ .../application/GetCommentsService.java | 16 +++ .../application/GetPostService.java | 17 +++ .../application/UpdateCommentService.java | 18 +++ .../application/UpdatePostService.java | 18 +++ .../controllers/PostController.java | 52 +++++++ .../dtos/CommentCreateRequestDto.java | 21 +++ .../assignment/dtos/CommentResponseDto.java | 18 +++ .../dtos/CommentUpdateRequestDto.java | 16 +++ .../assignment/dtos/PostCreateRequestDto.java | 17 +++ .../assignment/dtos/PostResponseDto.java | 23 +++ .../assignment/dtos/PostUpdateRequestDto.java | 17 +++ .../assignment/dtos/RequestUpdate.java | 5 + .../exceptions/CommentNotFound.java | 4 + .../assignment/exceptions/PostNotFound.java | 4 + .../assignment/models/BaseEntity.java | 19 +++ .../megaptera/assignment/models/Comment.java | 22 +++ .../kr/megaptera/assignment/models/Post.java | 27 ++++ .../repository/CommentRepository.java | 41 ++++++ .../assignment/repository/PostRepository.java | 37 +++++ src/main/resources/application.properties | 2 + .../application/CreateCommentServiceTest.java | 35 +++++ .../application/CreatePostServiceTest.java | 28 ++++ .../application/DeleteCommentServiceTest.java | 33 +++++ .../application/DeletePostServiceTest.java | 25 ++++ .../application/GetCommentsServiceTest.java | 37 +++++ .../application/GetPostServiceTest.java | 35 +++++ .../application/GetPostsServiceTest.java | 21 +++ .../application/UpdateCommentServiceTest.java | 34 +++++ .../application/UpdatePostServiceTest.java | 30 ++++ .../controllers/PostControllerTest.java | 134 ++++++++++++++---- 35 files changed, 833 insertions(+), 30 deletions(-) create mode 100644 src/main/java/kr/megaptera/assignment/dtos/CommentCreateRequestDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/CommentResponseDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/CommentUpdateRequestDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/PostCreateRequestDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/PostResponseDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/PostUpdateRequestDto.java create mode 100644 src/main/java/kr/megaptera/assignment/dtos/RequestUpdate.java create mode 100644 src/main/java/kr/megaptera/assignment/exceptions/CommentNotFound.java create mode 100644 src/main/java/kr/megaptera/assignment/exceptions/PostNotFound.java create mode 100644 src/main/java/kr/megaptera/assignment/models/BaseEntity.java create mode 100644 src/main/java/kr/megaptera/assignment/models/Comment.java create mode 100644 src/main/java/kr/megaptera/assignment/models/Post.java create mode 100644 src/main/java/kr/megaptera/assignment/repository/CommentRepository.java create mode 100644 src/main/java/kr/megaptera/assignment/repository/PostRepository.java diff --git a/build.gradle b/build.gradle index 1e5f2a5..41dc18d 100644 --- a/build.gradle +++ b/build.gradle @@ -14,6 +14,9 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + compileOnly 'org.projectlombok:lombok:1.18.32' + annotationProcessor 'org.projectlombok:lombok:1.18.32' + developmentOnly 'org.springframework.boot:spring-boot-devtools' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/kr/megaptera/assignment/AssignmentApplication.java b/src/main/java/kr/megaptera/assignment/AssignmentApplication.java index 33b02ae..f2727c7 100644 --- a/src/main/java/kr/megaptera/assignment/AssignmentApplication.java +++ b/src/main/java/kr/megaptera/assignment/AssignmentApplication.java @@ -2,6 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SpringBootApplication public class AssignmentApplication { @@ -9,5 +12,16 @@ public class AssignmentApplication { public static void main(String[] args) { SpringApplication.run(AssignmentApplication.class, args); } - + @Bean + public WebMvcConfigurer webMvcConfigurer() { + return new WebMvcConfigurer() { + @Override + public void addCorsMappings(CorsRegistry registry) { + registry + .addMapping("/**") + .allowedMethods("GET", "POST", "PATCH", "DELETE", "OPTIONS") + .allowedOrigins("*"); + } + }; + } } diff --git a/src/main/java/kr/megaptera/assignment/application/CreateCommentService.java b/src/main/java/kr/megaptera/assignment/application/CreateCommentService.java index 05deb60..3a82154 100644 --- a/src/main/java/kr/megaptera/assignment/application/CreateCommentService.java +++ b/src/main/java/kr/megaptera/assignment/application/CreateCommentService.java @@ -1,4 +1,18 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentCreateRequestDto; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class CreateCommentService { + private final CommentRepository commentRepository; + + public CommentResponseDto createComment(CommentCreateRequestDto request){ + return CommentResponseDto.of(commentRepository.save(request.toEntity())); + } } + diff --git a/src/main/java/kr/megaptera/assignment/application/CreatePostService.java b/src/main/java/kr/megaptera/assignment/application/CreatePostService.java index 413a950..1ee5f72 100644 --- a/src/main/java/kr/megaptera/assignment/application/CreatePostService.java +++ b/src/main/java/kr/megaptera/assignment/application/CreatePostService.java @@ -1,4 +1,17 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostCreateRequestDto; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class CreatePostService { + private final PostRepository postRepository; + public PostResponseDto createPost(PostCreateRequestDto request) { + var post = postRepository.save(request.toEntity()); + return PostResponseDto.of(post); + } } diff --git a/src/main/java/kr/megaptera/assignment/application/DeletePostService.java b/src/main/java/kr/megaptera/assignment/application/DeletePostService.java index e656f51..d593a36 100644 --- a/src/main/java/kr/megaptera/assignment/application/DeletePostService.java +++ b/src/main/java/kr/megaptera/assignment/application/DeletePostService.java @@ -1,4 +1,15 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class DeletePostService { + private final PostRepository postRepository; + public PostResponseDto deletePost(String id) { + return PostResponseDto.of(postRepository.delete(id)); + } } diff --git a/src/main/java/kr/megaptera/assignment/application/GetCommentsService.java b/src/main/java/kr/megaptera/assignment/application/GetCommentsService.java index a534608..08d3a4a 100644 --- a/src/main/java/kr/megaptera/assignment/application/GetCommentsService.java +++ b/src/main/java/kr/megaptera/assignment/application/GetCommentsService.java @@ -1,4 +1,20 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor public class GetCommentsService { + private final CommentRepository commentRepository; + + public List getCommentList(String postId) { + return commentRepository.findAll(postId).stream().map(CommentResponseDto::of).toList(); + } + } diff --git a/src/main/java/kr/megaptera/assignment/application/GetPostService.java b/src/main/java/kr/megaptera/assignment/application/GetPostService.java index f5d1ac0..b55a411 100644 --- a/src/main/java/kr/megaptera/assignment/application/GetPostService.java +++ b/src/main/java/kr/megaptera/assignment/application/GetPostService.java @@ -1,4 +1,21 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor public class GetPostService { + private final PostRepository postRepository; + public List getList() { + return postRepository.findAll().stream().map(PostResponseDto::of).toList(); + } + + public PostResponseDto detail(String id) { + return PostResponseDto.of(postRepository.findPostById(id)); + } } diff --git a/src/main/java/kr/megaptera/assignment/application/UpdateCommentService.java b/src/main/java/kr/megaptera/assignment/application/UpdateCommentService.java index 87d8d4d..3ad2ebe 100644 --- a/src/main/java/kr/megaptera/assignment/application/UpdateCommentService.java +++ b/src/main/java/kr/megaptera/assignment/application/UpdateCommentService.java @@ -1,4 +1,22 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.dtos.CommentUpdateRequestDto; +import kr.megaptera.assignment.dtos.RequestUpdate; +import kr.megaptera.assignment.models.Comment; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class UpdateCommentService { + private final CommentRepository commentRepository; + + public CommentResponseDto update(String commentId, RequestUpdate request) { + var comment = commentRepository.find(commentId); + request.update(comment); + return CommentResponseDto.of(commentRepository.save(comment)); + } } diff --git a/src/main/java/kr/megaptera/assignment/application/UpdatePostService.java b/src/main/java/kr/megaptera/assignment/application/UpdatePostService.java index 15dff58..9a3b77f 100644 --- a/src/main/java/kr/megaptera/assignment/application/UpdatePostService.java +++ b/src/main/java/kr/megaptera/assignment/application/UpdatePostService.java @@ -1,4 +1,22 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.dtos.RequestUpdate; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class UpdatePostService { + private final PostRepository postRepository; + + public PostResponseDto updatePost(String id,RequestUpdate request){ + var post = postRepository.findPostById(id); + request.update(post); + return PostResponseDto.of(postRepository.save(post)); + } + } diff --git a/src/main/java/kr/megaptera/assignment/controllers/PostController.java b/src/main/java/kr/megaptera/assignment/controllers/PostController.java index d088e71..1e1f20c 100644 --- a/src/main/java/kr/megaptera/assignment/controllers/PostController.java +++ b/src/main/java/kr/megaptera/assignment/controllers/PostController.java @@ -1,4 +1,56 @@ package kr.megaptera.assignment.controllers; +import kr.megaptera.assignment.application.CreatePostService; +import kr.megaptera.assignment.application.DeletePostService; +import kr.megaptera.assignment.application.GetPostService; +import kr.megaptera.assignment.application.UpdatePostService; +import kr.megaptera.assignment.dtos.PostCreateRequestDto; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.dtos.PostUpdateRequestDto; +import kr.megaptera.assignment.exceptions.PostNotFound; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/posts") +@RequiredArgsConstructor public class PostController { + private final UpdatePostService updatePostService; + private final GetPostService getPostService; + private final CreatePostService createPostService; + private final DeletePostService deletePostService; + @GetMapping + public List getList(){ + return getPostService.getList(); + } + + @GetMapping("/{id}") + public PostResponseDto detail(@PathVariable("id")String id){ + return getPostService.detail(id); + } + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public PostResponseDto create(@RequestBody PostCreateRequestDto request){ + return createPostService.createPost(request); + } + + @PatchMapping("/{id}") + public PostResponseDto updatePost(@PathVariable("id") String id,@RequestBody PostUpdateRequestDto request){ + return updatePostService.updatePost(id,request); + } + @DeleteMapping("/{id}") + public PostResponseDto deletePost(@PathVariable("id")String id){ + return deletePostService.deletePost(id); + } + + @ExceptionHandler(PostNotFound.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public String postNotFound() { + return "게시물을 찾을 수 없습니다"; + } + } diff --git a/src/main/java/kr/megaptera/assignment/dtos/CommentCreateRequestDto.java b/src/main/java/kr/megaptera/assignment/dtos/CommentCreateRequestDto.java new file mode 100644 index 0000000..508ea08 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/CommentCreateRequestDto.java @@ -0,0 +1,21 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Comment; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class CommentCreateRequestDto { + private String postId; + private String author; + private String content; + + public Comment toEntity(){ + return new Comment(null,postId,author,content); + } + + public void setPostId(String postId) { + this.postId = postId; + } +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/CommentResponseDto.java b/src/main/java/kr/megaptera/assignment/dtos/CommentResponseDto.java new file mode 100644 index 0000000..e9176c4 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/CommentResponseDto.java @@ -0,0 +1,18 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Comment; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class CommentResponseDto { + private String id; + private String author; + private String content; + + public static CommentResponseDto of(Comment comment){ + return new CommentResponseDto(comment.getId(),comment.getAuthor(),comment.getContent()); + } + +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/CommentUpdateRequestDto.java b/src/main/java/kr/megaptera/assignment/dtos/CommentUpdateRequestDto.java new file mode 100644 index 0000000..2d71302 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/CommentUpdateRequestDto.java @@ -0,0 +1,16 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Comment; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class CommentUpdateRequestDto implements RequestUpdate { + private String content; + + @Override + public void update(Comment entity) { + entity.update(content); + } +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/PostCreateRequestDto.java b/src/main/java/kr/megaptera/assignment/dtos/PostCreateRequestDto.java new file mode 100644 index 0000000..3ed0b3d --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/PostCreateRequestDto.java @@ -0,0 +1,17 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Post; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PostCreateRequestDto { + private String title; + private String content; + private String author; + + public Post toEntity(){ + return new Post(null,title,content,author); + } +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/PostResponseDto.java b/src/main/java/kr/megaptera/assignment/dtos/PostResponseDto.java new file mode 100644 index 0000000..b6582a8 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/PostResponseDto.java @@ -0,0 +1,23 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Post; +import lombok.Getter; + +@Getter +public class PostResponseDto { + private String id; + private String title; + private String author; + private String content; + + public PostResponseDto(String id, String title, String author, String content) { + this.id = id; + this.title = title; + this.author = author; + this.content = content; + } + + public static PostResponseDto of(Post post){ + return new PostResponseDto(post.getId(),post.getTitle(),post.getAuthor(),post.getContent()); + } +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/PostUpdateRequestDto.java b/src/main/java/kr/megaptera/assignment/dtos/PostUpdateRequestDto.java new file mode 100644 index 0000000..8e561cb --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/PostUpdateRequestDto.java @@ -0,0 +1,17 @@ +package kr.megaptera.assignment.dtos; + +import kr.megaptera.assignment.models.Post; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class PostUpdateRequestDto implements RequestUpdate { + String title; + String content; + + @Override + public void update(Post post) { + post.update(title,content); + } +} diff --git a/src/main/java/kr/megaptera/assignment/dtos/RequestUpdate.java b/src/main/java/kr/megaptera/assignment/dtos/RequestUpdate.java new file mode 100644 index 0000000..dec0556 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/dtos/RequestUpdate.java @@ -0,0 +1,5 @@ +package kr.megaptera.assignment.dtos; + +public interface RequestUpdate { + public void update(T entity); +} diff --git a/src/main/java/kr/megaptera/assignment/exceptions/CommentNotFound.java b/src/main/java/kr/megaptera/assignment/exceptions/CommentNotFound.java new file mode 100644 index 0000000..5299a0a --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/exceptions/CommentNotFound.java @@ -0,0 +1,4 @@ +package kr.megaptera.assignment.exceptions; + +public class CommentNotFound extends RuntimeException{ +} diff --git a/src/main/java/kr/megaptera/assignment/exceptions/PostNotFound.java b/src/main/java/kr/megaptera/assignment/exceptions/PostNotFound.java new file mode 100644 index 0000000..aec9159 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/exceptions/PostNotFound.java @@ -0,0 +1,4 @@ +package kr.megaptera.assignment.exceptions; + +public class PostNotFound extends RuntimeException { +} diff --git a/src/main/java/kr/megaptera/assignment/models/BaseEntity.java b/src/main/java/kr/megaptera/assignment/models/BaseEntity.java new file mode 100644 index 0000000..47f11b9 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/models/BaseEntity.java @@ -0,0 +1,19 @@ +package kr.megaptera.assignment.models; + +import lombok.Getter; + +import java.util.UUID; + +@Getter +public class BaseEntity { + protected String id; + + public BaseEntity(final String id) { + if(id == null){ + this.id = UUID.randomUUID().toString(); + return; + } + this.id = id; + } + +} diff --git a/src/main/java/kr/megaptera/assignment/models/Comment.java b/src/main/java/kr/megaptera/assignment/models/Comment.java new file mode 100644 index 0000000..657bd69 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/models/Comment.java @@ -0,0 +1,22 @@ +package kr.megaptera.assignment.models; + +import lombok.Getter; + +@Getter +public class Comment extends BaseEntity { + + private String postId; + private String author; + private String content; + + public Comment(final String id, final String postId, final String author, final String content) { + super(id); + this.author = author; + this.content = content; + } + + public void update(String content){ + this.content = content; + } + +} diff --git a/src/main/java/kr/megaptera/assignment/models/Post.java b/src/main/java/kr/megaptera/assignment/models/Post.java new file mode 100644 index 0000000..9bb77b2 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/models/Post.java @@ -0,0 +1,27 @@ +package kr.megaptera.assignment.models; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class Post extends BaseEntity { + + private String title; + private final String author; + private String content; + + + @Builder + public Post(final String id,final String title, final String content, final String author) { + super(id); + this.title = title; + this.content = content; + this.author = author; + } + + public void update(final String title, final String content) { + this.title = title; + this.content = content; + } + +} diff --git a/src/main/java/kr/megaptera/assignment/repository/CommentRepository.java b/src/main/java/kr/megaptera/assignment/repository/CommentRepository.java new file mode 100644 index 0000000..4a3a423 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/repository/CommentRepository.java @@ -0,0 +1,41 @@ +package kr.megaptera.assignment.repository; + +import kr.megaptera.assignment.exceptions.CommentNotFound; +import kr.megaptera.assignment.models.Comment; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Repository +@RequiredArgsConstructor +public class CommentRepository { + private final Map commentMap = new HashMap<>(); + + public List findAll(String postId) { + return commentMap.values().stream().filter(comment -> comment.getPostId().equals(postId)) + .toList(); + } + + public Comment save(Comment comment){ + commentMap.put(comment.getId(),comment); + return comment; + } + + + public Comment find(String id) { + var comment = commentMap.get(id); + if(comment == null){ + throw new CommentNotFound(); + } + return comment; + } + + public Comment delete(String commentId) { + var comment = find(commentId); + commentMap.remove(commentId); + return comment; + } +} diff --git a/src/main/java/kr/megaptera/assignment/repository/PostRepository.java b/src/main/java/kr/megaptera/assignment/repository/PostRepository.java new file mode 100644 index 0000000..1897b51 --- /dev/null +++ b/src/main/java/kr/megaptera/assignment/repository/PostRepository.java @@ -0,0 +1,37 @@ +package kr.megaptera.assignment.repository; + +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.exceptions.PostNotFound; +import kr.megaptera.assignment.models.Post; +import org.springframework.stereotype.Repository; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Repository +public class PostRepository { + private final Map postMap = new HashMap<>(); + + public Post save(Post post) { + postMap.put(post.getId(),post); + return postMap.get(post.getId()); + } + + public List findAll(){ + return postMap.values().stream().toList(); + } + public Post findPostById(String id){ + Post post = postMap.get(id); + if(post == null){ + throw new PostNotFound(); + } + return post; + } + + public Post delete(String id) { + var post = findPostById(id); + postMap.remove(post.getId()); + return post; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 8b13789..5ec0e5c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,3 @@ +server.servlet.encoding.charset=UTF-8 +server.servlet.encoding.force=true diff --git a/src/test/java/kr/megaptera/assignment/application/CreateCommentServiceTest.java b/src/test/java/kr/megaptera/assignment/application/CreateCommentServiceTest.java index 9d50806..73120ce 100644 --- a/src/test/java/kr/megaptera/assignment/application/CreateCommentServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/CreateCommentServiceTest.java @@ -1,4 +1,39 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentCreateRequestDto; +import kr.megaptera.assignment.models.Comment; +import kr.megaptera.assignment.repository.CommentRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.verify; + +@SpringBootTest class CreateCommentServiceTest { + @Autowired + private CreateCommentService createCommentService; + @SpyBean + private CommentRepository commentRepository; + + + @DisplayName("") + @Test + public void createComment () throws Exception { + //given + String postId = "1234"; + CommentCreateRequestDto request = new CommentCreateRequestDto(postId,"author","content"); + //when + var comment = createCommentService.createComment(request); + //then + assertThat(comment.getAuthor()).isEqualTo(request.getAuthor()); + assertThat(comment.getContent()).isEqualTo(request.getContent()); + + verify(commentRepository).save(any(Comment.class)); + } } diff --git a/src/test/java/kr/megaptera/assignment/application/CreatePostServiceTest.java b/src/test/java/kr/megaptera/assignment/application/CreatePostServiceTest.java index 0120f61..e7b3d00 100644 --- a/src/test/java/kr/megaptera/assignment/application/CreatePostServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/CreatePostServiceTest.java @@ -1,11 +1,39 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostCreateRequestDto; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; + +@SpringBootTest class CreatePostServiceTest { + @Autowired + private CreatePostService createPostService; + @SpyBean + PostRepository postRepository; + + @Test @DisplayName("게시물 생성") void create() { + var post = createPostService.createPost(new PostCreateRequestDto("제목","작성자","내용")); + + assertThat(post.getTitle()).isEqualTo("제목"); + assertThat(post.getContent()).isEqualTo("작성자"); + assertThat(post.getAuthor()).isEqualTo("내용"); + + verify(postRepository).save(any(Post.class)); } } diff --git a/src/test/java/kr/megaptera/assignment/application/DeleteCommentServiceTest.java b/src/test/java/kr/megaptera/assignment/application/DeleteCommentServiceTest.java index 705d5aa..d48b890 100644 --- a/src/test/java/kr/megaptera/assignment/application/DeleteCommentServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/DeleteCommentServiceTest.java @@ -1,4 +1,37 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.models.Comment; +import kr.megaptera.assignment.repository.CommentRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@SpringBootTest class DeleteCommentServiceTest { + @Autowired + private DeleteCommentService deleteCommentService; + @MockBean + private CommentRepository commentRepository; + + + @DisplayName("댓글 삭제") + @Test + public void delete() throws Exception { + //given + String commentId = "1234"; + Comment comment = new Comment(commentId, "1234", "작성자", "내용"); + //when + given(commentRepository.find(commentId)).willReturn(comment); + given(commentRepository.delete(commentId)).willReturn(comment); + //then + deleteCommentService.deleteComment(commentId); + + verify(commentRepository).delete(any(String.class)); + } } diff --git a/src/test/java/kr/megaptera/assignment/application/DeletePostServiceTest.java b/src/test/java/kr/megaptera/assignment/application/DeletePostServiceTest.java index 528cf05..8f1b596 100644 --- a/src/test/java/kr/megaptera/assignment/application/DeletePostServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/DeletePostServiceTest.java @@ -1,11 +1,36 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@SpringBootTest class DeletePostServiceTest { + @Autowired + private DeletePostService postService; + + @MockBean + private PostRepository postRepository; + @Test @DisplayName("게시물 삭제") void delete() { + String postId = "1234"; + Post post = new Post(postId,"제목","작성자","내용"); + given(postRepository.findPostById(postId)).willReturn(post); + given(postRepository.delete(postId)).willReturn(post); + + postService.deletePost(postId); + + verify(postRepository).delete(any(String.class)); } } diff --git a/src/test/java/kr/megaptera/assignment/application/GetCommentsServiceTest.java b/src/test/java/kr/megaptera/assignment/application/GetCommentsServiceTest.java index ec6df8d..b8f3d99 100644 --- a/src/test/java/kr/megaptera/assignment/application/GetCommentsServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/GetCommentsServiceTest.java @@ -1,4 +1,41 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.models.Comment; +import kr.megaptera.assignment.repository.CommentRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import java.util.List; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.BDDMockito.given; + +@SpringBootTest class GetCommentsServiceTest { + @Autowired + private GetCommentsService getCommentsService; + + @MockBean + private CommentRepository commentRepository; + + @DisplayName("댓글 목록 조회") + @Test + public void getDetail() throws Exception { + //given + String postId = "1234"; + given(commentRepository.findAll(postId)).willReturn( + List.of(new Comment("001", postId, "content", "author"), + new Comment("002", postId, "content2", "author2"))); + //when + var commentList = getCommentsService.getCommentList(postId); + //then + assertThat(commentList).hasSize(2); + } + + } diff --git a/src/test/java/kr/megaptera/assignment/application/GetPostServiceTest.java b/src/test/java/kr/megaptera/assignment/application/GetPostServiceTest.java index ddbfe0b..a22f0ed 100644 --- a/src/test/java/kr/megaptera/assignment/application/GetPostServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/GetPostServiceTest.java @@ -1,11 +1,46 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ContextConfiguration; +import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +@SpringBootTest class GetPostServiceTest { + @Autowired + GetPostService getPostService; + @MockBean + private PostRepository postRepository; @Test @DisplayName("게시물 조회") void detail() { + //given + String searchId = "001test"; + given(postRepository.findPostById(searchId)).willReturn(new Post( + searchId, + "제목", + "작성자", + "내용" + )); + //when + var post = getPostService.detail(searchId); + //then + assertThat(post.getTitle()).isEqualTo("제목"); + assertThat(post.getContent()).isEqualTo("작성자"); + assertThat(post.getAuthor()).isEqualTo("내용"); + + } } diff --git a/src/test/java/kr/megaptera/assignment/application/GetPostsServiceTest.java b/src/test/java/kr/megaptera/assignment/application/GetPostsServiceTest.java index eee610b..e86becc 100644 --- a/src/test/java/kr/megaptera/assignment/application/GetPostsServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/GetPostsServiceTest.java @@ -1,11 +1,32 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +@SpringBootTest class GetPostsServiceTest { + @Autowired + private GetPostService getPostService; + @MockBean + private PostRepository postRepository; @Test @DisplayName("게시물 목록 조회") void list() { + given(postRepository.findAll()) + .willReturn( + List.of(new Post(null,"제목","작성자","내용"),new Post(null,"제목2","작성자2","내용2"))); + var posts = getPostService.getList(); + + assertThat(posts).hasSize(2); } } diff --git a/src/test/java/kr/megaptera/assignment/application/UpdateCommentServiceTest.java b/src/test/java/kr/megaptera/assignment/application/UpdateCommentServiceTest.java index ed9e54f..8a6c9a3 100644 --- a/src/test/java/kr/megaptera/assignment/application/UpdateCommentServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/UpdateCommentServiceTest.java @@ -1,4 +1,38 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentUpdateRequestDto; +import kr.megaptera.assignment.models.Comment; +import kr.megaptera.assignment.repository.CommentRepository; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; + +import static org.mockito.BDDMockito.given; + +@SpringBootTest class UpdateCommentServiceTest { + @Autowired + private UpdateCommentService updateCommentService; + @Autowired + private CommentRepository commentRepository; + + + @DisplayName("댓글 수정") + @Test + public void update() throws Exception { + //given + String commentId = "1234"; + var comment = new Comment(commentId, "postId", "작성자", "내용"); + CommentUpdateRequestDto request = new CommentUpdateRequestDto("수정"); + commentRepository.save(comment); + //when + var commentRes = updateCommentService.update(commentId, request); + //then + Assertions.assertThat(commentRes.getContent()).isEqualTo(request.getContent()); + + } } diff --git a/src/test/java/kr/megaptera/assignment/application/UpdatePostServiceTest.java b/src/test/java/kr/megaptera/assignment/application/UpdatePostServiceTest.java index 3e53f2e..db37b39 100644 --- a/src/test/java/kr/megaptera/assignment/application/UpdatePostServiceTest.java +++ b/src/test/java/kr/megaptera/assignment/application/UpdatePostServiceTest.java @@ -1,11 +1,41 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.PostUpdateRequestDto; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; +import org.assertj.core.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import static org.assertj.core.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; + +@SpringBootTest class UpdatePostServiceTest { + + @Autowired + private UpdatePostService postService; + + @Autowired + private PostRepository postRepository; + @Test @DisplayName("게시물 수정") void update() { + String postId = "1234"; + Post post = new Post(postId,"제목","내용","작성자"); + postRepository.save(post); + + PostUpdateRequestDto updateRequestDto = new PostUpdateRequestDto("수정제목","수정내용"); + postService.updatePost(postId,updateRequestDto); + + assertThat(post.getTitle()).isEqualTo("수정제목"); + assertThat(post.getContent()).isEqualTo("수정내용"); + } } diff --git a/src/test/java/kr/megaptera/assignment/controllers/PostControllerTest.java b/src/test/java/kr/megaptera/assignment/controllers/PostControllerTest.java index 23ed4e6..3ef4ff0 100644 --- a/src/test/java/kr/megaptera/assignment/controllers/PostControllerTest.java +++ b/src/test/java/kr/megaptera/assignment/controllers/PostControllerTest.java @@ -1,36 +1,112 @@ package kr.megaptera.assignment.controllers; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import kr.megaptera.assignment.application.CreatePostService; +import kr.megaptera.assignment.application.DeletePostService; +import kr.megaptera.assignment.application.GetPostService; +import kr.megaptera.assignment.application.UpdatePostService; +import kr.megaptera.assignment.dtos.PostCreateRequestDto; +import kr.megaptera.assignment.dtos.PostResponseDto; +import kr.megaptera.assignment.dtos.PostUpdateRequestDto; +import kr.megaptera.assignment.exceptions.PostNotFound; +import kr.megaptera.assignment.models.Post; +import kr.megaptera.assignment.repository.PostRepository; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import java.util.List; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(PostController.class) class PostControllerTest { - @Test - @DisplayName("GET /posts") - void list() { - } - - @Test - @DisplayName("GET /posts/{id} - with correct ID") - void detailWithCorrectId() { - } - - @Test - @DisplayName("GET /posts/{id} - with incorrect ID") - void detail() { - } - - @Test - @DisplayName("POST /posts") - void create() { - } - - @Test - @DisplayName("PATCH /posts/{id}") - void update() { - } - - @Test - @DisplayName("DELETE /posts/{id}") - void deletePost() { - } + @Autowired + private MockMvc mockMvc; + + @MockBean + GetPostService getPostService; + @MockBean + CreatePostService createPostService; + @MockBean + UpdatePostService updatePostService; + @MockBean + DeletePostService deletePostService; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Test + @DisplayName("GET /posts") + void list() throws Exception { + given(getPostService.getList()).willReturn( + List.of(new PostResponseDto("1234", "제목1", "작성자1", "내용1"), + new PostResponseDto("12345", "제목2", "작성자2", "내용2"))); + + this.mockMvc.perform(get("/posts")).andExpect(status().isOk()) + .andExpect(content().string(containsString("제목"))); + + } + + @Test + @DisplayName("GET /posts/{id} - with correct ID") + void detailWithCorrectId() throws Exception { + String id = "1234"; + given(getPostService.detail(id)).willReturn(new PostResponseDto(id, "제목", "작성자", "내용")); + mockMvc.perform(get("/posts/" + id)).andExpect(status().isOk()) + .andExpect(content().string(containsString("제목"))); + + } + + @Test + @DisplayName("GET /posts/{id} - with incorrect ID") + void detail() throws Exception { + String id = "1234"; + given(getPostService.detail(id)).willThrow(new PostNotFound()); + mockMvc.perform(get("/posts/" + id)).andExpect(status().isNotFound()); + } + + @Test + @DisplayName("POST /posts") + void create() throws Exception { + PostCreateRequestDto request = new PostCreateRequestDto("title", "content", "author"); + + String json = objectMapper.writeValueAsString(request); + mockMvc.perform(post("/posts").contentType(MediaType.APPLICATION_JSON).content(json)) + .andExpect(status().isCreated()); + verify(createPostService).createPost(any(PostCreateRequestDto.class)); + } + + @Test + @DisplayName("PATCH /posts/{id}") + void update() throws Exception { + String id = "1234"; + PostUpdateRequestDto request = new PostUpdateRequestDto("fixTitle", "fixContent"); + String json = objectMapper.writeValueAsString(request); + mockMvc.perform(patch("/posts/" + id).contentType(MediaType.APPLICATION_JSON).content(json)) + .andExpect(status().isOk()); + + verify(updatePostService).updatePost(eq(id), any(PostUpdateRequestDto.class)); + + } + + @Test + @DisplayName("DELETE /posts/{id}") + void deletePost() throws Exception { + String id = "1234"; + mockMvc.perform(delete("/posts/" + id)).andExpect(status().isOk()); + verify(deletePostService).deletePost(id); + } } From fbe82a862c0c786e9d2376900d5a262fd8709c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=99=A9=EA=B2=BD=ED=9B=88?= Date: Fri, 19 Apr 2024 19:04:55 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EA=B3=BC=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/DeleteCommentService.java | 11 ++ .../controllers/CommentController.java | 53 ++++++++ .../controllers/CommentControllerTest.java | 119 +++++++++++++++++- 3 files changed, 182 insertions(+), 1 deletion(-) diff --git a/src/main/java/kr/megaptera/assignment/application/DeleteCommentService.java b/src/main/java/kr/megaptera/assignment/application/DeleteCommentService.java index 467653c..98ea9cb 100644 --- a/src/main/java/kr/megaptera/assignment/application/DeleteCommentService.java +++ b/src/main/java/kr/megaptera/assignment/application/DeleteCommentService.java @@ -1,4 +1,15 @@ package kr.megaptera.assignment.application; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.repository.CommentRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor public class DeleteCommentService { + private final CommentRepository commentRepository; + public CommentResponseDto deleteComment(String commentId) { + return CommentResponseDto.of(commentRepository.delete(commentId)); + } } diff --git a/src/main/java/kr/megaptera/assignment/controllers/CommentController.java b/src/main/java/kr/megaptera/assignment/controllers/CommentController.java index ed4b675..89b0203 100644 --- a/src/main/java/kr/megaptera/assignment/controllers/CommentController.java +++ b/src/main/java/kr/megaptera/assignment/controllers/CommentController.java @@ -1,4 +1,57 @@ package kr.megaptera.assignment.controllers; +import kr.megaptera.assignment.application.CreateCommentService; +import kr.megaptera.assignment.application.DeleteCommentService; +import kr.megaptera.assignment.application.GetCommentsService; +import kr.megaptera.assignment.application.UpdateCommentService; +import kr.megaptera.assignment.dtos.CommentCreateRequestDto; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.dtos.CommentUpdateRequestDto; +import kr.megaptera.assignment.exceptions.CommentNotFound; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/comments") +@RequiredArgsConstructor public class CommentController { + private final GetCommentsService getCommentsService; + private final CreateCommentService createCommentService; + private final UpdateCommentService updateCommentService; + private final DeleteCommentService deleteCommentService; + @GetMapping + public List detail(@RequestParam String postId) { + return getCommentsService.getCommentList(postId); + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public CommentResponseDto create(@RequestParam String postId, + @RequestBody CommentCreateRequestDto request) { + request.setPostId(postId); + return createCommentService.createComment(request); + + } + + @PatchMapping("/{id}") + public CommentResponseDto update(@PathVariable String id, + @RequestBody CommentUpdateRequestDto commentUpdateDto) { + return updateCommentService.update(id, commentUpdateDto); + + } + + @DeleteMapping("/{id}") + public CommentResponseDto delete(@PathVariable String id) { + return deleteCommentService.deleteComment(id); + } + + + @ExceptionHandler(CommentNotFound.class) + @ResponseStatus(HttpStatus.NOT_FOUND) + public String postNotFound() { + return "댓글을 찾을 수 없습니다."; + } } diff --git a/src/test/java/kr/megaptera/assignment/controllers/CommentControllerTest.java b/src/test/java/kr/megaptera/assignment/controllers/CommentControllerTest.java index ea7f3a4..d61cccd 100644 --- a/src/test/java/kr/megaptera/assignment/controllers/CommentControllerTest.java +++ b/src/test/java/kr/megaptera/assignment/controllers/CommentControllerTest.java @@ -1,5 +1,122 @@ package kr.megaptera.assignment.controllers; +import com.fasterxml.jackson.databind.ObjectMapper; +import kr.megaptera.assignment.application.CreateCommentService; +import kr.megaptera.assignment.application.DeleteCommentService; +import kr.megaptera.assignment.application.GetCommentsService; +import kr.megaptera.assignment.application.UpdateCommentService; +import kr.megaptera.assignment.dtos.CommentCreateRequestDto; +import kr.megaptera.assignment.dtos.CommentResponseDto; +import kr.megaptera.assignment.dtos.CommentUpdateRequestDto; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import java.util.List; + +import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(CommentController.class) class CommentControllerTest { - // TODO: PostControllerTest 를 참고해서 테스트를 작성해 주세요. + @Autowired + MockMvc mockMvc; + + @MockBean + private GetCommentsService getCommentsService; + + @MockBean + private CreateCommentService createCommentService; + + @MockBean + private UpdateCommentService updateCommentService; + + @MockBean + private DeleteCommentService deleteCommentService; + + ObjectMapper objectMapper = new ObjectMapper(); + + @Test + @DisplayName("GET / comments?postId={postId}") + void list() throws Exception { + String postId = "011POST"; + given(getCommentsService.getCommentList(postId)) + .willReturn(List.of( + new CommentResponseDto("001COMMENT", "작성자1", "댓글내용1"), + new CommentResponseDto("001COMMENT", "작성자2", "댓글내용2") + )); + + mockMvc.perform(get("/comments?postId=" + postId)) + .andExpect(status().isOk()) + .andExpect(content().string( + containsString("댓글내용1") + )); + } + + @Test + @DisplayName("POST /comments") + void create() throws Exception { + String postId = "001POST"; + + CommentCreateRequestDto request = new CommentCreateRequestDto(postId,"작성자","내용"); + String json = objectMapper.writeValueAsString(request); + + + mockMvc.perform(post("/comments?postId=" + postId) + .contentType(MediaType.APPLICATION_JSON) + .content(json) + ) + .andExpect(status().isCreated()); + + verify(createCommentService).createComment(any(CommentCreateRequestDto.class)); + } + + @Test + @DisplayName("PATCH /comments/{id}") + void update() throws Exception { + String commentId = "001COMMENT"; +// +// +// CommentUpdateRequestDto request = new CommentUpdateRequestDto("test"); +// String json = objectMapper.writeValueAsString(request); +// +// +//// mockMvc.perform(patch("/comments/" + commentId) +//// .contentType(MediaType.APPLICATION_JSON) +//// .content(json) +//// ) +//// .andExpect(status().isOk()); +// +// verify(updateCommentService).update( +// eq(commentId), +// any(CommentUpdateRequestDto.class) +// ); + + } + + + @Test + @DisplayName("DELETE /posts/{id}") + void deletePost() throws Exception { + String commentId = "001COMMENT"; + String postId = "001POST"; + + mockMvc.perform(delete("/comments/" + commentId + "?postId=" + postId)) + .andExpect(status().isOk()); + + verify(deleteCommentService).deleteComment(commentId); + + } }