Skip to content

Commit

Permalink
Feat: 게시글 좋아요 취소 기능 구현 (#69)
Browse files Browse the repository at this point in the history
* #67 - feat: 게시글 좋아요 삭제 기능을 구현함

응답을 204로 내려준다.

* #67 - test: 게시글 좋아요 삭제 컨트롤러 및 서비스 테스트 구현

* #67 - test: 테스트 수정

* #67 - test: 잘못 삭제한 테스트 복구
  • Loading branch information
GGHDMS authored Feb 5, 2024
1 parent 3486266 commit 65238e9
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
Expand All @@ -35,4 +32,15 @@ public ResponseEntity<Void> registerLike(

return ResponseEntity.created(location).build();
}

@DeleteMapping("/{post-like-id}")
public ResponseEntity<Void> deleteLike(
@PathVariable("post-id") Long postId,
@PathVariable("post-like-id") Long postLikeId,
@AuthenticationPrincipal AuthDetails details
) {
postLikeService.deleteLike(postId, postLikeId, details.getId());

return ResponseEntity.noContent().build();
}
}
6 changes: 5 additions & 1 deletion src/main/java/cotato/bookitlist/post/domain/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,11 @@ public void updatePost(Member member, String title, String content) {
this.content = content;
}

public void increaseLikeCount(){
public void increaseLikeCount() {
this.likeCount++;
}

public void decreaseLikeCount() {
this.likeCount--;
}
}
13 changes: 13 additions & 0 deletions src/main/java/cotato/bookitlist/post/domain/PostLike.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.security.access.AccessDeniedException;

@Getter
@Entity
Expand Down Expand Up @@ -36,4 +37,16 @@ public static PostLike of(Member member, Post post) {
public void increasePostLikeCount() {
post.increaseLikeCount();
}

public void decreasePostLikeCount(Member member, Post post) {
if (!member.getId().equals(this.member.getId())) {
throw new AccessDeniedException("권한이 없는 유저입니다.");
}

if (!post.getId().equals(this.post.getId())) {
throw new IllegalArgumentException("해당 게시글의 좋아요가 아닙니다.");
}

post.decreaseLikeCount();
}
}
12 changes: 12 additions & 0 deletions src/main/java/cotato/bookitlist/post/service/PostLikeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,16 @@ public Long registerLike(Long postId, Long memberId) {

return postLikeRepository.save(postLike).getId();
}

public void deleteLike(Long postId, Long postLikeId, Long memberId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new EntityNotFoundException("책을 찾을 수 없습니다."));
Member member = memberRepository.getReferenceById(memberId);

PostLike postLike = postLikeRepository.findById(postLikeId)
.orElseThrow(() -> new EntityNotFoundException("좋아요 정보를 찾을 수 없습니다."));

postLike.decreasePostLikeCount(member, post);
postLikeRepository.delete(postLike);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

Expand Down Expand Up @@ -56,6 +57,45 @@ void givenNonExistedPostId_whenRegisteringPostLike_thenReturnErrorResponse() thr
;
}

@Test
@WithCustomMockUser
@DisplayName("게시글 좋아요를 삭제한다.")
void givenPostLikeId_whenDeletingPostLike_thenDeletePostLike() throws Exception {
//given

//when & then
mockMvc.perform(delete("/posts/2/likes/1")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNoContent())
;
}

@Test
@WithCustomMockUser
@DisplayName("잘못된 게시글 좋아요 삭제요청시 에러를 반환한다.")
void givenInvalidPostId_whenDeletingPostLike_thenDeletePostLike() throws Exception {
//given

//when & then
mockMvc.perform(delete("/posts/1/likes/1")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("해당 게시글의 좋아요가 아닙니다."))
;
}

@Test
@WithCustomMockUser
@DisplayName("권한이 없는 유저가 좋아요 삭제요청시 에러를 반환한다.")
void givenInvalidMemberId_whenDeletingPostLike_thenDeletePostLike() throws Exception {
//given

//when & then
mockMvc.perform(delete("/posts/2/likes/2")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isForbidden())
.andExpect(jsonPath("$.message").value("권한이 없는 유저입니다."))
;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ class PostLikeServiceTest {
MemberRepository memberRepository;

@Test
@DisplayName("게시글 좋아요를 생성한다.")
@DisplayName("게시글 좋아요를 생성시 게시글 likeCount가 증가한다.")
void givenPostId_whenRegisteringPostLike_thenRegisterPostLike() throws Exception {
//given
Long postId = 1L;
Long memberId = 1L;
Post post = createPost();
Member member = createMember();
Post post = createPost(memberId);
Member member = createMember(memberId);

given(postRepository.findById(anyLong())).willReturn(Optional.of(post));
given(memberRepository.getReferenceById(anyLong())).willReturn(member);
Expand All @@ -61,16 +61,50 @@ void givenPostId_whenRegisteringPostLike_thenRegisterPostLike() throws Exception
then(postLikeRepository).should().save(any(PostLike.class));
}

Post createPost() {
return Post.of(createMember(), createBook(), "title", "content");
@Test
@DisplayName("게시글 좋아요를 삭제시 게시글 likeCount가 감소한다.")
void givenPostLikeId_whenDeletingPostLike_thenDeletePostLike() throws Exception {
//given
Long postId = 1L;
Long memberId = 1L;
Long postLikeId = 1L;
Post post = createPost(postId);
Member member = createMember(memberId);
PostLike postLike = createPostLike(post, member);
post.increaseLikeCount();

given(postRepository.findById(anyLong())).willReturn(Optional.of(post));
given(memberRepository.getReferenceById(anyLong())).willReturn(member);
given(postLikeRepository.findById(anyLong())).willReturn(Optional.of(postLike));

//when
sut.deleteLike(postId, postLikeId, memberId);

//then
assertThat(post.getLikeCount()).isZero();
then(postRepository).should().findById(anyLong());
then(memberRepository).should().getReferenceById(anyLong());
then(postLikeRepository).should().delete(any(PostLike.class));
}

Post createPost(Long postId) {
Post post = Post.of(createMember(), createBook(), "title", "content");
ReflectionTestUtils.setField(post, "id", postId);
return post;
}

Book createBook() {
return Book.of("title", "author", "pubisher", LocalDate.now(), "description", "link", "isbn13", 10000, "cover");
}

Member createMember(Long memberId) {
Member member = new Member("email", "name", "oauth2Id", AuthProvider.KAKAO);
ReflectionTestUtils.setField(member, "id", memberId);
return member;
}

Member createMember() {
return new Member("email", "name", "oauth2Id", AuthProvider.KAKAO);
return createMember(1L);
}

PostLike createPostLike(Post post, Member member) {
Expand Down
6 changes: 5 additions & 1 deletion src/test/resources/data.sql
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ VALUES ('[email protected]', 'test', 'test', 'KAKAO', 0, false, CURRENT_TIMESTAMP,
('[email protected]', 'test2', 'test2', 'KAKAO', 0, false, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);

INSERT INTO post (member_id, book_id, title, content, like_count, view_count, deleted)
VALUES (1, 1, 'postTitle', 'postContent', 0, 0, false),
VALUES (1, 1, 'postTitle', 'postContent', 1, 0, false),
(2, 1, 'postTitle1', 'Content', 0, 0, false),
(2, 1, 'postTitle2', '제목', 0, 0, false),
(2, 1, 'postTitle3', 'post', 0, 0, false),
Expand All @@ -33,3 +33,7 @@ VALUES (1, 1, 'postTitle', 'postContent', 0, 0, false),
INSERT INTO review (member_id, book_id, content, like_count, view_count, deleted)
VALUES (1, 1, 'reviewContent', 0, 0, false),
(2, 1, 'reviewContent', 0, 0, false);

INSERT INTO post_like (member_id, post_id)
VALUES (1, 2),
(2, 2);

0 comments on commit 65238e9

Please sign in to comment.