Skip to content

Commit

Permalink
[feat #158] 채팅 요청 상세 조회 API (#159)
Browse files Browse the repository at this point in the history
* [feat] : 채팅 요청 상세 조회 응답 추가

* [feat] : 채팅 요청 상세 조회 비즈니스 로직 추가

* [feat] : 채팅 요청 상세 조회 비즈니스 로직 테스트

* [feat] : 채팅 요청 상세 조회 API 메서드 추가

* [test] : 채팅 요청 상세 조회 API 메서드 테스트

* [feat] : 채팅 요청 API pk 필드명 수정

* [rename] : memberInfo DTO 위치 이동

* [remove] : 불필요한 예외 로직 처리 삭제

* [refactor] : 채팅 파트너 구하는 로직 도메인으로 이동

* [refactor] : 채팅 파트너 구하는 로직 mapper가 아닌 서비스 내에서 호출

* [style] : 코드 리포멧팅

* [style] : 줄바꿈 취소
  • Loading branch information
hyun2371 authored Nov 23, 2024
1 parent e145d22 commit 26bfa04
Show file tree
Hide file tree
Showing 22 changed files with 142 additions and 53 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.dnd.gongmuin.answer.dto;

import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record AnswerDetailResponse(
Long answerId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.dnd.gongmuin.answer.domain.Answer;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.member.dto.response.MemberInfo;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.springframework.web.bind.annotation.RestController;

import com.dnd.gongmuin.chat_inquiry.dto.AcceptChatResponse;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryDetailResponse;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryResponse;
import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryRequest;
import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryResponse;
Expand Down Expand Up @@ -42,7 +43,17 @@ public ResponseEntity<CreateChatInquiryResponse> createChatInquiry(
return ResponseEntity.ok(response);
}

@Operation(summary = "채팅방 요청 목록 조회 API", description = "회원의 채팅방 목록을 조회한다.")
@Operation(summary = "채팅 요청 상세 조회 API", description = "채팅방 요청을 조회한다.")
@GetMapping("/api/chat/inquiries/{chatInquiryId}")
public ResponseEntity<ChatInquiryDetailResponse> getChatInquiryById(
@PathVariable("chatInquiryId") Long chatInquiryId,
@AuthenticationPrincipal Member member
) {
ChatInquiryDetailResponse response = chatInquiryService.getChatInquiryById(chatInquiryId, member);
return ResponseEntity.ok(response);
}

@Operation(summary = "채팅 요청 목록 조회 API", description = "회원의 채팅 목록을 조회한다.")
@GetMapping("/api/chat/inquiries")
public ResponseEntity<PageResponse<ChatInquiryResponse>> getChatInquiresByMember(
@AuthenticationPrincipal Member member,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class ChatInquiry extends TimeBaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "chat_proposal_id", nullable = false)
@Column(name = "chat_inquiry_id", nullable = false)
private Long id;

@ManyToOne(fetch = LAZY)
Expand Down Expand Up @@ -90,4 +90,12 @@ public void updateStatusRejected() {
status = InquiryStatus.REJECTED;
inquirer.increaseCredit(CHAT_REWARD);
}

public boolean isInquirer(Member member) {
return member.equals(this.inquirer);
}

public Member getChatPartner(Member member) {
return isInquirer(member) ? this.answerer : this.inquirer;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.dnd.gongmuin.chat_inquiry.dto;

import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record ChatInquiryDetailResponse(
Long chatInquiryId,
String inquiryMessage,
String inquiryStatus,
boolean isInquirer,
MemberInfo chatPartner
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import com.dnd.gongmuin.chat_inquiry.domain.InquiryStatus;
import com.dnd.gongmuin.chatroom.domain.ChatRoom;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.dto.response.MemberInfo;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
Expand Down Expand Up @@ -44,6 +44,24 @@ public static CreateChatInquiryResponse toCreateChatInquiryResponse(
);
}

public static ChatInquiryDetailResponse toChatInquiryDetailResponse(
ChatInquiry chatInquiry,
Member chatPartner,
boolean isInquirer
) {
return new ChatInquiryDetailResponse(chatInquiry.getId(),
chatInquiry.getMessage(),
chatInquiry.getStatus().getLabel(),
isInquirer,
new MemberInfo(
chatPartner.getId(),
chatPartner.getNickname(),
chatPartner.getJobGroup().getLabel(),
chatPartner.getProfileImageNo()
)
);
}

public static AcceptChatResponse toAcceptChatResponse(
ChatInquiry chatInquiry,
ChatRoom chatRoom
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.dnd.gongmuin.chat_inquiry.dto;

import com.dnd.gongmuin.chat_inquiry.domain.InquiryStatus;
import com.dnd.gongmuin.member.domain.JobGroup;
import com.dnd.gongmuin.member.dto.response.MemberInfo;
import com.dnd.gongmuin.chat_inquiry.domain.ChatInquiry;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.querydsl.core.annotations.QueryProjection;

public record ChatInquiryResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.dnd.gongmuin.chat_inquiry.dto;

import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record CreateChatInquiryResponse(
Long chatInquiryId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.dnd.gongmuin.chat_inquiry.domain.ChatInquiry;
import com.dnd.gongmuin.chat_inquiry.dto.AcceptChatResponse;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryDetailResponse;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryMapper;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryResponse;
import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryRequest;
Expand Down Expand Up @@ -70,6 +71,17 @@ public CreateChatInquiryResponse createChatInquiry(CreateChatInquiryRequest requ
return ChatInquiryMapper.toCreateChatInquiryResponse(chatInquiry);
}

@Transactional(readOnly = true)
public ChatInquiryDetailResponse getChatInquiryById(Long chatInquiryId, Member member) {
ChatInquiry chatInquiry = getChatInquiryById(chatInquiryId);

return ChatInquiryMapper.toChatInquiryDetailResponse(
chatInquiry,
chatInquiry.getChatPartner(member),
chatInquiry.isInquirer(member)
);
}

@Transactional(readOnly = true)
public PageResponse<ChatInquiryResponse> getChatInquiresByMember(Member member, Pageable pageable) {
Slice<ChatInquiryResponse> responsePage = chatInquiryRepository.getChatInquiresByMember(
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/com/dnd/gongmuin/chatroom/domain/ChatRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,12 @@ public static ChatRoom of(
) {
return new ChatRoom(questionPost, inquirer, answerer);
}

public boolean isInquirer(Member member) {
return member.equals(this.inquirer);
}

public Member getChatPartner(Member member) {
return isInquirer(member) ? this.answerer : this.inquirer;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
import com.dnd.gongmuin.chatroom.dto.response.ChatRoomSimpleResponse;
import com.dnd.gongmuin.chatroom.dto.response.LatestChatMessage;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.dto.response.MemberInfo;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
Expand All @@ -29,10 +29,10 @@ public static ChatRoom toChatRoom(

public static ChatRoomDetailResponse toChatRoomDetailResponse(
ChatRoom chatRoom,
Member chatPartner
Member chatPartner,
boolean isInquirer
) {
QuestionPost questionPost = chatRoom.getQuestionPost();
boolean isInquirer = !chatPartner.equals(chatRoom.getInquirer());
return new ChatRoomDetailResponse(
questionPost.getId(),
questionPost.getJobGroup().getLabel(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.dnd.gongmuin.chatroom.dto.response;

import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record ChatRoomDetailResponse(
Long questionPostId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.dnd.gongmuin.chatroom.dto.response;

import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record ChatRoomSimpleResponse(
Long chatRoomId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
public enum ChatErrorCode implements ErrorCode {

INVALID_MESSAGE_TYPE("메시지 타입을 올바르게 입력해주세요.", "CH_001"),
NOT_FOUND_CHAT_ROOM("해당 아이디의 채팅방이 존재하지 않습니다.", "CH_002"),
UNAUTHORIZED_CHAT_ROOM("채팅방 조회 권한이 없습니다.", "CH_003");
NOT_FOUND_CHAT_ROOM("해당 아이디의 채팅방이 존재하지 않습니다.", "CH_002");

private final String message;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
import com.dnd.gongmuin.common.dto.PageMapper;
import com.dnd.gongmuin.common.dto.PageResponse;
import com.dnd.gongmuin.common.exception.runtime.NotFoundException;
import com.dnd.gongmuin.common.exception.runtime.ValidationException;
import com.dnd.gongmuin.member.domain.Member;

import lombok.RequiredArgsConstructor;
Expand Down Expand Up @@ -73,8 +72,12 @@ public PageResponse<ChatRoomSimpleResponse> getChatRoomsByMember(Member member,
@Transactional(readOnly = true)
public ChatRoomDetailResponse getChatRoomById(Long chatRoomId, Member member) {
ChatRoom chatRoom = getChatRoomById(chatRoomId);
Member chatPartner = getChatPartner(member, chatRoom);
return ChatRoomMapper.toChatRoomDetailResponse(chatRoom, chatPartner);

return ChatRoomMapper.toChatRoomDetailResponse(
chatRoom,
chatRoom.getChatPartner(member),
chatRoom.isInquirer(member)
);
}

private List<ChatRoomSimpleResponse> getChatRoomSimpleResponses(List<LatestChatMessage> latestChatMessages,
Expand All @@ -101,14 +104,4 @@ private ChatRoom getChatRoomById(Long id) {
return chatRoomRepository.findById(id)
.orElseThrow(() -> new NotFoundException(ChatErrorCode.NOT_FOUND_CHAT_ROOM));
}

private Member getChatPartner(Member member, ChatRoom chatRoom) {
if (member.equals(chatRoom.getAnswerer())) {
return chatRoom.getInquirer();
}
if (member.equals(chatRoom.getInquirer())) {
return chatRoom.getAnswerer();
}
throw new ValidationException(ChatErrorCode.UNAUTHORIZED_CHAT_ROOM);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.dnd.gongmuin.question_post.dto.response;
package com.dnd.gongmuin.member.dto.response;

public record MemberInfo(
Long memberId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import com.dnd.gongmuin.member.domain.JobGroup;
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.dto.response.MemberInfo;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.domain.QuestionPostImage;
import com.dnd.gongmuin.question_post.dto.request.RegisterQuestionPostRequest;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.question_post.dto.response.QuestionPostDetailResponse;
import com.dnd.gongmuin.question_post.dto.response.RegisterQuestionPostResponse;
import com.dnd.gongmuin.question_post.dto.response.UpdateQuestionPostResponse;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;

import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record QuestionPostDetailResponse(
Long questionPostId,
String title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import java.util.List;

import com.dnd.gongmuin.member.dto.response.MemberInfo;

public record RegisterQuestionPostResponse(
Long questionPostId,
String title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@
import com.dnd.gongmuin.chatroom.dto.response.ChatRoomInfo;
import com.dnd.gongmuin.chatroom.dto.response.ChatRoomSimpleResponse;
import com.dnd.gongmuin.chatroom.dto.response.LatestChatMessage;
import com.dnd.gongmuin.chatroom.exception.ChatErrorCode;
import com.dnd.gongmuin.chatroom.repository.ChatMessageQueryRepository;
import com.dnd.gongmuin.chatroom.repository.ChatMessageRepository;
import com.dnd.gongmuin.chatroom.repository.ChatRoomRepository;
import com.dnd.gongmuin.chatroom.service.ChatRoomService;
import com.dnd.gongmuin.common.exception.runtime.ValidationException;
import com.dnd.gongmuin.common.fixture.ChatMessageFixture;
import com.dnd.gongmuin.common.fixture.ChatRoomFixture;
import com.dnd.gongmuin.common.fixture.MemberFixture;
Expand Down Expand Up @@ -158,24 +156,4 @@ void getChatRoomById_Answerer() {
.isEqualTo(inquirer.getId())
);
}

@DisplayName("[채팅방에 속하지 않은 사람은 채팅방을 조회할 수 없다.]")
@Test
void getChatRoomById_Unauthorized() {
//given
Long chatRoomId = 1L;
Member inquirer = MemberFixture.member(1L);
Member answerer = MemberFixture.member(2L);
Member unrelatedMember = MemberFixture.member(3L);
QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer);
ChatRoom chatRoom = ChatRoomFixture.chatRoom(questionPost, inquirer, answerer);

given(chatRoomRepository.findById(chatRoomId))
.willReturn(Optional.of(chatRoom));

//when & then
assertThatThrownBy(() -> chatRoomService.getChatRoomById(chatRoomId, unrelatedMember))
.isInstanceOf(ValidationException.class)
.hasMessageContaining(ChatErrorCode.UNAUTHORIZED_CHAT_ROOM.getMessage());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void teardown() {
creditHistoryRepository.deleteAll();
memberRepository.deleteAll();
questionPostRepository.deleteAll();
chatInquiryRepository.deleteAll();
chatRoomRepository.deleteAll();
chatMessageRepository.deleteAll();
}
Expand All @@ -82,6 +83,32 @@ void createChatInquiry() throws Exception {
.andDo(MockMvcResultHandlers.print());
}

@DisplayName("[채팅 요청 아이디로 상세 채팅 요청을 조회할 수 있다.]")
@Test
void getChatInquiryById() throws Exception {
//given
Member chatPartner = memberRepository.save(MemberFixture.member5());
QuestionPost questionPost = questionPostRepository.save(QuestionPostFixture.questionPost(loginMember));
ChatInquiry chatInquiry = chatInquiryRepository.save(
ChatInquiryFixture.chatInquiry(questionPost, loginMember, chatPartner, INQUIRY_MESSAGE)
);

//when & then
mockMvc.perform(get("/api/chat/inquiries/{chatInquiryId}", chatInquiry.getId())
.cookie(accessToken))
.andExpect(status().isOk())
.andExpect(jsonPath("$.chatInquiryId")
.value(chatInquiry.getId()))
.andExpect(jsonPath("$.inquiryStatus")
.value(InquiryStatus.PENDING.getLabel()))
.andExpect(jsonPath("$.chatPartner.memberId")
.value(chatPartner.getId()))
.andExpect(jsonPath("$.isInquirer")
.value(chatInquiry.getInquirer().equals(loginMember)))
.andExpect(jsonPath("$.inquiryStatus")
.value(InquiryStatus.PENDING.getLabel()));
}

@DisplayName("[회원의 채팅 요청 목록을 조회할 수 있다.]")
@Test
void getChatInquiresByMember() throws Exception {
Expand Down
Loading

0 comments on commit 26bfa04

Please sign in to comment.