Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ internal fun DataModule(
).registerSubtype(
TreeTargetingDto.VisitNodeDto::class.java,
TreeTargetingDto.VisitNodeDto.VISIT_JSON_NAME
).registerSubtype(
TreeTargetingDto.PushPermissionDto::class.java,
TreeTargetingDto.PushPermissionDto.PUSH_PERMISSION_JSON_NAME
)
).create()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ package cloud.mindbox.mobile_sdk.di.modules
import cloud.mindbox.mobile_sdk.abtests.CustomerAbMixer
import cloud.mindbox.mobile_sdk.abtests.CustomerAbMixerImpl
import cloud.mindbox.mobile_sdk.abtests.InAppABTestLogic
import cloud.mindbox.mobile_sdk.inapp.domain.CallbackInteractorImpl
import cloud.mindbox.mobile_sdk.inapp.domain.InAppProcessingManagerImpl
import cloud.mindbox.mobile_sdk.inapp.domain.InAppEventManagerImpl
import cloud.mindbox.mobile_sdk.inapp.domain.InAppFilteringManagerImpl
import cloud.mindbox.mobile_sdk.inapp.domain.InAppInteractorImpl
import cloud.mindbox.mobile_sdk.inapp.domain.*
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.interactors.CallbackInteractor
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.interactors.InAppInteractor
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.managers.InAppProcessingManager
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.managers.InAppEventManager
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.managers.InAppFilteringManager
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.managers.InAppProcessingManager
import cloud.mindbox.mobile_sdk.managers.UserVisitManager
import cloud.mindbox.mobile_sdk.managers.UserVisitManagerImpl

Expand Down Expand Up @@ -54,8 +50,7 @@ internal fun DomainModule(

override val inAppFilteringManager: InAppFilteringManager
get() = InAppFilteringManagerImpl(
inAppRepository = inAppRepository,
permissionManager = permissionManager
inAppRepository = inAppRepository
)

override val inAppABTestLogic: InAppABTestLogic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,11 @@ internal class InAppMapper {
segmentationExternalId = treeTargetingDto.segmentationExternalId!!,
segmentExternalId = treeTargetingDto.segmentExternalId!!
)

is TreeTargetingDto.PushPermissionDto -> TreeTargeting.PushPermissionNode(
type = TreeTargetingDto.PushPermissionDto.PUSH_PERMISSION_JSON_NAME,
value = treeTargetingDto.value!!
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ internal class InAppValidatorImpl(
GREATER_OR_EQUALS, LOWER_OR_EQUALS, EQUALS, NOT_EQUALS
) && (targeting.value?.let { it > 0 } == true)
}

is TreeTargetingDto.PushPermissionDto -> {
!targeting.type.isNullOrBlank() && targeting.value != null
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package cloud.mindbox.mobile_sdk.inapp.domain

import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.PermissionManager
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.managers.InAppFilteringManager
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.repositories.InAppRepository
import cloud.mindbox.mobile_sdk.inapp.domain.models.InApp
import cloud.mindbox.mobile_sdk.inapp.domain.models.InAppType
import cloud.mindbox.mobile_sdk.inapp.domain.models.Layer
import cloud.mindbox.mobile_sdk.logger.MindboxLoggerImpl
import cloud.mindbox.mobile_sdk.logger.mindboxLogI
import cloud.mindbox.mobile_sdk.models.InAppEventType

internal class InAppFilteringManagerImpl(
private val inAppRepository: InAppRepository,
private val permissionManager:PermissionManager
private val inAppRepository: InAppRepository
) :
InAppFilteringManager {

Expand Down Expand Up @@ -57,25 +52,5 @@ internal class InAppFilteringManagerImpl(
abtestsInAppsPool: Collection<String>
): List<InApp> = inApps.filter { inApp: InApp -> abtestsInAppsPool.contains(inApp.id) }

override fun filterPushInAppsByPermissionStatus(inApps: List<InApp>): List<InApp> =
if (permissionManager.isNotificationEnabled()) {
mindboxLogI("Notification already enabled. Remove pushAction inapps")
inApps.filter { inApp ->
inApp.form.variants.any { hasInAppImageLayerWithRedirectUrlAction(it) }
}
} else {
mindboxLogI("Notification doesn't enabled. Use all inapps")
inApps
}

private fun hasInAppImageLayerWithRedirectUrlAction(inAppVariant: InAppType): Boolean {
val layers = when (inAppVariant) {
is InAppType.Snackbar -> inAppVariant.layers
is InAppType.ModalWindow -> inAppVariant.layers
}
return layers.firstOrNull { layer ->
layer is Layer.ImageLayer && layer.action is Layer.ImageLayer.Action.RedirectUrlAction
} != null
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,8 @@ internal class InAppInteractorImpl(
if (isInAppShown()) inAppTargetingChannel.send(event)
!isInAppShown().also { mindboxLogD("InApp shown: $it") }
}.map { event ->
val filteredInApps =
inAppFilteringManager.filterUnShownInAppsByEvent(inApps, event).run {
inAppFilteringManager.filterPushInAppsByPermissionStatus(this)
}.also {
mindboxLogI("InApps was filtered by notification status")
}
val filteredInApps = inAppFilteringManager.filterUnShownInAppsByEvent(inApps, event)
mindboxLogI("Event: ${event.name} combined with $filteredInApps")

inAppProcessingManager.chooseInAppToShow(
filteredInApps,
event
Expand Down Expand Up @@ -110,10 +104,7 @@ internal class InAppInteractorImpl(
logI("Whole InApp list = $inApps")
logI("InApps that has already sent targeting ${inAppsMap.entries}")
inAppTargetingChannel.consumeAsFlow().collect { event ->
val filteredInApps =
inAppFilteringManager.filterUnShownInAppsByEvent(inApps, event).run {
inAppFilteringManager.filterPushInAppsByPermissionStatus(this)
}
val filteredInApps = inAppFilteringManager.filterInAppsByEvent(inApps, event)
logI("inapps for event $event are = $filteredInApps")
for (inApp in filteredInApps) {
if (inAppsMap[inApp.id]?.contains(event.hashCode()) != true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,4 @@ internal interface InAppFilteringManager {

fun filterABTestsInApps(inApps: List<InApp>, abtestsInAppsPool: Collection<String>): List<InApp>

fun filterPushInAppsByPermissionStatus(inApps: List<InApp>): List<InApp>

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cloud.mindbox.mobile_sdk.inapp.domain.models

import cloud.mindbox.mobile_sdk.di.mindboxInject
import cloud.mindbox.mobile_sdk.inapp.domain.interfaces.PermissionManager
import cloud.mindbox.mobile_sdk.logger.mindboxLogD
import cloud.mindbox.mobile_sdk.repository.MindboxPreferences

Expand Down Expand Up @@ -391,4 +392,33 @@ internal sealed class TreeTargeting(open val type: String) :
return emptySet()
}
}

internal data class PushPermissionNode(override val type: String, val value: Boolean): TreeTargeting(type) {

private val permissionManager: PermissionManager by mindboxInject { permissionManager }

override fun checkTargeting(data: TargetingData): Boolean {
return permissionManager.isNotificationEnabled() == value
}

override suspend fun fetchTargetingInfo(data: TargetingData) {
return
}

override fun hasSegmentationNode(): Boolean {
return false
}

override fun hasGeoNode(): Boolean {
return false
}

override fun hasOperationNode(): Boolean {
return false
}

override suspend fun getOperationsSet(): Set<String> {
return emptySet()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,15 @@ internal sealed class TreeTargetingDto {
const val VISIT_JSON_NAME = "visit"
}
}

internal data class PushPermissionDto(
@SerializedName("${"$"}type")
val type: String?,
@SerializedName("value")
val value: Boolean?
): TreeTargetingDto() {
companion object {
const val PUSH_PERMISSION_JSON_NAME = "pushEnabled"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1849,6 +1849,78 @@ internal class InAppValidatorTest {
)
}

@Test
fun `validate targeting dto is pushPermissionNode and value is null`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingPushPermissionNodeDto().copy(
type = "notBlank", value = null
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is pushPermissionNode and value is true`() {
assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingPushPermissionNodeDto().copy(
type = "notBlank", value = true
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is pushPermissionNode and value is false`() {
assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingPushPermissionNodeDto().copy(
type = "notBlank", value = false
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is pushPermissionNode and type is null`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingPushPermissionNodeDto().copy(
type = null, value = true
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `in-app version is lower than required`() {
val lowInAppVersion = Constants.SDK_VERSION_NUMERIC - 1
Expand Down
Loading