diff --git a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java index 842b70fc..fed5fe37 100644 --- a/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java +++ b/src/main/java/com/dnd/gongmuin/chat/controller/ChatRoomController.java @@ -1,7 +1,5 @@ package com.dnd.gongmuin.chat.controller; -import java.util.List; - import org.springframework.data.domain.Pageable; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -10,12 +8,12 @@ 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.AcceptChatResponse; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatProposalResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomSimpleResponse; import com.dnd.gongmuin.chat.dto.response.CreateChatRoomResponse; @@ -57,15 +55,25 @@ public ResponseEntity createChatRoom( return ResponseEntity.ok(response); } - @Operation(summary = "채팅방 목록 조회 API", description = "회원의 채팅방 목록을 조회한다.") + @Operation(summary = "채팅방 활성화 목록 조회 API", description = "회원의 채팅방 목록을 조회한다.") @GetMapping("/api/chat-rooms") public ResponseEntity> getChatRoomsByMember( - @RequestParam("statuses") List statuses, @AuthenticationPrincipal Member member, Pageable pageable ) { - PageResponse response = chatRoomService.getChatRoomsByMember(member, statuses, - pageable); + PageResponse response + = chatRoomService.getChatRoomsByMember(member, pageable); + return ResponseEntity.ok(response); + } + + @Operation(summary = "채팅방 요청 목록 조회 API", description = "회원의 채팅방 목록을 조회한다.") + @GetMapping("/api/chat-rooms/proposals") + public ResponseEntity> getChatProposalsByMember( + @AuthenticationPrincipal Member member, + Pageable pageable + ) { + PageResponse response + = chatRoomService.getChatProposalsByMember(member, pageable); return ResponseEntity.ok(response); } diff --git a/src/main/java/com/dnd/gongmuin/chat/domain/ChatStatus.java b/src/main/java/com/dnd/gongmuin/chat/domain/ChatStatus.java index 644a4bcc..beef2fbe 100644 --- a/src/main/java/com/dnd/gongmuin/chat/domain/ChatStatus.java +++ b/src/main/java/com/dnd/gongmuin/chat/domain/ChatStatus.java @@ -1,7 +1,6 @@ package com.dnd.gongmuin.chat.domain; import java.util.Arrays; -import java.util.List; import com.dnd.gongmuin.chat.exception.ChatErrorCode; import com.dnd.gongmuin.common.exception.runtime.ValidationException; @@ -26,15 +25,6 @@ public static ChatStatus from(String input) { .orElseThrow(() -> new ValidationException(ChatErrorCode.NOT_FOUND_CHAT_STATUS)); } - public static List from(List inputs) { - return inputs.stream() - .map(input -> Arrays.stream(ChatStatus.values()) - .filter(status -> status.isEqual(input)) - .findAny() - .orElseThrow(() -> new ValidationException(ChatErrorCode.NOT_FOUND_CHAT_STATUS))) - .toList(); - } - private boolean isEqual(String input) { return input.equals(this.label); } diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java b/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java index 173cc9ae..a759af5a 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/ChatRoomMapper.java @@ -2,6 +2,8 @@ import com.dnd.gongmuin.chat.domain.ChatRoom; import com.dnd.gongmuin.chat.dto.response.AcceptChatResponse; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; +import com.dnd.gongmuin.chat.dto.response.ChatProposalResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomSimpleResponse; @@ -90,7 +92,6 @@ public static ChatRoomSimpleResponse toChatRoomSimpleResponse( ) { return new ChatRoomSimpleResponse( chatRoomInfo.chatRoomId(), - chatRoomInfo.chatStatus(), new MemberInfo( chatRoomInfo.partnerId(), chatRoomInfo.partnerNickname(), @@ -103,4 +104,24 @@ public static ChatRoomSimpleResponse toChatRoomSimpleResponse( ); } + public static ChatProposalResponse toChatProposalResponse( + ChatProposalInfo chatProposalInfo, + LatestChatMessage latestChatMessage + ) { + return new ChatProposalResponse( + chatProposalInfo.chatRoomId(), + chatProposalInfo.chatStatus(), + chatProposalInfo.isInquirer(), + new MemberInfo( + chatProposalInfo.partnerId(), + chatProposalInfo.partnerNickname(), + chatProposalInfo.partnerJobGroup(), + chatProposalInfo.partnerProfileImageNo() + ), + latestChatMessage.content(), + latestChatMessage.type(), + latestChatMessage.createdAt().toString() + ); + } + } diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalInfo.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalInfo.java new file mode 100644 index 00000000..4fbe75d4 --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalInfo.java @@ -0,0 +1,36 @@ +package com.dnd.gongmuin.chat.dto.response; + +import com.dnd.gongmuin.chat.domain.ChatStatus; +import com.dnd.gongmuin.member.domain.JobGroup; +import com.querydsl.core.annotations.QueryProjection; + +public record ChatProposalInfo( + Long chatRoomId, + String chatStatus, + boolean isInquirer, + Long partnerId, + String partnerNickname, + String partnerJobGroup, + int partnerProfileImageNo +) { + @QueryProjection + public ChatProposalInfo( + Long chatRoomId, + ChatStatus chatStatus, + boolean isInquirer, + Long partnerId, + String partnerNickname, + JobGroup partnerJobGroup, + int partnerProfileImageNo + ) { + this( + chatRoomId, + chatStatus.getLabel(), + isInquirer, + partnerId, + partnerNickname, + partnerJobGroup.getLabel(), + partnerProfileImageNo + ); + } +} diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalResponse.java new file mode 100644 index 00000000..7dc09842 --- /dev/null +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatProposalResponse.java @@ -0,0 +1,13 @@ +package com.dnd.gongmuin.chat.dto.response; + +import com.dnd.gongmuin.question_post.dto.response.MemberInfo; + +public record ChatProposalResponse ( + Long chatRoomId, + String chatStatus, + boolean isInquirer, + MemberInfo chatPartner, + String latestMessage, + String messageType, + String messageCreatedAt +){} diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomInfo.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomInfo.java index 676209f4..52bc26f3 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomInfo.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomInfo.java @@ -1,12 +1,10 @@ package com.dnd.gongmuin.chat.dto.response; -import com.dnd.gongmuin.chat.domain.ChatStatus; import com.dnd.gongmuin.member.domain.JobGroup; import com.querydsl.core.annotations.QueryProjection; public record ChatRoomInfo( Long chatRoomId, - String chatStatus, Long partnerId, String partnerNickname, String partnerJobGroup, @@ -15,7 +13,6 @@ public record ChatRoomInfo( @QueryProjection public ChatRoomInfo( Long chatRoomId, - ChatStatus chatStatus, Long partnerId, String partnerNickname, JobGroup partnerJobGroup, @@ -23,7 +20,6 @@ public ChatRoomInfo( ) { this( chatRoomId, - chatStatus.getLabel(), partnerId, partnerNickname, partnerJobGroup.getLabel(), diff --git a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomSimpleResponse.java b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomSimpleResponse.java index bc33d049..136b893c 100644 --- a/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomSimpleResponse.java +++ b/src/main/java/com/dnd/gongmuin/chat/dto/response/ChatRoomSimpleResponse.java @@ -4,7 +4,6 @@ public record ChatRoomSimpleResponse( Long chatRoomId, - String chatStatus, MemberInfo chatPartner, String latestMessage, String messageType, diff --git a/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepository.java b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepository.java index c2008604..8e6e3d67 100644 --- a/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepository.java +++ b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepository.java @@ -6,12 +6,14 @@ import org.springframework.data.domain.Slice; import com.dnd.gongmuin.chat.domain.ChatStatus; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; import com.dnd.gongmuin.member.domain.Member; public interface ChatRoomQueryRepository { - Slice getChatRoomsByMember(Member member, List chatStatuses, Pageable pageable); + Slice getChatRoomsByMember(Member member, Pageable pageable); + Slice getChatProposalsByMember(Member member, Pageable pageable); List getAutoRejectedInquirerIds(); diff --git a/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepositoryImpl.java b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepositoryImpl.java index a74978d9..2d1a8342 100644 --- a/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepositoryImpl.java +++ b/src/main/java/com/dnd/gongmuin/chat/repository/ChatRoomQueryRepositoryImpl.java @@ -1,5 +1,6 @@ package com.dnd.gongmuin.chat.repository; + import static com.dnd.gongmuin.chat.domain.QChatRoom.*; import java.time.LocalDateTime; @@ -10,7 +11,9 @@ import org.springframework.data.domain.SliceImpl; import com.dnd.gongmuin.chat.domain.ChatStatus; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; +import com.dnd.gongmuin.chat.dto.response.QChatProposalInfo; import com.dnd.gongmuin.chat.dto.response.QChatRoomInfo; import com.dnd.gongmuin.member.domain.Member; import com.querydsl.core.types.dsl.CaseBuilder; @@ -25,17 +28,53 @@ public class ChatRoomQueryRepositoryImpl implements ChatRoomQueryRepository { public Slice getChatRoomsByMember( Member member, - List chatStatuses, Pageable pageable ) { List content = queryFactory .select(new QChatRoomInfo( + chatRoom.id, + new CaseBuilder() + .when(chatRoom.inquirer.id.eq(member.getId())) + .then(chatRoom.answerer.id) + .otherwise(chatRoom.inquirer.id), + + new CaseBuilder() + .when(chatRoom.inquirer.id.eq(member.getId())) + .then(chatRoom.answerer.nickname) + .otherwise(chatRoom.inquirer.nickname), + new CaseBuilder() + .when(chatRoom.inquirer.id.eq(member.getId())) + .then(chatRoom.answerer.jobGroup) + .otherwise(chatRoom.inquirer.jobGroup), + new CaseBuilder() + .when(chatRoom.inquirer.id.eq(member.getId())) + .then(chatRoom.answerer.profileImageNo) + .otherwise(chatRoom.inquirer.profileImageNo) + )) + .from(chatRoom) + .where(chatRoom.inquirer.id.eq(member.getId()) + .or(chatRoom.answerer.id.eq(member.getId())) + .and(chatRoom.status.eq(ChatStatus.ACCEPTED))) + .fetch(); + + boolean hasNext = hasNext(pageable.getPageSize(), content); + return new SliceImpl<>(content, pageable, hasNext); + } + + public Slice getChatProposalsByMember(Member member, Pageable pageable){ + List content = queryFactory + .select(new QChatProposalInfo( chatRoom.id, chatRoom.status, + new CaseBuilder() + .when(chatRoom.inquirer.id.eq(member.getId())) + .then(true) + .otherwise(false), new CaseBuilder() .when(chatRoom.inquirer.id.eq(member.getId())) .then(chatRoom.answerer.id) .otherwise(chatRoom.inquirer.id), + new CaseBuilder() .when(chatRoom.inquirer.id.eq(member.getId())) .then(chatRoom.answerer.nickname) @@ -52,7 +91,7 @@ public Slice getChatRoomsByMember( .from(chatRoom) .where(chatRoom.inquirer.id.eq(member.getId()) .or(chatRoom.answerer.id.eq(member.getId())) - .and(chatRoom.status.in(chatStatuses))) + .and(chatRoom.status.in(List.of(ChatStatus.REJECTED, ChatStatus.PENDING)))) .fetch(); boolean hasNext = hasNext(pageable.getPageSize(), content); diff --git a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java index 20fb7116..8e6bd754 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -13,12 +13,13 @@ import org.springframework.transaction.annotation.Transactional; import com.dnd.gongmuin.chat.domain.ChatRoom; -import com.dnd.gongmuin.chat.domain.ChatStatus; import com.dnd.gongmuin.chat.dto.ChatMessageMapper; import com.dnd.gongmuin.chat.dto.ChatRoomMapper; import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.AcceptChatResponse; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; +import com.dnd.gongmuin.chat.dto.response.ChatProposalResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomSimpleResponse; @@ -94,11 +95,10 @@ public CreateChatRoomResponse createChatRoom(CreateChatRoomRequest request, Memb } @Transactional(readOnly = true) - public PageResponse getChatRoomsByMember(Member member, List chatStatuses, - Pageable pageable) { + public PageResponse getChatRoomsByMember(Member member, Pageable pageable) { // 회원 채팅방 정보 가져오기 Slice chatRoomInfos = chatRoomRepository.getChatRoomsByMember( - member, ChatStatus.from(chatStatuses), pageable + member, pageable ); // chatRoomId 리스트 추출 @@ -118,6 +118,26 @@ public PageResponse getChatRoomsByMember(Member member, return new PageResponse<>(responses, responses.size(), chatRoomInfos.hasNext()); } + @Transactional(readOnly = true) + public PageResponse getChatProposalsByMember(Member member, Pageable pageable) { + Slice chatProposalInfos = chatRoomRepository.getChatProposalsByMember( + member, pageable + ); + + List chatRoomIds = chatProposalInfos.stream() + .map(ChatProposalInfo::chatRoomId) + .toList(); + + List latestChatMessages + = chatMessageQueryRepository.findLatestChatByChatRoomIds(chatRoomIds); + + List responses = getChatProposalResponse(latestChatMessages, + chatProposalInfos); + + return new PageResponse<>(responses, responses.size(), chatProposalInfos.hasNext()); + } + + @Transactional(readOnly = true) public ChatRoomDetailResponse getChatRoomById(Long chatRoomId, Member member) { ChatRoom chatRoom = getChatRoomById(chatRoomId); @@ -181,6 +201,26 @@ private List getChatRoomSimpleResponses(List getChatProposalResponse(List latestChatMessages, + Slice chatProposalInfos) { + // -> 순서 보장 x + Map messageMap = latestChatMessages.stream() + .collect(Collectors.toMap(LatestChatMessage::chatRoomId, message -> message)); + + // 최신순 정렬 및 변환 + return chatProposalInfos.stream() + .sorted( + Comparator.comparing( + (ChatProposalInfo info) -> messageMap.get(info.chatRoomId()).createdAt() + ).reversed()) + .map(chatProposalInfo -> { + LatestChatMessage latestMessage = messageMap.get(chatProposalInfo.chatRoomId()); + return ChatRoomMapper.toChatProposalResponse( + chatProposalInfo, latestMessage + ); + }).toList(); + } + private ChatRoom getChatRoomById(Long id) { return chatRoomRepository.findById(id) .orElseThrow(() -> new NotFoundException(ChatErrorCode.NOT_FOUND_CHAT_ROOM)); diff --git a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java index 5b8c39d4..b0b9a4ee 100644 --- a/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/controller/ChatRoomControllerTest.java @@ -98,7 +98,7 @@ void createChatRoom() throws Exception { .andExpect(jsonPath("$.receiverInfo.profileImageNo").value(answerer.getProfileImageNo())); } - @DisplayName("[회원의 요청 상태 채팅방 목록을 조회할 수 있다.]") + @DisplayName("[회원의 채팅방 목록을 조회할 수 있다.]") @Test void getChatRoomsByMember() throws Exception { //given @@ -111,13 +111,14 @@ void getChatRoomsByMember() throws Exception { ) ); ChatRoom chatRoom1 = chatRoomRepository.save( - ChatRoomFixture.chatRoom(questionPosts.get(0), member1, loginMember)); + ChatRoomFixture.acceptedChatRoom(questionPosts.get(0), member1, loginMember)); ChatRoom chatRoom2 = chatRoomRepository.save( - ChatRoomFixture.chatRoom(questionPosts.get(0), member2, loginMember)); + ChatRoomFixture.acceptedChatRoom(questionPosts.get(0), member2, loginMember)); ChatRoom chatRoom3 = chatRoomRepository.save( - ChatRoomFixture.chatRoom(questionPosts.get(1), loginMember, member1)); + ChatRoomFixture.acceptedChatRoom(questionPosts.get(1), loginMember, member1)); ChatRoom unrelatedChatroom = chatRoomRepository.save( - ChatRoomFixture.chatRoom(questionPosts.get(1), member2, member1)); + ChatRoomFixture.acceptedChatRoom(questionPosts.get(1), member2, member1)); + chatMessageRepository.saveAll( List.of( chatMessageRepository.save( @@ -140,8 +141,7 @@ void getChatRoomsByMember() throws Exception { // when & then mockMvc.perform(get("/api/chat-rooms") - .cookie(accessToken) - .param("statuses", ChatStatus.PENDING.getLabel())) + .cookie(accessToken)) .andExpect(status().isOk()) .andExpect(jsonPath("$.size").value(3)) .andExpect(jsonPath("$.content[0].chatRoomId").value(chatRoom3.getId())) @@ -156,6 +156,55 @@ void getChatRoomsByMember() throws Exception { .andDo(MockMvcResultHandlers.print()); } + @DisplayName("[회원의 채팅 요청 목록을 조회할 수 있다.]") + @Test + void getChatProposalsByMember() throws Exception { + //given + Member member1 = memberRepository.save(MemberFixture.member4()); + Member member2 = memberRepository.save(MemberFixture.member5()); + List questionPosts = questionPostRepository.saveAll( + List.of( + questionPostRepository.save(QuestionPostFixture.questionPost(member1)), + questionPostRepository.save(QuestionPostFixture.questionPost(member2)) + ) + ); + ChatRoom chatRoom1 = chatRoomRepository.save( + ChatRoomFixture.chatRoom(questionPosts.get(0), member1, loginMember)); + ChatRoom chatRoom2 = chatRoomRepository.save( + ChatRoomFixture.chatRoom(questionPosts.get(1), loginMember, member1)); + ChatRoom unrelatedChatroom = chatRoomRepository.save( + ChatRoomFixture.chatRoom(questionPosts.get(1), member2, member1)); + + chatMessageRepository.saveAll( + List.of( + chatMessageRepository.save( + ChatMessageFixture.chatMessage(chatRoom1.getId(), "11", LocalDateTime.now())), + chatMessageRepository.save( + ChatMessageFixture.chatMessage(chatRoom2.getId(), "21", LocalDateTime.now())), + chatMessageRepository.save( + ChatMessageFixture.chatMessage(unrelatedChatroom.getId(), "31", LocalDateTime.now())) + ) + ); + + // when & then + mockMvc.perform(get("/api/chat-rooms/proposals") + .cookie(accessToken)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.size").value(2)) + .andExpect(jsonPath("$.content[0].chatRoomId").value(chatRoom2.getId())) + .andExpect(jsonPath("$.content[0].latestMessage").value("21")) + .andExpect(jsonPath("$.content[0].chatPartner.memberId").value(member1.getId())) + .andExpect(jsonPath("$.content[0].isInquirer").value(true)) + .andExpect(jsonPath("$.content[0].chatStatus").value(ChatStatus.PENDING.getLabel())) + + .andExpect(jsonPath("$.content[1].chatRoomId").value(chatRoom1.getId())) + .andExpect(jsonPath("$.content[1].latestMessage").value("11")) + .andExpect(jsonPath("$.content[1].chatPartner.memberId").value(member1.getId())) + .andExpect(jsonPath("$.content[1].isInquirer").value(false)) + .andExpect(jsonPath("$.content[1].chatStatus").value(ChatStatus.PENDING.getLabel())) + .andDo(MockMvcResultHandlers.print()); + } + @DisplayName("[채팅방 아이디로 채팅방을 상세조회할 수 있다.]") @Test void getChatRoomById() throws Exception { diff --git a/src/test/java/com/dnd/gongmuin/chat/repository/ChatRoomRepositoryTest.java b/src/test/java/com/dnd/gongmuin/chat/repository/ChatRoomRepositoryTest.java index 313b617f..45b34212 100644 --- a/src/test/java/com/dnd/gongmuin/chat/repository/ChatRoomRepositoryTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/repository/ChatRoomRepositoryTest.java @@ -15,6 +15,7 @@ import com.dnd.gongmuin.chat.domain.ChatRoom; import com.dnd.gongmuin.chat.domain.ChatStatus; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; import com.dnd.gongmuin.common.fixture.ChatRoomFixture; import com.dnd.gongmuin.common.fixture.MemberFixture; @@ -44,7 +45,7 @@ class ChatRoomRepositoryTest extends DataJpaTestSupport { @Autowired CreditHistoryRepository creditHistoryRepository; - @DisplayName("회원이 속한 채팅방을 모두 조회할 수 있다.") + @DisplayName("회원이 속한 채팅방 목록을 조회할 수 있다.") @Test void getChatRoomsByMember() { //given @@ -53,15 +54,15 @@ void getChatRoomsByMember() { Member answerer = memberRepository.save(MemberFixture.member()); QuestionPost questionPost = questionPostRepository.save(QuestionPostFixture.questionPost(questioner)); List chatRooms = chatRoomRepository.saveAll(List.of( - chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, questioner, answerer)), - chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, questioner, target)), - chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, target, answerer)) + chatRoomRepository.save(ChatRoomFixture.acceptedChatRoom(questionPost, questioner, answerer)), + chatRoomRepository.save(ChatRoomFixture.acceptedChatRoom(questionPost, questioner, target)), + chatRoomRepository.save(ChatRoomFixture.acceptedChatRoom(questionPost, target, answerer)) )); - //when - List chatRoomInfos = chatRoomRepository.getChatRoomsByMember(target, List.of(ChatStatus.PENDING), - pageRequest) + //when + List chatRoomInfos = chatRoomRepository.getChatRoomsByMember(target, pageRequest) .getContent(); + //then Assertions.assertAll( () -> assertThat(chatRoomInfos).hasSize(2), @@ -72,6 +73,34 @@ void getChatRoomsByMember() { ); } + @DisplayName("회원의 채팅 요청 목록을 조회할 수 있다.") + @Test + void getChatProposalsByMember() { + //given + Member questioner = memberRepository.save(MemberFixture.member()); + Member target = memberRepository.save(MemberFixture.member()); + Member answerer = memberRepository.save(MemberFixture.member()); + QuestionPost questionPost = questionPostRepository.save(QuestionPostFixture.questionPost(questioner)); + List chatRooms = chatRoomRepository.saveAll(List.of( + chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, questioner, answerer)), + chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, questioner, target)), + chatRoomRepository.save(ChatRoomFixture.chatRoom(questionPost, target, answerer)) + )); + + //when + List chatProposalInfos = chatRoomRepository.getChatProposalsByMember(target, pageRequest) + .getContent(); + + //then + Assertions.assertAll( + () -> assertThat(chatProposalInfos).hasSize(2), + () -> assertThat(chatProposalInfos.get(0).chatRoomId()).isEqualTo(chatRooms.get(1).getId()), + () -> assertThat(chatProposalInfos.get(0).partnerId()).isEqualTo(questioner.getId()), + () -> assertThat(chatProposalInfos.get(1).chatRoomId()).isEqualTo(chatRooms.get(2).getId()), + () -> assertThat(chatProposalInfos.get(1).partnerId()).isEqualTo(answerer.getId()) + ); + } + @DisplayName("요청중인 채팅방이 일주일이 지나면, 채팅방 상태를 거절함으로 바꾼다.") @Test void updateChatRoomStatusRejected() { diff --git a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java index a6ad61eb..1775ddb6 100644 --- a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java @@ -26,6 +26,8 @@ import com.dnd.gongmuin.chat.dto.request.CreateChatRoomRequest; import com.dnd.gongmuin.chat.dto.response.AcceptChatResponse; import com.dnd.gongmuin.chat.dto.response.ChatMessageResponse; +import com.dnd.gongmuin.chat.dto.response.ChatProposalInfo; +import com.dnd.gongmuin.chat.dto.response.ChatProposalResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomDetailResponse; import com.dnd.gongmuin.chat.dto.response.ChatRoomInfo; import com.dnd.gongmuin.chat.dto.response.ChatRoomSimpleResponse; @@ -191,7 +193,7 @@ void createChatRoom_fail() { .hasMessageContaining(MemberErrorCode.NOT_ENOUGH_CREDIT.getMessage()); } - @DisplayName("[회원이 속한 수락 상태 채팅방 목록을 조회할 수 있다.]") + @DisplayName("[회원이 속한 채팅방 목록을 조회할 수 있다.]") @Test void getChatRoomsByMember() { //given @@ -199,21 +201,57 @@ void getChatRoomsByMember() { Member targetMember = MemberFixture.member(1L); Member partner = MemberFixture.member(2L); ChatRoomInfo chatRoomInfo = new ChatRoomInfo( - chatRoomId, ChatStatus.ACCEPTED, partner.getId(), + chatRoomId, partner.getId(), partner.getNickname(), partner.getJobGroup(), partner.getProfileImageNo() ); LatestChatMessage latestChatMessage = new LatestChatMessage( chatRoomId, "와", "텍스트", LocalDateTime.now() ); - given(chatRoomRepository.getChatRoomsByMember(targetMember, List.of(ChatStatus.ACCEPTED), pageRequest)) + given(chatRoomRepository.getChatRoomsByMember(targetMember, pageRequest)) .willReturn(new SliceImpl<>(List.of(chatRoomInfo), pageRequest, false)); given(chatMessageQueryRepository.findLatestChatByChatRoomIds(List.of(chatRoomId))) .willReturn(List.of(latestChatMessage)); //when List response = chatRoomService.getChatRoomsByMember( - targetMember, List.of(ChatStatus.ACCEPTED.getLabel()), pageRequest).content(); + targetMember, pageRequest).content(); + + //then + assertAll( + () -> assertThat(response).hasSize(1), + () -> assertThat(response.get(0).chatRoomId()) + .isEqualTo(chatRoomId), + () -> assertThat(response.get(0).chatPartner().memberId()) + .isEqualTo(partner.getId()), + () -> assertThat(response.get(0).latestMessage()) + .isEqualTo(latestChatMessage.content()) + ); + } + + @DisplayName("[회원이 속한 채팅 요청 목록을 조회할 수 있다.]") + @Test + void getChatProposalsByMember() { + //given + Long chatRoomId = 1L; + Member targetMember = MemberFixture.member(1L); + Member partner = MemberFixture.member(2L); + ChatProposalInfo chatProposalInfo = new ChatProposalInfo( + chatRoomId, ChatStatus.PENDING, true, partner.getId(), + partner.getNickname(), partner.getJobGroup(), partner.getProfileImageNo() + ); + LatestChatMessage latestChatMessage = new LatestChatMessage( + chatRoomId, "와", "텍스트", LocalDateTime.now() + ); + + given(chatRoomRepository.getChatProposalsByMember(targetMember, pageRequest)) + .willReturn(new SliceImpl<>(List.of(chatProposalInfo), pageRequest, false)); + given(chatMessageQueryRepository.findLatestChatByChatRoomIds(List.of(chatRoomId))) + .willReturn(List.of(latestChatMessage)); + + //when + List response = chatRoomService.getChatProposalsByMember( + targetMember, pageRequest).content(); //then assertAll( diff --git a/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java b/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java index 424ff212..e0406b68 100644 --- a/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java +++ b/src/test/java/com/dnd/gongmuin/common/fixture/ChatRoomFixture.java @@ -3,6 +3,7 @@ import org.springframework.test.util.ReflectionTestUtils; import com.dnd.gongmuin.chat.domain.ChatRoom; +import com.dnd.gongmuin.chat.domain.ChatStatus; import com.dnd.gongmuin.member.domain.Member; import com.dnd.gongmuin.question_post.domain.QuestionPost; @@ -24,6 +25,20 @@ public static ChatRoom chatRoom( ); } + public static ChatRoom acceptedChatRoom( + QuestionPost questionPost, + Member inquirer, + Member answerer + ) { + ChatRoom chatRoom = ChatRoom.of( + questionPost, + inquirer, + answerer + ); + ReflectionTestUtils.setField(chatRoom, "status", ChatStatus.ACCEPTED); + return chatRoom; + } + public static ChatRoom chatRoom( Long id, QuestionPost questionPost,