From 6a9ff9f04012cd9e5e098d9f31ba62d4598b4838 Mon Sep 17 00:00:00 2001 From: dudxo Date: Mon, 30 Sep 2024 19:20:39 +0900 Subject: [PATCH 1/5] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=95=8C=EB=A6=BC=20=ED=83=80=EC=9E=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dnd/gongmuin/notification/domain/NotificationType.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/dnd/gongmuin/notification/domain/NotificationType.java b/src/main/java/com/dnd/gongmuin/notification/domain/NotificationType.java index 66ce4f66..09bd9ee9 100644 --- a/src/main/java/com/dnd/gongmuin/notification/domain/NotificationType.java +++ b/src/main/java/com/dnd/gongmuin/notification/domain/NotificationType.java @@ -14,7 +14,9 @@ public enum NotificationType { ANSWER("답변"), CHOSEN("채택"), - CHAT("채팅"); + CHAT_REQUEST("채팅신청"), + CHAT_REJECT("채팅거절"), + CHAT_ACCEPT("채팅수락"); private final String label; From 1fbb974bfbd8c6132dc9ba72623c2c43bc82ac64 Mon Sep 17 00:00:00 2001 From: dudxo Date: Mon, 30 Sep 2024 19:22:43 +0900 Subject: [PATCH 2/5] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=8B=9C=20=EC=B1=84=ED=8C=85=20=EC=8B=A0?= =?UTF-8?q?=EC=B2=AD=20=EC=95=8C=EB=A6=BC=20=EC=9D=B4=EB=B2=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=B0=9C=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gongmuin/chat/service/ChatRoomService.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) 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 69dced06..7c79a28e 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -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; @@ -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; @@ -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())) { @@ -68,10 +73,17 @@ public PageResponse 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 ); } From 6c16de8fb2556dc73a9591dcb30d933ab0636141 Mon Sep 17 00:00:00 2001 From: dudxo Date: Mon, 30 Sep 2024 19:24:39 +0900 Subject: [PATCH 3/5] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EC=88=98=EB=9D=BD=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=9C=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dnd/gongmuin/chat/service/ChatRoomService.java | 4 ++++ 1 file changed, 4 insertions(+) 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 7c79a28e..969d312b 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -132,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); } From 309f2ca8ab64aaf6924fd7f51e3ae90ea5d04283 Mon Sep 17 00:00:00 2001 From: dudxo Date: Mon, 30 Sep 2024 19:25:10 +0900 Subject: [PATCH 4/5] =?UTF-8?q?[feat]=20:=20=EC=B1=84=ED=8C=85=EB=B0=A9=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EA=B1=B0=EC=A0=88=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EB=B0=9C=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/dnd/gongmuin/chat/service/ChatRoomService.java | 4 ++++ 1 file changed, 4 insertions(+) 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 969d312b..ffe4de2b 100644 --- a/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java +++ b/src/main/java/com/dnd/gongmuin/chat/service/ChatRoomService.java @@ -145,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); } From ac3765bca2eee3960a01bf8aa84b5d47981cc2b6 Mon Sep 17 00:00:00 2001 From: dudxo Date: Mon, 30 Sep 2024 20:04:52 +0900 Subject: [PATCH 5/5] =?UTF-8?q?[test]=20:=20=EC=B1=84=ED=8C=85=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=95=8C=EB=A6=BC=20=EC=83=9D=EC=84=B1=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chat/service/ChatRoomServiceTest.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) 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 ddf00f78..4fc567cd 100644 --- a/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java +++ b/src/test/java/com/dnd/gongmuin/chat/service/ChatRoomServiceTest.java @@ -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; @@ -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; @@ -57,6 +59,9 @@ class ChatRoomServiceTest { @Mock private QuestionPostRepository questionPostRepository; + @Mock + private ApplicationEventPublisher eventPublisher; + @InjectMocks private ChatRoomService chatRoomService; @@ -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() { @@ -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() { @@ -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)) + ); + } } \ No newline at end of file