diff --git a/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/AcceptClubServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/AcceptClubServiceImpl.kt index 5a308981..a6ee87cb 100644 --- a/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/AcceptClubServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/AcceptClubServiceImpl.kt @@ -5,18 +5,18 @@ import com.msg.gcms.domain.club.domain.entity.Club import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.club.enums.ClubStatus import com.msg.gcms.domain.club.exception.ClubNotFoundException +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import java.lang.Exception @Service @Transactional(rollbackFor = [Exception::class]) class AcceptClubServiceImpl( private val clubRepository: ClubRepository, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : AcceptClubService { override fun execute(clubId: Long) { val club = clubRepository.findByIdOrNull(clubId) ?: throw ClubNotFoundException() @@ -39,6 +39,14 @@ class AcceptClubServiceImpl( ) clubRepository.save(newClub) - messageSendUtil.send(club.user, "동아리 개설 승인", "동아리 개설 신청이 승인되었어요.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 개설 승인", + content = "동아리 개설 신청이 승인되었어요.", + type = SendType.CLUB + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/RejectClubServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/RejectClubServiceImpl.kt index 1284a3fb..50c8a521 100644 --- a/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/RejectClubServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/admin/service/impl/RejectClubServiceImpl.kt @@ -5,8 +5,9 @@ import com.msg.gcms.domain.admin.service.RejectClubService import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.club.enums.ClubStatus import com.msg.gcms.domain.club.exception.ClubNotFoundException +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -15,7 +16,7 @@ import org.springframework.transaction.annotation.Transactional @Transactional(rollbackFor = [Exception::class]) class RejectClubServiceImpl( private val clubRepository: ClubRepository, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : RejectClubService { override fun execute(clubId: Long) { val club = clubRepository.findByIdOrNull(clubId) ?: throw ClubNotFoundException() @@ -25,6 +26,14 @@ class RejectClubServiceImpl( } clubRepository.delete(club) - messageSendUtil.send(club.user, "동아리 개설 거절", "동아리 개설 신청이 거절되었어요.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 개설 거절", + content = "동아리 개설 신청이 거절되었어요.", + type = SendType.CLUB + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/AcceptApplicantServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/AcceptApplicantServiceImpl.kt index 8140350c..eec27916 100644 --- a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/AcceptApplicantServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/AcceptApplicantServiceImpl.kt @@ -14,9 +14,10 @@ import com.msg.gcms.domain.user.domain.entity.User import com.msg.gcms.domain.user.domain.repository.UserRepository import com.msg.gcms.domain.user.exception.UserNotFoundException import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import java.util.* @@ -28,7 +29,7 @@ class AcceptApplicantServiceImpl( private val userRepository: UserRepository, private val applicantConverter: ApplicantConverter, private val userUtil: UserUtil, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : AcceptApplicantService { override fun execute(clubId: Long, acceptDto: AcceptDto) { @@ -52,6 +53,13 @@ class AcceptApplicantServiceImpl( val clubMember = applicantConverter.toEntity(clubInfo, applicantUser) clubMemberRepository.save(clubMember) - messageSendUtil.send(applicantUser, "동아리 신청 수락", "${clubInfo.name}에 수락되셨습니다.", SendType.CLUB) + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = applicantUser, + title = "동아리 신청 수락", + content = "${clubInfo.name}에 수락되셨습니다.", + type = SendType.CLUB + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/CancelApplicationServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/CancelApplicationServiceImpl.kt index c90f2b55..9ae7ad18 100644 --- a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/CancelApplicationServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/CancelApplicationServiceImpl.kt @@ -6,9 +6,10 @@ import com.msg.gcms.domain.applicant.service.CancelApplicationService import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.club.exception.ClubNotFoundException import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull @ServiceWithTransaction @@ -16,7 +17,7 @@ class CancelApplicationServiceImpl( private val clubRepository: ClubRepository, private val applicantRepository: ApplicantRepository, private val userUtil: UserUtil, - private val messageSendUtil: MessageSendUtil, + private val applicationEventPublisher: ApplicationEventPublisher ) : CancelApplicationService { override fun execute(clubId: Long) { val club = clubRepository.findByIdOrNull(clubId) @@ -26,6 +27,14 @@ class CancelApplicationServiceImpl( .find { it.user == user } ?: throw NotApplicantException() applicantRepository.delete(applicant) - messageSendUtil.send(club.user, "동아리 신청 취소", "${user.nickname}님이 ${club.name}에 신청 취소했습니다.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 신청 취소", + content = "${user.nickname}님이 ${club.name}에 신청 취소했습니다.", + type = SendType.CLUB + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/ClubApplyServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/ClubApplyServiceImpl.kt index 9afaa7d9..6a00d72c 100644 --- a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/ClubApplyServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/ClubApplyServiceImpl.kt @@ -13,9 +13,10 @@ import com.msg.gcms.domain.club.exception.ClubNotFoundException import com.msg.gcms.domain.club.exception.ClubNotOpeningException import com.msg.gcms.domain.clubMember.domain.repository.ClubMemberRepository import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull @ServiceWithTransaction @@ -25,7 +26,7 @@ class ClubApplyServiceImpl( private val clubMemberRepository: ClubMemberRepository, private val applicantSaveUtil: ApplicantSaveUtil, private val applicantRepository: ApplicantRepository, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : ClubApplyService { override fun execute(clubId: Long): ClubApplyDto { val club = clubRepository.findByIdOrNull(clubId) @@ -46,7 +47,16 @@ class ClubApplyServiceImpl( throw DuplicateClubTypeApplicantException() val applicant = applicantSaveUtil.saveApplicant(club, user) - messageSendUtil.send(club.user, "동아리 신청 요청", "${user.nickname}님이 ${club.name}에 신청했습니다.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 신청 요청", + content = "${user.nickname}님이 ${club.name}에 신청했습니다.", + type = SendType.CLUB + ) + ) + return ClubApplyDto(applicant) } diff --git a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/RejectApplicantServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/RejectApplicantServiceImpl.kt index a58adbf8..10fc2832 100644 --- a/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/RejectApplicantServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/applicant/service/impl/RejectApplicantServiceImpl.kt @@ -13,9 +13,10 @@ import com.msg.gcms.domain.user.domain.entity.User import com.msg.gcms.domain.user.domain.repository.UserRepository import com.msg.gcms.domain.user.exception.UserNotFoundException import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import java.util.* @@ -25,7 +26,7 @@ class RejectApplicantServiceImpl( private val userRepository: UserRepository, private val applicantRepository: ApplicantRepository, private val userUtil: UserUtil, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : RejectApplicantService { override fun execute(clubId: Long, rejectDto: RejectDto) { val clubInfo: Club = clubRepository.findByIdOrNull(clubId) @@ -44,6 +45,13 @@ class RejectApplicantServiceImpl( applicantRepository.delete(applicant) - messageSendUtil.send(applicantUser, "동아리 신청 거절", "${clubInfo.name}에 거절되셨습니다.", SendType.CLUB) + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = applicantUser, + title = "동아리 신청 거절", + content = "${clubInfo.name}에 거절되셨습니다.", + type = SendType.CLUB + ) + ) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/DelegateHeadServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/DelegateHeadServiceImpl.kt index 1e294410..f134adad 100644 --- a/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/DelegateHeadServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/DelegateHeadServiceImpl.kt @@ -13,9 +13,10 @@ import com.msg.gcms.domain.clubMember.util.UpdateClubHeadUtil import com.msg.gcms.domain.user.domain.repository.UserRepository import com.msg.gcms.domain.user.exception.UserNotFoundException import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull @ServiceWithTransaction @@ -25,7 +26,7 @@ class DelegateHeadServiceImpl( private val userRepository: UserRepository, private val updateClubHeadUtil: UpdateClubHeadUtil, private val userUtil: UserUtil, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : DelegateHeadService { override fun execute(clubId: Long, delegateHeadDto: DelegateHeadDto): ChangeHeadDto { val club = (clubRepository.findByIdOrNull(clubId) @@ -40,7 +41,16 @@ class DelegateHeadServiceImpl( .find { it.user.id == delegateHeadDto.uuid } ?: throw NotClubMemberException() updateClubHeadUtil.updateClubHead(club, clubMember, head) - messageSendUtil.send(clubMember.user, "부장 위임", "${club.name}의 부장으로 위임되셨습니다.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = clubMember.user, + title = "부장 위임", + content = "${club.name}의 부장으로 위임되셨습니다.", + type = SendType.CLUB + ) + ) + return ChangeHeadDto(clubMember.user, head) } } \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/ExitClubMemberServiceImpl.kt b/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/ExitClubMemberServiceImpl.kt index 0b3ce42b..8dd5d3b3 100644 --- a/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/ExitClubMemberServiceImpl.kt +++ b/src/main/kotlin/com/msg/gcms/domain/clubMember/service/impl/ExitClubMemberServiceImpl.kt @@ -12,9 +12,10 @@ import com.msg.gcms.domain.clubMember.exception.ClubMemberReleaseNotFoundExcepti import com.msg.gcms.domain.clubMember.presentation.data.dto.ClubMemberExitDto import com.msg.gcms.domain.clubMember.service.ExitClubMemberService import com.msg.gcms.global.annotation.ServiceWithTransaction +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull @ServiceWithTransaction @@ -22,7 +23,7 @@ class ExitClubMemberServiceImpl( private val userUtil: UserUtil, private val clubRepository: ClubRepository, private val clubMemberRepository: ClubMemberRepository, - private val messageSendUtil: MessageSendUtil + private val applicationEventPublisher: ApplicationEventPublisher ) : ExitClubMemberService { override fun execute(clubMemberExitDto: ClubMemberExitDto) { val user = userUtil.fetchCurrentUser() @@ -36,7 +37,15 @@ class ExitClubMemberServiceImpl( } val memberRelease: ClubMember = getClubMemberToRelease(club, clubMemberExitDto.uuid) clubMemberRepository.delete(memberRelease) - messageSendUtil.send(memberRelease.user, "동아리 방출", "${club.name}에서 방출당했습니다.", SendType.CLUB) + + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = memberRelease.user, + title = "동아리 방출", + content = "${club.name}에서 방출당했습니다.", + type = SendType.CLUB + ) + ) } private fun getClubMemberToRelease(club: Club, uuid: String): ClubMember = diff --git a/src/main/kotlin/com/msg/gcms/domain/user/domain/entity/DeviceToken.kt b/src/main/kotlin/com/msg/gcms/domain/user/domain/entity/DeviceToken.kt index c4fa83d5..8631efa9 100644 --- a/src/main/kotlin/com/msg/gcms/domain/user/domain/entity/DeviceToken.kt +++ b/src/main/kotlin/com/msg/gcms/domain/user/domain/entity/DeviceToken.kt @@ -19,5 +19,5 @@ class DeviceToken ( @JoinColumn(name = "user_id", columnDefinition = "BINARY(16)") val user: User, - val token: String, + val token: String?, ) \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/global/event/SendMessageEvent.kt b/src/main/kotlin/com/msg/gcms/global/event/SendMessageEvent.kt new file mode 100644 index 00000000..46c87e03 --- /dev/null +++ b/src/main/kotlin/com/msg/gcms/global/event/SendMessageEvent.kt @@ -0,0 +1,11 @@ +package com.msg.gcms.global.event + +import com.msg.gcms.domain.user.domain.entity.User +import com.msg.gcms.global.fcm.enums.SendType + +data class SendMessageEvent( + val user: User, + val title: String, + val content: String, + val type: SendType +) \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/global/handler/MessageEventHandler.kt b/src/main/kotlin/com/msg/gcms/global/handler/MessageEventHandler.kt new file mode 100644 index 00000000..af08789e --- /dev/null +++ b/src/main/kotlin/com/msg/gcms/global/handler/MessageEventHandler.kt @@ -0,0 +1,40 @@ +package com.msg.gcms.global.handler + +import com.google.firebase.messaging.* +import com.msg.gcms.domain.user.domain.repository.DeviceTokenRepository +import com.msg.gcms.global.event.SendMessageEvent +import org.springframework.data.repository.findByIdOrNull +import org.springframework.stereotype.Component +import org.springframework.transaction.event.TransactionPhase +import org.springframework.transaction.event.TransactionalEventListener + +@Component +class MessageEventHandler( + private val deviceTokenRepository: DeviceTokenRepository +) { + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + fun send(sendMessageEvent: SendMessageEvent) { + val deviceToken = deviceTokenRepository.findByIdOrNull(sendMessageEvent.user.id) + ?: return + + if(!deviceToken.token.isNullOrBlank()) { + val message = Message.builder() + .setToken(deviceToken.token) + .putData("type", sendMessageEvent.type.name) + .setNotification( + Notification.builder() + .setTitle(sendMessageEvent.title) + .setBody(sendMessageEvent.content) + .build() + ) + .setApnsConfig( + ApnsConfig.builder() + .setAps(Aps.builder().setSound("default").build()) + .build() + ) + .build() + + FirebaseMessaging.getInstance().sendAsync(message) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/global/util/MessageSendUtil.kt b/src/main/kotlin/com/msg/gcms/global/util/MessageSendUtil.kt deleted file mode 100644 index 22017c72..00000000 --- a/src/main/kotlin/com/msg/gcms/global/util/MessageSendUtil.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.msg.gcms.global.util - -import com.msg.gcms.domain.user.domain.entity.User -import com.msg.gcms.global.fcm.enums.SendType -import java.util.* - -interface MessageSendUtil { - fun sendMessage(token: String, title: String, content: String, type: SendType) - fun send(user: User, title: String, content: String, type: SendType) -} \ No newline at end of file diff --git a/src/main/kotlin/com/msg/gcms/global/util/impl/MessageSendUtilImpl.kt b/src/main/kotlin/com/msg/gcms/global/util/impl/MessageSendUtilImpl.kt deleted file mode 100644 index eabcfda8..00000000 --- a/src/main/kotlin/com/msg/gcms/global/util/impl/MessageSendUtilImpl.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.msg.gcms.global.util.impl - -import com.google.firebase.messaging.* -import com.msg.gcms.domain.user.domain.entity.User -import com.msg.gcms.domain.user.domain.repository.DeviceTokenRepository -import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil -import org.springframework.data.repository.findByIdOrNull -import org.springframework.stereotype.Component - -@Component -class MessageSendUtilImpl( - private val deviceTokenRepository: DeviceTokenRepository, -) : MessageSendUtil { - override fun sendMessage(token: String, title: String, content: String, type: SendType) { - val message = Message.builder() - .setToken(token) - .putData("type", type.name) - .setNotification( - Notification.builder() - .setTitle(title) - .setBody(content) - .build() - ) - .setApnsConfig( - ApnsConfig.builder() - .setAps(Aps.builder().setSound("default").build()) - .build() - ) - .build() - - FirebaseMessaging.getInstance().sendAsync(message) - } - - override fun send(user: User, title: String, content: String, type: SendType) { - val deviceToken = deviceTokenRepository.findByIdOrNull(user.id) - ?: return - if(deviceToken.token == "" || deviceToken.token == null) - return - sendMessage(deviceToken.token, title, content, type) - } -} \ No newline at end of file diff --git a/src/test/kotlin/com/msg/gcms/domain/applicant/service/AcceptApplicantServiceTest.kt b/src/test/kotlin/com/msg/gcms/domain/applicant/service/AcceptApplicantServiceTest.kt index 517976f6..dd675c7c 100644 --- a/src/test/kotlin/com/msg/gcms/domain/applicant/service/AcceptApplicantServiceTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/applicant/service/AcceptApplicantServiceTest.kt @@ -9,13 +9,13 @@ import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.clubMember.domain.entity.ClubMember import com.msg.gcms.domain.clubMember.domain.repository.ClubMemberRepository import com.msg.gcms.domain.user.domain.repository.UserRepository -import com.msg.gcms.global.util.MessageSendUtil +import com.msg.gcms.global.event.SendMessageEvent +import com.msg.gcms.global.fcm.enums.SendType import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.core.spec.style.BehaviorSpec -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify +import io.mockk.* +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import java.util.* @@ -27,7 +27,7 @@ class AcceptApplicantServiceTest : BehaviorSpec({ val userRepository = mockk() val applicantConverter = mockk() val userUtil = mockk() - val messageSendUtil = mockk() + val applicationEventPublisher = mockk() val acceptApplicantService = AcceptApplicantServiceImpl( clubRepository = clubRepository, @@ -36,7 +36,7 @@ class AcceptApplicantServiceTest : BehaviorSpec({ clubMemberRepository = clubMemberRepository, userRepository = userRepository, userUtil = userUtil, - messageSendUtil = messageSendUtil + applicationEventPublisher = applicationEventPublisher ) given("동아리 ID와 유저가 주어졌을때") { @@ -66,6 +66,16 @@ class AcceptApplicantServiceTest : BehaviorSpec({ club = club ) } returns applicant + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = user, + title = "동아리 신청 수락", + content = "${club.name}에 수락되셨습니다.", + type = SendType.CLUB + ) + ) + } just Runs every { applicantRepository.delete(applicant) } returns Unit diff --git a/src/test/kotlin/com/msg/gcms/domain/applicant/service/CancelApplicationServiceTest.kt b/src/test/kotlin/com/msg/gcms/domain/applicant/service/CancelApplicationServiceTest.kt index 602d920b..94d50097 100644 --- a/src/test/kotlin/com/msg/gcms/domain/applicant/service/CancelApplicationServiceTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/applicant/service/CancelApplicationServiceTest.kt @@ -5,23 +5,22 @@ import com.msg.gcms.domain.applicant.repository.ApplicantRepository import com.msg.gcms.domain.applicant.service.impl.CancelApplicationServiceImpl import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.club.exception.ClubNotFoundException +import com.msg.gcms.global.event.SendMessageEvent import com.msg.gcms.global.fcm.enums.SendType -import com.msg.gcms.global.util.MessageSendUtil import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify +import io.mockk.* +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull class CancelApplicationServiceTest : BehaviorSpec({ val userUtil = mockk() val applicantRepository = mockk() val clubRepository = mockk() - val messageSendUtil = mockk() - val cancelApplicationServiceImpl = CancelApplicationServiceImpl(clubRepository, applicantRepository, userUtil, messageSendUtil) + val applicationEventPublisher = mockk() + val cancelApplicationServiceImpl = CancelApplicationServiceImpl(clubRepository, applicantRepository, userUtil, applicationEventPublisher) given("유저, 신청된 동아리가 주어지고"){ val user = TestUtils.TestDataUtil.user().entity() @@ -32,7 +31,17 @@ class CancelApplicationServiceTest : BehaviorSpec({ every { clubRepository.findByIdOrNull(club.id) } returns club every { applicantRepository.delete(applicant) } returns Unit every { userUtil.fetchCurrentUser() } returns user - every { messageSendUtil.send(user, "동아리 신청 취소", "${user.nickname}님이 ${club.name}에 신청 취소했습니다.", SendType.CLUB) } returns Unit + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 신청 취소", + content = "${user.nickname}님이 ${club.name}에 신청 취소했습니다.", + type = SendType.CLUB + ) + ) + } just Runs + `when`("서비스를 실행하면"){ cancelApplicationServiceImpl.execute(club.id) then("delete가 실행되어야함"){ diff --git a/src/test/kotlin/com/msg/gcms/domain/applicant/service/ClubApplyServiceTest.kt b/src/test/kotlin/com/msg/gcms/domain/applicant/service/ClubApplyServiceTest.kt index 1a9d0649..ac7b6dc0 100644 --- a/src/test/kotlin/com/msg/gcms/domain/applicant/service/ClubApplyServiceTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/applicant/service/ClubApplyServiceTest.kt @@ -6,20 +6,22 @@ import com.msg.gcms.domain.applicant.exception.DuplicateClubTypeApplicantExcepti import com.msg.gcms.domain.applicant.repository.ApplicantRepository import com.msg.gcms.domain.applicant.service.impl.ClubApplyServiceImpl import com.msg.gcms.domain.applicant.util.ApplicantSaveUtil -import com.msg.gcms.domain.club.domain.entity.Club import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.club.exception.ClubNotFoundException import com.msg.gcms.domain.clubMember.domain.entity.ClubMember import com.msg.gcms.domain.clubMember.domain.repository.ClubMemberRepository -import com.msg.gcms.domain.user.domain.entity.User -import com.msg.gcms.global.util.MessageSendUtil +import com.msg.gcms.global.event.SendMessageEvent +import com.msg.gcms.global.fcm.enums.SendType import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe +import io.mockk.Runs import io.mockk.every +import io.mockk.just import io.mockk.mockk +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull class ClubApplyServiceTest : BehaviorSpec({ @@ -28,15 +30,33 @@ class ClubApplyServiceTest : BehaviorSpec({ val clubMemberRepository = mockk() val applicantRepository = mockk() val applicantSaveUtil = mockk() - val messageSendUtil = mockk() + val applicationEventPublisher = mockk() - val clubApplyServiceImpl = ClubApplyServiceImpl(userUtil, clubRepository, clubMemberRepository, applicantSaveUtil, applicantRepository, messageSendUtil) + val clubApplyServiceImpl = ClubApplyServiceImpl(userUtil, clubRepository, clubMemberRepository, applicantSaveUtil, applicantRepository, applicationEventPublisher) given("유저와 동아리가 주어지고"){ val user = TestUtils.TestDataUtil.user().entity() - val club = TestUtils.TestDataUtil.club().entity() + val club = TestUtils.TestDataUtil.club().entity(true) val applicant = Applicant(1, club, user) - init(clubRepository, club, userUtil, user, clubMemberRepository, applicantRepository, applicantSaveUtil, applicant) + + every { clubRepository.findByIdOrNull(club.id) } returns club + every { userUtil.fetchCurrentUser() } returns user + every { applicantRepository.existsByUserAndClub(user, club) } returns false + every { clubMemberRepository.findByUserAndClub(user, club) } returns null + every { applicantRepository.countByClubTypeAndUser(club.type, user) } returns 0 + every { applicantSaveUtil.saveApplicant(club, user) } returns applicant + + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = club.user, + title = "동아리 신청 요청", + content = "${user.nickname}님이 ${club.name}에 신청했습니다.", + type = SendType.CLUB + ) + ) + } just Runs + `when`("서비스를 실행하면"){ val result = clubApplyServiceImpl.execute(club.id) then("결과값은 동일한 동아리와 유저를 가지고 있어야한다"){ @@ -48,26 +68,26 @@ class ClubApplyServiceTest : BehaviorSpec({ val club = TestUtils.TestDataUtil.club().entity(user) every { clubRepository.findByIdOrNull(club.id) } returns club every { clubMemberRepository.findByUserAndClub(user, club) } returns null + every { applicantRepository.existsByUserAndClub(user, club) } returns false then("AlreadyClubMemberException이 터져야 한다"){ shouldThrow { clubApplyServiceImpl.execute(club.id) } } } - init(clubRepository, club, userUtil, user, clubMemberRepository, applicantRepository, applicantSaveUtil, applicant) `when`("유저가 동아리 소속이라면"){ val tempClub = TestUtils.TestDataUtil.club().entity(user) val clubMember = ClubMember(1, tempClub, user) val club = TestUtils.TestDataUtil.club().entity(tempClub, listOf(clubMember)) every { clubRepository.findByIdOrNull(club.id) } returns club every { clubMemberRepository.findByUserAndClub(user, club) } returns clubMember + every { applicantRepository.existsByUserAndClub(user, club) } returns false then("AlreadyClubMemberException이 터져야 한다"){ shouldThrow { clubApplyServiceImpl.execute(club.id) } } } - init(clubRepository, club, userUtil, user, clubMemberRepository, applicantRepository, applicantSaveUtil, applicant) `when`("동아리를 못찾았으면"){ every { clubRepository.findByIdOrNull(club.id) } returns null then("ClubNotFoundException이 터져야 한다"){ @@ -76,8 +96,8 @@ class ClubApplyServiceTest : BehaviorSpec({ } } } - init(clubRepository, club, userUtil, user, clubMemberRepository, applicantRepository, applicantSaveUtil, applicant) `when`("같은 타입의 동아리에 신청했으면"){ + every { clubRepository.findByIdOrNull(club.id) } returns club every { applicantRepository.countByClubTypeAndUser(club.type, user) } returns 1 then("DuplicateClubTypeApplicantException"){ shouldThrow { @@ -86,21 +106,4 @@ class ClubApplyServiceTest : BehaviorSpec({ } } } -}) - -private fun init( - clubRepository: ClubRepository, - club: Club, - userUtil: UserUtil, - user: User, - clubMemberRepository: ClubMemberRepository, - applicantRepository: ApplicantRepository, - applicantSaveUtil: ApplicantSaveUtil, - applicant: Applicant -) { - every { clubRepository.findByIdOrNull(club.id) } returns club - every { userUtil.fetchCurrentUser() } returns user - every { clubMemberRepository.findByUserAndClub(user, club) } returns null - every { applicantRepository.countByClubTypeAndUser(club.type, user) } returns 0 - every { applicantSaveUtil.saveApplicant(club, user) } returns applicant -} \ No newline at end of file +}) \ No newline at end of file diff --git a/src/test/kotlin/com/msg/gcms/domain/applicant/service/RejectApplicantServiceTest.kt b/src/test/kotlin/com/msg/gcms/domain/applicant/service/RejectApplicantServiceTest.kt index 555a2fd2..91c148a2 100644 --- a/src/test/kotlin/com/msg/gcms/domain/applicant/service/RejectApplicantServiceTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/applicant/service/RejectApplicantServiceTest.kt @@ -9,13 +9,13 @@ import com.msg.gcms.domain.club.domain.repository.ClubRepository import com.msg.gcms.domain.clubMember.domain.entity.ClubMember import com.msg.gcms.domain.clubMember.domain.repository.ClubMemberRepository import com.msg.gcms.domain.user.domain.repository.UserRepository -import com.msg.gcms.global.util.MessageSendUtil +import com.msg.gcms.global.event.SendMessageEvent +import com.msg.gcms.global.fcm.enums.SendType import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.core.spec.style.BehaviorSpec -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify +import io.mockk.* +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull import java.util.* @@ -26,14 +26,14 @@ class RejectApplicantServiceTest : BehaviorSpec({ val userRepository = mockk() val applicantConverter = mockk() val userUtil = mockk() - val messageSendUtil = mockk() + val applicationEventPublisher = mockk() val rejectApplicantService = RejectApplicantServiceImpl( clubRepository = clubRepository, applicantRepository = applicantRepository, userRepository = userRepository, userUtil = userUtil, - messageSendUtil = messageSendUtil + applicationEventPublisher = applicationEventPublisher ) given("동아리 ID와 유저가 주어졌을때") { @@ -66,6 +66,17 @@ class RejectApplicantServiceTest : BehaviorSpec({ every { applicantRepository.delete(applicant) } returns Unit + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = user, + title = "동아리 신청 거절", + content = "${club.name}에 거절되셨습니다.", + type = SendType.CLUB + ) + ) + } just Runs + `when`("서비스를 실행하면") { rejectApplicantService.execute(1, rejectDto) then("delete가 실행되어야 함") { diff --git a/src/test/kotlin/com/msg/gcms/domain/clubmember/service/DelegateHeadServiceTest.kt b/src/test/kotlin/com/msg/gcms/domain/clubmember/service/DelegateHeadServiceTest.kt index 3c405954..0ac68f74 100644 --- a/src/test/kotlin/com/msg/gcms/domain/clubmember/service/DelegateHeadServiceTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/clubmember/service/DelegateHeadServiceTest.kt @@ -9,13 +9,17 @@ import com.msg.gcms.domain.clubMember.presentation.data.dto.DelegateHeadDto import com.msg.gcms.domain.clubMember.service.impl.DelegateHeadServiceImpl import com.msg.gcms.domain.clubMember.util.UpdateClubHeadUtil import com.msg.gcms.domain.user.domain.repository.UserRepository -import com.msg.gcms.global.util.MessageSendUtil +import com.msg.gcms.global.event.SendMessageEvent +import com.msg.gcms.global.fcm.enums.SendType import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.core.spec.style.BehaviorSpec import io.kotest.matchers.shouldBe +import io.mockk.Runs import io.mockk.every +import io.mockk.just import io.mockk.mockk +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull class DelegateHeadServiceTest : BehaviorSpec({ @@ -24,8 +28,10 @@ class DelegateHeadServiceTest : BehaviorSpec({ val userRepository = mockk() val clubMemberRepository = mockk() val updateClubHeadUtil = mockk() - val messageSendUtil = mockk() - val delegateHeadServiceImpl = DelegateHeadServiceImpl(clubRepository, clubMemberRepository, userRepository, updateClubHeadUtil, userUtil, messageSendUtil) + val applicationEventPublisher = mockk() + + val delegateHeadServiceImpl = DelegateHeadServiceImpl(clubRepository, clubMemberRepository, userRepository, updateClubHeadUtil, userUtil, applicationEventPublisher) + given("동아리, 부장, 동아리 멤버가 주어지고"){ val head = TestUtils.data().user().entity() val member = TestUtils.data().user().entity() @@ -68,6 +74,16 @@ class DelegateHeadServiceTest : BehaviorSpec({ every { userRepository.existsById(member.id) } returns true every { clubMemberRepository.findAllByClub(club) } returns listOf(clubMember) every { updateClubHeadUtil.updateClubHead(club, clubMember, head) } returns club + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = clubMember.user, + title = "부장 위임", + content = "${club.name}의 부장으로 위임되셨습니다.", + type = SendType.CLUB + ) + ) + } just Runs val request = DelegateHeadDto(uuid = member.id) `when`("서비스를 실행하면"){ val response = delegateHeadServiceImpl.execute(1, request) diff --git a/src/test/kotlin/com/msg/gcms/domain/clubmember/service/ExitClubMemberTest.kt b/src/test/kotlin/com/msg/gcms/domain/clubmember/service/ExitClubMemberTest.kt index ec05c875..0f2db179 100644 --- a/src/test/kotlin/com/msg/gcms/domain/clubmember/service/ExitClubMemberTest.kt +++ b/src/test/kotlin/com/msg/gcms/domain/clubmember/service/ExitClubMemberTest.kt @@ -7,22 +7,23 @@ import com.msg.gcms.domain.clubMember.domain.repository.ClubMemberRepository import com.msg.gcms.domain.clubMember.exception.ClubMemberExitOneSelfException import com.msg.gcms.domain.clubMember.presentation.data.dto.ClubMemberExitDto import com.msg.gcms.domain.clubMember.service.impl.ExitClubMemberServiceImpl -import com.msg.gcms.global.util.MessageSendUtil +import com.msg.gcms.global.event.SendMessageEvent +import com.msg.gcms.global.fcm.enums.SendType import com.msg.gcms.global.util.UserUtil import com.msg.gcms.testUtils.TestUtils import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec -import io.mockk.every -import io.mockk.mockk -import io.mockk.verify +import io.mockk.* +import org.springframework.context.ApplicationEventPublisher import org.springframework.data.repository.findByIdOrNull class ExitClubMemberTest : BehaviorSpec({ val userUtil = mockk() val clubRepository = mockk() val clubMemberRepository = mockk() - val messageSendUtil = mockk() - val exitClubMemberService = ExitClubMemberServiceImpl(userUtil, clubRepository, clubMemberRepository, messageSendUtil) + val applicationEventPublisher = mockk() + + val exitClubMemberService = ExitClubMemberServiceImpl(userUtil, clubRepository, clubMemberRepository, applicationEventPublisher) Given("clubMemberExitDto 주어졌을때") { val user = (1..2) @@ -32,10 +33,21 @@ class ExitClubMemberTest : BehaviorSpec({ .map { TestUtils.data().clubMember().entity(club, it) } var clubMemberExitDto = ClubMemberExitDto(clubId = club.id, user[0].id.toString()) every { userUtil.fetchCurrentUser() } returns club.user + When("해당 동아리에 멤버를 삭제 할 때") { every { clubRepository.findByIdOrNull(club.id) } returns club every { clubMemberRepository.findByClub(club) } returns clubMember every { clubMemberRepository.delete(clubMember[0]) } returns Unit + every { + applicationEventPublisher.publishEvent( + SendMessageEvent( + user = clubMember[0].user, + title = "동아리 방출", + content = "${club.name}에서 방출당했습니다.", + type = SendType.CLUB + ) + ) + } just Runs exitClubMemberService.execute(clubMemberExitDto) Then("그때 delete쿼리가 실행되어야함"){ verify(exactly = 1){ clubMemberRepository.delete(clubMember[0]) } diff --git a/src/test/kotlin/com/msg/gcms/testUtils/ClubDataUtil.kt b/src/test/kotlin/com/msg/gcms/testUtils/ClubDataUtil.kt index 6e61b057..6b8e1f90 100644 --- a/src/test/kotlin/com/msg/gcms/testUtils/ClubDataUtil.kt +++ b/src/test/kotlin/com/msg/gcms/testUtils/ClubDataUtil.kt @@ -93,7 +93,7 @@ object ClubDataUtil { teacher = teacher(), contact = contact(), type = ClubType.values().random(), - isOpened = nextBoolean(), + isOpened = true, user = user, activityImg = listOf(), applicant = listOf(),