From 4ff69948b50334bf93256850e170a02c8bfefd7d Mon Sep 17 00:00:00 2001 From: Jiwon Kang <135416359+zwo-n@users.noreply.github.com> Date: Fri, 3 Oct 2025 17:17:55 +0900 Subject: [PATCH 1/3] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 395edc5..d8ca717 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ # backend-study-sns +강지원 From 163fb9ed05b728fbe8570ac58eea478e14c15e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EC=A7=80=EC=9B=90?= Date: Wed, 8 Oct 2025 13:42:37 +0900 Subject: [PATCH 2/3] =?UTF-8?q?post,comment=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + build.gradle | 18 +++++++- .../devSns/controller/CommentController.java | 31 +++++++++++++ .../devSns/controller/PostController.java | 44 +++++++++++++++++++ .../com/example/devSns/entity/Comment.java | 32 ++++++++++++++ .../java/com/example/devSns/entity/Post.java | 41 +++++++++++++++++ .../devSns/repository/CommentRepository.java | 9 ++++ .../devSns/repository/PostRepository.java | 6 +++ .../devSns/service/CommentService.java | 33 ++++++++++++++ .../example/devSns/service/PostService.java | 44 +++++++++++++++++++ src/main/resources/application.properties | 12 +++++ 11 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/devSns/controller/CommentController.java create mode 100644 src/main/java/com/example/devSns/controller/PostController.java create mode 100644 src/main/java/com/example/devSns/entity/Comment.java create mode 100644 src/main/java/com/example/devSns/entity/Post.java create mode 100644 src/main/java/com/example/devSns/repository/CommentRepository.java create mode 100644 src/main/java/com/example/devSns/repository/PostRepository.java create mode 100644 src/main/java/com/example/devSns/service/CommentService.java create mode 100644 src/main/java/com/example/devSns/service/PostService.java diff --git a/.gitignore b/.gitignore index c2065bc..4c75e42 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ out/ ### VS Code ### .vscode/ + +.env \ No newline at end of file diff --git a/build.gradle b/build.gradle index 610d6a6..cf03320 100644 --- a/build.gradle +++ b/build.gradle @@ -19,11 +19,27 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' - testImplementation 'org.springframework.boot:spring-boot-starter-test' + implementation 'com.mysql:mysql-connector-j:9.0.0' + implementation 'me.paulschwarz:spring-dotenv:4.0.0' + + testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + + // lombok + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' + testCompileOnly 'org.projectlombok:lombok' + testAnnotationProcessor 'org.projectlombok:lombok' } +configurations { + compileOnly { + extendsFrom annotationProcessor + } +} tasks.named('test') { useJUnitPlatform() } diff --git a/src/main/java/com/example/devSns/controller/CommentController.java b/src/main/java/com/example/devSns/controller/CommentController.java new file mode 100644 index 0000000..a040745 --- /dev/null +++ b/src/main/java/com/example/devSns/controller/CommentController.java @@ -0,0 +1,31 @@ +package com.example.devSns.controller; + +import com.example.devSns.entity.Comment; +import com.example.devSns.service.CommentService; +import org.springframework.web.bind.annotation.*; +import java.util.List; + +@RestController +@RequestMapping("post/{postId}/comment") +public class CommentController { + private CommentService commentService; + + public CommentController(CommentService commentService) { + this.commentService = commentService; + } + + @GetMapping + public List getComments(@PathVariable Long postId) { + return commentService.getCommentByPost(postId); + } + + @PostMapping + public Comment createComment(@PathVariable Long postId, @RequestBody Comment comment) { + return commentService.addComment(postId, comment); + } + + @DeleteMapping("/{commentId}") + public void deleteComment(@PathVariable Long commentId) { + commentService.deleteComment(commentId); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/controller/PostController.java b/src/main/java/com/example/devSns/controller/PostController.java new file mode 100644 index 0000000..1a2a41f --- /dev/null +++ b/src/main/java/com/example/devSns/controller/PostController.java @@ -0,0 +1,44 @@ +package com.example.devSns.controller; + +import com.example.devSns.entity.Post; +import com.example.devSns.service.PostService; +import org.springframework.web.bind.annotation.*; + +import java.time.LocalDateTime; +import java.util.List; + +@RestController +@RequestMapping("/post") +public class PostController { + private final PostService postService; + + public PostController(PostService postService) { + this.postService = postService; + } + + @GetMapping + public List getAllPosts(){ + return postService.findAll(); + } + + @GetMapping("/{id}") + public Post getPostById(@PathVariable Long id){ + return postService.findById(id).orElseThrow(()-> new RuntimeException("post not found")); + } + + @PostMapping + public Post createPost(@RequestBody Post post){ + return postService.save(post); + } + + @PutMapping("/{id}") + public Post updatePost(@PathVariable Long id, @RequestBody Post updatedPost){ + + return postService.updatePost(id,updatedPost); + } + + @DeleteMapping("/{id}") + public void deletePost(@PathVariable Long id){ + postService.delete(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entity/Comment.java b/src/main/java/com/example/devSns/entity/Comment.java new file mode 100644 index 0000000..4eb30dc --- /dev/null +++ b/src/main/java/com/example/devSns/entity/Comment.java @@ -0,0 +1,32 @@ +package com.example.devSns.entity; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import jakarta.persistence.*; +import lombok.*; +import java.time.LocalDateTime; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Comment{ + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String content; + private String username; + private LocalDateTime createdAt; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name="post_id") + @JsonBackReference + private Post post; + + @PrePersist + public void onCreate(){ + createdAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entity/Post.java b/src/main/java/com/example/devSns/entity/Post.java new file mode 100644 index 0000000..143a980 --- /dev/null +++ b/src/main/java/com/example/devSns/entity/Post.java @@ -0,0 +1,41 @@ +package com.example.devSns.entity; + +import com.fasterxml.jackson.annotation.JsonManagedReference; +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Post { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String content; + private int likes; + private String username; + private LocalDateTime createdAt; + private LocalDateTime updatedAt; + + @OneToMany(mappedBy = "post", cascade = CascadeType.ALL,orphanRemoval = true) + @JsonManagedReference + private List comments = new ArrayList<>(); + @PrePersist + public void onCreate(){ + createdAt = LocalDateTime.now(); + updatedAt = LocalDateTime.now(); + } + + @PreUpdate + public void onUpdate(){ + updatedAt = LocalDateTime.now(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/repository/CommentRepository.java b/src/main/java/com/example/devSns/repository/CommentRepository.java new file mode 100644 index 0000000..c293959 --- /dev/null +++ b/src/main/java/com/example/devSns/repository/CommentRepository.java @@ -0,0 +1,9 @@ +package com.example.devSns.repository; + +import com.example.devSns.entity.Comment; +import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + +public interface CommentRepository extends JpaRepository { + List findByPost_Id(Long postId); +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/repository/PostRepository.java b/src/main/java/com/example/devSns/repository/PostRepository.java new file mode 100644 index 0000000..4fd8426 --- /dev/null +++ b/src/main/java/com/example/devSns/repository/PostRepository.java @@ -0,0 +1,6 @@ +package com.example.devSns.repository; + +import com.example.devSns.entity.Post; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PostRepository extends JpaRepository {} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/service/CommentService.java b/src/main/java/com/example/devSns/service/CommentService.java new file mode 100644 index 0000000..c2e8157 --- /dev/null +++ b/src/main/java/com/example/devSns/service/CommentService.java @@ -0,0 +1,33 @@ +package com.example.devSns.service; + +import com.example.devSns.entity.Comment; +import com.example.devSns.entity.Post; +import com.example.devSns.repository.CommentRepository; +import com.example.devSns.repository.PostRepository; +import org.springframework.stereotype.Service; +import java.util.List; + +@Service +public class CommentService { + private final CommentRepository commentRepository; + private final PostRepository postRepository; + + public CommentService(CommentRepository commentRepository, PostRepository postRepository) { + this.commentRepository = commentRepository; + this.postRepository = postRepository; + } + + public List getCommentByPost(Long postId){ + return commentRepository.findByPost_Id(postId); + } + + public Comment addComment(Long postId, Comment comment){ + Post post = postRepository.findById(postId).orElseThrow(()-> new IllegalArgumentException("게시글 없음")); + comment.setPost(post); + return commentRepository.save(comment); + } + + public void deleteComment(Long id){ + commentRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/devSns/service/PostService.java b/src/main/java/com/example/devSns/service/PostService.java new file mode 100644 index 0000000..e9dce8b --- /dev/null +++ b/src/main/java/com/example/devSns/service/PostService.java @@ -0,0 +1,44 @@ +package com.example.devSns.service; + +import com.example.devSns.entity.Post; +import com.example.devSns.repository.PostRepository; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; + +@Service +public class PostService { + private final PostRepository postRepository; + + public PostService(PostRepository postRepository) { + this.postRepository = postRepository; + } + + public List findAll(){ + return postRepository.findAll(); + } + + public Optional findById(Long id){ + return postRepository.findById(id); + } + + public Post save(Post post){ + return postRepository.save(post); + } + public Post updatePost(Long id, Post updatedPost) { + Post existingPost = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found")); + + updatedPost.setCreatedAt(existingPost.getCreatedAt()); + updatedPost.setUpdatedAt(LocalDateTime.now()); + + updatedPost.setId(id); + + return postRepository.save(updatedPost); + } + + public void delete(Long id){ + postRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f3f10af..f3fabed 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,13 @@ spring.application.name=devSns + +# DB ???? +spring.datasource.url=${DATASOURCE_URL} +spring.datasource.username=${DATASOURCE_USERNAME} +spring.datasource.password=${DATASOURCE_PASSWORD} +# DB ???? +spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver + +spring.jpa.hibernate.ddl-auto=update +# true? ???? ?? ???? sql?? ???? ??? ? ????. +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect \ No newline at end of file From 611ebd14de0c1b5bd8ccb40916dcf1d04c2ee109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EC=A7=80=EC=9B=90?= Date: Fri, 7 Nov 2025 17:30:53 +0900 Subject: [PATCH 3/3] feat: week 2 comment update --- .DS_Store | Bin 0 -> 6148 bytes build.gradle | 7 ++ .../devSns/controller/CommentController.java | 14 ++- .../devSns/controller/PostController.java | 7 +- .../com/example/devSns/entity/Comment.java | 15 ++- .../java/com/example/devSns/entity/Post.java | 9 +- .../devSns/service/CommentService.java | 14 ++- .../example/devSns/service/PostService.java | 15 +-- .../example/devSns/CommentControllerTest.java | 107 ++++++++++++++++++ .../example/devSns/PostControllerTest.java | 92 +++++++++++++++ 10 files changed, 261 insertions(+), 19 deletions(-) create mode 100644 .DS_Store create mode 100644 src/test/java/com/example/devSns/CommentControllerTest.java create mode 100644 src/test/java/com/example/devSns/PostControllerTest.java diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..66c495cad1e192f5b59f8080838d661ea3faf602 GIT binary patch literal 6148 zcmeHK%}T>S5Z<+|-BN@c6nb3nTCmnqEM7vaFJMFuDm5VmgE3p$gd9pCXMG``#OHBl zcUuVNETS_o`_0bJX7fRIGmJ6r<HHvmnb?Ua-8!*^N?3xV3}u zHl7zV=kQXcSrDi5r7no0Iix(?#c8ApPvvQ}(zU(`h>qyYoZfmp8lLy%a5CQX<$5w4 z^yTPmyxDZb(ecT}_3R~iP1TzrlH<-%4h-zZ_nk!sF+dCu1H=F^P{)A1K}5GMNIqhK z82Hx=;Q1gy5nYR=L49<F42ZO*J5c9S3$on2c#bXO$ZId Izz;C+1pr<}VgLXD literal 0 HcmV?d00001 diff --git a/build.gradle b/build.gradle index cf03320..0527f19 100644 --- a/build.gradle +++ b/build.gradle @@ -33,6 +33,13 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' testCompileOnly 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' + + // test + testImplementation 'org.springframework.boot:spring-boot-starter-test' + +} +test{ + useJUnitPlatform() } configurations { diff --git a/src/main/java/com/example/devSns/controller/CommentController.java b/src/main/java/com/example/devSns/controller/CommentController.java index a040745..71ed3ae 100644 --- a/src/main/java/com/example/devSns/controller/CommentController.java +++ b/src/main/java/com/example/devSns/controller/CommentController.java @@ -2,11 +2,13 @@ import com.example.devSns.entity.Comment; import com.example.devSns.service.CommentService; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; @RestController -@RequestMapping("post/{postId}/comment") +@RequestMapping("/post/{postId}/comment") public class CommentController { private CommentService commentService; @@ -28,4 +30,14 @@ public Comment createComment(@PathVariable Long postId, @RequestBody Comment com public void deleteComment(@PathVariable Long commentId) { commentService.deleteComment(commentId); } + + @PatchMapping("/{commentId}") + public ResponseEntity updateComment( + @PathVariable Long commentId, + @RequestBody Map request + ) { + String newContent = request.get("content"); + Comment updated = commentService.updateComment(commentId, newContent); + return ResponseEntity.ok(updated); + } } \ No newline at end of file diff --git a/src/main/java/com/example/devSns/controller/PostController.java b/src/main/java/com/example/devSns/controller/PostController.java index 1a2a41f..d279035 100644 --- a/src/main/java/com/example/devSns/controller/PostController.java +++ b/src/main/java/com/example/devSns/controller/PostController.java @@ -2,10 +2,12 @@ import com.example.devSns.entity.Post; import com.example.devSns.service.PostService; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.List; +import java.util.Optional; @RestController @RequestMapping("/post") @@ -22,8 +24,9 @@ public List getAllPosts(){ } @GetMapping("/{id}") - public Post getPostById(@PathVariable Long id){ - return postService.findById(id).orElseThrow(()-> new RuntimeException("post not found")); + public ResponseEntity getPostById(@PathVariable Long id){ + Post post = postService.findById(id); + return ResponseEntity.ok(post); } @PostMapping diff --git a/src/main/java/com/example/devSns/entity/Comment.java b/src/main/java/com/example/devSns/entity/Comment.java index 4eb30dc..5ead634 100644 --- a/src/main/java/com/example/devSns/entity/Comment.java +++ b/src/main/java/com/example/devSns/entity/Comment.java @@ -7,7 +7,6 @@ @Entity @Getter -@Setter @NoArgsConstructor @AllArgsConstructor @Builder @@ -20,8 +19,12 @@ public class Comment{ private String username; private LocalDateTime createdAt; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name="post_id") + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn( + name="post_id", + nullable = false, + foreignKey = @ForeignKey(name = "fk_diary_user_id_ref_user_id") + ) @JsonBackReference private Post post; @@ -29,4 +32,10 @@ public class Comment{ public void onCreate(){ createdAt = LocalDateTime.now(); } + public void update(String content){ + this.content = content; + } + public void assignTo(Post post){ + this.post = post; + } } \ No newline at end of file diff --git a/src/main/java/com/example/devSns/entity/Post.java b/src/main/java/com/example/devSns/entity/Post.java index 143a980..645b299 100644 --- a/src/main/java/com/example/devSns/entity/Post.java +++ b/src/main/java/com/example/devSns/entity/Post.java @@ -10,7 +10,6 @@ @Entity @Getter -@Setter @NoArgsConstructor @AllArgsConstructor @Builder @@ -28,6 +27,7 @@ public class Post { @OneToMany(mappedBy = "post", cascade = CascadeType.ALL,orphanRemoval = true) @JsonManagedReference private List comments = new ArrayList<>(); + @PrePersist public void onCreate(){ createdAt = LocalDateTime.now(); @@ -38,4 +38,11 @@ public void onCreate(){ public void onUpdate(){ updatedAt = LocalDateTime.now(); } + public void update(String content){ + this.content = content; + } + public void addComment(Comment comment){ + comments.add(comment); + comment.assignTo(this); + } } \ No newline at end of file diff --git a/src/main/java/com/example/devSns/service/CommentService.java b/src/main/java/com/example/devSns/service/CommentService.java index c2e8157..4414e49 100644 --- a/src/main/java/com/example/devSns/service/CommentService.java +++ b/src/main/java/com/example/devSns/service/CommentService.java @@ -5,6 +5,8 @@ import com.example.devSns.repository.CommentRepository; import com.example.devSns.repository.PostRepository; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import java.util.List; @Service @@ -17,13 +19,21 @@ public CommentService(CommentRepository commentRepository, PostRepository postRe this.postRepository = postRepository; } + @Transactional(readOnly = true) public List getCommentByPost(Long postId){ return commentRepository.findByPost_Id(postId); } public Comment addComment(Long postId, Comment comment){ - Post post = postRepository.findById(postId).orElseThrow(()-> new IllegalArgumentException("게시글 없음")); - comment.setPost(post); + Post post = postRepository.findById(postId).orElseThrow(()-> new IllegalArgumentException("post not found")); + + post.addComment(comment); + postRepository.save(post); + return commentRepository.save(comment); + } + public Comment updateComment(Long commentId, String newContent){ + Comment comment = commentRepository.findById(commentId).orElseThrow(() -> new IllegalArgumentException("comment not found")); + comment.update(newContent); return commentRepository.save(comment); } diff --git a/src/main/java/com/example/devSns/service/PostService.java b/src/main/java/com/example/devSns/service/PostService.java index e9dce8b..ddedba3 100644 --- a/src/main/java/com/example/devSns/service/PostService.java +++ b/src/main/java/com/example/devSns/service/PostService.java @@ -20,8 +20,8 @@ public List findAll(){ return postRepository.findAll(); } - public Optional findById(Long id){ - return postRepository.findById(id); + public Post findById(Long id){ + return postRepository.findById(id).orElseThrow(()-> new IllegalArgumentException("Post not found")); } public Post save(Post post){ @@ -29,16 +29,11 @@ public Post save(Post post){ } public Post updatePost(Long id, Post updatedPost) { Post existingPost = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found")); - - updatedPost.setCreatedAt(existingPost.getCreatedAt()); - updatedPost.setUpdatedAt(LocalDateTime.now()); - - updatedPost.setId(id); - - return postRepository.save(updatedPost); + existingPost.update(updatedPost.getContent()); + return postRepository.save(existingPost); } public void delete(Long id){ postRepository.deleteById(id); } -} \ No newline at end of file +} diff --git a/src/test/java/com/example/devSns/CommentControllerTest.java b/src/test/java/com/example/devSns/CommentControllerTest.java new file mode 100644 index 0000000..b648b36 --- /dev/null +++ b/src/test/java/com/example/devSns/CommentControllerTest.java @@ -0,0 +1,107 @@ +package com.example.devSns; + +import com.example.devSns.entity.Comment; +import com.example.devSns.entity.Post; +import com.example.devSns.repository.CommentRepository; +import com.example.devSns.repository.PostRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@SpringBootTest +@AutoConfigureMockMvc +class CommentControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private PostRepository postRepository; + + @Autowired + private CommentRepository commentRepository; + + private Post savedPost; + + @BeforeEach + void setUp() { + commentRepository.deleteAll(); + postRepository.deleteAll(); + + savedPost = postRepository.save(Post.builder() + .username("dardar") + .content("댓글 테스트용 게시글") + .build()); + } + + @Test + void 댓글_작성_성공() throws Exception { + String json = """ + { + "username": "tester", + "content": "좋은 글이네요!" + } + """; + + mockMvc.perform(post("/post/" + savedPost.getId() + "/comment") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("tester")) + .andExpect(jsonPath("$.content").value("좋은 글이네요!")); + } + + @Test + void 댓글_조회_성공() throws Exception { + Comment comment = commentRepository.save(Comment.builder() + .username("tester") + .content("조회용 댓글") + .post(savedPost) + .build()); + + mockMvc.perform(get("/post/" + savedPost.getId() + "/comment")) + .andExpect(status().isOk()) + .andExpect(jsonPath("$[0].content").value("조회용 댓글")) + .andExpect(jsonPath("$[0].username").value("tester")); + } + + @Test + void 댓글_수정_성공() throws Exception { + Comment comment = commentRepository.save(Comment.builder() + .username("tester") + .content("원본 댓글") + .post(savedPost) + .build()); + + String updateJson = """ + { + "content": "수정된 댓글입니다." + } + """; + + mockMvc.perform(patch("/post/" + savedPost.getId() + "/comment/" + comment.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(updateJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.content").value("수정된 댓글입니다.")); + } + + @Test + void 댓글_삭제_성공() throws Exception { + Comment comment = commentRepository.save(Comment.builder() + .username("tester") + .content("삭제용 댓글") + .post(savedPost) + .build()); + + mockMvc.perform(delete("/post/" + savedPost.getId() + "/comment/" + comment.getId())) + .andExpect(status().isOk()); + } +} diff --git a/src/test/java/com/example/devSns/PostControllerTest.java b/src/test/java/com/example/devSns/PostControllerTest.java new file mode 100644 index 0000000..ffe8f6a --- /dev/null +++ b/src/test/java/com/example/devSns/PostControllerTest.java @@ -0,0 +1,92 @@ +package com.example.devSns; + +import com.example.devSns.entity.Post; +import com.example.devSns.repository.PostRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +@SpringBootTest +@AutoConfigureMockMvc +class PostControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private PostRepository postRepository; + + @BeforeEach + void cleanDB() { + postRepository.deleteAll(); + } + + @Test + void 게시글_생성_성공() throws Exception { + String json = """ + { + "username": "dardar", + "content": "테스트 게시글입니다." + } + """; + + mockMvc.perform(post("/post") + .contentType(MediaType.APPLICATION_JSON) + .content(json)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("dardar")) + .andExpect(jsonPath("$.content").value("테스트 게시글입니다.")); + } + + @Test + void 게시글_조회_성공() throws Exception { + Post post = Post.builder() + .username("tester") + .content("조회용 게시글") + .build(); + postRepository.save(post); + + mockMvc.perform(get("/post/" + post.getId())) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.username").value("tester")) + .andExpect(jsonPath("$.content").value("조회용 게시글")); + } + + @Test + void 게시글_수정_성공() throws Exception { + Post post = postRepository.save(Post.builder() + .username("tester") + .content("원본 내용") + .build()); + + String updateJson = """ + { + "content": "수정된 내용" + } + """; + + mockMvc.perform(put("/post/" + post.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(updateJson)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.content").value("수정된 내용")); + } + + @Test + void 게시글_삭제_성공() throws Exception { + Post post = postRepository.save(Post.builder() + .username("tester") + .content("삭제 대상 게시글") + .build()); + + mockMvc.perform(delete("/post/" + post.getId())) + .andExpect(status().isOk()); + } +}