From b3ffa52e8fff414bf32f97e4587847993d850195 Mon Sep 17 00:00:00 2001 From: belljun3395 <195850@jnu.ac.kr> Date: Wed, 25 Sep 2024 22:55:41 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[Fix/#413]=20=ED=8F=89=EC=9D=BC=EC=97=90=20?= =?UTF-8?q?=EB=A7=A4=EC=9D=BC=20=EC=A0=84=EC=86=A1=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=95=9C=20=EA=B5=AC=EB=8F=85=EC=9D=B4=20=EB=B3=B4=EB=82=B4?= =?UTF-8?q?=EC=A7=80=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#414)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../article/reader/WorkBookSubscriberReader.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/batch/src/main/kotlin/com/few/batch/service/article/reader/WorkBookSubscriberReader.kt b/batch/src/main/kotlin/com/few/batch/service/article/reader/WorkBookSubscriberReader.kt index 3936a537f..4f018f1ab 100644 --- a/batch/src/main/kotlin/com/few/batch/service/article/reader/WorkBookSubscriberReader.kt +++ b/batch/src/main/kotlin/com/few/batch/service/article/reader/WorkBookSubscriberReader.kt @@ -45,10 +45,19 @@ class WorkBookSubscriberReader( } private fun sendDayCondition(sendDayField: TableField, sendDayCode: BatchDayCode): Condition { - return if (sendDayCode == BatchDayCode.MON_TUE_WED_THU_FRI_SAT_SUN) { - sendDayField.eq(BatchDayCode.MON_TUE_WED_THU_FRI.code).or(sendDayField.eq(BatchDayCode.MON_TUE_WED_THU_FRI_SAT_SUN.code)) - } else { - sendDayField.eq(sendDayCode.code) + return when (sendDayCode) { + /** 평일인 경우 매일을 포함하여 전송한다 */ + BatchDayCode.MON_TUE_WED_THU_FRI -> { + sendDayField.eq(BatchDayCode.MON_TUE_WED_THU_FRI.code) + .or(sendDayField.eq(BatchDayCode.MON_TUE_WED_THU_FRI_SAT_SUN.code)) + } + /** 매일의 경우 매일만 전송한다 */ + BatchDayCode.MON_TUE_WED_THU_FRI_SAT_SUN -> { + sendDayField.eq(BatchDayCode.MON_TUE_WED_THU_FRI_SAT_SUN.code) + } + else -> { + throw IllegalArgumentException("Invalid sendDayCode: $sendDayCode") + } } } } \ No newline at end of file From dc11b63408bbf14c196ff4009131a36c9a472b1e Mon Sep 17 00:00:00 2001 From: belljun3395 <195850@jnu.ac.kr> Date: Thu, 26 Sep 2024 21:26:51 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[Refactor/#415]=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=20=EC=A0=84=EC=86=A1=20=EB=AA=A9=EC=A0=81=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=20=ED=94=84=EB=A1=9C=EB=B0=94=EC=9D=B4=EB=8D=94=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=A0=84=EC=86=A1=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EB=B0=94=EC=9D=B4=EB=8D=94=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EA=B7=B8=EB=A6=AC=EA=B3=A0=20=EC=A0=84=EC=86=A1=20?= =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EC=8B=9D=EB=B3=84=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#416)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 이메일 전송 후 전송한 이메일 식벽을 위한 값 추가 * refactor: JavaEmailSendProvider 이메일 전송 후 전송한 이메일 식벽을 위한 값 추가 반영 * refactor: AwsSESEmailSendProvider 이메일 전송 후 전송한 이메일 식벽을 위한 값 추가 반영 * feat: aws 구성 구분을 위한 getWithConfigurationSetName 추가 * feat: ArticleAwsSESEmailSendProvider 구현 * refactor: 이메일 전송 프로바이더를 설정할 수 있도록 수정 * refactor: emailSendProvider ArticleAwsSESEmailSendProvider를 주입받도록 수정 * fix: 변경사항 테스트 반영 --- .../member/usecase/SaveMemberUseCaseTest.kt | 6 +++--- .../kotlin/com/few/email/sender/EmailSender.kt | 14 +++++++++++--- .../provider/ArticleAwsSESEmailSendProvider.kt | 17 +++++++++++++++++ .../sender/provider/AwsSESEmailSendProvider.kt | 17 ++++++++++++----- .../email/sender/provider/EmailSendProvider.kt | 5 ++++- .../sender/provider/JavaEmailSendProvider.kt | 3 ++- .../service/article/SendArticleEmailService.kt | 4 ++-- 7 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 email/src/main/kotlin/com/few/email/sender/provider/ArticleAwsSESEmailSendProvider.kt diff --git a/api/src/test/kotlin/com/few/api/domain/member/usecase/SaveMemberUseCaseTest.kt b/api/src/test/kotlin/com/few/api/domain/member/usecase/SaveMemberUseCaseTest.kt index 3b0f28650..84a483522 100644 --- a/api/src/test/kotlin/com/few/api/domain/member/usecase/SaveMemberUseCaseTest.kt +++ b/api/src/test/kotlin/com/few/api/domain/member/usecase/SaveMemberUseCaseTest.kt @@ -40,7 +40,7 @@ class SaveMemberUseCaseTest : BehaviorSpec({ val token = "encryptedToken" every { idEncryption.encrypt(any()) } returns token - every { sendAuthEmailService.send(any()) } returns Unit + every { sendAuthEmailService.send(any()) } returns "messageId" then("인증 이메일 발송 성공 응답을 반환한다") { val useCaseOut = useCase.execute(useCaseIn) @@ -64,7 +64,7 @@ class SaveMemberUseCaseTest : BehaviorSpec({ val token = "encryptedToken" every { idEncryption.encrypt(any()) } returns token - every { sendAuthEmailService.send(any()) } returns Unit + every { sendAuthEmailService.send(any()) } returns "messageId" then("인증 이메일 발송 성공 응답을 반환한다") { val useCaseOut = useCase.execute(useCaseIn) @@ -90,7 +90,7 @@ class SaveMemberUseCaseTest : BehaviorSpec({ val token = "encryptedToken" every { idEncryption.encrypt(any()) } returns token - every { sendAuthEmailService.send(any()) } returns Unit + every { sendAuthEmailService.send(any()) } returns "messageId" then("인증 이메일 발송 성공 응답을 반환한다") { val useCaseOut = useCase.execute(useCaseIn) diff --git a/email/src/main/kotlin/com/few/email/sender/EmailSender.kt b/email/src/main/kotlin/com/few/email/sender/EmailSender.kt index 3c7b13890..a4a47e173 100644 --- a/email/src/main/kotlin/com/few/email/sender/EmailSender.kt +++ b/email/src/main/kotlin/com/few/email/sender/EmailSender.kt @@ -6,15 +6,23 @@ import org.springframework.boot.autoconfigure.mail.MailProperties abstract class EmailSender>( private val mailProperties: MailProperties, - private val emailSendProvider: EmailSendProvider, + private val defaultEmailSendProvider: EmailSendProvider, ) { - fun send(args: T) { + fun send(args: T, emailSendProvider: EmailSendProvider? = null): String { val from = mailProperties.username val to = args.to val subject = args.subject val message = getHtml(args) - emailSendProvider.sendEmail("FEW Letter <$from>", to, subject, message) + return emailSendProvider?.sendEmail("FEW Letter <$from>", to, subject, message) + ?: run { + defaultEmailSendProvider.sendEmail( + "FEW Letter <$from>", + to, + subject, + message + ) + } } abstract fun getHtml(args: T): String diff --git a/email/src/main/kotlin/com/few/email/sender/provider/ArticleAwsSESEmailSendProvider.kt b/email/src/main/kotlin/com/few/email/sender/provider/ArticleAwsSESEmailSendProvider.kt new file mode 100644 index 000000000..f725045c1 --- /dev/null +++ b/email/src/main/kotlin/com/few/email/sender/provider/ArticleAwsSESEmailSendProvider.kt @@ -0,0 +1,17 @@ +package com.few.email.sender.provider + +import com.amazonaws.services.simpleemail.AmazonSimpleEmailService +import org.springframework.stereotype.Component + +@Component +class ArticleAwsSESEmailSendProvider( + amazonSimpleEmailService: AmazonSimpleEmailService, + javaEmailSendProvider: JavaEmailSendProvider, +) : AwsSESEmailSendProvider( + amazonSimpleEmailService, + javaEmailSendProvider +) { + override fun getWithConfigurationSetName(): String { + return "few-article-configuration-set" + } +} \ No newline at end of file diff --git a/email/src/main/kotlin/com/few/email/sender/provider/AwsSESEmailSendProvider.kt b/email/src/main/kotlin/com/few/email/sender/provider/AwsSESEmailSendProvider.kt index 5bbdaefc0..b649fa16c 100644 --- a/email/src/main/kotlin/com/few/email/sender/provider/AwsSESEmailSendProvider.kt +++ b/email/src/main/kotlin/com/few/email/sender/provider/AwsSESEmailSendProvider.kt @@ -4,11 +4,9 @@ import com.amazonaws.services.simpleemail.AmazonSimpleEmailService import com.amazonaws.services.simpleemail.model.* import io.github.oshai.kotlinlogging.KotlinLogging import org.springframework.context.annotation.Primary -import org.springframework.context.annotation.Profile import org.springframework.stereotype.Component @Primary -@Profile("prd") @Component class AwsSESEmailSendProvider( private val amazonSimpleEmailService: AmazonSimpleEmailService, @@ -19,7 +17,7 @@ class AwsSESEmailSendProvider( private const val UTF_8 = "utf-8" } - override fun sendEmail(from: String, to: String, subject: String, message: String) { + override fun sendEmail(from: String, to: String, subject: String, message: String): String { val destination = Destination().withToAddresses(to) val sendMessage = Message() .withSubject(Content().withCharset(UTF_8).withData(subject)) @@ -29,10 +27,10 @@ class AwsSESEmailSendProvider( .withSource(from) .withDestination(destination) .withMessage(sendMessage) - .withConfigurationSetName("few-configuration-set") + .withConfigurationSetName(getWithConfigurationSetName()) runCatching { - amazonSimpleEmailService.sendEmail(sendEmailRequest) + amazonSimpleEmailService.sendEmail(sendEmailRequest).messageId }.onFailure { log.warn { "Failed to send email using AWS SES. Falling back to JavaMailSender. Error: $it" @@ -48,6 +46,15 @@ class AwsSESEmailSendProvider( } throw it } + }.let { + return it.getOrThrow() } } + + /** + * Default configuration set name is "few-configuration-set" + */ + fun getWithConfigurationSetName(): String { + return "few-configuration-set" + } } \ No newline at end of file diff --git a/email/src/main/kotlin/com/few/email/sender/provider/EmailSendProvider.kt b/email/src/main/kotlin/com/few/email/sender/provider/EmailSendProvider.kt index 72ac099c8..85fb4287a 100644 --- a/email/src/main/kotlin/com/few/email/sender/provider/EmailSendProvider.kt +++ b/email/src/main/kotlin/com/few/email/sender/provider/EmailSendProvider.kt @@ -1,5 +1,8 @@ package com.few.email.sender.provider interface EmailSendProvider { - fun sendEmail(from: String, to: String, subject: String, message: String) + /** + * @return 전송한 이메일 식벽을 위한 값 + */ + fun sendEmail(from: String, to: String, subject: String, message: String): String } \ No newline at end of file diff --git a/email/src/main/kotlin/com/few/email/sender/provider/JavaEmailSendProvider.kt b/email/src/main/kotlin/com/few/email/sender/provider/JavaEmailSendProvider.kt index 0309d3bdc..fd9274d71 100644 --- a/email/src/main/kotlin/com/few/email/sender/provider/JavaEmailSendProvider.kt +++ b/email/src/main/kotlin/com/few/email/sender/provider/JavaEmailSendProvider.kt @@ -13,7 +13,7 @@ class JavaEmailSendProvider( companion object { private const val UTF_8 = "utf-8" } - override fun sendEmail(from: String, to: String, subject: String, message: String) { + override fun sendEmail(from: String, to: String, subject: String, message: String): String { val sendMessage: MimeMessage = emailSender.createMimeMessage() val helper = MimeMessageHelper(sendMessage, UTF_8) try { @@ -25,5 +25,6 @@ class JavaEmailSendProvider( throw RuntimeException(e) } emailSender.send(sendMessage) + return sendMessage.messageID } } \ No newline at end of file diff --git a/email/src/main/kotlin/com/few/email/service/article/SendArticleEmailService.kt b/email/src/main/kotlin/com/few/email/service/article/SendArticleEmailService.kt index 128a1dead..86898d7eb 100644 --- a/email/src/main/kotlin/com/few/email/service/article/SendArticleEmailService.kt +++ b/email/src/main/kotlin/com/few/email/service/article/SendArticleEmailService.kt @@ -1,7 +1,7 @@ package com.few.email.service.article import com.few.email.sender.EmailSender -import com.few.email.sender.provider.EmailSendProvider +import com.few.email.sender.provider.ArticleAwsSESEmailSendProvider import com.few.email.service.article.dto.SendArticleEmailArgs import org.springframework.boot.autoconfigure.mail.MailProperties import org.springframework.stereotype.Component @@ -13,7 +13,7 @@ import java.util.* @Component class SendArticleEmailService( mailProperties: MailProperties, - emailSendProvider: EmailSendProvider, + emailSendProvider: ArticleAwsSESEmailSendProvider, private val templateEngine: TemplateEngine, ) : EmailSender(mailProperties, emailSendProvider) { From ab6006d75e86b37bb1b6f4d6e8a4fe8296adca0c Mon Sep 17 00:00:00 2001 From: belljun3395 <195850@jnu.ac.kr> Date: Thu, 26 Sep 2024 21:27:17 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[Fix/#417]=20=EB=A9=A4=EB=B2=84=EA=B0=80=20?= =?UTF-8?q?=EA=B5=AC=EB=8F=85=20=EC=A0=84=EC=86=A1=20=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=EC=9D=84=20=EB=B3=80=EA=B2=BD=ED=95=9C=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=A1=9C=20=EC=B6=94=EA=B0=80=20=EA=B5=AC=EB=8F=85=ED=95=98?= =?UTF-8?q?=EC=97=AC=EB=8F=84=20=EA=B8=B0=EB=B3=B8=20=EA=B5=AC=EB=8F=85=20?= =?UTF-8?q?=EC=A0=84=EC=86=A1=20=EC=8B=9C=EA=B0=84=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EB=90=98=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20(#418)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 구독 전송 정보 조회 쿼리 생성 및 구독 생성 쿼리 수정 * fix: 멤버가 구독 전송 시간을 변경한 상태로 추가 구독하여도 기본 구독 전송 시간으로 생성되는 문제 해결 * fix: 변경 사항 반영 --- .../repo/dao/subscription/SubscriptionDao.kt | 20 +++++++++ .../InsertWorkbookSubscriptionCommand.kt | 5 +++ .../SelectSubscriptionSendStatusQuery.kt | 5 +++ .../record/SubscriptionSendStatus.kt | 10 +++++ .../usecase/SubscribeWorkbookUseCase.kt | 27 ++++++++++-- .../usecase/SubscribeWorkbookUseCaseTest.kt | 43 +++++++++++++++++++ 6 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/query/SelectSubscriptionSendStatusQuery.kt create mode 100644 api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/record/SubscriptionSendStatus.kt diff --git a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/SubscriptionDao.kt b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/SubscriptionDao.kt index 693a60945..20e0fb2da 100644 --- a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/SubscriptionDao.kt +++ b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/SubscriptionDao.kt @@ -42,6 +42,8 @@ class SubscriptionDao( dslContext.insertInto(SUBSCRIPTION) .set(SUBSCRIPTION.MEMBER_ID, command.memberId) .set(SUBSCRIPTION.TARGET_WORKBOOK_ID, command.workbookId) + .set(SUBSCRIPTION.SEND_DAY, command.sendDay) + .set(SUBSCRIPTION.SEND_TIME, command.sendTime) fun reSubscribeWorkbookSubscription(command: InsertWorkbookSubscriptionCommand) { reSubscribeWorkBookSubscriptionCommand(command) @@ -53,6 +55,8 @@ class SubscriptionDao( .set(SUBSCRIPTION.DELETED_AT, null as LocalDateTime?) .set(SUBSCRIPTION.UNSUBS_OPINION, null as String?) .set(SUBSCRIPTION.MODIFIED_AT, LocalDateTime.now()) + .set(SUBSCRIPTION.SEND_DAY, command.sendDay) + .set(SUBSCRIPTION.SEND_TIME, command.sendTime) .where(SUBSCRIPTION.MEMBER_ID.eq(command.memberId)) .and(SUBSCRIPTION.TARGET_WORKBOOK_ID.eq(command.workbookId)) @@ -282,4 +286,20 @@ class SubscriptionDao( .from(SUBSCRIPTION) .where(SUBSCRIPTION.MEMBER_ID.eq(query.memberId)) .and(SUBSCRIPTION.TARGET_WORKBOOK_ID.eq(query.workbookId)) + + fun selectSubscriptionSendStatus(query: SelectSubscriptionSendStatusQuery): List { + return selectSubscriptionSendStatusQuery(query) + .fetchInto(SubscriptionSendStatus::class.java) + } + + fun selectSubscriptionSendStatusQuery(query: SelectSubscriptionSendStatusQuery) = + dslContext.select( + SUBSCRIPTION.MEMBER_ID, + SUBSCRIPTION.TARGET_WORKBOOK_ID, + SUBSCRIPTION.SEND_TIME, + SUBSCRIPTION.SEND_DAY + ) + .from(SUBSCRIPTION) + .where(SUBSCRIPTION.MEMBER_ID.eq(query.memberId)) + .and(SUBSCRIPTION.DELETED_AT.isNull) } \ No newline at end of file diff --git a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/command/InsertWorkbookSubscriptionCommand.kt b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/command/InsertWorkbookSubscriptionCommand.kt index dcce7b894..b36985930 100644 --- a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/command/InsertWorkbookSubscriptionCommand.kt +++ b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/command/InsertWorkbookSubscriptionCommand.kt @@ -1,6 +1,11 @@ package com.few.api.repo.dao.subscription.command +import com.few.data.common.code.DayCode +import java.time.LocalTime + data class InsertWorkbookSubscriptionCommand( val workbookId: Long, val memberId: Long, + val sendDay: String? = DayCode.MON_TUE_WED_THU_FRI.code, + val sendTime: LocalTime? = LocalTime.of(8, 0), ) \ No newline at end of file diff --git a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/query/SelectSubscriptionSendStatusQuery.kt b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/query/SelectSubscriptionSendStatusQuery.kt new file mode 100644 index 000000000..3f07c581d --- /dev/null +++ b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/query/SelectSubscriptionSendStatusQuery.kt @@ -0,0 +1,5 @@ +package com.few.api.repo.dao.subscription.query + +data class SelectSubscriptionSendStatusQuery( + val memberId: Long, +) \ No newline at end of file diff --git a/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/record/SubscriptionSendStatus.kt b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/record/SubscriptionSendStatus.kt new file mode 100644 index 000000000..616c5f817 --- /dev/null +++ b/api-repo/src/main/kotlin/com/few/api/repo/dao/subscription/record/SubscriptionSendStatus.kt @@ -0,0 +1,10 @@ +package com.few.api.repo.dao.subscription.record + +import java.time.LocalTime + +data class SubscriptionSendStatus( + val memberId: Long, + val workbookId: Long, + val sendDay: String, + val sendTime: LocalTime, +) \ No newline at end of file diff --git a/api/src/main/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCase.kt b/api/src/main/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCase.kt index 7296d4f7a..fb04f3640 100644 --- a/api/src/main/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCase.kt +++ b/api/src/main/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCase.kt @@ -13,6 +13,7 @@ import com.few.api.domain.subscription.usecase.model.WorkbookSubscriptionStatus import com.few.api.exception.common.NotFoundException import com.few.api.exception.subscribe.SubscribeIllegalArgumentException import com.few.api.repo.dao.subscription.query.CountWorkbookMappedArticlesQuery +import com.few.api.repo.dao.subscription.query.SelectSubscriptionSendStatusQuery import org.springframework.context.ApplicationEventPublisher import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional @@ -28,10 +29,28 @@ class SubscribeWorkbookUseCase( fun execute(useCaseIn: SubscribeWorkbookUseCaseIn) { val subTargetWorkbookId = useCaseIn.workbookId val memberId = useCaseIn.memberId - val command = InsertWorkbookSubscriptionCommand( - memberId = memberId, - workbookId = subTargetWorkbookId - ) + + val command = subscriptionDao.selectSubscriptionSendStatus( + SelectSubscriptionSendStatusQuery( + memberId = memberId + ) + ).takeIf { + it.isNotEmpty() + }?.let { + /** 현재 구독 중인 정보가 있다면 해당 정보를 통해 구독 정보를 생성 */ + InsertWorkbookSubscriptionCommand( + memberId = memberId, + workbookId = subTargetWorkbookId, + sendDay = it[0].sendDay, + sendTime = it[0].sendTime + ) + } ?: run { + /** 현재 구독 중인 정보가 없다면 기본 정보로 구독 정보를 생성 */ + InsertWorkbookSubscriptionCommand( + memberId = memberId, + workbookId = subTargetWorkbookId + ) + } val workbookSubscriptionHistory = subscriptionDao.selectTopWorkbookSubscriptionStatus( SelectAllWorkbookSubscriptionStatusNotConsiderDeletedAtQuery( diff --git a/api/src/test/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCaseTest.kt b/api/src/test/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCaseTest.kt index dc0c18949..61ba5bf79 100644 --- a/api/src/test/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCaseTest.kt +++ b/api/src/test/kotlin/com/few/api/domain/subscription/usecase/SubscribeWorkbookUseCaseTest.kt @@ -3,7 +3,9 @@ package com.few.api.domain.subscription.usecase import com.few.api.domain.subscription.event.dto.WorkbookSubscriptionEvent import com.few.api.domain.subscription.usecase.dto.SubscribeWorkbookUseCaseIn import com.few.api.repo.dao.subscription.SubscriptionDao +import com.few.api.repo.dao.subscription.record.SubscriptionSendStatus import com.few.api.repo.dao.subscription.record.WorkbookSubscriptionStatus +import com.few.data.common.code.DayCode import io.github.oshai.kotlinlogging.KotlinLogging import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.BehaviorSpec @@ -13,6 +15,7 @@ import io.mockk.verify import io.mockk.just import io.mockk.Runs import org.springframework.context.ApplicationEventPublisher +import java.time.LocalTime class SubscribeWorkbookUseCaseTest : BehaviorSpec({ val log = KotlinLogging.logger {} @@ -33,6 +36,15 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ val useCaseIn = SubscribeWorkbookUseCaseIn(workbookId = workbookId, memberId = memberId) `when`("멤버의 구독 히스토리가 없는 경우") { + every { subscriptionDao.selectSubscriptionSendStatus(any()) } returns listOf( + SubscriptionSendStatus( + workbookId = workbookId, + memberId = memberId, + sendDay = DayCode.MON_TUE_WED_THU_FRI.code, + sendTime = LocalTime.of(8, 0) + ) + ) + every { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } returns null every { subscriptionDao.insertWorkbookSubscription(any()) } just Runs @@ -45,6 +57,7 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ then("구독한다") { useCase.execute(useCaseIn) + verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 1) { subscriptionDao.insertWorkbookSubscription(any()) } verify(exactly = 0) { subscriptionDao.countWorkbookMappedArticles(any()) } @@ -54,6 +67,15 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ } `when`("이미 구독한 히스토리가 있고 구독이 취소된 경우") { + every { subscriptionDao.selectSubscriptionSendStatus(any()) } returns listOf( + SubscriptionSendStatus( + workbookId = workbookId, + memberId = memberId, + sendDay = DayCode.MON_TUE_WED_THU_FRI.code, + sendTime = LocalTime.of(8, 0) + ) + ) + val day = 2 every { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } returns WorkbookSubscriptionStatus( workbookId = workbookId, @@ -74,6 +96,7 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ then("재구독한다") { useCase.execute(useCaseIn) + verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 0) { subscriptionDao.insertWorkbookSubscription(any()) } verify(exactly = 1) { subscriptionDao.countWorkbookMappedArticles(any()) } @@ -83,6 +106,15 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ } `when`("이미 구독한 히스토리가 있고 구독을 완료한 경우") { + every { subscriptionDao.selectSubscriptionSendStatus(any()) } returns listOf( + SubscriptionSendStatus( + workbookId = workbookId, + memberId = memberId, + sendDay = DayCode.MON_TUE_WED_THU_FRI.code, + sendTime = LocalTime.of(8, 0) + ) + ) + val day = 3 every { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } returns WorkbookSubscriptionStatus( workbookId = workbookId, @@ -103,6 +135,7 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ then("예외가 발생한다") { shouldThrow { useCase.execute(useCaseIn) } + verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 0) { subscriptionDao.insertWorkbookSubscription(any()) } verify(exactly = 1) { subscriptionDao.countWorkbookMappedArticles(any()) } @@ -112,12 +145,22 @@ class SubscribeWorkbookUseCaseTest : BehaviorSpec({ } `when`("구독 중인 경우") { + every { subscriptionDao.selectSubscriptionSendStatus(any()) } returns listOf( + SubscriptionSendStatus( + workbookId = workbookId, + memberId = memberId, + sendDay = DayCode.MON_TUE_WED_THU_FRI.code, + sendTime = LocalTime.of(8, 0) + ) + ) + val day = 2 every { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } returns WorkbookSubscriptionStatus(workbookId = workbookId, isActiveSub = true, day) then("예외가 발생한다") { shouldThrow { useCase.execute(useCaseIn) } + verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 1) { subscriptionDao.selectTopWorkbookSubscriptionStatus(any()) } verify(exactly = 0) { subscriptionDao.insertWorkbookSubscription(any()) } verify(exactly = 0) { subscriptionDao.countWorkbookMappedArticles(any()) }