Skip to content

Commit

Permalink
[feat #115] �채팅 신청/수락/거절 알림 API (#124)
Browse files Browse the repository at this point in the history
* [feat] : 채팅 관련 알림 타입 추가

* [feat] : 채팅방 생성 시 채팅 신청 알림 이벤트 발행

* [feat] : 채팅방 요청 수락 알림 이벤트 발행

* [feat] : 채팅방 요청 거절 알림 이벤트 발행

* [test] : 채팅 관련 알림 생성 단위 테스트 추가
  • Loading branch information
dudxo authored Sep 30, 2024
1 parent 67b4cee commit 32c36f1
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 4 deletions.
26 changes: 23 additions & 3 deletions src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.dnd.gongmuin.chat.service;

import static com.dnd.gongmuin.notification.domain.NotificationType.*;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
Expand Down Expand Up @@ -33,6 +36,7 @@
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.exception.MemberErrorCode;
import com.dnd.gongmuin.member.repository.MemberRepository;
import com.dnd.gongmuin.notification.dto.NotificationEvent;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.dto.response.MemberInfo;
import com.dnd.gongmuin.question_post.exception.QuestionPostErrorCode;
Expand All @@ -49,6 +53,7 @@ public class ChatRoomService {
private final ChatRoomRepository chatRoomRepository;
private final MemberRepository memberRepository;
private final QuestionPostRepository questionPostRepository;
private final ApplicationEventPublisher eventPublisher;

private static void validateIfAnswerer(Member member, ChatRoom chatRoom) {
if (!Objects.equals(member.getId(), chatRoom.getAnswerer().getId())) {
Expand All @@ -68,10 +73,17 @@ public PageResponse<ChatMessageResponse> getChatMessages(Long chatRoomId, Pageab
public ChatRoomDetailResponse createChatRoom(CreateChatRoomRequest request, Member inquirer) {
QuestionPost questionPost = getQuestionPostById(request.questionPostId());
Member answerer = getMemberById(request.answererId());

ChatRoom chatRoom = chatRoomRepository.save(
ChatRoomMapper.toChatRoom(questionPost, inquirer, answerer)
);

eventPublisher.publishEvent(
new NotificationEvent(CHAT_REQUEST, chatRoom.getId(), inquirer.getId(), answerer)
);

return ChatRoomMapper.toChatRoomDetailResponse(
chatRoomRepository.save(
ChatRoomMapper.toChatRoom(questionPost, inquirer, answerer)
),
chatRoom,
answerer
);
}
Expand Down Expand Up @@ -120,6 +132,10 @@ public AcceptChatResponse acceptChat(Long chatRoomId, Member member) {
validateIfAnswerer(member, chatRoom);
chatRoom.updateStatusAccepted();

eventPublisher.publishEvent(
new NotificationEvent(CHAT_ACCEPT, chatRoom.getId(), member.getId(), chatRoom.getInquirer())
);

return ChatRoomMapper.toAcceptChatResponse(chatRoom);
}

Expand All @@ -129,6 +145,10 @@ public RejectChatResponse rejectChat(Long chatRoomId, Member member) {
validateIfAnswerer(member, chatRoom);
chatRoom.updateStatusRejected();

eventPublisher.publishEvent(
new NotificationEvent(CHAT_REJECT, chatRoom.getId(), member.getId(), chatRoom.getInquirer())
);

return ChatRoomMapper.toRejectChatResponse(chatRoom);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public enum NotificationType {

ANSWER("답변"),
CHOSEN("채택"),
CHAT("채팅");
CHAT_REQUEST("채팅신청"),
CHAT_REJECT("채팅거절"),
CHAT_ACCEPT("채팅수락");

private final String label;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.SliceImpl;
import org.springframework.test.util.ReflectionTestUtils;
Expand All @@ -36,6 +37,7 @@
import com.dnd.gongmuin.member.domain.Member;
import com.dnd.gongmuin.member.exception.MemberErrorCode;
import com.dnd.gongmuin.member.repository.MemberRepository;
import com.dnd.gongmuin.notification.dto.NotificationEvent;
import com.dnd.gongmuin.question_post.domain.QuestionPost;
import com.dnd.gongmuin.question_post.repository.QuestionPostRepository;

Expand All @@ -57,6 +59,9 @@ class ChatRoomServiceTest {
@Mock
private QuestionPostRepository questionPostRepository;

@Mock
private ApplicationEventPublisher eventPublisher;

@InjectMocks
private ChatRoomService chatRoomService;

Expand Down Expand Up @@ -107,6 +112,37 @@ void createChatRoom() {
);
}

@DisplayName("[요청자가 채팅방을 생성 시 생성 알림이 발행된다.]")
@Test
void createChatRoomWithEventPublish() {
//given
Member inquirer = MemberFixture.member(1L);
Member answerer = MemberFixture.member(2L);
QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer);
CreateChatRoomRequest request = new CreateChatRoomRequest(
questionPost.getId(),
answerer.getId()
);
ChatRoom chatRoom = ChatRoomFixture.chatRoom(questionPost, inquirer, answerer);

given(questionPostRepository.findById(questionPost.getId()))
.willReturn(Optional.of(questionPost));
given(memberRepository.findById(answerer.getId()))
.willReturn(Optional.of(answerer));
given(chatRoomRepository.save(any(ChatRoom.class)))
.willReturn(chatRoom);

//when
ChatRoomDetailResponse response = chatRoomService.createChatRoom(request, inquirer);

//then
assertAll(
() -> assertThat(response.questionPostId()).isEqualTo(request.questionPostId()),
() -> assertThat(response.receiverInfo().memberId()).isEqualTo(request.answererId()),
() -> verify(eventPublisher, times(1)).publishEvent(any(NotificationEvent.class))
);
}

@DisplayName("[요청자의 크레딧이 2000미만이면 채팅방을 생성할 수 없다.]")
@Test
void createChatRoom_fail() {
Expand Down Expand Up @@ -229,6 +265,33 @@ void acceptChat() {
);
}

@DisplayName("[답변자가 채팅 요청을 수락할 때 채팅 수락 알림이 발행된다.]")
@Test
void acceptChatWithEventPublish() {
//given
Long chatRoomId = 1L;
Member inquirer = MemberFixture.member(1L);
Member answerer = MemberFixture.member(2L);
int previousCredit = answerer.getCredit();
QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer);
ChatRoom chatRoom = ChatRoomFixture.chatRoom(questionPost, inquirer, answerer);

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

//when
AcceptChatResponse response = chatRoomService.acceptChat(chatRoomId, answerer);

//then
assertAll(
() -> assertThat(response.chatStatus())
.isEqualTo(ChatStatus.ACCEPTED.getLabel()),
() -> assertThat(response.credit())
.isEqualTo(previousCredit + CHAT_REWARD),
() -> verify(eventPublisher, times(1)).publishEvent(any(NotificationEvent.class))
);
}

@DisplayName("[답변자가 채팅 요청을 거절할 수 있다.]")
@Test
void rejectChat() {
Expand All @@ -249,4 +312,27 @@ void rejectChat() {
assertThat(response.chatStatus())
.isEqualTo(ChatStatus.REJECTED.getLabel());
}

@DisplayName("[답변자가 채팅 요청을 거절할 때 채팅 거절 알림이 발행된다.]")
@Test
void rejectChatWithEventPublish() {
//given
Long chatRoomId = 1L;
Member inquirer = MemberFixture.member(1L);
Member answerer = MemberFixture.member(2L);
QuestionPost questionPost = QuestionPostFixture.questionPost(inquirer);
ChatRoom chatRoom = ChatRoomFixture.chatRoom(questionPost, inquirer, answerer);

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

//when
RejectChatResponse response = chatRoomService.rejectChat(chatRoomId, answerer);

//then
assertAll(
() -> assertThat(response.chatStatus()).isEqualTo(ChatStatus.REJECTED.getLabel()),
() -> verify(eventPublisher, times(1)).publishEvent(any(NotificationEvent.class))
);
}
}

0 comments on commit 32c36f1

Please sign in to comment.