diff --git a/src/docs/asciidoc/api/talkroom/talkroom.adoc b/src/docs/asciidoc/api/talkroom/talkroom.adoc index 345fbe0..5b4878f 100644 --- a/src/docs/asciidoc/api/talkroom/talkroom.adoc +++ b/src/docs/asciidoc/api/talkroom/talkroom.adoc @@ -61,4 +61,17 @@ include::{snippets}/talkroom/delete/path-parameters.adoc[] ==== HTTP Response include::{snippets}/talkroom/delete/http-response.adoc[] -include::{snippets}/talkroom/delete/response-fields.adoc[] \ No newline at end of file +include::{snippets}/talkroom/delete/response-fields.adoc[] + +[[talkroom-findAllByUser]] +=== 나의 토크방 모아보기 + +==== HTTP Request + +include::{snippets}/talkroom/findUserTalkRoom/http-request.adoc[] +include::{snippets}/talkroom/findUserTalkRoom/query-parameters.adoc[] + +==== HTTP Response + +include::{snippets}/talkroom/findUserTalkRoom/http-response.adoc[] +include::{snippets}/talkroom/findUserTalkRoom/response-fields.adoc[] diff --git a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java index 0ba505d..6e240f8 100644 --- a/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java +++ b/src/main/java/com/jisungin/api/talkroom/TalkRoomController.java @@ -81,4 +81,17 @@ public ApiResponse deleteTalkRoom(@PathVariable Long talkRoomId, @Auth Lon .build(); } + @GetMapping("/users/talk-rooms") + public ApiResponse findUserTalkRoom( + @RequestParam(value = "page", required = false, defaultValue = "1") Integer page, + @RequestParam(value = "size", required = false, defaultValue = "10") Integer size, + @RequestParam(value = "userTalkRoomsFilter", required = false) boolean userTalkRoomsFilter, + @RequestParam(value = "commentedFilter", required = false) boolean commentedFilter, + @RequestParam(value = "likedFilter", required = false) boolean likedFilter, + @Auth Long userId) { + return ApiResponse.ok( + talkRoomService.findUserTalkRoom(Offset.of(page, size), size, userTalkRoomsFilter, commentedFilter, + likedFilter, userId)); + } + } diff --git a/src/main/java/com/jisungin/application/comment/CommentFindAllResponse.java b/src/main/java/com/jisungin/application/comment/CommentFindAllResponse.java index 7c5cb30..48e39e4 100644 --- a/src/main/java/com/jisungin/application/comment/CommentFindAllResponse.java +++ b/src/main/java/com/jisungin/application/comment/CommentFindAllResponse.java @@ -49,7 +49,7 @@ public static List create(List com .content(comment.getContent()) .commentLikeCount(comment.getCommentLikeCount()) .commentImages(commentImageUrls) - .registeredDateTime(comment.getRegisteredDateTime()) + .registeredDateTime(comment.getRegisteredDateTime().withNano(0)) .build(); }) .collect(Collectors.toList()); diff --git a/src/main/java/com/jisungin/application/comment/CommentService.java b/src/main/java/com/jisungin/application/comment/CommentService.java index 034402c..11b2ac0 100644 --- a/src/main/java/com/jisungin/application/comment/CommentService.java +++ b/src/main/java/com/jisungin/application/comment/CommentService.java @@ -51,7 +51,8 @@ public CommentResponse writeComment(CommentCreateServiceRequest request, Long ta TalkRoom talkRoom = talkRoomRepository.findById(talkRoomId) .orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND)); - Optional userReadingStatus = userLibraryRepository.findByUserId(user.getId()); + Optional userReadingStatus = userLibraryRepository.findByUserId(user.getId(), + talkRoom.getBook().getIsbn()); List talkRoomReadingStatus = talkRoomRoleRepository.findTalkRoomRoleByTalkRoomId( talkRoom.getId()); @@ -66,6 +67,8 @@ public CommentResponse writeComment(CommentCreateServiceRequest request, Long ta request.getImageUrls().stream() .map(url -> CommentImage.createImages(comment, url)) .forEach(commentImageRepository::save); + } else { + commentImageRepository.save(CommentImage.createImages(comment, "")); } List imageUrls = commentImageRepository.findByCommentIdWithImageUrl(comment.getId()); diff --git a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java index 24f8aa8..8037aa9 100644 --- a/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java +++ b/src/main/java/com/jisungin/application/talkroom/TalkRoomService.java @@ -168,4 +168,29 @@ public void deleteTalkRoom(Long talkRoomId, Long userId) { talkRoomRepository.delete(talkRoom); } + public TalkRoomPageResponse findUserTalkRoom(Long offset, Integer size, boolean userTalkRoomsFilter, + boolean commentedFilter, + boolean likedFilter, + Long userId) { + User user = userRepository.findById(userId).orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); + + List findTalkRoom = talkRoomRepository.findByTalkRoomOwner(offset, size, + userTalkRoomsFilter, commentedFilter, + likedFilter, + user.getId()); + + Map> talkRoomRoleMap = talkRoomRoleRepository.findTalkRoomRoleByIds( + findTalkRoom.stream().map(TalkRoomQueryResponse::getId).toList()); + + List response = TalkRoomFindAllResponse.create(findTalkRoom, + talkRoomRoleMap); + + Long totalCount = talkRoomRepository.countTalkRoomsByUserId(user.getId(), userTalkRoomsFilter, commentedFilter, + likedFilter); + + List likeTalkRoomIds = talkRoomLikeRepository.userLikeTalkRooms(userId); + + return TalkRoomPageResponse.of(PageResponse.of(findTalkRoom.size(), totalCount, response), likeTalkRoomIds); + } + } diff --git a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java index 20b574d..4b27270 100644 --- a/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java +++ b/src/main/java/com/jisungin/application/talkroom/response/TalkRoomFindAllResponse.java @@ -62,7 +62,7 @@ public static List create(List t .bookThumbnail(talkRoom.getBookThumbnail()) .likeCount(talkRoom.getLikeCount()) .readingStatuses(talkRoomReadingStatus) - .registeredDateTime(talkRoom.getRegisteredDateTime()) + .registeredDateTime(talkRoom.getRegisteredDateTime().withNano(0)) .build(); }) .toList(); diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepository.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepository.java index be9e7b0..2771147 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepository.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepository.java @@ -18,4 +18,5 @@ public interface TalkRoomRepository extends JpaRepository, TalkR "select t from TalkRoom t join t.user u join t.book b where t.id = :talkRoomId" ) TalkRoom findByIdWithUserAndBook(@Param("talkRoomId") Long id); + } diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java index 46e08a1..9105b8b 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryCustom.java @@ -17,4 +17,9 @@ List findAllTalkRoom(long offset, int size, String order, TalkRoomQueryResponse findOneTalkRoom(Long talkRoomId); + List findByTalkRoomOwner(Long offset, Integer size, boolean userTalkRoomsFilter, + boolean commentFilter, + boolean likeFilter, Long id); + + Long countTalkRoomsByUserId(Long userId, boolean userTalkRoomsFilter, boolean commentFilter, boolean likeFilter); } diff --git a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java index ddee3ee..76bfa39 100644 --- a/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java +++ b/src/main/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryImpl.java @@ -83,7 +83,53 @@ public TalkRoomQueryResponse findOneTalkRoom(Long talkRoomId) { return findTalkRoomByTalkRoomId(talkRoomId); } + @Override + public List findByTalkRoomOwner(Long offset, Integer size, boolean userTalkRoomsFilter, + boolean commentFilter, + boolean likeFilter, Long userId) { + return queryFactory.select(new QTalkRoomQueryResponse( + talkRoom.id, + user.profileImage, + user.name.as("username"), + talkRoom.title, + talkRoom.content, + book.title.as("bookName"), + book.authors.as("bookAuthor"), + book.thumbnail.as("bookThumbnail"), + talkRoomLike.count().as("likeCount"), + talkRoom.registeredDateTime.as("registeredDateTime") + )) + .from(talkRoom) + .join(talkRoom.user, user) + .join(talkRoom.book, book) + .leftJoin(talkRoomLike).on(talkRoom.eq(talkRoomLike.talkRoom)) + .leftJoin(comment).on(talkRoom.eq(comment.talkRoom)) + .where(userTalkRoomEq(userTalkRoomsFilter, userId), commentEq(commentFilter, userId), + likeEq(likeFilter, userId)) + .groupBy(talkRoom.id) + .offset(offset) + .limit(size) + .orderBy(talkRoom.registeredDateTime.desc()) + .fetch(); + } + + @Override + public Long countTalkRoomsByUserId(Long userId, boolean userTalkRoomsFilter, boolean commentFilter, + boolean likeFilter) { + return queryFactory + .select(talkRoom.count()) + .from(talkRoom) + .join(talkRoom.book, book) + .leftJoin(talkRoomLike).on(talkRoom.eq(talkRoomLike.talkRoom)) + .leftJoin(comment).on(talkRoom.eq(comment.talkRoom)) + .join(talkRoom.user, user) + .where(userTalkRoomEq(userTalkRoomsFilter, userId), commentEq(commentFilter, userId), + likeEq(likeFilter, userId)) + .fetchOne(); + } + // 토크룸 페이징 조회 쿼리 + private List findTalkRoomBySearch(long offset, int size, String order, String search, String day, LocalDateTime now) { JPAQuery jpaQuery = queryFactory.select(new QTalkRoomQueryResponse( @@ -116,6 +162,18 @@ private List findTalkRoomBySearch(long offset, int size, return response; } + private BooleanExpression userTalkRoomEq(boolean userTalkRoomsFilter, Long userId) { + return userTalkRoomsFilter ? talkRoom.user.id.eq(userId) : null; + } + + private BooleanExpression commentEq(boolean commentFilter, Long userId) { + return commentFilter ? comment.user.id.eq(userId) : null; + } + + private BooleanExpression likeEq(boolean likeFilter, Long userId) { + return likeFilter ? talkRoomLike.user.id.eq(userId) : null; + } + private void addJoinByOrder(JPAQuery jpaQuery, OrderType orderType) { if (RECENT_COMMENT.equals(orderType)) { jpaQuery diff --git a/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepositoryCustom.java b/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepositoryCustom.java index ccdf86f..1a7ecd6 100644 --- a/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepositoryCustom.java +++ b/src/main/java/com/jisungin/domain/talkroomlike/repository/TalkRoomLikeRepositoryCustom.java @@ -1,5 +1,7 @@ package com.jisungin.domain.talkroomlike.repository; public interface TalkRoomLikeRepositoryCustom { + boolean existsTalkRoomLike(Long talkRoomId, Long userId); + } diff --git a/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepository.java b/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepository.java index a67a7e5..7bac095 100644 --- a/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepository.java +++ b/src/main/java/com/jisungin/domain/userlibrary/repository/UserLibraryRepository.java @@ -10,9 +10,9 @@ public interface UserLibraryRepository extends JpaRepository, UserLibraryRepositoryCustom { @Query( - "SELECT ul.status FROM UserLibrary ul JOIN ul.user u WHERE u.id = :id" + "SELECT ul.status FROM UserLibrary ul JOIN ul.user u JOIN ul.book b WHERE u.id = :id AND b.isbn = :isbn" ) - Optional findByUserId(@Param("id") Long userId); + Optional findByUserId(@Param("id") Long userId, @Param("isbn") String isbn); @Query( "SELECT ul FROM UserLibrary ul " diff --git a/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java b/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java index ee8e9b4..5e844ae 100644 --- a/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java +++ b/src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java @@ -223,4 +223,19 @@ void deleteTalkRoom() throws Exception { .andExpect(jsonPath("$.message").value("삭제 성공")); } + @Test + @DisplayName("유저가 생성한 토크방을 조회한다.") + void getTalkRoomsOwner() throws Exception { + // when // then + mockMvc.perform(get("/v1/users/talk-rooms?page=1&size=10&order=recent") + .contentType(APPLICATION_JSON) + .session(mockHttpSession) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value("200")) + .andExpect(jsonPath("$.status").value("OK")) + .andExpect(jsonPath("$.message").value("OK")); + } + } \ No newline at end of file diff --git a/src/test/java/com/jisungin/application/comment/CommentServiceTest.java b/src/test/java/com/jisungin/application/comment/CommentServiceTest.java index 9195afb..576e82c 100644 --- a/src/test/java/com/jisungin/application/comment/CommentServiceTest.java +++ b/src/test/java/com/jisungin/application/comment/CommentServiceTest.java @@ -118,7 +118,7 @@ void writeComment() { // then assertThat(response) .extracting("content", "userName", "imageUrls") - .contains("의견 남기기", "user@gmail.com", List.of()); + .contains("의견 남기기", "user@gmail.com", List.of("")); } @Test @@ -514,6 +514,7 @@ void findAllComments() throws Exception { .talkRoom(talkRoom) .user(user) .content("의견 " + i) + .registeredDateTime(LocalDateTime.now()) .build()) .collect(Collectors.toList()); @@ -553,6 +554,7 @@ void findAllCommentsWithImage() throws Exception { .talkRoom(talkRoom) .user(user) .content("의견 " + i) + .registeredDateTime(LocalDateTime.now()) .build()) .toList(); @@ -601,6 +603,7 @@ void findAllCommentsWithLike() throws Exception { .talkRoom(talkRoom) .user(user) .content("의견 " + i) + .registeredDateTime(LocalDateTime.now()) .build()) .collect(Collectors.toList()); @@ -652,6 +655,7 @@ private static TalkRoom createTalkRoom(Book book, User user) { .title("토크방") .content("내용") .user(user) + .registeredDateTime(LocalDateTime.now()) .build(); } diff --git a/src/test/java/com/jisungin/application/talkroom/TalkRoomServiceTest.java b/src/test/java/com/jisungin/application/talkroom/TalkRoomServiceTest.java index 44244cf..ba46af9 100644 --- a/src/test/java/com/jisungin/application/talkroom/TalkRoomServiceTest.java +++ b/src/test/java/com/jisungin/application/talkroom/TalkRoomServiceTest.java @@ -139,6 +139,37 @@ void createTalkRoomWithNotReadingStatus() { .hasMessage("참가 조건은 1개 이상이어야 합니다."); } + @Test + @DisplayName("토크방을 생성할 때 참가 조건이 None으로 생성할 수 있다.") + void createTalkRoomWithNone() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + List books = bookRepository.findAll(); + + TalkRoomCreateServiceRequest request = TalkRoomCreateServiceRequest.builder() + .bookIsbn(books.get(0).getIsbn()) + .title("토크방") + .content("내용") + .readingStatus(List.of("상관없음")) + .build(); + + // when + TalkRoomFindOneResponse response = talkRoomService.createTalkRoom(request, user.getId(), LocalDateTime.now()); + + // then + List readingStatuses = response.getReadingStatuses(); + assertThat(response) + .extracting("id", "profileImage", "username", "title", "content", "bookName", "bookThumbnail", + "likeCount", "likeTalkRoom") + .contains(response.getId(), "image", "user@gmail.com", "토크방", "내용", "제목", "이미지", 0L, false); + assertThat(readingStatuses.size()).isEqualTo(1); + } + @Test @DisplayName("토크방을 생성했던 사용자가 토크방의 제목을 수정한다.") void editTalkRoom() { @@ -779,6 +810,7 @@ void findAllTalkRoomWithSearch() { .book(book) .title("검색어") .content("내용") + .registeredDateTime(LocalDateTime.now()) .build(); TalkRoom talkRoom2 = TalkRoom.builder() @@ -786,6 +818,7 @@ void findAllTalkRoomWithSearch() { .book(book) .title("아무내용 검색어 아무내용") .content("내용") + .registeredDateTime(LocalDateTime.now()) .build(); TalkRoom talkRoom3 = TalkRoom.builder() @@ -793,6 +826,7 @@ void findAllTalkRoomWithSearch() { .book(book) .title("아무내용 아무내용 검색어") .content("내용") + .registeredDateTime(LocalDateTime.now()) .build(); talkRoomRepository.save(talkRoom1); @@ -948,6 +982,207 @@ void findAllTalkRoomWithDay() throws Exception { assertThat(15L).isEqualTo(talkRoomAll.size()); } + @Test + @DisplayName("유저 본인이 생성한 토론방을 조회 한다.") + void getTalkRoomsOwner() { + // given + User user1 = createUser(); + userRepository.save(user1); + + User user2 = User.builder() + .email("user2@gmail.com") + .name("userB") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .profileImage("sssss") + .build(); + + userRepository.save(user2); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom1 = listTalkRooms(10, user1, book); + List talkRoom2 = listTalkRooms(10, user2, book); + + talkRoomRepository.saveAll(talkRoom1); + talkRoomRepository.saveAll(talkRoom2); + + for (TalkRoom t : talkRoom1) { + createTalkRoomRole(t); + } + + for (TalkRoom t : talkRoom2) { + createTalkRoomRole(t); + } + + // when + TalkRoomPageResponse response = talkRoomService.findUserTalkRoom(Offset.of(1, 10), 10, true, false, false, + user1.getId()); + + // then + assertThat(10).isEqualTo(response.getResponse().getTotalCount()); + assertThat(20).isEqualTo(talkRoomRepository.findAll().size()); + } + + @Test + @DisplayName("유저 본인이 생성한 토크방 중 좋아요 누른 토크방을 조회한다.") + void getTalkRoomsOwnerWithLike() { + // given + User user1 = createUser(); + userRepository.save(user1); + + User user2 = User.builder() + .email("user2@gmail.com") + .name("userB") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .profileImage("sssss") + .build(); + + userRepository.save(user2); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom1 = listTalkRooms(10, user1, book); + List talkRoom2 = listTalkRooms(10, user2, book); + + talkRoomRepository.saveAll(talkRoom1); + talkRoomRepository.saveAll(talkRoom2); + + for (TalkRoom t : talkRoom1) { + createTalkRoomRole(t); + } + + for (TalkRoom t : talkRoom2) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5).mapToObj(i -> TalkRoomLike.builder() + .user(user1) + .talkRoom(talkRoom1.get(i)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomPageResponse response = talkRoomService.findUserTalkRoom(Offset.of(1, 10), 10, true, false, true, + user1.getId()); + + // then + assertThat(5).isEqualTo(response.getResponse().getTotalCount()); + assertThat(20).isEqualTo(talkRoomRepository.findAll().size()); + } + + @Test + @DisplayName("유저가 좋아요 누른 토크방을 조회한다.") + void getTalkRoomsWithLike() { + // given + User user1 = createUser(); + userRepository.save(user1); + + User user2 = User.builder() + .email("user2@gmail.com") + .name("userB") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .profileImage("sssss") + .build(); + + userRepository.save(user2); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom2 = listTalkRooms(10, user2, book); + + talkRoomRepository.saveAll(talkRoom2); + + for (TalkRoom t : talkRoom2) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 8).mapToObj(i -> TalkRoomLike.builder() + .user(user1) + .talkRoom(talkRoom2.get(i)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + TalkRoomPageResponse response = talkRoomService.findUserTalkRoom(Offset.of(1, 10), 10, false, false, true, + user1.getId()); + + // then + assertThat(8).isEqualTo(response.getResponse().getTotalCount()); + assertThat(10).isEqualTo(talkRoomRepository.findAll().size()); + } + + @Test + @DisplayName("유저가 좋아요 누른 토크방을 조회한다.") + void getTalkRoomsWithComment() { + // given + User user1 = createUser(); + userRepository.save(user1); + + User user2 = User.builder() + .email("user2@gmail.com") + .name("userB") + .oauthId( + OauthId.builder() + .oauthId("oauthId2") + .oauthType(OauthType.KAKAO) + .build() + ) + .profileImage("sssss") + .build(); + + userRepository.save(user2); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = listTalkRooms(10, user2, book); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 8).mapToObj(i -> Comment.builder() + .user(user1) + .talkRoom(talkRoom.get(i)) + .content("의견") + .build()) + .toList(); + + commentRepository.saveAll(comments); + + // when + TalkRoomPageResponse response = talkRoomService.findUserTalkRoom(Offset.of(1, 10), 10, false, true, false, + user1.getId()); + + // then + assertThat(8).isEqualTo(response.getResponse().getTotalCount()); + assertThat(10).isEqualTo(talkRoomRepository.findAll().size()); + } + private static List listUsers() { return IntStream.range(0, 10) .mapToObj(i -> User.builder() @@ -969,6 +1204,7 @@ private static List listTalkRooms(int endExclusive, User users, Book b .book(book) .title("토론방 " + i) .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) .build()) .toList(); } @@ -998,6 +1234,7 @@ private static TalkRoom createTalkRoom(Book book, User user) { .title("토크방") .content("내용") .user(user) + .registeredDateTime(LocalDateTime.now()) .build(); } diff --git a/src/test/java/com/jisungin/docs/talkroom/TalkRoomControllerDocsTest.java b/src/test/java/com/jisungin/docs/talkroom/TalkRoomControllerDocsTest.java index 6acefe6..6c939b0 100644 --- a/src/test/java/com/jisungin/docs/talkroom/TalkRoomControllerDocsTest.java +++ b/src/test/java/com/jisungin/docs/talkroom/TalkRoomControllerDocsTest.java @@ -1,6 +1,7 @@ package com.jisungin.docs.talkroom; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; @@ -395,6 +396,101 @@ void deleteTalkRoom() throws Exception { )); } + @Test + @DisplayName("유저 본인이 작성한 토론방 조회 API") + void findAllTalkRoomsOwner() throws Exception { + List talkRoomFindAllResponses = createTalkRoomFindAllResponses(); + + PageResponse pageResponse = PageResponse.builder() + .queryResponse(talkRoomFindAllResponses) + .size(10) + .totalCount(10) + .build(); + + TalkRoomPageResponse response = TalkRoomPageResponse.builder() + .response(pageResponse) + .userLikeTalkRoomIds(null) + .build(); + + given(talkRoomService.findUserTalkRoom(anyLong(), any(Integer.class), anyBoolean(), anyBoolean(), anyBoolean(), + anyLong())) + .willReturn(response); + + mockMvc.perform( + get("/v1/users/talk-rooms") + .param("page", "1") + .param("size", "10") + .param("userTalkRoomsFilter", "true") + .param("commentFilter", "false") + .param("likeFilter", "false") + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isOk()) + .andDo(document("talkroom/findUserTalkRoom", + preprocessRequest(prettyPrint()), + preprocessResponse(prettyPrint()), + queryParameters( + parameterWithName("page") + .description("페이지 번호"), + parameterWithName("size") + .description("페이지 사이즈"), + parameterWithName("userTalkRoomsFilter") + .description("내가 작성한 토크방인 경우 true, 아닌 경우 false"), + parameterWithName("commentFilter") + .description( + "내가 작성한 토크방에 의견을 단 경우 true, 아닌 경우 false"), + parameterWithName("likeFilter") + .description("내가 작성한 토크방에 좋아요를 누른 경우 true, 아닌 경우 false") + ), + 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.userLikeTalkRoomIds").type(JsonFieldType.ARRAY) + .description("로그인한 유저가 좋아요 누른 토론방 ID").optional(), + fieldWithPath("data.response").type(JsonFieldType.OBJECT) + .description("토론방과 관련된 데이터"), + fieldWithPath("data.response.totalCount").type(JsonFieldType.NUMBER) + .description("토론방 총 개수"), + fieldWithPath("data.response.size").type(JsonFieldType.NUMBER) + .description("토론방 반환 사이즈"), + fieldWithPath("data.response.queryResponse").type(JsonFieldType.ARRAY) + .description("토론방 데이터"), + fieldWithPath("data.response.queryResponse[].id").type(JsonFieldType.NUMBER) + .description("토론방 ID"), + fieldWithPath("data.response.queryResponse[].profileImage").type(JsonFieldType.STRING) + .description("유저 이미지 URL"), + fieldWithPath("data.response.queryResponse[].username").type(JsonFieldType.STRING) + .description("유저 이름"), + fieldWithPath("data.response.queryResponse[].title").type(JsonFieldType.STRING) + .description("토론방 제목"), + fieldWithPath("data.response.queryResponse[].content").type(JsonFieldType.STRING) + .description("토론방 본문"), + fieldWithPath("data.response.queryResponse[].bookName").type(JsonFieldType.STRING) + .description("책 제목"), + fieldWithPath("data.response.queryResponse[].bookAuthor").type(JsonFieldType.STRING) + .description("책 저자"), + fieldWithPath("data.response.queryResponse[].bookThumbnail").type(JsonFieldType.STRING) + .description("책 이미지 URL"), + fieldWithPath("data.response.queryResponse[].likeCount").type(JsonFieldType.NUMBER) + .description("토론방 좋아요 개수"), + fieldWithPath("data.response.queryResponse[].readingStatuses").type(JsonFieldType.ARRAY) + .description("토론방 참가 조건"), + fieldWithPath("data.response.queryResponse[].registeredDateTime").type( + JsonFieldType.ARRAY) + .description("토론방 생성 시간") + + ) + )); + + } + private List createTalkRoomFindAllResponses() { return IntStream.range(1, 11) .mapToObj(i -> TalkRoomFindAllResponse.builder() diff --git a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java index 90df6ab..b339f4f 100644 --- a/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java +++ b/src/test/java/com/jisungin/domain/talkroom/repository/TalkRoomRepositoryTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.groups.Tuple.tuple; import com.jisungin.RepositoryTestSupport; +import com.jisungin.api.Offset; import com.jisungin.application.SearchServiceRequest; import com.jisungin.application.talkroom.response.TalkRoomQueryResponse; import com.jisungin.domain.ReadingStatus; @@ -12,12 +13,12 @@ import com.jisungin.domain.comment.Comment; import com.jisungin.domain.comment.repository.CommentRepository; import com.jisungin.domain.commentlike.repository.CommentLikeRepository; -import com.jisungin.domain.user.OauthId; -import com.jisungin.domain.user.OauthType; import com.jisungin.domain.talkroom.TalkRoom; import com.jisungin.domain.talkroom.TalkRoomRole; import com.jisungin.domain.talkroomlike.TalkRoomLike; import com.jisungin.domain.talkroomlike.repository.TalkRoomLikeRepository; +import com.jisungin.domain.user.OauthId; +import com.jisungin.domain.user.OauthType; import com.jisungin.domain.user.User; import com.jisungin.domain.user.repository.UserRepository; import java.time.LocalDateTime; @@ -716,6 +717,237 @@ void findAllTalkRoomWithMonth() throws Exception { assertThat("내용 14").isEqualTo(response.get(0).getContent()); } + @Test + @DisplayName("querydsl 필터 적용 테스트 -> 의견을 남긴") + void filterWithComment() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(user) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 2) + .mapToObj(i -> Comment.builder() + .user(user) + .talkRoom(talkRoom.get(i)) + .content("의견") + .build()) + .toList(); + + commentRepository.saveAll(comments); + + // when + List response = talkRoomRepository.findByTalkRoomOwner(Offset.of(0, 10), 10, true, true, + false, + user.getId()); + + // then + assertThat(2L).isEqualTo(response.size()); + assertThat("토론방 1").isEqualTo(response.get(0).getTitle()); + assertThat("토론방 0").isEqualTo(response.get(1).getTitle()); + } + + @Test + @DisplayName("querydsl 필터 적용 테스트 -> 좋아요") + void filterWithLike() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(user) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 2) + .mapToObj(i -> TalkRoomLike.builder() + .user(user) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + List response = talkRoomRepository.findByTalkRoomOwner(Offset.of(0, 10), 10, true, false, + true, + user.getId()); + + // then + assertThat(2L).isEqualTo(response.size()); + assertThat("토론방 1").isEqualTo(response.get(0).getTitle()); + assertThat("토론방 0").isEqualTo(response.get(1).getTitle()); + } + + @Test + @DisplayName("querydsl 필터 적용 테스트 -> 의견을 남기고 좋아요를 누른 경우") + void filterWithCommentAndLike() { + // given + User user = createUser(); + userRepository.save(user); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 20) + .mapToObj(i -> TalkRoom.builder() + .user(user) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + List comments = IntStream.range(0, 5) + .mapToObj(i -> Comment.builder() + .user(user) + .talkRoom(talkRoom.get(i)) + .content("의견") + .build()) + .toList(); + + commentRepository.saveAll(comments); + + List likes = IntStream.range(0, 7) + .mapToObj(i -> TalkRoomLike.builder() + .user(user) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + talkRoomLikeRepository.saveAll(likes); + + // when + List response = talkRoomRepository.findByTalkRoomOwner(Offset.of(0, 10), 10, true, true, + true, + user.getId()); + + // then + assertThat(5L).isEqualTo(response.size()); + } + + @Test + @DisplayName("querydsl 필터 적용 테스트 -> 좋아요") + void filterWithLike2() { + // given + User user = createUser(); + userRepository.save(user); + + User user1 = User.builder() + .name("user1") + .email("user1") + .oauthId( + OauthId.builder() + .oauthId("oauthId1") + .oauthType(OauthType.KAKAO) + .build() + ) + .profileImage("image") + .build(); + + userRepository.save(user1); + + Book book = createBook(); + bookRepository.save(book); + + List talkRoom = IntStream.range(0, 5) + .mapToObj(i -> TalkRoom.builder() + .user(user) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom); + + List talkRoom1 = IntStream.range(5, 10) + .mapToObj(i -> TalkRoom.builder() + .user(user1) + .book(book) + .title("토론방 " + i) + .content("내용 " + i) + .registeredDateTime(LocalDateTime.now()) + .build()) + .toList(); + + talkRoomRepository.saveAll(talkRoom1); + + for (TalkRoom t : talkRoom) { + createTalkRoomRole(t); + } + + for (TalkRoom t : talkRoom1) { + createTalkRoomRole(t); + } + + List likes = IntStream.range(0, 5) + .mapToObj(i -> TalkRoomLike.builder() + .user(user) + .talkRoom(talkRoom.get(i)) + .build()) + .toList(); + + List likes1 = IntStream.range(0, 5) + .mapToObj(i -> TalkRoomLike.builder() + .user(user) + .talkRoom(talkRoom1.get(i)) + .build()) + .toList(); + talkRoomLikeRepository.saveAll(likes); + talkRoomLikeRepository.saveAll(likes1); + // when + List response = talkRoomRepository.findByTalkRoomOwner(Offset.of(0, 10), 10, false, + false, + true, + user.getId()); + + List all = talkRoomLikeRepository.findAll(); + // then + assertThat(10L).isEqualTo(response.size()); + assertThat("토론방 9").isEqualTo(response.get(0).getTitle()); + assertThat("토론방 8").isEqualTo(response.get(1).getTitle()); + } + private static Comment createComment(TalkRoom talkRoom, User user) { return Comment.builder() .talkRoom(talkRoom)