From 4d6539d630d3cb80f51d272ab0db394ea82648e4 Mon Sep 17 00:00:00 2001 From: kimdohyung Date: Mon, 25 Mar 2024 19:47:05 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20API=20=EC=B6=94=EA=B0=80=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jisungin/api/review/ReviewController.java | 30 ++++++++++++++ .../review/request/ReviewCreateRequest.java | 37 +++++++++++++++++ .../application/review/ReviewService.java | 41 +++++++++++++++++++ .../request/ReviewCreateServiceRequest.java | 24 +++++++++++ .../review/response/ReviewResponse.java | 33 +++++++++++++++ .../com/jisungin/domain/review/Review.java | 9 ++++ 6 files changed, 174 insertions(+) create mode 100644 src/main/java/com/jisungin/api/review/ReviewController.java create mode 100644 src/main/java/com/jisungin/api/review/request/ReviewCreateRequest.java create mode 100644 src/main/java/com/jisungin/application/review/ReviewService.java create mode 100644 src/main/java/com/jisungin/application/review/request/ReviewCreateServiceRequest.java create mode 100644 src/main/java/com/jisungin/application/review/response/ReviewResponse.java diff --git a/src/main/java/com/jisungin/api/review/ReviewController.java b/src/main/java/com/jisungin/api/review/ReviewController.java new file mode 100644 index 0000000..399f5f7 --- /dev/null +++ b/src/main/java/com/jisungin/api/review/ReviewController.java @@ -0,0 +1,30 @@ +package com.jisungin.api.review; + +import com.jisungin.api.ApiResponse; +import com.jisungin.api.oauth.Auth; +import com.jisungin.api.oauth.AuthContext; +import com.jisungin.api.review.request.ReviewCreateRequest; +import com.jisungin.application.review.ReviewService; +import com.jisungin.application.review.response.ReviewResponse; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequestMapping("/v1/reviews") +@RequiredArgsConstructor +@RestController +public class ReviewController { + + private final ReviewService reviewService; + + @PostMapping + public ApiResponse createReview( + @Valid @RequestBody ReviewCreateRequest request, + @Auth AuthContext authContext) { + return ApiResponse.ok(reviewService.createReview(request.toServiceRequest(), authContext.getUserId())); + } + +} diff --git a/src/main/java/com/jisungin/api/review/request/ReviewCreateRequest.java b/src/main/java/com/jisungin/api/review/request/ReviewCreateRequest.java new file mode 100644 index 0000000..b4167e3 --- /dev/null +++ b/src/main/java/com/jisungin/api/review/request/ReviewCreateRequest.java @@ -0,0 +1,37 @@ +package com.jisungin.api.review.request; + +import com.jisungin.application.review.request.ReviewCreateServiceRequest; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ReviewCreateRequest { + + @NotBlank(message = "리뷰 작성 시 책 isbn은 필수입니다.") + private String bookIsbn; + + @NotBlank(message = "리뷰 작성 시 내용은 필수입니다.") + private String content; + + @NotBlank(message = "리뷰 작성 시 별점은 필수입니다.") + private String rating; + + @Builder + private ReviewCreateRequest(String bookIsbn, String content, String rating) { + this.bookIsbn = bookIsbn; + this.content = content; + this.rating = rating; + } + + public ReviewCreateServiceRequest toServiceRequest() { + return ReviewCreateServiceRequest.builder() + .bookIsbn(bookIsbn) + .content(content) + .rating(Double.parseDouble(rating)) + .build(); + } + +} diff --git a/src/main/java/com/jisungin/application/review/ReviewService.java b/src/main/java/com/jisungin/application/review/ReviewService.java new file mode 100644 index 0000000..5dafd2b --- /dev/null +++ b/src/main/java/com/jisungin/application/review/ReviewService.java @@ -0,0 +1,41 @@ +package com.jisungin.application.review; + +import com.jisungin.application.review.request.ReviewCreateServiceRequest; +import com.jisungin.application.review.response.ReviewResponse; +import com.jisungin.domain.book.Book; +import com.jisungin.domain.book.repository.BookRepository; +import com.jisungin.domain.review.Review; +import com.jisungin.domain.review.repository.ReviewRepository; +import com.jisungin.domain.user.User; +import com.jisungin.domain.user.repository.UserRepository; +import com.jisungin.exception.BusinessException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.jisungin.exception.ErrorCode.*; + +@RequiredArgsConstructor +@Transactional(readOnly = true) +@Service +public class ReviewService { + + private final ReviewRepository reviewRepository; + private final UserRepository userRepository; + private final BookRepository bookRepository; + + @Transactional + public ReviewResponse createReview(ReviewCreateServiceRequest request, Long userId) { + User user = userRepository.findById(userId) + .orElseThrow(() -> new BusinessException(USER_NOT_FOUND)); + + Book book = bookRepository.findById(request.getBookIsbn()) + .orElseThrow(() -> new BusinessException(BOOK_NOT_FOUND)); + + Review savedReview = reviewRepository.save(Review.create( + user, book, request.getContent(), request.getRating() + )); + return ReviewResponse.of(savedReview.getBook(), savedReview.getContent(), savedReview.getRating()); + } + +} diff --git a/src/main/java/com/jisungin/application/review/request/ReviewCreateServiceRequest.java b/src/main/java/com/jisungin/application/review/request/ReviewCreateServiceRequest.java new file mode 100644 index 0000000..212fdb6 --- /dev/null +++ b/src/main/java/com/jisungin/application/review/request/ReviewCreateServiceRequest.java @@ -0,0 +1,24 @@ +package com.jisungin.application.review.request; + +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ReviewCreateServiceRequest { + + private String bookIsbn; + + private String content; + + private Double rating; + + @Builder + public ReviewCreateServiceRequest(String bookIsbn, String content, Double rating) { + this.bookIsbn = bookIsbn; + this.content = content; + this.rating = rating; + } + +} diff --git a/src/main/java/com/jisungin/application/review/response/ReviewResponse.java b/src/main/java/com/jisungin/application/review/response/ReviewResponse.java new file mode 100644 index 0000000..7144deb --- /dev/null +++ b/src/main/java/com/jisungin/application/review/response/ReviewResponse.java @@ -0,0 +1,33 @@ +package com.jisungin.application.review.response; + +import com.jisungin.domain.book.Book; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class ReviewResponse { + + private Book book; + + private String content; + + private Double rating; + + @Builder + private ReviewResponse(Book book, String content, Double rating) { + this.book = book; + this.content = content; + this.rating = rating; + } + + public static ReviewResponse of(Book book, String content, Double rating) { + return ReviewResponse.builder() + .book(book) + .content(content) + .rating(rating) + .build(); + } + +} diff --git a/src/main/java/com/jisungin/domain/review/Review.java b/src/main/java/com/jisungin/domain/review/Review.java index c3766bd..a45cf28 100644 --- a/src/main/java/com/jisungin/domain/review/Review.java +++ b/src/main/java/com/jisungin/domain/review/Review.java @@ -42,4 +42,13 @@ private Review(User user, Book book, String content, Double rating) { this.rating = rating; } + public static Review create(User user, Book book, String content, Double rating) { + return Review.builder() + .user(user) + .book(book) + .content(content) + .rating(rating) + .build(); + } + } From 2cd83caeb360e6ad3ca54ca027d99a9f1e9a852e Mon Sep 17 00:00:00 2001 From: kimdohyung Date: Mon, 25 Mar 2024 20:14:04 +0900 Subject: [PATCH 2/5] =?UTF-8?q?test:=20=EB=A6=AC=EB=B7=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/jisungin/ControllerTestSupport.java | 11 +- .../api/review/ReviewControllerTest.java | 97 +++++++++++++ .../application/review/ReviewServiceTest.java | 135 ++++++++++++++++++ 3 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/jisungin/api/review/ReviewControllerTest.java create mode 100644 src/test/java/com/jisungin/application/review/ReviewServiceTest.java diff --git a/src/test/java/com/jisungin/ControllerTestSupport.java b/src/test/java/com/jisungin/ControllerTestSupport.java index 4666d3b..5928924 100644 --- a/src/test/java/com/jisungin/ControllerTestSupport.java +++ b/src/test/java/com/jisungin/ControllerTestSupport.java @@ -3,8 +3,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.jisungin.api.comment.CommentController; import com.jisungin.api.oauth.AuthContext; +import com.jisungin.api.review.ReviewController; import com.jisungin.api.talkroom.TalkRoomController; import com.jisungin.application.comment.CommentService; +import com.jisungin.application.review.ReviewService; import com.jisungin.application.talkroom.TalkRoomService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -13,7 +15,8 @@ @WebMvcTest(controllers = { TalkRoomController.class, - CommentController.class + CommentController.class, + ReviewController.class }) public abstract class ControllerTestSupport { @@ -23,6 +26,9 @@ public abstract class ControllerTestSupport { @Autowired protected ObjectMapper objectMapper; + @MockBean + protected AuthContext authContext; + @MockBean protected TalkRoomService talkRoomService; @@ -30,5 +36,6 @@ public abstract class ControllerTestSupport { protected CommentService commentService; @MockBean - protected AuthContext authContext; + protected ReviewService reviewService; + } diff --git a/src/test/java/com/jisungin/api/review/ReviewControllerTest.java b/src/test/java/com/jisungin/api/review/ReviewControllerTest.java new file mode 100644 index 0000000..41115db --- /dev/null +++ b/src/test/java/com/jisungin/api/review/ReviewControllerTest.java @@ -0,0 +1,97 @@ +package com.jisungin.api.review; + +import com.jisungin.ControllerTestSupport; +import com.jisungin.api.review.request.ReviewCreateRequest; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.http.MediaType; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +class ReviewControllerTest extends ControllerTestSupport { + + @DisplayName("유저가 리뷰를 등록한다.") + @Test + void createReview() throws Exception { + //given + ReviewCreateRequest request = ReviewCreateRequest.builder() + .bookIsbn("123456") + .content("재밌어요.") + .rating("4.5") + .build(); + + //when //then + mockMvc.perform( + post("/v1/reviews") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andDo(print()); + } + + @DisplayName("책 isbn과 함께 리뷰를 등록해야 한다.") + @Test + void createReviewWithoutBookIsbn() throws Exception { + //given + ReviewCreateRequest request = ReviewCreateRequest.builder() + .content("재밌어요.") + .rating("4.5") + .build(); + + //when //then + mockMvc.perform( + post("/v1/reviews") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("400")) + .andExpect(jsonPath("$.message").value("리뷰 작성 시 책 isbn은 필수입니다.")) + .andDo(print()); + } + + @DisplayName("리뷰 내용과 함께 리뷰를 등록해야 한다.") + @Test + void createReviewWithoutContent() throws Exception { + //given + ReviewCreateRequest request = ReviewCreateRequest.builder() + .bookIsbn("123456") + .rating("4.5") + .build(); + + //when //then + mockMvc.perform( + post("/v1/reviews") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("400")) + .andExpect(jsonPath("$.message").value("리뷰 작성 시 내용은 필수입니다.")) + .andDo(print()); + } + + @DisplayName("별점과 함께 리뷰를 등록해야 한다.") + @Test + void createReviewWithoutRating() throws Exception { + //given + ReviewCreateRequest request = ReviewCreateRequest.builder() + .bookIsbn("123456") + .content("재밌어요.") + .build(); + + //when //then + mockMvc.perform( + post("/v1/reviews") + .content(objectMapper.writeValueAsString(request)) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("400")) + .andExpect(jsonPath("$.message").value("리뷰 작성 시 별점은 필수입니다.")) + .andDo(print()); + } + +} \ No newline at end of file diff --git a/src/test/java/com/jisungin/application/review/ReviewServiceTest.java b/src/test/java/com/jisungin/application/review/ReviewServiceTest.java new file mode 100644 index 0000000..089794d --- /dev/null +++ b/src/test/java/com/jisungin/application/review/ReviewServiceTest.java @@ -0,0 +1,135 @@ +package com.jisungin.application.review; + +import com.jisungin.ServiceTestSupport; +import com.jisungin.application.review.request.ReviewCreateServiceRequest; +import com.jisungin.application.review.response.ReviewResponse; +import com.jisungin.domain.book.Book; +import com.jisungin.domain.book.repository.BookRepository; +import com.jisungin.domain.oauth.OauthId; +import com.jisungin.domain.oauth.OauthType; +import com.jisungin.domain.review.Review; +import com.jisungin.domain.review.repository.ReviewRepository; +import com.jisungin.domain.user.User; +import com.jisungin.domain.user.repository.UserRepository; +import com.jisungin.exception.BusinessException; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.LocalDateTime; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; + +class ReviewServiceTest extends ServiceTestSupport { + + @Autowired + private ReviewRepository reviewRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private BookRepository bookRepository; + + @Autowired + private ReviewService reviewService; + + @AfterEach + void tearDown() { + reviewRepository.deleteAllInBatch(); + bookRepository.deleteAllInBatch(); + userRepository.deleteAllInBatch(); + } + + @DisplayName("유저가 리뷰를 등록한다.") + @Test + void createReview() { + //given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + ReviewCreateServiceRequest request = ReviewCreateServiceRequest.builder() + .bookIsbn(book.getIsbn()) + .content("내용이 좋아요.") + .rating(4.5) + .build(); + + //when + ReviewResponse reviewResponse = reviewService.createReview(request, user.getId()); + + //then + List reviews = reviewRepository.findAll(); + + assertThat(reviewResponse.getBook()) + .extracting("isbn", "title", "content") + .contains("123456", "제목", "내용"); + + assertThat(reviews).hasSize(1) + .extracting("content", "rating") + .contains( + tuple("내용이 좋아요.", 4.5) + ); + + } + + @DisplayName("유저가 리뷰를 등록하는 책이 존재해야 한다") + @Test + void createReviewWithoutBook() { + //given + User user = createUser(); + userRepository.save(user); + + ReviewCreateServiceRequest request = ReviewCreateServiceRequest.builder() + .bookIsbn("123457") + .build(); + + //when //then + assertThatThrownBy(() -> reviewService.createReview(request, user.getId())) + .isInstanceOf(BusinessException.class) + .hasMessage("책을 찾을 수 없습니다."); + } + + @DisplayName("리뷰를 등록하는 유저가 존재해야 한다.") + @Test + void createReviewWithoutUser() { + //given + ReviewCreateServiceRequest request = ReviewCreateServiceRequest.builder() + .build(); + + //when //then + assertThatThrownBy(() -> reviewService.createReview(request, 1L)) + .isInstanceOf(BusinessException.class) + .hasMessage("사용자를 찾을 수 없습니다."); + } + + private static User createUser() { + return User.builder() + .name("김도형") + .profileImage("image") + .oauthId( + OauthId.builder() + .oauthId("oauthId") + .oauthType(OauthType.KAKAO) + .build() + ) + .build(); + } + + private static Book createBook() { + return Book.builder() + .title("제목") + .content("내용") + .authors("김도형") + .isbn("123456") + .publisher("지성인") + .dateTime(LocalDateTime.of(2024, 1, 1, 0, 0)) + .imageUrl("image") + .build(); + } + +} \ No newline at end of file From 534ed1ef2d7e83b07d6118f25374d56636f1f89f Mon Sep 17 00:00:00 2001 From: kimdohyung Date: Mon, 25 Mar 2024 22:48:57 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20API=20=EC=B6=94=EA=B0=80=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jisungin/api/review/ReviewController.java | 17 ++++++++++------- .../application/review/ReviewService.java | 15 +++++++++++++++ .../java/com/jisungin/domain/user/User.java | 4 ++++ .../java/com/jisungin/exception/ErrorCode.java | 3 ++- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/jisungin/api/review/ReviewController.java b/src/main/java/com/jisungin/api/review/ReviewController.java index 399f5f7..884effb 100644 --- a/src/main/java/com/jisungin/api/review/ReviewController.java +++ b/src/main/java/com/jisungin/api/review/ReviewController.java @@ -8,10 +8,7 @@ import com.jisungin.application.review.response.ReviewResponse; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RequestMapping("/v1/reviews") @RequiredArgsConstructor @@ -21,10 +18,16 @@ public class ReviewController { private final ReviewService reviewService; @PostMapping - public ApiResponse createReview( - @Valid @RequestBody ReviewCreateRequest request, - @Auth AuthContext authContext) { + public ApiResponse createReview(@Valid @RequestBody ReviewCreateRequest request, + @Auth AuthContext authContext) { return ApiResponse.ok(reviewService.createReview(request.toServiceRequest(), authContext.getUserId())); } + @DeleteMapping("/{reviewId}") + public ApiResponse deleteReview(@PathVariable Long reviewId, + @Auth AuthContext authContext) { + reviewService.deleteReview(reviewId, authContext.getUserId()); + return ApiResponse.ok(null); + } + } diff --git a/src/main/java/com/jisungin/application/review/ReviewService.java b/src/main/java/com/jisungin/application/review/ReviewService.java index 5dafd2b..d9c4942 100644 --- a/src/main/java/com/jisungin/application/review/ReviewService.java +++ b/src/main/java/com/jisungin/application/review/ReviewService.java @@ -38,4 +38,19 @@ public ReviewResponse createReview(ReviewCreateServiceRequest request, Long user return ReviewResponse.of(savedReview.getBook(), savedReview.getContent(), savedReview.getRating()); } + @Transactional + public void deleteReview(Long reviewId, Long userId) { + Review deleteReview = reviewRepository.findById(reviewId) + .orElseThrow(() -> new BusinessException(REVIEW_NOT_FOUND)); + + User reviewUser = deleteReview.getUser(); + User user = userRepository.findById(userId) + .orElseThrow(() -> new BusinessException(USER_NOT_FOUND)); + + if (!user.isSame(reviewUser.getId())) { + throw new BusinessException(UNAUTHORIZED_REQUEST); + } + reviewRepository.delete(deleteReview); + } + } diff --git a/src/main/java/com/jisungin/domain/user/User.java b/src/main/java/com/jisungin/domain/user/User.java index 36c7a94..8be2ed2 100644 --- a/src/main/java/com/jisungin/domain/user/User.java +++ b/src/main/java/com/jisungin/domain/user/User.java @@ -56,4 +56,8 @@ public boolean isMe(Long userId) { return this.id.equals(userId); } + public boolean isSame(Long userId) { + return this.id.equals(userId); + } + } diff --git a/src/main/java/com/jisungin/exception/ErrorCode.java b/src/main/java/com/jisungin/exception/ErrorCode.java index 35b14b8..f8d5bc2 100644 --- a/src/main/java/com/jisungin/exception/ErrorCode.java +++ b/src/main/java/com/jisungin/exception/ErrorCode.java @@ -15,7 +15,8 @@ public enum ErrorCode { OAUTH_TYPE_NOT_FOUND(404, "지원하지 않는 소셜 로그인입니다."), TALK_ROOM_NOT_FOUND(400, "토크방을 찾을 수 없습니다."), UNAUTHORIZED_REQUEST(400, "권한이 없는 사용자입니다."), - COMMENT_NOT_FOUND(404, "의견을 찾을 수 없습니다."); + COMMENT_NOT_FOUND(404, "의견을 찾을 수 없습니다."), + REVIEW_NOT_FOUND(404, "리뷰를 찾을 수 없습니다."); private final int code; From 760f3c74ab9b2571e98ec27cc751986173d99fce Mon Sep 17 00:00:00 2001 From: kimdohyung Date: Mon, 25 Mar 2024 20:54:06 +0900 Subject: [PATCH 4/5] =?UTF-8?q?test:=20=EB=A6=AC=EB=B7=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/review/ReviewControllerTest.java | 17 ++++++ .../application/review/ReviewServiceTest.java | 53 +++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/jisungin/api/review/ReviewControllerTest.java b/src/test/java/com/jisungin/api/review/ReviewControllerTest.java index 41115db..f66310f 100644 --- a/src/test/java/com/jisungin/api/review/ReviewControllerTest.java +++ b/src/test/java/com/jisungin/api/review/ReviewControllerTest.java @@ -94,4 +94,21 @@ void createReviewWithoutRating() throws Exception { .andDo(print()); } + @DisplayName("리뷰를 삭제한다.") + @Test + void deleteReview() throws Exception { + //given + Long deleteReviewId = 1L; + + //when //then + mockMvc.perform( + delete("/v1/reviews/{reviewId}", deleteReviewId) + .contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andDo(print()); + } + } \ No newline at end of file diff --git a/src/test/java/com/jisungin/application/review/ReviewServiceTest.java b/src/test/java/com/jisungin/application/review/ReviewServiceTest.java index 089794d..c461b6c 100644 --- a/src/test/java/com/jisungin/application/review/ReviewServiceTest.java +++ b/src/test/java/com/jisungin/application/review/ReviewServiceTest.java @@ -47,7 +47,7 @@ void tearDown() { @Test void createReview() { //given - User user = createUser(); + User user = createUser("1"); userRepository.save(user); Book book = createBook(); @@ -81,7 +81,7 @@ void createReview() { @Test void createReviewWithoutBook() { //given - User user = createUser(); + User user = createUser("1"); userRepository.save(user); ReviewCreateServiceRequest request = ReviewCreateServiceRequest.builder() @@ -107,13 +107,58 @@ void createReviewWithoutUser() { .hasMessage("사용자를 찾을 수 없습니다."); } - private static User createUser() { + @DisplayName("리뷰를 삭제한다.") + @Test + void deleteReview() { + //given + User user = createUser("1"); + Book book = createBook(); + Review review = createReview(user, book); + userRepository.save(user); + bookRepository.save(book); + reviewRepository.save(review); + + //when + reviewService.deleteReview(review.getId(), user.getId()); + + //then + assertThat(reviewRepository.findAll()).isEmpty(); + } + + @DisplayName("다른 유저가 리뷰를 삭제한다.") + @Test + void deleteReviewWithAnotherUser() { + //given + User user1 = createUser("1"); + User user2 = createUser("2"); + Book book = createBook(); + Review review = createReview(user1, book); + userRepository.saveAll(List.of(user1, user2)); + bookRepository.save(book); + reviewRepository.save(review); + + //when //then + assertThatThrownBy(() -> reviewService.deleteReview(review.getId(), user2.getId())) + .isInstanceOf(BusinessException.class) + .hasMessage("권한이 없는 사용자입니다."); + } + + private static Review createReview(User user, Book book) { + return Review.builder() + .user(user) + .book(book) + .content("내용") + .rating(4.5) + .build(); + } + + private static User createUser(String oauthId) { return User.builder() .name("김도형") .profileImage("image") .oauthId( OauthId.builder() - .oauthId("oauthId") + .oauthId(oauthId) .oauthType(OauthType.KAKAO) .build() ) From dbf939fec1d689c7faf7a06c3d7987cb9d8d3995 Mon Sep 17 00:00:00 2001 From: kimdohyung Date: Tue, 26 Mar 2024 19:20:23 +0900 Subject: [PATCH 5/5] =?UTF-8?q?refactor:=20=EC=9D=BC=EC=B9=98=20=EC=97=AC?= =?UTF-8?q?=EB=B6=80=20=ED=8C=90=EB=8B=A8=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=EC=A0=9C=EA=B1=B0=20(#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/jisungin/application/review/ReviewService.java | 2 +- src/main/java/com/jisungin/domain/user/User.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/com/jisungin/application/review/ReviewService.java b/src/main/java/com/jisungin/application/review/ReviewService.java index d9c4942..dc2a599 100644 --- a/src/main/java/com/jisungin/application/review/ReviewService.java +++ b/src/main/java/com/jisungin/application/review/ReviewService.java @@ -47,7 +47,7 @@ public void deleteReview(Long reviewId, Long userId) { User user = userRepository.findById(userId) .orElseThrow(() -> new BusinessException(USER_NOT_FOUND)); - if (!user.isSame(reviewUser.getId())) { + if (!user.isMe(reviewUser.getId())) { throw new BusinessException(UNAUTHORIZED_REQUEST); } reviewRepository.delete(deleteReview); diff --git a/src/main/java/com/jisungin/domain/user/User.java b/src/main/java/com/jisungin/domain/user/User.java index 8be2ed2..36c7a94 100644 --- a/src/main/java/com/jisungin/domain/user/User.java +++ b/src/main/java/com/jisungin/domain/user/User.java @@ -56,8 +56,4 @@ public boolean isMe(Long userId) { return this.id.equals(userId); } - public boolean isSame(Long userId) { - return this.id.equals(userId); - } - }