Skip to content

Commit

Permalink
[Refactor/#363] SubscribeWorkbookUseCase 모델 변환 (#365)
Browse files Browse the repository at this point in the history
* feat: WorkbookSubscriptionStatus 구현

* feat: WorkbookSubscriptionHistory 구현

* feat: CancelledWorkbookSubscriptionHistory 구현

* test: WorkbookSubscriptionHistoryTest 구현

* refactor: Subscribe 모델 적용하여 리펙토링

* refactor: workbookSubscriptionStatus 접근 제어자 protected로 수정

* chore: init 메서드 위치 수정

* refactor: 생성자 변경에 따른 테스트 수정
  • Loading branch information
belljun3395 authored Aug 27, 2024
1 parent 0eb26b2 commit dd4fb32
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import com.few.api.repo.dao.subscription.SubscriptionDao
import com.few.api.repo.dao.subscription.command.InsertWorkbookSubscriptionCommand
import com.few.api.repo.dao.subscription.query.SelectAllWorkbookSubscriptionStatusNotConsiderDeletedAtQuery
import com.few.api.domain.subscription.usecase.dto.SubscribeWorkbookUseCaseIn
import com.few.api.domain.subscription.usecase.model.CancelledWorkbookSubscriptionHistory
import com.few.api.domain.subscription.usecase.model.WorkbookSubscriptionHistory
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
Expand All @@ -27,24 +30,45 @@ class SubscribeWorkbookUseCase(
workbookId = subTargetWorkbookId
)

val subscriptionStatus = subscriptionDao.selectTopWorkbookSubscriptionStatus(
val workbookSubscriptionHistory = subscriptionDao.selectTopWorkbookSubscriptionStatus(
SelectAllWorkbookSubscriptionStatusNotConsiderDeletedAtQuery(memberId = memberId, workbookId = subTargetWorkbookId)
)
).run {
if (this != null) {
WorkbookSubscriptionHistory(
false,
WorkbookSubscriptionStatus(
workbookId = this.workbookId,
isActiveSub = this.isActiveSub,
day = this.day
)
)
} else {
WorkbookSubscriptionHistory(
true
)
}
}

when {
/** 구독한 히스토리가 없는 경우 */
subscriptionStatus == null -> {
workbookSubscriptionHistory.isNew -> {
subscriptionDao.insertWorkbookSubscription(command)
}

/** 이미 구독한 히스토리가 있고 구독이 취소된 경우 */
!subscriptionStatus.isActiveSub -> {
val lastDay = subscriptionDao.countWorkbookMappedArticles(CountWorkbookMappedArticlesQuery(subTargetWorkbookId)) ?: throw NotFoundException("workbook.notfound.id")
if (lastDay <= subscriptionStatus.day) {
workbookSubscriptionHistory.isCancelSub -> {
val cancelledWorkbookSubscriptionHistory = CancelledWorkbookSubscriptionHistory(workbookSubscriptionHistory)
val lastDay = CountWorkbookMappedArticlesQuery(subTargetWorkbookId).let {
subscriptionDao.countWorkbookMappedArticles(it)
} ?: throw NotFoundException("workbook.notfound.id")

if (cancelledWorkbookSubscriptionHistory.isSubEnd(lastDay)) {
/** 이미 구독이 종료된 경우 */
throw SubscribeIllegalArgumentException("subscribe.state.end")
} else {
/** 재구독인 경우 */
subscriptionDao.reSubscribeWorkbookSubscription(command)
}
/** 재구독 */
subscriptionDao.reSubscribeWorkbookSubscription(command)
}

/** 구독 중인 경우 */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.few.api.domain.subscription.usecase.model

class CancelledWorkbookSubscriptionHistory(
workbookSubscriptionHistory: WorkbookSubscriptionHistory,
) : WorkbookSubscriptionHistory(
workbookSubscriptionHistory
) {

init {
require(isCancelSub) {
"CanceledWorkbookSubscriptionHistory is not for active subscription."
}
}

/**
* 구독이 종료되었는지 여부 확인
*/
fun isSubEnd(lastDay: Int): Boolean {
return (lastDay <= workbookSubscriptionStatus!!.day)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.few.api.domain.subscription.usecase.model

open class WorkbookSubscriptionHistory(
val isNew: Boolean,
protected val workbookSubscriptionStatus: WorkbookSubscriptionStatus? = null,
) {

init {
if (isNew) {
require(workbookSubscriptionStatus == null) {
"If new subscription, workbookSubscriptionStatus should be null."
}
} else {
require(workbookSubscriptionStatus != null) {
"If not new subscription, workbookSubscriptionStatus should not be null."
}
}
}

constructor(workbookSubscriptionHistory: WorkbookSubscriptionHistory) : this(
workbookSubscriptionHistory.isNew,
workbookSubscriptionHistory.workbookSubscriptionStatus
)

/**
* 이전 구독 히스토리가 존재하고, 현재 구독이 취소된 경우
*/
val isCancelSub: Boolean
get() {
return !isNew && !workbookSubscriptionStatus!!.isActiveSub
}

val subDay: Int
get() {
return workbookSubscriptionStatus?.day ?: 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.few.api.domain.subscription.usecase.model

class WorkbookSubscriptionStatus(
val workbookId: Long,
val isActiveSub: Boolean,
val day: Int,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package com.few.api.domain.subscription.usecase.model

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test

class WorkbookSubscriptionHistoryTest {

@Test
fun `새로 생성된 구독인데 구독 상태가 존재하는 경우`() {
// given & when & then
assertThrows(IllegalArgumentException::class.java) {
WorkbookSubscriptionHistory(
isNew = true,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = true,
day = 1
)
)
}
}

@Test
fun `새로 생성된 구독이 아닌데 구독 상태가 존재하지 않는 경우`() {
// given & when & then
assertThrows(IllegalArgumentException::class.java) {
WorkbookSubscriptionHistory(
isNew = false
)
}
}

@Test
fun `새로 생성된 구독이 아니고 구독 상태가 취소된 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = false,
day = 1
)
)

// when
val isCancel = workbookSubscriptionHistory.isCancelSub

// then
assertTrue(isCancel)
}

@Test
fun `새로 생성된 구독이 아니고 구독 상태가 취소되지 않은 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = true,
day = 1
)
)

// when
val isCancel = workbookSubscriptionHistory.isCancelSub

// then
assertFalse(isCancel)
}

@Test
fun `새로 생성된 구독인 경우 구독 날짜`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = true
)

// when
val subDay = workbookSubscriptionHistory.subDay

// then
assertEquals(1, subDay)
}

@Test
fun `새로 생성된 구독이 아닌 경우 구독 날짜`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = true,
day = 2
)
)

// when
val subDay = workbookSubscriptionHistory.subDay

// then
assertEquals(2, subDay)
}

@Nested
inner class CancelledWorkbookSubscriptionHistoryTest {

@Test
fun `구독 취소된 히스토리가 취소되지 않은 구독 히스토리로 생성되는 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = true,
day = 1
)
)

// when & then
assertThrows(IllegalArgumentException::class.java) {
CancelledWorkbookSubscriptionHistory(workbookSubscriptionHistory)
}
}

@Test
fun `구독 취소된 히스토리가 새로운 구독 히스토리로 생성되는 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = true
)

// when & then
assertThrows(IllegalArgumentException::class.java) {
CancelledWorkbookSubscriptionHistory(workbookSubscriptionHistory)
}
}

@Test
fun `구독 취소된 히스토리가 종료된 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = false,
day = 1
)
)

// when
val cancelledWorkbookSubscriptionHistory = CancelledWorkbookSubscriptionHistory(workbookSubscriptionHistory)
val isSubEnd = cancelledWorkbookSubscriptionHistory.isSubEnd(1)

// then
assertTrue(isSubEnd)
}

@Test
fun `구독 취소된 히스토리가 종료되지 않은 경우`() {
// given
val workbookSubscriptionHistory = WorkbookSubscriptionHistory(
isNew = false,
workbookSubscriptionStatus = WorkbookSubscriptionStatus(
workbookId = 1,
isActiveSub = false,
day = 1
)
)

// when
val cancelledWorkbookSubscriptionHistory = CancelledWorkbookSubscriptionHistory(workbookSubscriptionHistory)
val isSubEnd = cancelledWorkbookSubscriptionHistory.isSubEnd(2)

// then
assertFalse(isSubEnd)
}
}
}

0 comments on commit dd4fb32

Please sign in to comment.