diff --git a/src/docs/asciidoc/api/userlibrary/userlibrary.adoc b/src/docs/asciidoc/api/userlibrary/userlibrary.adoc index b09859d..2c11aa6 100644 --- a/src/docs/asciidoc/api/userlibrary/userlibrary.adoc +++ b/src/docs/asciidoc/api/userlibrary/userlibrary.adoc @@ -60,3 +60,15 @@ include::{snippets}/user-library/delete/path-parameters.adoc[] ===== Response Body include::{snippets}/user-library/delete/response-body.adoc[] include::{snippets}/user-library/delete/response-fields.adoc[] + +=== 독서 상태 페이지 조회 + +==== HTTP Request +include::{snippets}/user-library/get-status/http-request.adoc[] +include::{snippets}/user-library/get-status/query-parameters.adoc[] + +==== HTTP Response +include::{snippets}/user-library/get-status/http-response.adoc[] +===== Response Body +include::{snippets}/user-library/get-status/response-body.adoc[] +include::{snippets}/user-library/get-status/response-fields.adoc[] \ No newline at end of file diff --git a/src/main/java/com/jisungin/application/rating/RatingService.java b/src/main/java/com/jisungin/application/rating/RatingService.java index 84d6550..95bf632 100644 --- a/src/main/java/com/jisungin/application/rating/RatingService.java +++ b/src/main/java/com/jisungin/application/rating/RatingService.java @@ -48,13 +48,17 @@ public RatingCreateResponse creatingRating(Long userId, RatingCreateServiceReque public RatingGetOneResponse getRating(Long userId, String isbn) { User user = userRepository.findById(userId) - .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + .orElse(null); Book book = bookRepository.findById(isbn) .orElseThrow(() -> new BusinessException(ErrorCode.BOOK_NOT_FOUND)); Rating rating = ratingRepository.findRatingByUserAndBook(user, book) - .orElseThrow(() -> new BusinessException(RATING_NOT_FOUND)); + .orElse(null); + + if (rating == null || user == null) { + return RatingGetOneResponse.of(null, null, book.getIsbn()); + } return RatingGetOneResponse.of(rating.getId(), rating.getRating(), book.getIsbn()); } diff --git a/src/main/java/com/jisungin/application/review/response/ReviewContentResponse.java b/src/main/java/com/jisungin/application/review/response/ReviewContentResponse.java index 862c9ec..16807ea 100644 --- a/src/main/java/com/jisungin/application/review/response/ReviewContentResponse.java +++ b/src/main/java/com/jisungin/application/review/response/ReviewContentResponse.java @@ -25,11 +25,14 @@ public class ReviewContentResponse { private String bookImage; + private String authors; + + private String publisher; + @Builder @QueryProjection - public ReviewContentResponse( - Long reviewId, String userImage, String userName, Double rating, String content, - String isbn, String title, String bookImage) { + public ReviewContentResponse(Long reviewId, String userImage, String userName, Double rating, String content, + String isbn, String title, String bookImage, String authors, String publisher) { this.reviewId = reviewId; this.userImage = userImage; this.userName = userName; @@ -38,6 +41,7 @@ public ReviewContentResponse( this.isbn = isbn; this.title = title; this.bookImage = bookImage; + this.authors = authors; + this.publisher = publisher; } - } diff --git a/src/main/java/com/jisungin/application/userlibrary/response/UserReadingStatusResponse.java b/src/main/java/com/jisungin/application/userlibrary/response/UserReadingStatusResponse.java index 596f708..bf86f2b 100644 --- a/src/main/java/com/jisungin/application/userlibrary/response/UserReadingStatusResponse.java +++ b/src/main/java/com/jisungin/application/userlibrary/response/UserReadingStatusResponse.java @@ -9,6 +9,8 @@ @NoArgsConstructor public class UserReadingStatusResponse { + private String isbn; + private String bookImage; private String bookTitle; @@ -17,7 +19,8 @@ public class UserReadingStatusResponse { @QueryProjection @Builder - public UserReadingStatusResponse(String bookImage, String bookTitle, Double ratingAvg) { + public UserReadingStatusResponse(String isbn, String bookImage, String bookTitle, Double ratingAvg) { + this.isbn = isbn; this.bookImage = bookImage; this.bookTitle = bookTitle; this.ratingAvg = ratingAvg; diff --git a/src/main/java/com/jisungin/domain/review/repository/ReviewRepositoryImpl.java b/src/main/java/com/jisungin/domain/review/repository/ReviewRepositoryImpl.java index 9050df5..7b01aae 100644 --- a/src/main/java/com/jisungin/domain/review/repository/ReviewRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/review/repository/ReviewRepositoryImpl.java @@ -82,7 +82,8 @@ private List getReviewContents( return queryFactory .select(new QReviewContentResponse( review.id, review.user.profileImage, review.user.name, rating1.rating, review.content, - review.book.isbn, review.book.title, review.book.imageUrl + review.book.isbn, review.book.title, review.book.imageUrl, review.book.authors, + review.book.publisher )) .from(review) .leftJoin(rating1).on(review.user.eq(rating1.user), review.book.eq(rating1.book)) diff --git a/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepositoryImpl.java b/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepositoryImpl.java index 669b77d..790185e 100644 --- a/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepositoryImpl.java @@ -27,7 +27,8 @@ public PageResponse findAllReadingStatusOrderBy( Long userId, ReadingStatus readingStatus, ReadingStatusOrderType orderType, int size, int offset) { log.info("--------------start--------------"); List userReadingStatuses = queryFactory - .select(new QUserReadingStatusResponse(userLibrary.book.imageUrl, userLibrary.book.title, rating1.rating.avg())) + .select(new QUserReadingStatusResponse( + userLibrary.book.isbn, userLibrary.book.imageUrl, userLibrary.book.title, rating1.rating.avg())) .from(userLibrary) .join(rating1).on(userLibrary.book.eq(rating1.book)) .where(userLibrary.user.id.eq(userId), userLibrary.status.eq(readingStatus)) diff --git a/src/test/java/com/jisungin/application/rating/RatingServiceTest.java b/src/test/java/com/jisungin/application/rating/RatingServiceTest.java index 7b62f73..1b0cb5a 100644 --- a/src/test/java/com/jisungin/application/rating/RatingServiceTest.java +++ b/src/test/java/com/jisungin/application/rating/RatingServiceTest.java @@ -85,7 +85,7 @@ void createRatingTwice() { .hasMessage("이미 별점이 존재합니다."); } - @DisplayName("유저가 해당 책의 별점을 조회한다.") + @DisplayName("유저가 해당 등록한 별점을 조회한다.") @Test void getRating() { //given @@ -102,6 +102,37 @@ void getRating() { assertThat(result.getIsbn()).isEqualTo(savadRating.getBook().getIsbn()); } + @DisplayName("유저가 해당 등록하지 않은 책의 별점을 조회한다.") + @Test + void getRatingWithEmpty() { + //given + User user = userRepository.save(createUser("1")); + Book book = bookRepository.save(createBook("제목1", "내용1", "1234")); + + //when + RatingGetOneResponse result = ratingService.getRating(user.getId(), book.getIsbn()); + + //then + assertThat(result.getId()).isNull(); + assertThat(result.getRating()).isNull(); + assertThat(result.getIsbn()).isEqualTo(book.getIsbn()); + } + + @DisplayName("게스트가 책의 별점을 조회한다.") + @Test + void getRatingWithGuest() { + //given + Book book = bookRepository.save(createBook("제목1", "내용1", "1234")); + + //when + RatingGetOneResponse result = ratingService.getRating(-1L, book.getIsbn()); + + //then + assertThat(result.getId()).isNull(); + assertThat(result.getRating()).isNull(); + assertThat(result.getIsbn()).isEqualTo(book.getIsbn()); + } + @DisplayName("유저가 별점을 수정한다.") @Test void updateRating() { diff --git a/src/test/java/com/jisungin/docs/user/UserControllerDocsTest.java b/src/test/java/com/jisungin/docs/user/UserControllerDocsTest.java index 0d893df..00015ae 100644 --- a/src/test/java/com/jisungin/docs/user/UserControllerDocsTest.java +++ b/src/test/java/com/jisungin/docs/user/UserControllerDocsTest.java @@ -8,7 +8,9 @@ import com.jisungin.application.user.UserService; import com.jisungin.application.user.request.ReviewContentGetAllServiceRequest; import com.jisungin.application.user.request.UserRatingGetAllServiceRequest; +import com.jisungin.application.user.request.UserReadingStatusGetAllServiceRequest; import com.jisungin.application.user.response.UserInfoResponse; +import com.jisungin.application.userlibrary.response.UserReadingStatusResponse; import com.jisungin.docs.RestDocsSupport; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -179,9 +181,12 @@ void getUserReviews() throws Exception { .description("책 ISBN"), fieldWithPath("data.reviewContents.queryResponse[].title").type(JsonFieldType.STRING) .description("책 제목"), - fieldWithPath("data.reviewContents.queryResponse[].bookImage").type( - JsonFieldType.STRING) + fieldWithPath("data.reviewContents.queryResponse[].bookImage").type(JsonFieldType.STRING) .description("책 표지"), + fieldWithPath("data.reviewContents.queryResponse[].authors").type(JsonFieldType.STRING) + .description("책 저자"), + fieldWithPath("data.reviewContents.queryResponse[].publisher").type(JsonFieldType.STRING) + .description("책 출판사"), fieldWithPath("data.reviewContents.totalCount").type(JsonFieldType.NUMBER) .description("총 리뷰 개수"), fieldWithPath("data.reviewContents.size").type(JsonFieldType.NUMBER) @@ -192,6 +197,75 @@ void getUserReviews() throws Exception { )); } + @DisplayName("유저 독서 상태 페이징 조회 API") + @Test + void getReadingStatuses() throws Exception { + List readingStatusesResponse = createReadingStatusResponse(); + + PageResponse response = PageResponse.builder() + .size(10) + .totalCount(10) + .queryResponse(readingStatusesResponse) + .build(); + + given(userService.getUserReadingStatuses(anyLong(), any(UserReadingStatusGetAllServiceRequest.class))) + .willReturn(response); + + mockMvc.perform(get("/v1/users/statuses") + .param("page", "1") + .param("size", "10") + .param("order", "dictionary") + .param("status", "want") + .contentType(APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")) + .andDo(print()) + .andDo(document("user-library/get-status", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + queryParameters( + parameterWithName("page") + .description("페이지 번호"), + parameterWithName("size") + .description("페이지 사이즈"), + parameterWithName("order") + .description( + "정렬 기준 : dictionary(가나다순), rating_avg_desc(평균 별점 높은 순)"), + parameterWithName("status") + .description( + "선택 기준 : want(읽고 싶은), reading(읽는 중), pause(잠시 멈춤)," + + "stop(중단), none(상관없음)") + ), + responseFields( + fieldWithPath("code").type(JsonFieldType.NUMBER) + .description("코드"), + fieldWithPath("status").type(JsonFieldType.STRING) + .description("상태"), + fieldWithPath("message").type(JsonFieldType.STRING) + .description("메시지"), + fieldWithPath("data").type(JsonFieldType.OBJECT) + .description("응답 데이터"), + fieldWithPath("data.queryResponse").type(JsonFieldType.ARRAY) + .description("책 목록"), + fieldWithPath("data.queryResponse[].isbn").type(JsonFieldType.STRING) + .description("책 isbn"), + fieldWithPath("data.queryResponse[].bookTitle").type(JsonFieldType.STRING) + .description("책 제목"), + fieldWithPath("data.queryResponse[].bookImage").type(JsonFieldType.STRING) + .description("책 표지"), + fieldWithPath("data.queryResponse[].ratingAvg").type(JsonFieldType.NUMBER) + .description("책 평균 별점"), + fieldWithPath("data.totalCount").type(JsonFieldType.NUMBER) + .description("데이터 총 개수"), + fieldWithPath("data.size").type(JsonFieldType.NUMBER) + .description("해당 페이지 데이터 개수") + ) + )); + } + @DisplayName("유저 상세 조회 API") @Test void getUserInfo() throws Exception { @@ -252,6 +326,8 @@ private List createReviewFindAllResponse() { .isbn(String.valueOf(i)) .title("title" + i) .bookImage("bookImage" + i) + .authors("저자" + i) + .publisher("출판사" + i) .build()) .toList(); } @@ -263,4 +339,15 @@ private List createLikeReviewIds() { .collect(Collectors.toList()); } + private List createReadingStatusResponse() { + return IntStream.range(0, 10) + .mapToObj(i -> UserReadingStatusResponse.builder() + .isbn(String.valueOf(i)) + .bookTitle("책 제목" + i) + .bookImage("책 표지" + i) + .ratingAvg(i % 5.0 + 1) + .build()) + .toList(); + } + }