feat(subbanner): 서브 배너 도메인과 링크 불변식을 추가한다
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.subbanner.domain
|
||||||
|
|
||||||
|
import java.time.LocalDateTime
|
||||||
|
|
||||||
|
data class SubBanner(
|
||||||
|
val id: Long? = null,
|
||||||
|
val placement: SubBannerPlacement,
|
||||||
|
val imagePath: String,
|
||||||
|
val webUrl: String?,
|
||||||
|
val androidDeepLink: String?,
|
||||||
|
val iosDeepLink: String?,
|
||||||
|
val startDate: LocalDateTime?,
|
||||||
|
val endDate: LocalDateTime?
|
||||||
|
) {
|
||||||
|
init {
|
||||||
|
require(!webUrl.isNullOrBlank() || !androidDeepLink.isNullOrBlank() || !iosDeepLink.isNullOrBlank()) {
|
||||||
|
"At least one link must be nonblank"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.subbanner.domain
|
||||||
|
|
||||||
|
enum class SubBannerPlacement {
|
||||||
|
HOME_RECOMMENDATION,
|
||||||
|
CONTENT_RECOMMENDATION
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package kr.co.vividnext.sodalive.v2.subbanner.domain
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Assertions.assertThrows
|
||||||
|
import org.junit.jupiter.api.DisplayName
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
class SubBannerTest {
|
||||||
|
@Test
|
||||||
|
@DisplayName("세 링크 중 하나 이상이 있는 7개 조합은 허용하고 모두 null이면 거부한다")
|
||||||
|
fun shouldRejectAllEmptyLinksAndAllowSevenNonEmptyCombinations() {
|
||||||
|
for (mask in 1..7) {
|
||||||
|
val webUrl = if (mask and 1 != 0) "https://example.com/banner?next=%2Fhome" else null
|
||||||
|
val androidDeepLink = if (mask and 2 != 0) "sodalive://content/123?from=banner" else null
|
||||||
|
val iosDeepLink = if (mask and 4 != 0) "sodalive-ios://content/123#detail" else null
|
||||||
|
|
||||||
|
val banner = banner(webUrl, androidDeepLink, iosDeepLink)
|
||||||
|
|
||||||
|
assertEquals(webUrl, banner.webUrl)
|
||||||
|
assertEquals(androidDeepLink, banner.androidDeepLink)
|
||||||
|
assertEquals(iosDeepLink, banner.iosDeepLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThrows(IllegalArgumentException::class.java) { banner(null, null, null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("null과 빈 문자열 및 공백만으로 된 모든 조합을 거부한다")
|
||||||
|
fun shouldRejectAllBlankLinksAndAllowAnyNonblankLink() {
|
||||||
|
val emptyLinks = listOf(null, "", " ", "\t\n")
|
||||||
|
for (webUrl in emptyLinks) {
|
||||||
|
for (androidDeepLink in emptyLinks) {
|
||||||
|
for (iosDeepLink in emptyLinks) {
|
||||||
|
assertThrows(IllegalArgumentException::class.java) { banner(webUrl, androidDeepLink, iosDeepLink) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("https://example.com", banner("https://example.com", " ", "").webUrl)
|
||||||
|
assertEquals("sodalive://home", banner(" ", "sodalive://home", "").androidDeepLink)
|
||||||
|
assertEquals("sodalive-ios://home", banner("", " ", "sodalive-ios://home").iosDeepLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun banner(webUrl: String?, androidDeepLink: String?, iosDeepLink: String?): SubBanner = SubBanner(
|
||||||
|
placement = SubBannerPlacement.HOME_RECOMMENDATION,
|
||||||
|
imagePath = "sub-banner/image.png",
|
||||||
|
webUrl = webUrl,
|
||||||
|
androidDeepLink = androidDeepLink,
|
||||||
|
iosDeepLink = iosDeepLink,
|
||||||
|
startDate = null,
|
||||||
|
endDate = null
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user