test #445
@@ -53,7 +53,11 @@ class HomeRecommendationFacade(
|
|||||||
memberId = member?.id,
|
memberId = member?.id,
|
||||||
includeAdultLives = includeAdult
|
includeAdultLives = includeAdult
|
||||||
).map { it.toItem() },
|
).map { it.toItem() },
|
||||||
banners = queryService.findHomeBanners(HOME_BANNER_LIMIT, member?.id)
|
banners = queryService.findHomeBanners(
|
||||||
|
limit = HOME_BANNER_LIMIT,
|
||||||
|
memberId = member?.id,
|
||||||
|
includeAdultBanners = includeAdult
|
||||||
|
)
|
||||||
.map { RecommendationBannerResponse.from(it.toBanner()) },
|
.map { RecommendationBannerResponse.from(it.toBanner()) },
|
||||||
recentlyActiveCreators = queryService.findRecentlyActiveCreators(
|
recentlyActiveCreators = queryService.findRecentlyActiveCreators(
|
||||||
HOME_ACTIVE_CREATOR_LIMIT,
|
HOME_ACTIVE_CREATOR_LIMIT,
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ class DefaultAudioRecommendationQueryRepository(
|
|||||||
.leftJoin(series.member, seriesOwner)
|
.leftJoin(series.member, seriesOwner)
|
||||||
.where(
|
.where(
|
||||||
audioContentBanner.isActive.isTrue,
|
audioContentBanner.isActive.isTrue,
|
||||||
audioContentBanner.tab.isNull,
|
audioContentBanner.tab.id.eq(2L),
|
||||||
|
adultBannerCondition(canViewAdultContent),
|
||||||
activeBannerTargetCondition(memberId, bannerCreator, seriesOwner)
|
activeBannerTargetCondition(memberId, bannerCreator, seriesOwner)
|
||||||
)
|
)
|
||||||
.orderBy(audioContentBanner.orders.asc(), randomTieBreaker.asc())
|
.orderBy(audioContentBanner.orders.asc(), randomTieBreaker.asc())
|
||||||
@@ -544,6 +545,10 @@ class DefaultAudioRecommendationQueryRepository(
|
|||||||
return if (canViewAdultContent) null else series.isAdult.isFalse
|
return if (canViewAdultContent) null else series.isAdult.isFalse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun adultBannerCondition(canViewAdultContent: Boolean): BooleanExpression? {
|
||||||
|
return if (canViewAdultContent) null else audioContentBanner.isAdult.isFalse
|
||||||
|
}
|
||||||
|
|
||||||
private fun adultAudioCondition(canViewAdultContent: Boolean): BooleanExpression? {
|
private fun adultAudioCondition(canViewAdultContent: Boolean): BooleanExpression? {
|
||||||
return if (canViewAdultContent) null else audioContent.isAdult.isFalse
|
return if (canViewAdultContent) null else audioContent.isAdult.isFalse
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ class DefaultHomeRecommendationQueryRepository(
|
|||||||
|
|
||||||
override fun findHomeBanners(
|
override fun findHomeBanners(
|
||||||
limit: Int,
|
limit: Int,
|
||||||
memberId: Long?
|
memberId: Long?,
|
||||||
|
includeAdultBanners: Boolean
|
||||||
): List<HomeBannerRecommendationRecord> {
|
): List<HomeBannerRecommendationRecord> {
|
||||||
val bannerCreator = QMember("bannerCreator")
|
val bannerCreator = QMember("bannerCreator")
|
||||||
val seriesOwner = QMember("seriesOwner")
|
val seriesOwner = QMember("seriesOwner")
|
||||||
@@ -115,6 +116,7 @@ class DefaultHomeRecommendationQueryRepository(
|
|||||||
.where(
|
.where(
|
||||||
audioContentBanner.isActive.isTrue,
|
audioContentBanner.isActive.isTrue,
|
||||||
audioContentBanner.tab.isNull,
|
audioContentBanner.tab.isNull,
|
||||||
|
includeAdultBannerCondition(includeAdultBanners),
|
||||||
activeBannerTargetCondition(memberId, bannerCreator, seriesOwner)
|
activeBannerTargetCondition(memberId, bannerCreator, seriesOwner)
|
||||||
)
|
)
|
||||||
.orderBy(audioContentBanner.orders.asc(), randomTieBreaker.asc())
|
.orderBy(audioContentBanner.orders.asc(), randomTieBreaker.asc())
|
||||||
@@ -1265,6 +1267,10 @@ class DefaultHomeRecommendationQueryRepository(
|
|||||||
return if (includeAdultCommunities) null else creatorCommunity.isAdult.isFalse
|
return if (includeAdultCommunities) null else creatorCommunity.isAdult.isFalse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun includeAdultBannerCondition(includeAdultBanners: Boolean): BooleanExpression? {
|
||||||
|
return if (includeAdultBanners) null else audioContentBanner.isAdult.isFalse
|
||||||
|
}
|
||||||
|
|
||||||
private fun includeAdultLiveCondition(includeAdultLives: Boolean): BooleanExpression? {
|
private fun includeAdultLiveCondition(includeAdultLives: Boolean): BooleanExpression? {
|
||||||
return if (includeAdultLives) null else liveRoom.isAdult.isFalse
|
return if (includeAdultLives) null else liveRoom.isAdult.isFalse
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ class HomeRecommendationQueryService(
|
|||||||
|
|
||||||
fun findHomeBanners(
|
fun findHomeBanners(
|
||||||
limit: Int = DEFAULT_BANNER_LIMIT,
|
limit: Int = DEFAULT_BANNER_LIMIT,
|
||||||
memberId: Long? = null
|
memberId: Long? = null,
|
||||||
|
includeAdultBanners: Boolean = false
|
||||||
): List<HomeBannerRecommendationRecord> {
|
): List<HomeBannerRecommendationRecord> {
|
||||||
return queryPort.findHomeBanners(limit, memberId)
|
return queryPort.findHomeBanners(limit, memberId, includeAdultBanners)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findRecentlyActiveCreators(
|
fun findRecentlyActiveCreators(
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ interface HomeRecommendationQueryPort {
|
|||||||
|
|
||||||
fun findHomeBanners(
|
fun findHomeBanners(
|
||||||
limit: Int,
|
limit: Int,
|
||||||
memberId: Long? = null
|
memberId: Long? = null,
|
||||||
|
includeAdultBanners: Boolean = false
|
||||||
): List<HomeBannerRecommendationRecord>
|
): List<HomeBannerRecommendationRecord>
|
||||||
|
|
||||||
fun findRecentlyActiveCreators(
|
fun findRecentlyActiveCreators(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package kr.co.vividnext.sodalive.v2.api.home.application
|
package kr.co.vividnext.sodalive.v2.api.home.application
|
||||||
|
|
||||||
|
import kr.co.vividnext.sodalive.member.Member
|
||||||
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
import kr.co.vividnext.sodalive.member.contentpreference.MemberContentPreferenceService
|
||||||
import kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryService
|
import kr.co.vividnext.sodalive.v2.recommendation.application.HomeRecommendationQueryService
|
||||||
import kr.co.vividnext.sodalive.v2.recommendation.domain.RecommendedSectionType
|
import kr.co.vividnext.sodalive.v2.recommendation.domain.RecommendedSectionType
|
||||||
@@ -44,6 +45,17 @@ class HomeRecommendationFacadeTest {
|
|||||||
assertFalse(response.firstAudioContents[2].isPointAvailable)
|
assertFalse(response.firstAudioContents[2].isPointAvailable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("홈 추천은 회원의 성인 콘텐츠 조회 가능 여부를 배너 조회에 전달한다")
|
||||||
|
fun shouldPassAdultVisibilityToHomeBannerQuery() {
|
||||||
|
val member = Member(password = "password", nickname = "member").apply { id = 10L }
|
||||||
|
Mockito.doReturn(true).`when`(preferenceService).canViewAdultContent(member)
|
||||||
|
|
||||||
|
facade.getHomeRecommendations(member)
|
||||||
|
|
||||||
|
assertTrue(queryPort.bannerIncludeAdultBanners)
|
||||||
|
}
|
||||||
|
|
||||||
private fun firstAudio(price: Int, isPointAvailable: Boolean): HomeFirstAudioContentRecord {
|
private fun firstAudio(price: Int, isPointAvailable: Boolean): HomeFirstAudioContentRecord {
|
||||||
return HomeFirstAudioContentRecord(
|
return HomeFirstAudioContentRecord(
|
||||||
contentId = price.toLong() + 1,
|
contentId = price.toLong() + 1,
|
||||||
@@ -61,6 +73,7 @@ class HomeRecommendationFacadeTest {
|
|||||||
|
|
||||||
private class FakeHomeRecommendationQueryPort : HomeRecommendationQueryPort {
|
private class FakeHomeRecommendationQueryPort : HomeRecommendationQueryPort {
|
||||||
var firstAudioContents: List<HomeFirstAudioContentRecord> = emptyList()
|
var firstAudioContents: List<HomeFirstAudioContentRecord> = emptyList()
|
||||||
|
var bannerIncludeAdultBanners: Boolean = false
|
||||||
|
|
||||||
override fun findLiveRecommendations(
|
override fun findLiveRecommendations(
|
||||||
offset: Long,
|
offset: Long,
|
||||||
@@ -69,7 +82,14 @@ class HomeRecommendationFacadeTest {
|
|||||||
includeAdultLives: Boolean
|
includeAdultLives: Boolean
|
||||||
): List<HomeLiveRecommendationRecord> = emptyList()
|
): List<HomeLiveRecommendationRecord> = emptyList()
|
||||||
|
|
||||||
override fun findHomeBanners(limit: Int, memberId: Long?): List<HomeBannerRecommendationRecord> = emptyList()
|
override fun findHomeBanners(
|
||||||
|
limit: Int,
|
||||||
|
memberId: Long?,
|
||||||
|
includeAdultBanners: Boolean
|
||||||
|
): List<HomeBannerRecommendationRecord> {
|
||||||
|
bannerIncludeAdultBanners = includeAdultBanners
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
override fun findRecentlyActiveCreators(
|
override fun findRecentlyActiveCreators(
|
||||||
limit: Int,
|
limit: Int,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import kr.co.vividnext.sodalive.content.comment.AudioContentComment
|
|||||||
import kr.co.vividnext.sodalive.content.like.AudioContentLike
|
import kr.co.vividnext.sodalive.content.like.AudioContentLike
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBanner
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBanner
|
||||||
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerType
|
import kr.co.vividnext.sodalive.content.main.banner.AudioContentBannerType
|
||||||
|
import kr.co.vividnext.sodalive.content.main.tab.AudioContentMainTab
|
||||||
import kr.co.vividnext.sodalive.content.theme.AudioContentTheme
|
import kr.co.vividnext.sodalive.content.theme.AudioContentTheme
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
|
import kr.co.vividnext.sodalive.creator.admin.content.series.Series
|
||||||
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesContent
|
import kr.co.vividnext.sodalive.creator.admin.content.series.SeriesContent
|
||||||
@@ -41,25 +42,58 @@ class DefaultAudioRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
private val repository = DefaultAudioRecommendationQueryRepository(queryFactory, entityManager, "https://cdn.test")
|
private val repository = DefaultAudioRecommendationQueryRepository(queryFactory, entityManager, "https://cdn.test")
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("배너는 홈 추천 배너와 같은 활성/탭/차단 정책과 CDN URL을 적용한다")
|
@DisplayName("배너는 콘텐츠 추천 탭과 성인 조회 가능 여부를 적용한다")
|
||||||
fun shouldFindBannersWithHomeBannerPolicy() {
|
fun shouldFindBannersForContentRecommendationTabWithAdultVisibility() {
|
||||||
val viewer = saveMember("viewer", MemberRole.USER)
|
val viewer = saveMember("viewer", MemberRole.USER)
|
||||||
val visibleCreator = saveMember("visible-creator", MemberRole.CREATOR)
|
val visibleCreator = saveMember("visible-creator", MemberRole.CREATOR)
|
||||||
val blockedCreator = saveMember("blocked-creator", MemberRole.CREATOR)
|
val blockedCreator = saveMember("blocked-creator", MemberRole.CREATOR)
|
||||||
val visibleBanner = saveBanner("visible.png", AudioContentBannerType.CREATOR, 1, creator = visibleCreator)
|
val recommendationTab = saveContentRecommendationTab()
|
||||||
val adultBanner = saveBanner("adult.png", AudioContentBannerType.LINK, 2, isAdult = true, link = "https://adult.test")
|
val visibleBanner = saveBanner(
|
||||||
saveBanner("inactive.png", AudioContentBannerType.LINK, 2, isActive = false, link = "https://inactive.test")
|
"visible.png",
|
||||||
saveBanner("blocked.png", AudioContentBannerType.CREATOR, 3, creator = blockedCreator)
|
AudioContentBannerType.CREATOR,
|
||||||
|
1,
|
||||||
|
creator = visibleCreator,
|
||||||
|
tab = recommendationTab
|
||||||
|
)
|
||||||
|
val adultBanner = saveBanner(
|
||||||
|
"adult.png",
|
||||||
|
AudioContentBannerType.LINK,
|
||||||
|
2,
|
||||||
|
isAdult = true,
|
||||||
|
link = "https://adult.test",
|
||||||
|
tab = recommendationTab
|
||||||
|
)
|
||||||
|
saveBanner(
|
||||||
|
"inactive.png",
|
||||||
|
AudioContentBannerType.LINK,
|
||||||
|
3,
|
||||||
|
isActive = false,
|
||||||
|
link = "https://inactive.test",
|
||||||
|
tab = recommendationTab
|
||||||
|
)
|
||||||
|
saveBanner(
|
||||||
|
"blocked.png",
|
||||||
|
AudioContentBannerType.CREATOR,
|
||||||
|
4,
|
||||||
|
creator = blockedCreator,
|
||||||
|
tab = recommendationTab
|
||||||
|
)
|
||||||
|
saveBanner("home.png", AudioContentBannerType.LINK, 1, link = "https://home.test")
|
||||||
saveBlock(viewer, blockedCreator)
|
saveBlock(viewer, blockedCreator)
|
||||||
flushAndClear()
|
flushAndClear()
|
||||||
|
|
||||||
val banners = repository.findBanners(limit = 20, memberId = viewer.id, canViewAdultContent = false)
|
val safeBanners = repository.findBanners(limit = 20, memberId = viewer.id, canViewAdultContent = false)
|
||||||
|
val allBanners = repository.findBanners(limit = 20, memberId = viewer.id, canViewAdultContent = true)
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
listOf("https://cdn.test/${visibleBanner.thumbnailImage}", "https://cdn.test/${adultBanner.thumbnailImage}"),
|
listOf("https://cdn.test/${visibleBanner.thumbnailImage}"),
|
||||||
banners.map { it.imageUrl }
|
safeBanners.map { it.imageUrl }
|
||||||
)
|
)
|
||||||
assertEquals(visibleCreator.id, banners.first().creatorId)
|
assertEquals(
|
||||||
|
listOf("https://cdn.test/${visibleBanner.thumbnailImage}", "https://cdn.test/${adultBanner.thumbnailImage}"),
|
||||||
|
allBanners.map { it.imageUrl }
|
||||||
|
)
|
||||||
|
assertEquals(visibleCreator.id, safeBanners.first().creatorId)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -369,7 +403,8 @@ class DefaultAudioRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
isActive: Boolean = true,
|
isActive: Boolean = true,
|
||||||
isAdult: Boolean = false,
|
isAdult: Boolean = false,
|
||||||
creator: Member? = null,
|
creator: Member? = null,
|
||||||
link: String? = null
|
link: String? = null,
|
||||||
|
tab: AudioContentMainTab? = null
|
||||||
): AudioContentBanner {
|
): AudioContentBanner {
|
||||||
val banner = AudioContentBanner(
|
val banner = AudioContentBanner(
|
||||||
thumbnailImage = thumbnailImage,
|
thumbnailImage = thumbnailImage,
|
||||||
@@ -380,10 +415,18 @@ class DefaultAudioRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
)
|
)
|
||||||
banner.creator = creator
|
banner.creator = creator
|
||||||
banner.link = link
|
banner.link = link
|
||||||
|
banner.tab = tab
|
||||||
entityManager.persist(banner)
|
entityManager.persist(banner)
|
||||||
return banner
|
return banner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun saveContentRecommendationTab(): AudioContentMainTab {
|
||||||
|
entityManager.createNativeQuery(
|
||||||
|
"insert into audio_content_main_tab (id, title, is_active) values (2, '추천', true)"
|
||||||
|
).executeUpdate()
|
||||||
|
return entityManager.getReference(AudioContentMainTab::class.java, 2L)
|
||||||
|
}
|
||||||
|
|
||||||
private fun saveSeries(
|
private fun saveSeries(
|
||||||
title: String,
|
title: String,
|
||||||
creator: Member,
|
creator: Member,
|
||||||
|
|||||||
@@ -262,6 +262,36 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
assertEquals(listOf(homeBanner.thumbnailImage), banners.map { it.thumbnailImage })
|
assertEquals(listOf(homeBanner.thumbnailImage), banners.map { it.thumbnailImage })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("홈 배너는 성인 콘텐츠 조회가 불가능하면 비성인 배너만 반환한다")
|
||||||
|
fun shouldExcludeAdultHomeBannersWhenAdultContentIsNotVisible() {
|
||||||
|
val safeBanner = saveBanner(
|
||||||
|
"safe-home-banner.png",
|
||||||
|
AudioContentBannerType.LINK,
|
||||||
|
orders = 1,
|
||||||
|
isActive = true,
|
||||||
|
link = "https://safe-home-banner.test"
|
||||||
|
)
|
||||||
|
val adultBanner = saveBanner(
|
||||||
|
"adult-home-banner.png",
|
||||||
|
AudioContentBannerType.LINK,
|
||||||
|
orders = 2,
|
||||||
|
isActive = true,
|
||||||
|
isAdult = true,
|
||||||
|
link = "https://adult-home-banner.test"
|
||||||
|
)
|
||||||
|
flushAndClear()
|
||||||
|
|
||||||
|
val safeBanners = repository.findHomeBanners(limit = 20)
|
||||||
|
val allBanners = repository.findHomeBanners(limit = 20, includeAdultBanners = true)
|
||||||
|
|
||||||
|
assertEquals(listOf(safeBanner.thumbnailImage), safeBanners.map { it.thumbnailImage })
|
||||||
|
assertEquals(
|
||||||
|
listOf(safeBanner.thumbnailImage, adultBanner.thumbnailImage),
|
||||||
|
allBanners.map { it.thumbnailImage }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("홈 배너는 비활성 대상 엔티티를 제외하고 LINK는 배너 자체 활성 상태만으로 조회한다")
|
@DisplayName("홈 배너는 비활성 대상 엔티티를 제외하고 LINK는 배너 자체 활성 상태만으로 조회한다")
|
||||||
fun shouldExcludeHomeBannersWithInactiveTargetsExceptLink() {
|
fun shouldExcludeHomeBannersWithInactiveTargetsExceptLink() {
|
||||||
@@ -2658,6 +2688,7 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
type: AudioContentBannerType,
|
type: AudioContentBannerType,
|
||||||
orders: Int,
|
orders: Int,
|
||||||
isActive: Boolean,
|
isActive: Boolean,
|
||||||
|
isAdult: Boolean = false,
|
||||||
creator: Member? = null,
|
creator: Member? = null,
|
||||||
event: Event? = null,
|
event: Event? = null,
|
||||||
series: Series? = null,
|
series: Series? = null,
|
||||||
@@ -2668,7 +2699,7 @@ class DefaultHomeRecommendationQueryRepositoryTest @Autowired constructor(
|
|||||||
thumbnailImage = thumbnailImage,
|
thumbnailImage = thumbnailImage,
|
||||||
type = type,
|
type = type,
|
||||||
lang = Lang.KO,
|
lang = Lang.KO,
|
||||||
isAdult = false,
|
isAdult = isAdult,
|
||||||
isActive = isActive,
|
isActive = isActive,
|
||||||
orders = orders
|
orders = orders
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -86,12 +86,13 @@ class HomeRecommendationQueryServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("홈 배너 추천은 기본 20개를 활성 배너 조회 포트에 위임한다")
|
@DisplayName("홈 배너 추천은 기본 20개와 성인 노출 여부를 조회 포트에 위임한다")
|
||||||
fun shouldFindHomeBannersWithDefaultLimit() {
|
fun shouldFindHomeBannersWithDefaultLimit() {
|
||||||
val banners = service.findHomeBanners(memberId = 100L)
|
val banners = service.findHomeBanners(memberId = 100L, includeAdultBanners = true)
|
||||||
|
|
||||||
assertEquals(20, port.bannerLimit)
|
assertEquals(20, port.bannerLimit)
|
||||||
assertEquals(100L, port.bannerMemberId)
|
assertEquals(100L, port.bannerMemberId)
|
||||||
|
assertEquals(true, port.bannerIncludeAdultBanners)
|
||||||
assertEquals(port.banners, banners)
|
assertEquals(port.banners, banners)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,6 +965,7 @@ class HomeRecommendationQueryServiceTest {
|
|||||||
var liveIncludeAdultLives: Boolean? = null
|
var liveIncludeAdultLives: Boolean? = null
|
||||||
var bannerLimit: Int? = null
|
var bannerLimit: Int? = null
|
||||||
var bannerMemberId: Long? = null
|
var bannerMemberId: Long? = null
|
||||||
|
var bannerIncludeAdultBanners: Boolean? = null
|
||||||
var activeCreatorLimit: Int? = null
|
var activeCreatorLimit: Int? = null
|
||||||
var activeCreatorMemberId: Long? = null
|
var activeCreatorMemberId: Long? = null
|
||||||
var activeCreatorIncludeAdultActivities: Boolean? = null
|
var activeCreatorIncludeAdultActivities: Boolean? = null
|
||||||
@@ -1063,9 +1065,14 @@ class HomeRecommendationQueryServiceTest {
|
|||||||
return liveRecommendations
|
return liveRecommendations
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun findHomeBanners(limit: Int, memberId: Long?): List<HomeBannerRecommendationRecord> {
|
override fun findHomeBanners(
|
||||||
|
limit: Int,
|
||||||
|
memberId: Long?,
|
||||||
|
includeAdultBanners: Boolean
|
||||||
|
): List<HomeBannerRecommendationRecord> {
|
||||||
bannerLimit = limit
|
bannerLimit = limit
|
||||||
bannerMemberId = memberId
|
bannerMemberId = memberId
|
||||||
|
bannerIncludeAdultBanners = includeAdultBanners
|
||||||
return banners
|
return banners
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user