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()) }