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

[fix #179] 채팅 요청 답변자 검증 로직 추가 #185

Merged
merged 5 commits into from
Jan 9, 2025
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
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) {
hyun2371 marked this conversation as resolved.
Show resolved Hide resolved
if (!answerRepository.existsByQuestionPostIdAndMember(questionPostId, answerer)) {
throw new ValidationException(ChatInquiryErrorCode.NOT_EXISTS_ANSWERER);
}
}

private void saveInquirerCreditHistory(Member inquirer) {
hyun2371 marked this conversation as resolved.
Show resolved Hide resolved
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
Loading