Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] TalkRoom 단건 조회 API 구현 #35

Merged
merged 2 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/main/java/com/jisungin/api/talkroom/TalkRoomController.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@
import com.jisungin.api.talkroom.request.TalkRoomSearchRequest;
import com.jisungin.application.response.PageResponse;
import com.jisungin.application.talkroom.TalkRoomService;
import com.jisungin.application.talkroom.response.TalkRoomQueryResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse;
import com.jisungin.application.talkroom.response.TalkRoomResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
Expand All @@ -35,8 +37,14 @@ public ApiResponse<TalkRoomResponse> createTalkRoom(@Valid @RequestBody TalkRoom
}

@GetMapping("/talk-rooms")
public ApiResponse<PageResponse<TalkRoomQueryResponse>> getTalkRooms(@ModelAttribute TalkRoomSearchRequest search) {
return ApiResponse.ok(talkRoomService.getTalkRooms(search.toService()));
public ApiResponse<PageResponse<TalkRoomFindAllResponse>> findAllTalkRoom(
@ModelAttribute TalkRoomSearchRequest search) {
return ApiResponse.ok(talkRoomService.findAllTalkRoom(search.toService()));
}

@GetMapping("/talk-room/{talkRoomId}")
public ApiResponse<TalkRoomFindOneResponse> findOneTalkRoom(@PathVariable Long talkRoomId) {
return ApiResponse.ok(talkRoomService.findOneTalkRoom(talkRoomId));
}

@PatchMapping("/talk-rooms")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import com.jisungin.application.talkroom.request.TalkRoomCreateServiceRequest;
import com.jisungin.application.talkroom.request.TalkRoomEditServiceRequest;
import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest;
import com.jisungin.application.talkroom.response.TalkRoomQueryResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse;
import com.jisungin.application.talkroom.response.TalkRoomResponse;
import com.jisungin.domain.ReadingStatus;
import com.jisungin.domain.book.Book;
Expand Down Expand Up @@ -52,15 +53,22 @@ public TalkRoomResponse createTalkRoom(TalkRoomCreateServiceRequest request, Lon
book.getImageUrl(), book.getTitle());
}

public PageResponse<TalkRoomQueryResponse> getTalkRooms(TalkRoomSearchServiceRequest search) {
return talkRoomRepository.getTalkRooms(search);
public PageResponse<TalkRoomFindAllResponse> findAllTalkRoom(TalkRoomSearchServiceRequest search) {
return talkRoomRepository.findAllTalkRoom(search);
}

public TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId) {
TalkRoom talkRoom = talkRoomRepository.findById(talkRoomId)
.orElseThrow(() -> new BusinessException(ErrorCode.TALK_ROOM_NOT_FOUND));

return talkRoomRepository.findOneTalkRoom(talkRoom.getId());
}

@Transactional
public TalkRoomResponse editTalkRoom(TalkRoomEditServiceRequest request, Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND));

TalkRoom talkRoom = talkRoomRepository.findByIdWithUserAndBook(request.getId());

if (!talkRoom.isTalkRoomOwner(user.getId())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

@Getter
@NoArgsConstructor
public class TalkRoomQueryResponse {
public class TalkRoomFindAllResponse {

private Long talkRoomId;
private String userName;
Expand All @@ -21,8 +21,8 @@ public class TalkRoomQueryResponse {

@Builder
@QueryProjection
public TalkRoomQueryResponse(Long talkRoomId, String userName, String title, String content, String bookName,
String bookImage) {
public TalkRoomFindAllResponse(Long talkRoomId, String userName, String title, String content, String bookName,
String bookImage) {
this.talkRoomId = talkRoomId;
this.userName = userName;
this.title = title;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.jisungin.application.talkroom.response;

import com.querydsl.core.annotations.QueryProjection;
import java.util.ArrayList;
import java.util.List;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class TalkRoomFindOneResponse {

private Long talkRoomId;
private String userName;
private String title;
private String content;
private String bookName;
private String bookImage;
private List<TalkRoomQueryReadingStatus> readingStatuses = new ArrayList<>();
private List<TalkRoomQueryComments> comments = new ArrayList<>();

@Builder
@QueryProjection
public TalkRoomFindOneResponse(Long talkRoomId, String userName, String title, String content, String bookName,
String bookImage) {
this.talkRoomId = talkRoomId;
this.userName = userName;
this.title = title;
this.content = content;
this.bookName = bookName;
this.bookImage = bookImage;
}

public void addTalkRoomStatus(List<TalkRoomQueryReadingStatus> readingStatuses) {
this.readingStatuses = readingStatuses;
}

public void addTalkRoomComments(List<TalkRoomQueryComments> comments) {
this.comments = comments;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.jisungin.application.talkroom.response;

import com.querydsl.core.annotations.QueryProjection;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
public class TalkRoomQueryComments {

private Long commentId;
private String userName;
private String content;

@Builder
@QueryProjection
public TalkRoomQueryComments(Long commentId, String userName, String content) {
this.commentId = commentId;
this.userName = userName;
this.content = content;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import com.jisungin.application.response.PageResponse;
import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest;
import com.jisungin.application.talkroom.response.TalkRoomQueryResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse;

public interface TalkRoomRepositoryCustom {

PageResponse<TalkRoomQueryResponse> getTalkRooms(TalkRoomSearchServiceRequest search);
PageResponse<TalkRoomFindAllResponse> findAllTalkRoom(TalkRoomSearchServiceRequest search);

TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId);
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
package com.jisungin.domain.talkroom.repository;

import static com.jisungin.domain.book.QBook.book;
import static com.jisungin.domain.comment.QComment.comment;
import static com.jisungin.domain.talkroom.QTalkRoom.talkRoom;
import static com.jisungin.domain.talkroom.QTalkRoomRole.talkRoomRole;
import static com.jisungin.domain.user.QUser.user;

import com.jisungin.application.response.PageResponse;
import com.jisungin.application.talkroom.request.TalkRoomSearchServiceRequest;
import com.jisungin.application.talkroom.response.QTalkRoomFindAllResponse;
import com.jisungin.application.talkroom.response.QTalkRoomFindOneResponse;
import com.jisungin.application.talkroom.response.QTalkRoomQueryComments;
import com.jisungin.application.talkroom.response.QTalkRoomQueryReadingStatus;
import com.jisungin.application.talkroom.response.QTalkRoomQueryResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindAllResponse;
import com.jisungin.application.talkroom.response.TalkRoomFindOneResponse;
import com.jisungin.application.talkroom.response.TalkRoomQueryComments;
import com.jisungin.application.talkroom.response.TalkRoomQueryReadingStatus;
import com.jisungin.application.talkroom.response.TalkRoomQueryResponse;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.jpa.impl.JPAQueryFactory;
import java.util.List;
Expand All @@ -24,10 +29,10 @@ public class TalkRoomRepositoryImpl implements TalkRoomRepositoryCustom {
private final JPAQueryFactory queryFactory;

@Override
public PageResponse<TalkRoomQueryResponse> getTalkRooms(TalkRoomSearchServiceRequest search) {
public PageResponse<TalkRoomFindAllResponse> findAllTalkRoom(TalkRoomSearchServiceRequest search) {

//루트 조회(toOne 코드를 모두 한번에 조회)
List<TalkRoomQueryResponse> findTalkRoom = findTalkRoom(search);
List<TalkRoomFindAllResponse> findTalkRoom = findTalkRoomBySearch(search);

//TalkRoomRole 컬렉션을 MAP 한방에 조회
Map<Long, List<TalkRoomQueryReadingStatus>> talkRoomRoleMap = findTalkRoomRoleMap(toTalkRoomIds(findTalkRoom));
Expand All @@ -37,14 +42,52 @@ public PageResponse<TalkRoomQueryResponse> getTalkRooms(TalkRoomSearchServiceReq

long totalCount = getTotalTalkRoomCount();

return PageResponse.<TalkRoomQueryResponse>builder()
return PageResponse.<TalkRoomFindAllResponse>builder()
.queryResponse(findTalkRoom)
.totalCount(totalCount)
.size(search.getSize())
.build();
}

private List<Long> toTalkRoomIds(List<TalkRoomQueryResponse> findTalkRoom) {
@Override
public TalkRoomFindOneResponse findOneTalkRoom(Long talkRoomId) {
TalkRoomFindOneResponse findOneTalkRoom = findTalkRoomByTalkRoomId(talkRoomId);

List<TalkRoomQueryReadingStatus> talkRoomRoles = findTalkRoomRoleByTalkRoomId(talkRoomId);
findOneTalkRoom.addTalkRoomStatus(talkRoomRoles);

List<TalkRoomQueryComments> talkRoomComments = findCommentsByTalkRoomId(talkRoomId);
findOneTalkRoom.addTalkRoomComments(talkRoomComments);

return findOneTalkRoom;

}

private List<TalkRoomQueryComments> findCommentsByTalkRoomId(Long talkRoomId) {
return queryFactory.select(new QTalkRoomQueryComments(
comment.id.as("commentId"),
user.name.as("userName"),
comment.content
))
.from(comment)
.join(comment.talkRoom, talkRoom)
.join(comment.user, user)
.where(comment.talkRoom.id.eq(talkRoomId))
.fetch();
}

private List<TalkRoomQueryReadingStatus> findTalkRoomRoleByTalkRoomId(Long talkRoomId) {
return queryFactory.select(new QTalkRoomQueryReadingStatus(
talkRoom.id,
talkRoomRole.readingStatus
))
.from(talkRoomRole)
.join(talkRoomRole.talkRoom, talkRoom)
.where(talkRoomRole.talkRoom.id.eq(talkRoomId))
.fetch();
}

private List<Long> toTalkRoomIds(List<TalkRoomFindAllResponse> findTalkRoom) {
return findTalkRoom.stream()
.map(t -> t.getTalkRoomId())
.collect(Collectors.toList());
Expand Down Expand Up @@ -73,8 +116,8 @@ private long getTotalTalkRoomCount() {
.fetchOne();
}

private List<TalkRoomQueryResponse> findTalkRoom(TalkRoomSearchServiceRequest search) {
return queryFactory.select(new QTalkRoomQueryResponse(
private List<TalkRoomFindAllResponse> findTalkRoomBySearch(TalkRoomSearchServiceRequest search) {
return queryFactory.select(new QTalkRoomFindAllResponse(
talkRoom.id.as("talkRoomId"),
user.name.as("userName"),
talkRoom.title,
Expand All @@ -91,6 +134,22 @@ private List<TalkRoomQueryResponse> findTalkRoom(TalkRoomSearchServiceRequest se
.fetch();
}

private TalkRoomFindOneResponse findTalkRoomByTalkRoomId(Long talkRoomId) {
return queryFactory.select(new QTalkRoomFindOneResponse(
talkRoom.id.as("talkRoomId"),
user.name.as("userName"),
talkRoom.title,
talkRoom.content,
book.title,
book.imageUrl.as("bookImage")
))
.from(talkRoom)
.join(talkRoom.user, user)
.join(talkRoom.book, book)
.where(talkRoom.id.eq(talkRoomId))
.fetchOne();
}

/**
* 아직 좋아요 기능이 구현 되지 않아 최신순으로만 정렬
*/
Expand Down
11 changes: 11 additions & 0 deletions src/test/java/com/jisungin/RepositoryTestSupport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.jisungin;

import com.jisungin.config.QueryDslConfig;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;

@DataJpaTest
@Import(QueryDslConfig.class)
public abstract class RepositoryTestSupport {

}
Comment on lines +7 to +11
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repository 테스트에 @Import(QueryDslConfig.class)를 적용하셨군요.
그래서 @DataJpaTest로 QueryDSL을 테스트 할 수 있는 건가요 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네네 !
@DataJpaTest 를 사용하게 되면 Bean 등록이 안되어 있어서 수동으로 등록해야 Bean에 등록이 되더라구요!

57 changes: 13 additions & 44 deletions src/test/java/com/jisungin/api/talkroom/TalkRoomControllerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,49 +174,18 @@ void getTalkRoomsEmpty() throws Exception {
.andExpect(jsonPath("$.message").value("OK"));
}

// private void createTalkRoomRole(TalkRoom talkRoom) {
// List<String> request = new ArrayList<>();
// request.add("읽는 중");
// request.add("읽음");
//
// List<ReadingStatus> readingStatus = ReadingStatus.createReadingStatus(request);
//
// readingStatus.stream().map(status -> TalkRoomRole.roleCreate(talkRoom, status))
// .forEach(talkRoomRoleRepository::save);
// }
//
// private static TalkRoom createTalkRoom(Book book, User user) {
// return TalkRoom.builder()
// .book(book)
// .title("토크방")
// .content("내용")
// .user(user)
// .build();
// }
//
// private static User createUser() {
// return User.builder()
// .name("[email protected]")
// .profileImage("image")
// .oauthId(
// OauthId.builder()
// .oauthId("oauthId")
// .oauthType(OauthType.KAKAO)
// .build()
// )
// .build();
// }
//
// private static Book createBook() {
// return Book.builder()
// .title("제목")
// .content("내용")
// .authors("작가")
// .isbn("11111")
// .publisher("publisher")
// .dateTime(LocalDateTime.now())
// .imageUrl("www")
// .build();
// }
@Test
@DisplayName("토크방 단건 조회를 한다.")
void findOneTalkRoom() throws Exception {
// when // then
mockMvc.perform(get("/v1/talk-room/1")
.contentType(APPLICATION_JSON)
)
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value("200"))
.andExpect(jsonPath("$.status").value("OK"))
.andExpect(jsonPath("$.message").value("OK"));
}

}
Loading
Loading