Skip to content
Open
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 @@ -20,6 +20,7 @@ import com.sourcepoint.mobile_core.models.SPCampaignType.Preferences
import com.sourcepoint.mobile_core.models.SPCampaigns
import com.sourcepoint.mobile_core.models.SPError
import com.sourcepoint.mobile_core.models.SPIDFAStatus
import com.sourcepoint.mobile_core.models.SPInternalFlags
import com.sourcepoint.mobile_core.models.SPMessageLanguage
import com.sourcepoint.mobile_core.models.SPPropertyName
import com.sourcepoint.mobile_core.models.consents.CCPAConsent
Expand Down Expand Up @@ -64,10 +65,12 @@ class Coordinator(
private val campaigns: SPCampaigns,
private val repository: Repository = Repository(),
private val timeoutInSeconds: Int = 5,
private val internalFlags: SPInternalFlags = SPInternalFlags(),
private val spClient: SPClient = SourcepointClient(
accountId = accountId,
propertyId = propertyId,
requestTimeoutInSeconds = timeoutInSeconds
requestTimeoutInSeconds = timeoutInSeconds,
internalFlags = internalFlags
),
internal var state: State = repository.state ?: State(accountId = accountId, propertyId = propertyId),
private var authId: String? = state.authId,
Expand Down Expand Up @@ -141,13 +144,15 @@ class Coordinator(
propertyName: SPPropertyName,
campaigns: SPCampaigns,
timeoutInSeconds: Int = 5,
internalFlags: SPInternalFlags = SPInternalFlags()
): this(
accountId = accountId,
propertyId = propertyId,
propertyName = propertyName,
campaigns = campaigns,
repository = Repository(),
timeoutInSeconds = timeoutInSeconds
timeoutInSeconds = timeoutInSeconds,
internalFlags = internalFlags
)

@Suppress("Unused")
Expand All @@ -157,14 +162,16 @@ class Coordinator(
propertyName: SPPropertyName,
campaigns: SPCampaigns,
timeoutInSeconds: Int = 5,
state: State? = null
state: State? = null,
internalFlags: SPInternalFlags = SPInternalFlags()
): this(
accountId = accountId,
propertyId = propertyId,
propertyName = propertyName,
campaigns = campaigns,
state = state ?: Repository().state ?: State(accountId = accountId, propertyId = propertyId),
timeoutInSeconds = timeoutInSeconds
timeoutInSeconds = timeoutInSeconds,
internalFlags = internalFlags
)

init {
Expand Down Expand Up @@ -1115,4 +1122,6 @@ class Coordinator(
override fun setTranslateMessage(value: Boolean) {
includeData.translateMessage = value
}

override suspend fun getUsnatLocation() = spClient.getUsnatLocation()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.sourcepoint.mobile_core.models.SPMessageLanguage
import com.sourcepoint.mobile_core.models.SPNetworkError
import com.sourcepoint.mobile_core.models.SPUnknownNetworkError
import com.sourcepoint.mobile_core.models.consents.SPUserData
import com.sourcepoint.mobile_core.network.responses.UsnatLocationResponse
import kotlinx.serialization.json.JsonObject
import kotlin.coroutines.cancellation.CancellationException

Expand Down Expand Up @@ -58,4 +59,7 @@ interface ICoordinator {
fun clearLocalData()

fun setTranslateMessage(value: Boolean)

@Throws(CancellationException::class)
suspend fun getUsnatLocation(): UsnatLocationResponse
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ enum class InvalidAPICode(val type: String) {
GDPR_PRIVACY_MANAGER("_GDPR-privacy-manager"),
CCPA_MESSAGE("_CCPA-message"),
GDPR_MESSAGE("_GDPR-message"),
USNAT_LOCATION(type = "_usnat_location"),
EMPTY("")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sourcepoint.mobile_core.models

data class SPInternalFlags(
val usePreprod: Boolean = false,
val geoOverride: String? = null,
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@file:Suppress("unused")
package com.sourcepoint.mobile_core.models

import kotlinx.serialization.KSerializer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.sourcepoint.mobile_core.models.SPCampaignType
import com.sourcepoint.mobile_core.models.SPClientTimeout
import com.sourcepoint.mobile_core.models.SPError
import com.sourcepoint.mobile_core.models.SPIDFAStatus
import com.sourcepoint.mobile_core.models.SPInternalFlags
import com.sourcepoint.mobile_core.models.SPNetworkError
import com.sourcepoint.mobile_core.models.SPUnableToParseBodyError
import com.sourcepoint.mobile_core.models.consents.GDPRConsent
Expand Down Expand Up @@ -39,6 +40,7 @@ import com.sourcepoint.mobile_core.network.responses.MetaDataResponse
import com.sourcepoint.mobile_core.network.responses.PreferencesChoiceResponse
import com.sourcepoint.mobile_core.network.responses.PvDataResponse
import com.sourcepoint.mobile_core.network.responses.USNatChoiceResponse
import com.sourcepoint.mobile_core.network.responses.UsnatLocationResponse
import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.call.body
Expand Down Expand Up @@ -114,6 +116,9 @@ interface SPClient {
@Throws(SPNetworkError::class, SPUnableToParseBodyError::class, CancellationException::class, HttpRequestTimeoutException::class)
suspend fun getMessages(request: MessagesRequest): MessagesResponse

@Throws(SPNetworkError::class, SPUnableToParseBodyError::class, CancellationException::class, HttpRequestTimeoutException::class)
suspend fun getUsnatLocation(): UsnatLocationResponse

suspend fun postReportIdfaStatus(
propertyId: Int?,
uuid: String?,
Expand Down Expand Up @@ -151,7 +156,8 @@ class SourcepointClient(
private val propertyId: Int,
httpEngine: HttpClientEngine?,
private val device: DeviceInformation,
private val requestTimeoutInSeconds: Int
private val requestTimeoutInSeconds: Int,
private val internalFlags: SPInternalFlags
): SPClient {
private val config: HttpClientConfig<*>.() -> Unit = {
install(HttpTimeout) { requestTimeoutMillis = requestTimeoutInSeconds.toLong() * 1000 }
Expand Down Expand Up @@ -180,25 +186,33 @@ class SourcepointClient(
}
private val http = if (httpEngine != null) HttpClient(httpEngine, config) else HttpClient(config)

constructor(accountId: Int, propertyId: Int, requestTimeoutInSeconds: Int = 5) : this(
accountId,
propertyId,
constructor(
accountId: Int,
propertyId: Int,
requestTimeoutInSeconds: Int = 5,
internalFlags: SPInternalFlags = SPInternalFlags()
) : this(
accountId = accountId,
propertyId = propertyId,
httpEngine = null,
device = DeviceInformation(),
requestTimeoutInSeconds = requestTimeoutInSeconds
requestTimeoutInSeconds = requestTimeoutInSeconds,
internalFlags = internalFlags
)

constructor(
accountId: Int,
propertyId: Int,
httpEngine: HttpClientEngine,
requestTimeoutInSeconds: Int = 5,
internalFlags: SPInternalFlags = SPInternalFlags()
) : this(
accountId,
propertyId,
httpEngine = httpEngine,
device = DeviceInformation(),
requestTimeoutInSeconds = requestTimeoutInSeconds
requestTimeoutInSeconds = requestTimeoutInSeconds,
internalFlags = internalFlags
)

private val baseWrapperUrl = "https://cdn.privacy-mgmt.com/"
Expand All @@ -223,7 +237,7 @@ class SourcepointClient(
executeAPIRequest(PV_DATA) {
http.post(URLBuilder(baseWrapperUrl).apply {
path("wrapper", "v2", "pv-data")
withParams(DefaultRequest())
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()) {
contentType(ContentType.Application.Json)
setBody(request)
Expand Down Expand Up @@ -256,7 +270,7 @@ class SourcepointClient(
executeAPIRequest(endpoint) {
http.post(URLBuilder(baseWrapperUrl).apply {
path("wrapper", "v2", "choice", fromCampaign, actionType.type.toString())
withParams(DefaultRequest())
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()) {
contentType(ContentType.Application.Json)
setBody(request)
Expand Down Expand Up @@ -303,6 +317,14 @@ class SourcepointClient(
}.build()).bodyOr(::reportErrorAndThrow)
}

override suspend fun getUsnatLocation(): UsnatLocationResponse =
executeAPIRequest(USNAT_LOCATION) {
http.get(URLBuilder(baseWrapperUrl).apply {
path("usnat", "admin", "location")
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()).bodyOr(::reportErrorAndThrow)
}

override suspend fun postReportIdfaStatus(
propertyId: Int?,
uuid: String?,
Expand All @@ -316,7 +338,7 @@ class SourcepointClient(
executeAPIRequest(IDFA_STATUS) {
http.post(URLBuilder(baseWrapperUrl).apply {
path("wrapper", "metrics", "v1", "apple-tracking")
withParams(DefaultRequest())
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()) {
contentType(ContentType.Application.Json)
setBody(
Expand Down Expand Up @@ -348,7 +370,7 @@ class SourcepointClient(
executeAPIRequest(CUSTOM_CONSENT) {
http.post(URLBuilder(baseWrapperUrl).apply {
path("wrapper", "tcfv2", "v1", "gdpr", "custom-consent")
withParams(DefaultRequest())
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()) {
contentType(ContentType.Application.Json)
setBody(
Expand Down Expand Up @@ -392,7 +414,7 @@ class SourcepointClient(
executeAPIRequest(ERROR_METRICS) {
http.post(URLBuilder(baseWrapperUrl).apply {
path("wrapper", "metrics", "v1", "custom-metrics")
withParams(DefaultRequest())
withParams(DefaultRequest(geoOverride = internalFlags.geoOverride))
}.build()) {
contentType(ContentType.Application.Json)
setBody(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.sourcepoint.mobile_core.DeviceInformation
import kotlinx.serialization.Serializable

@Serializable
open class DefaultRequest {
open class DefaultRequest(val geoOverride: String? = null) {
val env = "prod"
val scriptType = "mobile-core-${DeviceInformation().osName.name}"
val scriptVersion = BuildConfig.Version
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.sourcepoint.mobile_core.network.responses

import kotlinx.serialization.Serializable

@Serializable
data class UsnatLocationResponse(
val countryCode: String? = null,
val stateCode: String? = null,
val regionCode: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.sourcepoint.mobile_core.models.SPActionType.*
import com.sourcepoint.mobile_core.models.SPCampaign
import com.sourcepoint.mobile_core.models.SPCampaignType.*
import com.sourcepoint.mobile_core.models.SPCampaigns
import com.sourcepoint.mobile_core.models.SPInternalFlags
import com.sourcepoint.mobile_core.models.SPMessageLanguage
import com.sourcepoint.mobile_core.models.SPMessageLanguage.ENGLISH
import com.sourcepoint.mobile_core.models.SPPropertyName
Expand Down Expand Up @@ -468,7 +469,7 @@ class CoordinatorTest {
sampleRate = 1.0f,
additionsChangeDate = consents.gdpr!!.consents!!.dateCreated + 1.days,
legalBasisChangeDate = originalMetaData.gdpr!!.legalBasisChangeDate,
vendorListId = originalMetaData.gdpr!!.vendorListId,
vendorListId = originalMetaData.gdpr.vendorListId,
))
}
)
Expand All @@ -491,7 +492,7 @@ class CoordinatorTest {
sampleRate = 1.0f,
additionsChangeDate = originalMetaData.gdpr!!.additionsChangeDate,
legalBasisChangeDate = consents.gdpr!!.consents!!.dateCreated + 1.days,
vendorListId = originalMetaData.gdpr!!.vendorListId,
vendorListId = originalMetaData.gdpr.vendorListId,
))
}
)
Expand Down Expand Up @@ -631,4 +632,18 @@ class CoordinatorTest {
coordinator.loadMessages()
assertTrue(pvDataCalled)
}

@Test
fun getUsnatLocation() = runTestWithRetries {
Coordinator(
accountId = 99,
propertyId = 99,
propertyName = SPPropertyName.create("foo"),
campaigns = SPCampaigns(),
internalFlags = SPInternalFlags(geoOverride = "US-FL")
).getUsnatLocation().apply {
assertEquals("US", countryCode)
assertEquals("FL", stateCode)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import com.sourcepoint.mobile_core.network.responses.MetaDataResponse
import com.sourcepoint.mobile_core.network.responses.PreferencesChoiceResponse
import com.sourcepoint.mobile_core.network.responses.PvDataResponse
import com.sourcepoint.mobile_core.network.responses.USNatChoiceResponse
import com.sourcepoint.mobile_core.network.responses.UsnatLocationResponse

@Suppress("MemberVisibilityCanBePrivate")
class SPClientMock(
Expand All @@ -41,6 +42,7 @@ class SPClientMock(
var getMessages: (() -> MessagesResponse?)? = null,
var customConsentGDPR: (() -> GDPRConsent?)? = null,
var deleteCustomConsentGDPR: (() -> GDPRConsent?)? = null,
var getUsnatLocation: (() -> UsnatLocationResponse?)? = null,
) : SPClient {
override suspend fun getMetaData(campaigns: MetaDataRequest.Campaigns) =
getMetaData?.invoke() ?:
Expand Down Expand Up @@ -94,6 +96,9 @@ class SPClientMock(
original?.getMessages(request) ?:
MessagesResponse(campaigns = emptyList(), localState = "", nonKeyedLocalState = "")

override suspend fun getUsnatLocation(): UsnatLocationResponse =
getUsnatLocation?.invoke() ?: original?.getUsnatLocation() ?: UsnatLocationResponse()

override suspend fun postReportIdfaStatus(
propertyId: Int?,
uuid: String?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.sourcepoint.mobile_core.asserters.assertTrue
import com.sourcepoint.mobile_core.models.SPActionType
import com.sourcepoint.mobile_core.models.SPClientTimeout
import com.sourcepoint.mobile_core.models.SPIDFAStatus
import com.sourcepoint.mobile_core.models.SPInternalFlags
import com.sourcepoint.mobile_core.models.SPNetworkError
import com.sourcepoint.mobile_core.models.SPPropertyName
import com.sourcepoint.mobile_core.models.SPUnableToParseBodyError
Expand Down Expand Up @@ -45,11 +46,8 @@ class SourcepointClientTest {
private val propertyName = SPPropertyName.create("mobile.multicampaign.demo")
private val preferencesConfigId = "67e14cda9efe9bd2a90fa84a"
private val preferencesMessageId = "1306779"
private val api = SourcepointClient(
accountId = accountId,
propertyId = propertyId,
httpEngine = PlatformHttpClient.create().engine
)
private val httpEngine = PlatformHttpClient.create().engine
private var api = SourcepointClient(accountId, propertyId, httpEngine)

private fun mock(response: String = """{}""", status: Int = 200, delayInSeconds: Int = 0) = MockEngine { _ ->
delay(delayInSeconds.toLong() * 1000)
Expand Down Expand Up @@ -89,7 +87,7 @@ class SourcepointClientTest {
assertNotNull(response.preferences?.additionsChangeDate)

assertNotNull(response.globalcmp)
response.globalcmp?.apply {
response.globalcmp.apply {
assertNotEmpty(vendorListId)
assertNotEmpty(applicableSections)
assertTrue(applies)
Expand Down Expand Up @@ -244,7 +242,7 @@ class SourcepointClientTest {
response.campaigns.forEach { campaign ->
assertNotNull(campaign.url, "Empty url for ${campaign.type}")
assertNotNull(campaign.message, "Empty message for ${campaign.type}")
assertNotEmpty(campaign.message?.messageJson, "Empty message_json for ${campaign.type}")
assertNotEmpty(campaign.message.messageJson, "Empty message_json for ${campaign.type}")
assertNotNull(campaign.messageMetaData, "Empty messageMetaData for ${campaign.type}")
assertCampaignConsentsFromMessages(campaign)
}
Expand Down Expand Up @@ -496,4 +494,17 @@ class SourcepointClientTest {
}
}
}

@Test
fun testGetUsnatLocation() = runTestWithRetries {
SourcepointClient(
accountId,
propertyId,
httpEngine,
internalFlags = SPInternalFlags(geoOverride = "US-FL")
).getUsnatLocation().apply {
assertEquals("US", countryCode)
assertEquals("FL", stateCode)
}
}
}
Loading