11package com .back .domain .like .controller ;
22
3+ import com .back .domain .comment .entity .Comment ;
4+ import com .back .domain .comment .repository .CommentRepository ;
5+ import com .back .domain .like .entity .CommentLike ;
36import com .back .domain .like .entity .PostLike ;
7+ import com .back .domain .like .repository .CommentLikeRepository ;
48import com .back .domain .like .repository .PostLikeRepository ;
59import com .back .domain .post .entity .Post ;
610import com .back .domain .post .repository .PostRepository ;
4448@ Sql (
4549 statements = {
4650 "SET REFERENTIAL_INTEGRITY FALSE" ,
51+ "TRUNCATE TABLE COMMENT_LIKES" ,
52+ "TRUNCATE TABLE COMMENTS" ,
4753 "TRUNCATE TABLE POST_LIKES" ,
4854 "TRUNCATE TABLE POST" ,
4955 "TRUNCATE TABLE USERS" ,
56+ "ALTER TABLE COMMENT_LIKES ALTER COLUMN ID RESTART WITH 1" ,
57+ "ALTER TABLE COMMENTS ALTER COLUMN ID RESTART WITH 1" ,
5058 "ALTER TABLE POST_LIKES ALTER COLUMN ID RESTART WITH 1" ,
5159 "ALTER TABLE POST ALTER COLUMN ID RESTART WITH 1" ,
5260 "ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 1" ,
@@ -71,16 +79,24 @@ class LikeControllerTest {
7179 @ Autowired
7280 private PostLikeRepository postLikeRepository ;
7381
82+ @ Autowired
83+ private CommentRepository commentRepository ;
84+
85+ @ Autowired
86+ private CommentLikeRepository commentLikeRepository ;
87+
7488 static final int THREAD_POOL_SIZE = 50 ;
7589 static final int CONCURRENT_USERS = 50 ;
7690
7791 private Post testPost ;
7892 private User testUser ;
93+ private Comment testComment ;
7994
8095 @ BeforeEach
8196 void setUp () {
8297 testUser = createTestUser ("testuser" );
8398 testPost = createTestPost (testUser );
99+ testComment = createTestComment (testPost , testUser );
84100
85101 setAuthentication (testUser );
86102 }
@@ -142,6 +158,63 @@ void removeLike() throws Exception {
142158 }
143159 }
144160
161+ @ Nested
162+ @ DisplayName ("댓글 좋아요 등록 및 취소" )
163+ class CommentLikeFeatureTest {
164+
165+ @ Test
166+ @ DisplayName ("성공 - 50명 동시 댓글 좋아요 등록" )
167+ void addCommentLikeConcurrent () throws InterruptedException {
168+ List <User > testUsers = IntStream .rangeClosed (1 , CONCURRENT_USERS )
169+ .mapToObj (i -> createTestUser ("concurrent" + i ))
170+ .collect (Collectors .toList ());
171+
172+ userRepository .saveAll (testUsers );
173+ userRepository .flush ();
174+
175+ try (ExecutorService es = Executors .newFixedThreadPool (THREAD_POOL_SIZE )) {
176+ List <Callable <Void >> tasks = testUsers .stream ()
177+ .map (user -> (Callable <Void >) () -> {
178+ performCommentLike (user , testPost .getId (), testComment .getId ());
179+ return null ;
180+ })
181+ .toList ();
182+
183+ es .invokeAll (tasks );
184+ }
185+
186+ Comment comment = commentRepository .findById (testComment .getId ()).orElseThrow ();
187+ assertEquals (CONCURRENT_USERS , comment .getLikeCount ());
188+ }
189+
190+ @ Test
191+ @ DisplayName ("실패 - 이미 좋아요 누른 유저가 다시 좋아요 등록 시 예외" )
192+ void addCommentLikeAlreadyLiked () throws Exception {
193+ commentLikeRepository .save (CommentLike .builder ().user (testUser ).comment (testComment ).build ());
194+ commentLikeRepository .flush ();
195+
196+ mockMvc .perform (post ("/api/v1/posts/{postId}/comments/{commentId}/likes" , testPost .getId (), testComment .getId ()))
197+ .andExpect (status ().isBadRequest ())
198+ .andExpect (jsonPath ("$.code" ).value (ErrorCode .COMMENT_ALREADY_LIKED .getCode ()))
199+ .andExpect (jsonPath ("$.message" ).value (ErrorCode .COMMENT_ALREADY_LIKED .getMessage ()));
200+ }
201+
202+ @ Test
203+ @ DisplayName ("성공 - 댓글 좋아요 취소" )
204+ void removeCommentLike () throws Exception {
205+ commentLikeRepository .save (CommentLike .builder ().user (testUser ).comment (testComment ).build ());
206+ testComment .incrementLikeCount ();
207+ commentRepository .save (testComment );
208+ commentRepository .flush ();
209+
210+ mockMvc .perform (delete ("/api/v1/posts/{postId}/comments/{commentId}/likes" , testPost .getId (), testComment .getId ()))
211+ .andExpect (status ().isOk ());
212+
213+ Comment comment = commentRepository .findById (testComment .getId ()).orElseThrow ();
214+ assertEquals (0 , comment .getLikeCount ());
215+ }
216+ }
217+
145218 /**
146219 * 테스트에서 사용할 공통 메서드
147220 */
@@ -175,10 +248,25 @@ private void setAuthentication(User user) {
175248 );
176249 }
177250
251+ private Comment createTestComment (Post post , User user ) {
252+ return commentRepository .save (Comment .builder ()
253+ .post (post )
254+ .user (user )
255+ .content ("테스트 댓글" )
256+ .build ());
257+ }
258+
178259 private void performLike (User user , Long postId ) throws Exception {
179260 setAuthentication (user );
180261 mockMvc .perform (post ("/api/v1/posts/{postId}/likes" , postId ))
181262 .andExpect (status ().isOk ());
182263 SecurityContextHolder .clearContext ();
183264 }
265+
266+ private void performCommentLike (User user , Long postId , Long commentId ) throws Exception {
267+ setAuthentication (user );
268+ mockMvc .perform (post ("/api/v1/posts/{postId}/comments/{commentId}/likes" , postId , commentId ))
269+ .andExpect (status ().isOk ());
270+ SecurityContextHolder .clearContext ();
271+ }
184272}
0 commit comments