✨개요
🏃 목표
📢 좋아요를 취소하는 기능을 구현하자.
📜 접근방법
- 접근하려는 post의 id와 userName을 활용하여 좋아요를 눌렀는지 판단
- 좋아요를 누른 상태에서 다시 누른 거라면 해당 좋아요 데이터를 삭제한다.
- 또한 포스트가 삭제될 시 좋아요도 삭제될 수 있게끔 양방향 매핑을 한다.
✅ TO-DO
🔧 구현
좋아요 취소하기 컨트롤러 테스트
<@Test
@DisplayName("좋아요 취소 성공")
@WithMockUser
void like_cancel_SUCCESS() throws Exception {
when(likeService.like(any(), any()))
.thenReturn(new LikeResponse("좋아요를 취소했습니다."));
mockMvc.perform(post("/api/v1/posts/1/likes")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().isOk());
}
좋아요 취소하기 서비스 테스트
@Test
@DisplayName("좋아요 취소 성공")
void like_cancell_SUCCESS() {
when(userRepository.findByUserName(any()))
.thenReturn(Optional.of(user));
when(postRepository.findById(any()))
.thenReturn(Optional.of(post));
when(likeRepository.findByPostAndUser(any(),any()))
.thenReturn(Optional.of(like));
assertDoesNotThrow(() -> likeService.like(user.getUserName(), post.getId()));
}
좋아요 취소하기 서비스
LikeService
public LikeResponse like(String userName, Long postId) {
User findUser = AppUtil.findUser(userRepository, userName);
Post findPost = AppUtil.findPost(postRepository, postId);
Optional<Like> optionalLike = likeRepository.findByPostAndUser(findPost, findUser);
if (optionalLike.isPresent()) {
Like findLike = optionalLike.get();
likeRepository.delete(findLike);
return LikeResponse.of("좋아요를 취소했습니다.");
}
Like like = Like.of(findUser, findPost);
likeRepository.save(like);
return LikeResponse.of("좋아요를 눌렀습니다.");
}
LikeRepository
public interface LikeRepository extends JpaRepository<Like,Long> {
Optional<Like> findByPostAndUser(Post post, User user);
}
포스트, 좋아요 양방향 매핑 구현
Post
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Getter
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE post SET deleted_at = CURRENT_TIMESTAMP where id = ?")
public class Post extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String body;
@ManyToOne
@JoinColumn(name = "userId")
private User user;
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY, orphanRemoval = true)
private List<Comment> comments;
@OneToMany(mappedBy = "post", fetch = FetchType.LAZY, orphanRemoval = true)
private List<Like> likes;
public static Post of(String title, String body, User user) {
return Post.builder()
.title(title)
.body(body)
.user(user)
.build();
}
public void modify(String title, String body) {
this.title = title;
this.body = body;
}
}
🌉 회고
- 좋아요 취소하기 기능을 구현했다.
- 생각보다 구현하기 어렵지 않았다.
- 지금 구현한 로직은 포스트에 좋아요를 누른 적이 있는지 find jpa 함수를 사용하는 로직이다.
- 하지만 만약에 좋아요 테이블에 많은 데이터가 쌓이게 된다면 과연 성능에 문제가 생기지 않을 지 걱정이 되었다.