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 @@ -309,6 +309,9 @@ internal fun DataModule(
).registerSubtype(
TreeTargetingDto.ViewProductNodeDto::class.java,
TreeTargetingDto.ViewProductNodeDto.VIEW_PRODUCT_ID_JSON_NAME
).registerSubtype(
TreeTargetingDto.VisitNodeDto::class.java,
TreeTargetingDto.VisitNodeDto.VISIT_JSON_NAME
)
).create()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,12 @@ internal class InAppMapper {
)
}

is TreeTargetingDto.VisitNodeDto -> TreeTargeting.VisitNode(
TreeTargetingDto.VisitNodeDto.VISIT_JSON_NAME,
treeTargetingDto.kind.enumValue(),
treeTargetingDto.value!!
)

is TreeTargetingDto.TrueNodeDto -> TreeTargeting.TrueNode(TreeTargetingDto.TrueNodeDto.TRUE_JSON_NAME)
is TreeTargetingDto.IntersectionNodeDto -> TreeTargeting.IntersectionNode(
type = TreeTargetingDto.IntersectionNodeDto.AND_JSON_NAME,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ internal class InAppValidatorImpl(
ENDS_WITH
) && !targeting.value.isNullOrBlank()
}

is TreeTargetingDto.VisitNodeDto -> {
!targeting.type.isNullOrBlank() && targeting.kind.equalsAny(
GREATER_OR_EQUALS, LOWER_OR_EQUALS, EQUALS, NOT_EQUALS
) && (targeting.value?.let { it > 0 } == true)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А 0 не может быть?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

согласен что > 0
"value": 1 // required long > 0

}
}
}

Expand Down Expand Up @@ -182,5 +188,10 @@ internal class InAppValidatorImpl(
private const val NOT_SUBSTRING = "notSubstring"
private const val STARTS_WITH = "startsWith"
private const val ENDS_WITH = "endsWith"

private const val GREATER_OR_EQUALS = "gte"
private const val LOWER_OR_EQUALS = "lte"
private const val EQUALS = "equals"
private const val NOT_EQUALS = "notEquals"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cloud.mindbox.mobile_sdk.inapp.domain.models

import cloud.mindbox.mobile_sdk.di.mindboxInject
import cloud.mindbox.mobile_sdk.logger.mindboxLogD
import cloud.mindbox.mobile_sdk.repository.MindboxPreferences

internal interface ITargeting {
fun checkTargeting(data: TargetingData): Boolean
Expand Down Expand Up @@ -34,6 +35,13 @@ internal enum class Kind {
NEGATIVE
}

internal enum class KindVisit {
GTE,
LTE,
EQUALS,
NOT_EQUALS
}

internal enum class KindAny {
ANY,
NONE,
Expand Down Expand Up @@ -338,4 +346,49 @@ internal sealed class TreeTargeting(open val type: String) :
return false
}
}

internal data class VisitNode(override val type: String, val kind: KindVisit, val value: Long) :
TreeTargeting(type) {

override fun checkTargeting(data: TargetingData): Boolean {
val userVisitCount = MindboxPreferences.userVisitCount.toLong()
return when (kind) {
KindVisit.GTE -> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Зачем скобки ставить? мне нравится больше когда в одну строку
KindVisit.GTE -> value >= userVisitCount

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Я обычно всегда ставлю, на случай, что если придется что-то дописывать, то не пришлось бы их ставить потом. А у нас нет нигде какого-то код стайла, чтобы посмотреть как лучше писать

value >= userVisitCount
}

KindVisit.LTE -> {
value <= userVisitCount
}

KindVisit.EQUALS -> {
value == userVisitCount
}

KindVisit.NOT_EQUALS -> {
value != userVisitCount
}
}
}

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 @@ -170,5 +170,16 @@ internal sealed class TreeTargetingDto {
}
}


internal data class VisitNodeDto(
@SerializedName("${"$"}type")
val type: String?,
@SerializedName("kind")
val kind: String?,
@SerializedName("value")
val value: Long?
): TreeTargetingDto() {
companion object {
const val VISIT_JSON_NAME = "visit"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1651,6 +1651,204 @@ internal class InAppValidatorTest {
)
}

@Test
fun `validate targeting dto is visit node and its valid with gte`() {
Copy link
Collaborator

@sergeysozinov sergeysozinov Mar 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здесь бы получше было что-то такое validate targeting dto return true when is visit node and its valid with gte, но здесь сразу проверка, поэтому тест и так хорошо читается

assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "gte", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is visit node and its valid with lte`() {
assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "lte", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is visit node and its valid with equals`() {
assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "equals", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is visit node and its valid with not equals`() {
assertTrue(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "notEquals", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

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

@Test
fun `validate targeting dto is visit node and type is blank`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "", kind = "notBlank", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

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

@Test
fun `validate targeting dto is visit node and kind is blank`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

@Test
fun `validate targeting dto is visit node and kind is unknown`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "notBlank", value = 1L
), form = InAppStub.getInAppDto().form?.copy(
variants = listOf(
InAppStub.getModalWindowDto()
.copy(type = "def")
)
)
)
)
)
}

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

@Test
fun `validate targeting dto is visit node and value is less than 1`() {
assertFalse(
inAppValidator.validateInApp(
InAppStub.getInAppDto().copy(
targeting = InAppStub.getTargetingVisitNodeDto().copy(
type = "notBlank", kind = "notBlank", value = 0
), 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