Skip to content

Commit

Permalink
Feat: 게시글, 한줄요약 status 변경 api 구현 (#178)
Browse files Browse the repository at this point in the history
* #177 - feat: 게시글, 한줄요약 상태 변경 api 구현

* #177 - test: 게시글, 한줄요약 상태 변경 테스트 작성

* #177 - style: 단순 오타 수정
  • Loading branch information
GGHDMS authored Feb 21, 2024
1 parent 813a48b commit 7f20173
Show file tree
Hide file tree
Showing 11 changed files with 159 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,15 @@ public ResponseEntity<PostListResponse> getRecommendPosts(
return ResponseEntity.ok(postService.getRecommendPosts(type, start, details.getId()));
}

@PatchMapping("/{post-id}/status")
public ResponseEntity<Void> togglePostStatus(
@PathVariable("post-id") Long postId,
@AuthenticationPrincipal AuthDetails details
) {
postService.togglePostStatus(postId, details.getId());
return ResponseEntity.ok().build();
}

private void handlePostViewCount(HttpServletRequest request, HttpServletResponse response, Long postId) {
Cookie[] cookies = request.getCookies();
Cookie postViewCookie = findCookie(cookies);
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/cotato/bookitlist/post/domain/entity/Post.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,8 @@ public void validatePostLike(Member member) {
throw new AccessDeniedException("본인의 게시글은 좋아요할 수 없습니다.");
}
}

public void toggleStatus() {
status = (status == PostStatus.PRIVATE) ? PostStatus.PUBLIC : PostStatus.PRIVATE;
}
}
7 changes: 7 additions & 0 deletions src/main/java/cotato/bookitlist/post/service/PostService.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,11 @@ public PostListResponse getNewPosts(int start, Long memberId) {

return PostListResponse.from(postPage, memberId);
}

public void togglePostStatus(Long postId, Long memberId) {
Post post = postRepository.findByIdAndMemberId(postId, memberId)
.orElseThrow(() -> new EntityNotFoundException("게시글을 찾을 수 없습니다."));

post.toggleStatus();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ public ResponseEntity<ReviewSimpleResponse> getBestReviewOfBook(
return ResponseEntity.ok(reviewService.getBestReviewOfBook(isbn13));
}

@PatchMapping("/{review-id}/status")
public ResponseEntity<Void> toggleReviewStatus(
@PathVariable("review-id") Long reviewId,
@AuthenticationPrincipal AuthDetails details
) {
reviewService.toggleReviewStatus(reviewId, details.getId());
return ResponseEntity.ok().build();
}

private void handleReviewViewCount(HttpServletRequest request, HttpServletResponse response, Long reviewId) {
Cookie[] cookies = request.getCookies();
Cookie reviewViewCookie = findCookie(cookies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,8 @@ public void validateReviewLike(Member member) {
throw new AccessDeniedException("본인의 한줄요약은 좋아요할 수 없습니다.");
}
}

public void toggleStatus() {
status = (status == ReviewStatus.PRIVATE) ? ReviewStatus.PUBLIC : ReviewStatus.PRIVATE;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,11 @@ public ReviewSimpleResponse getBestReviewOfBook(String isbn13) {
return reviewRepository.findBestReview(book)
.orElseThrow(() -> new EntityNotFoundException("한줄요약을 찾을 수 없습니다."));
}

public void toggleReviewStatus(Long reviewId, Long memberId) {
Review review = reviewRepository.findByIdAndMemberId(reviewId, memberId)
.orElseThrow(() -> new EntityNotFoundException("한줄요약을 찾을 수 없습니다."));

review.toggleStatus();
}
}
6 changes: 5 additions & 1 deletion src/test/java/cotato/bookitlist/fixture/ReviewFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@
import static cotato.bookitlist.fixture.MemberFixture.createMember;

public class ReviewFixture {
public static Review createReview(Long reviewId) {
public static Review createReview(Long reviewId, Long memberId) {
Review review = Review.of(createMember(), createBook(), "content", ReviewStatus.PUBLIC);
ReflectionTestUtils.setField(review, "id", reviewId);
return review;
}

public static Review createReview(Long reviewId) {
return createReview(reviewId, 1L);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -557,5 +557,45 @@ void givenPageStartAndRecommendType_whenGettingNewPosts_thenReturnNewPosts() thr
.andExpect(jsonPath("$.postList[1].postId").value(2))
;
}

@Test
@WithCustomMockUser
@DisplayName("본인의 게시글 상태를 바꾼다")
void givenWithLogin_whenTogglingPostStatus_thenTogglePostStatus() throws Exception {
//given

//when & then
mockMvc.perform(patch("/posts/1/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
;
}

@Test
@WithCustomMockUser
@DisplayName("다른 사람 게시글 상태를 바꾼다")
void givenNonMyPost_whenTogglingPostStatus_thenErrorResponse() throws Exception {
//given

//when & then
mockMvc.perform(patch("/posts/2/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
;
}

@Test
@DisplayName("로그인 없이 게시글 상태를 바꾼면 에러를 반환한다.")
void givenWithNonLogin_whenTogglingPostStatus_thenReturnErrorResponse() throws Exception {
//given

//when & then
mockMvc.perform(patch("/posts/1/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized())
;
}


}

17 changes: 17 additions & 0 deletions src/test/java/cotato/bookitlist/post/service/PostServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cotato.bookitlist.post.service;

import cotato.bookitlist.post.domain.PostStatus;
import cotato.bookitlist.post.domain.entity.Post;
import cotato.bookitlist.post.repository.PostRepository;
import org.junit.jupiter.api.DisplayName;
Expand Down Expand Up @@ -59,4 +60,20 @@ void givenPostId_whenDeletingPost_thenDeletePost() throws Exception {
assertThat(post.getLikeCount()).isZero();
}

@Test
@DisplayName("본인의 게시글 상태를 바꾼다")
void givenWithLogin_whenTogglingPostStatus_thenTogglePostStatus() throws Exception {
//given
Long postId = 1L;
Long memberId = 1L;
Post post = createPost(postId, memberId);
given(postRepository.findByIdAndMemberId(postId, memberId)).willReturn(Optional.of(post));

//when
sut.togglePostStatus(postId, memberId);

//then
then(postRepository).should().findByIdAndMemberId(postId, memberId);
assertThat(post.getStatus()).isEqualTo(PostStatus.PRIVATE);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -537,4 +537,42 @@ void givenIsbn13NonReview_whenGettingBestReviewOfBook_thenReturnError() throws E
.andExpect(jsonPath("$.message").value("한줄요약을 찾을 수 없습니다."))
;
}

@Test
@WithCustomMockUser
@DisplayName("본인의 한줄요약 상태를 바꾼다")
void givenWithLogin_whenTogglingReviewStatus_thenToggleReviewStatus() throws Exception {
//given

//when & then
mockMvc.perform(patch("/reviews/1/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
;
}

@Test
@WithCustomMockUser
@DisplayName("다른 사람 한줄요약 상태를 바꾼다")
void givenNonMyReview_whenTogglingReviewStatus_thenErrorResponse() throws Exception {
//given

//when & then
mockMvc.perform(patch("/reviews/2/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound())
;
}

@Test
@DisplayName("로그인 없이 한줄요약 상태를 바꾼면 에러를 반환한다.")
void givenWithNonLogin_whenTogglingReviewStatus_thenReturnErrorResponse() throws Exception {
//given

//when & then
mockMvc.perform(patch("/reviews/1/status")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isUnauthorized())
;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cotato.bookitlist.review.service;

import cotato.bookitlist.review.domain.ReviewStatus;
import cotato.bookitlist.review.domain.entity.Review;
import cotato.bookitlist.review.repository.ReviewRepository;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -9,6 +10,8 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Optional;

import static cotato.bookitlist.fixture.ReviewFixture.createReview;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
Expand Down Expand Up @@ -39,4 +42,20 @@ void givenReviewId_whenIncreasingViewCount_thenIncreaseViewCount() {
assertThat(review.getViewCount()).isEqualTo(1);
}

@Test
@DisplayName("본인의 한줄요약 상태를 바꾼다")
void givenWithLogin_whenTogglingReviewStatus_thenToggleReviewStatus() throws Exception {
//given
Long reviewId = 1L;
Long memberId = 1L;
Review review = createReview(reviewId, memberId);
given(reviewRepository.findByIdAndMemberId(reviewId, memberId)).willReturn(Optional.of(review));

//when
sut.toggleReviewStatus(reviewId, memberId);

//then
then(reviewRepository).should().findByIdAndMemberId(reviewId, memberId);
assertThat(review.getStatus()).isEqualTo(ReviewStatus.PRIVATE);
}
}

0 comments on commit 7f20173

Please sign in to comment.