Skip to content

Commit

Permalink
[fix #179] 채팅 요청 답변자 검증 로직 추가 (#185)
Browse files Browse the repository at this point in the history
* [feat] : 채팅요청 에러 코드 추가

* [feat] : 채팅요청 검증 repository 함수 추가

* [feat] : 채팅요청 검증 비즈니스 로직 추가

* [test] : 채팅 요청 생성 실패 케이스 추가

* [test] : 검증 로직 추가 반영
  • Loading branch information
hyun2371 authored Jan 9, 2025
1 parent b8991ed commit 1292aed
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ public interface AnswerRepository extends JpaRepository<Answer, Long> {
@Query("select a from Answer a "
+ "join fetch a.member where a.id = :answerId")
Optional<Answer> findByIdWithMember(Long answerId);

boolean existsByQuestionPostIdAndMember(Long questionPostId, Member member);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ public enum ChatInquiryErrorCode implements ErrorCode {
NOT_FOUND_INQUIRY("해당 아이디의 채팅 요청이 존재하지 않습니다.", "CI_001"),
UNAUTHORIZED_REQUEST("채팅 요청을 수락을 하거나 거절할 권한이 없습니다.", "CI_002"),
UNABLE_TO_CHANGE_STATUS("이미 수락했거나 거절한 요청입니다.", "CI_003"),
NOT_FOUND_STATUS("채팅방 상태값을 올바르게 입력해주세요.", "CI_004");
NOT_FOUND_STATUS("채팅방 상태값을 올바르게 입력해주세요.", "CI_004"),
NOT_EXISTS_ANSWERER("해당 아이디의 답변자가 해당 게시글에 존재하지 않습니다.", "CI_005");

private final String message;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dnd.gongmuin.answer.repository.AnswerRepository;
import com.dnd.gongmuin.chat_inquiry.domain.ChatInquiry;
import com.dnd.gongmuin.chat_inquiry.dto.AcceptChatResponse;
import com.dnd.gongmuin.chat_inquiry.dto.ChatInquiryDetailResponse;
Expand Down Expand Up @@ -54,16 +55,19 @@ public class ChatInquiryService {
private final CreditHistoryService creditHistoryService;
private final ApplicationEventPublisher eventPublisher;
private final ChatMessageRepository chatMessageRepository;
private final AnswerRepository answerRepository;

@Transactional
public CreateChatInquiryResponse createChatInquiry(CreateChatInquiryRequest request, Member inquirer) {
QuestionPost questionPost = getQuestionPostById(request.questionPostId());
Member answerer = getMemberById(request.answererId());
validateChatAnswerer(request.questionPostId(), answerer);
ChatInquiry chatInquiry = chatInquiryRepository.save(
ChatInquiryMapper.toChatInquiry(questionPost, inquirer, answerer, request.inquiryMessage())
);
memberRepository.save(inquirer);
creditHistoryService.saveCreditHistory(CreditType.CHAT_REQUEST, CHAT_REWARD, inquirer);

saveInquirerCreditHistory(inquirer);

eventPublisher.publishEvent(
new NotificationEvent(NotificationType.CHAT_REQUEST, chatInquiry.getId(), inquirer.getId(), answerer)
);
Expand Down Expand Up @@ -140,6 +144,17 @@ public void rejectChatAuto() {
autoRejectedChatInquiryNotification(rejectedChatInquiryDtos);
}

private void validateChatAnswerer(Long questionPostId, Member answerer) {
if (!answerRepository.existsByQuestionPostIdAndMember(questionPostId, answerer)) {
throw new ValidationException(ChatInquiryErrorCode.NOT_EXISTS_ANSWERER);
}
}

private void saveInquirerCreditHistory(Member inquirer) {
memberRepository.save(inquirer);
creditHistoryService.saveCreditHistory(CreditType.CHAT_REQUEST, CHAT_REWARD, inquirer);
}

private List<Long> getRejectedInquirerIds(List<RejectedChatInquiryDto> rejectedChatInquiryDtos) {
return rejectedChatInquiryDtos.stream()
.map(dto -> dto.inquirer().getId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;

import com.dnd.gongmuin.answer.repository.AnswerRepository;
import com.dnd.gongmuin.chat_inquiry.domain.ChatInquiry;
import com.dnd.gongmuin.chat_inquiry.domain.InquiryStatus;
import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryRequest;
import com.dnd.gongmuin.chat_inquiry.repository.ChatInquiryRepository;
import com.dnd.gongmuin.chatroom.repository.ChatMessageRepository;
import com.dnd.gongmuin.chatroom.repository.ChatRoomRepository;
import com.dnd.gongmuin.common.fixture.AnswerFixture;
import com.dnd.gongmuin.common.fixture.ChatInquiryFixture;
import com.dnd.gongmuin.common.fixture.MemberFixture;
import com.dnd.gongmuin.common.fixture.QuestionPostFixture;
Expand All @@ -43,6 +45,9 @@ class ChatInquiryControllerTest extends ApiTestSupport {
@Autowired
private QuestionPostRepository questionPostRepository;

@Autowired
private AnswerRepository answerRepository;

@Autowired
private ChatRoomRepository chatRoomRepository;

Expand All @@ -57,6 +62,7 @@ void teardown() {
creditHistoryRepository.deleteAll();
memberRepository.deleteAll();
questionPostRepository.deleteAll();
answerRepository.deleteAll();
chatInquiryRepository.deleteAll();
chatRoomRepository.deleteAll();
chatMessageRepository.deleteAll();
Expand All @@ -69,11 +75,14 @@ void createChatInquiry() throws Exception {
int previousCredit = loginMember.getCredit();
Member answerer = memberRepository.save(MemberFixture.member5());
QuestionPost questionPost = questionPostRepository.save(QuestionPostFixture.questionPost(loginMember));
answerRepository.save(AnswerFixture.answer(questionPost.getId(), answerer));

CreateChatInquiryRequest request = new CreateChatInquiryRequest(
questionPost.getId(),
answerer.getId(),
INQUIRY_MESSAGE
);

//when & then
mockMvc.perform(post("/api/chat/inquiries")
.cookie(accessToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.springframework.data.domain.SliceImpl;
import org.springframework.test.util.ReflectionTestUtils;

import com.dnd.gongmuin.answer.repository.AnswerRepository;
import com.dnd.gongmuin.chat_inquiry.domain.ChatInquiry;
import com.dnd.gongmuin.chat_inquiry.domain.InquiryStatus;
import com.dnd.gongmuin.chat_inquiry.dto.AcceptChatResponse;
Expand All @@ -27,6 +28,7 @@
import com.dnd.gongmuin.chat_inquiry.dto.CreateChatInquiryResponse;
import com.dnd.gongmuin.chat_inquiry.dto.RejectChatResponse;
import com.dnd.gongmuin.chat_inquiry.dto.RejectedChatInquiryDto;
import com.dnd.gongmuin.chat_inquiry.exception.ChatInquiryErrorCode;
import com.dnd.gongmuin.chat_inquiry.repository.ChatInquiryRepository;
import com.dnd.gongmuin.chatroom.domain.ChatRoom;
import com.dnd.gongmuin.chatroom.repository.ChatMessageRepository;
Expand Down Expand Up @@ -65,6 +67,9 @@ class ChatInquiryServiceTest {
@Mock
private QuestionPostRepository questionPostRepository;

@Mock
private AnswerRepository answerRepository;

@Mock
private ApplicationEventPublisher eventPublisher;

Expand Down Expand Up @@ -98,6 +103,8 @@ void createInquiry() {
.willReturn(Optional.of(questionPost));
given(memberRepository.findById(answerer.getId()))
.willReturn(Optional.of(answerer));
given(answerRepository.existsByQuestionPostIdAndMember(questionPost.getId(), answerer))
.willReturn(true);
given(chatInquiryRepository.save(any(ChatInquiry.class))).willReturn(chatInquiry);

CreateChatInquiryResponse response = chatInquiryService.createChatInquiry(request, inquirer);
Expand Down Expand Up @@ -129,13 +136,42 @@ void createInquiry_fails() {
.willReturn(Optional.of(questionPost));
given(memberRepository.findById(answerer.getId()))
.willReturn(Optional.of(answerer));
given(answerRepository.existsByQuestionPostIdAndMember(questionPost.getId(), answerer))
.willReturn(true);

//when & then
assertThatThrownBy(() -> chatInquiryService.createChatInquiry(request, inquirer))
.isInstanceOf(ValidationException.class)
.hasMessageContaining(MemberErrorCode.NOT_ENOUGH_CREDIT.getMessage());
}

@DisplayName("[질문 게시글에 답변을 하지 않은 회원에게 채팅 신청할 수 없다.]")
@Test
void createChatInquiry_fails2() {
//given
Member inquirer = MemberFixture.member(1L);
Member answerer = MemberFixture.member(2L);
ReflectionTestUtils.setField(inquirer, "credit", CHAT_REWARD);
QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer);
CreateChatInquiryRequest request = new CreateChatInquiryRequest(
questionPost.getId(),
answerer.getId(),
INQUIRY_MESSAGE
);

given(questionPostRepository.findById(questionPost.getId()))
.willReturn(Optional.of(questionPost));
given(memberRepository.findById(answerer.getId()))
.willReturn(Optional.of(answerer));
given(answerRepository.existsByQuestionPostIdAndMember(questionPost.getId(), answerer))
.willReturn(false);

//when & then
assertThatThrownBy(() -> chatInquiryService.createChatInquiry(request, inquirer))
.isInstanceOf(ValidationException.class)
.hasMessageContaining(ChatInquiryErrorCode.NOT_EXISTS_ANSWERER.getMessage());
}

@DisplayName("[채팅 요청 아이디로 채팅 요청 상세를 조회할 수 있다.]")
@Test
void getChatInquiryById() {
Expand Down

0 comments on commit 1292aed

Please sign in to comment.