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 @@ -12,13 +12,13 @@ interface IUserBackendService {
* @param appId The ID of the OneSignal application this user will be created under.
* @param identities The identities to retrieve/modify this user in subsequent requests. Each identity key/value pair must be unique within
* the application.
* @param properties The properties for this user.
* @param subscriptions The subscriptions that should also be created and associated with the user. If subscriptions are already owned by a different user
* they will be transferred to this user.
*
* @return The backend response
*/
suspend fun createUser(appId: String, identities: Map<String, String>, properties: PropertiesObject, subscriptions: List<SubscriptionObject>): CreateUserResponse
suspend fun createUser(appId: String, identities: Map<String, String>, subscriptions: List<SubscriptionObject>): CreateUserResponse
// TODO: Change to send only the push subscription, optimally

/**
* Update the user identified by the [appId]/[aliasId]/[aliasLabel] on the backend.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@ internal class UserBackendService(
private val _httpClient: IHttpClient,
) : IUserBackendService {

override suspend fun createUser(appId: String, identities: Map<String, String>, properties: PropertiesObject, subscriptions: List<SubscriptionObject>): CreateUserResponse {
override suspend fun createUser(appId: String, identities: Map<String, String>, subscriptions: List<SubscriptionObject>): CreateUserResponse {
val requestJSON = JSONObject()

if (identities.isNotEmpty()) {
requestJSON.put("identity", JSONObject().putMap(identities))
}

if (properties.hasAtLeastOnePropertySet) {
requestJSON.put("properties", JSONConverter.convertToJSON(properties))
}

if (subscriptions.isNotEmpty()) {
requestJSON
.put("subscriptions", JSONConverter.convertToJSON(subscriptions))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class DeleteAliasOperation() : Operation(IdentityOperationExecutor.DELETE_ALIAS)
get() = getStringProperty(::label.name)
private set(value) { setStringProperty(::label.name, value) }

override val createComparisonKey: String get() = "$appId.User.$onesignalId"
override val createComparisonKey: String get() = ""
override val modifyComparisonKey: String get() = "$appId.User.$onesignalId.Alias.$label"
override val groupComparisonType: GroupComparisonType = GroupComparisonType.NONE
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class DeleteTagOperation() : Operation(UpdateUserOperationExecutor.DELETE_TAG) {
get() = getStringProperty(::key.name)
private set(value) { setStringProperty(::key.name, value) }

override val createComparisonKey: String get() = "$appId.User.$onesignalId"
override val createComparisonKey: String get() = ""
override val modifyComparisonKey: String get() = createComparisonKey
override val groupComparisonType: GroupComparisonType = GroupComparisonType.ALTER
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SetAliasOperation() : Operation(IdentityOperationExecutor.SET_ALIAS) {
get() = getStringProperty(::value.name)
private set(value) { setStringProperty(::value.name, value) }

override val createComparisonKey: String get() = "$appId.User.$onesignalId"
override val createComparisonKey: String get() = ""
override val modifyComparisonKey: String get() = "$appId.User.$onesignalId.Identity.$label"
override val groupComparisonType: GroupComparisonType = GroupComparisonType.ALTER
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SetPropertyOperation() : Operation(UpdateUserOperationExecutor.SET_PROPERT
get() = getOptAnyProperty(::value.name)
private set(value) { setOptAnyProperty(::value.name, value) }

override val createComparisonKey: String get() = "$appId.User.$onesignalId"
override val createComparisonKey: String get() = ""
override val modifyComparisonKey: String get() = createComparisonKey
override val groupComparisonType: GroupComparisonType = GroupComparisonType.ALTER
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SetTagOperation() : Operation(UpdateUserOperationExecutor.SET_TAG) {
get() = getStringProperty(::value.name)
private set(value) { setStringProperty(::value.name, value) }

override val createComparisonKey: String get() = "$appId.User.$onesignalId"
override val createComparisonKey: String get() = ""
override val modifyComparisonKey: String get() = createComparisonKey
override val groupComparisonType: GroupComparisonType = GroupComparisonType.ALTER
override val canStartExecute: Boolean get() = !IDManager.isLocalId(onesignalId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,13 @@ import com.onesignal.core.internal.operations.Operation
import com.onesignal.debug.internal.logging.Logging
import com.onesignal.user.internal.backend.IUserBackendService
import com.onesignal.user.internal.backend.IdentityConstants
import com.onesignal.user.internal.backend.PropertiesObject
import com.onesignal.user.internal.backend.SubscriptionObject
import com.onesignal.user.internal.backend.SubscriptionObjectType
import com.onesignal.user.internal.identity.IdentityModelStore
import com.onesignal.user.internal.operations.CreateSubscriptionOperation
import com.onesignal.user.internal.operations.DeleteAliasOperation
import com.onesignal.user.internal.operations.DeleteSubscriptionOperation
import com.onesignal.user.internal.operations.DeleteTagOperation
import com.onesignal.user.internal.operations.LoginUserOperation
import com.onesignal.user.internal.operations.SetAliasOperation
import com.onesignal.user.internal.operations.SetPropertyOperation
import com.onesignal.user.internal.operations.SetTagOperation
import com.onesignal.user.internal.operations.TransferSubscriptionOperation
import com.onesignal.user.internal.operations.UpdateSubscriptionOperation
import com.onesignal.user.internal.properties.PropertiesModel
Expand Down Expand Up @@ -103,7 +98,6 @@ internal class LoginUserOperationExecutor(

private suspend fun createUser(createUserOperation: LoginUserOperation, operations: List<Operation>): ExecutionResponse {
var identities = mapOf<String, String>()
var propertiesObject = PropertiesObject()
var subscriptions = mapOf<String, SubscriptionObject>()

if (createUserOperation.externalId != null) {
Expand All @@ -115,21 +109,16 @@ internal class LoginUserOperationExecutor(
// go through the operations grouped with this create user and apply them to the appropriate objects.
for (operation in operations) {
when (operation) {
is SetAliasOperation -> identities = createIdentityFromOperation(operation, identities)
is DeleteAliasOperation -> identities = createIdentityFromOperation(operation, identities)
is CreateSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions)
is TransferSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions)
is UpdateSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions)
is DeleteSubscriptionOperation -> subscriptions = createSubscriptionsFromOperation(operation, subscriptions)
is SetTagOperation -> propertiesObject = PropertyOperationHelper.createPropertiesFromOperation(operation, propertiesObject)
is DeleteTagOperation -> propertiesObject = PropertyOperationHelper.createPropertiesFromOperation(operation, propertiesObject)
is SetPropertyOperation -> propertiesObject = PropertyOperationHelper.createPropertiesFromOperation(operation, propertiesObject)
}
}

try {
val subscriptionList = subscriptions.toList()
val response = _userBackend.createUser(createUserOperation.appId, identities, propertiesObject, subscriptionList.map { it.second })
val response = _userBackend.createUser(createUserOperation.appId, identities, subscriptionList.map { it.second })
val idTranslations = mutableMapOf<String, String>()
// Add the "local-to-backend" ID translation to the IdentifierTranslator for any operations that were
// *not* executed but still reference the locally-generated IDs.
Expand Down Expand Up @@ -181,18 +170,6 @@ internal class LoginUserOperationExecutor(
}
}

private fun createIdentityFromOperation(operation: SetAliasOperation, identity: Map<String, String>): Map<String, String> {
val mutableIdentity = identity.toMutableMap()
mutableIdentity[operation.label] = operation.value
return mutableIdentity
}

private fun createIdentityFromOperation(operation: DeleteAliasOperation, identity: Map<String, String>): Map<String, String> {
val mutableIdentity = identity.toMutableMap()
mutableIdentity.remove(operation.label)
return mutableIdentity
}

private fun createSubscriptionsFromOperation(operation: TransferSubscriptionOperation, subscriptions: Map<String, SubscriptionObject>): Map<String, SubscriptionObject> {
val mutableSubscriptions = subscriptions.toMutableMap()
if (mutableSubscriptions.containsKey(operation.subscriptionId)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@ class UserBackendServiceTests : FunSpec({
coEvery { spyHttpClient.post(any(), any()) } returns HttpResponse(403, "FORBIDDEN")
val userBackendService = UserBackendService(spyHttpClient)
val identities = mapOf<String, String>()
val properties = PropertiesObject()
val subscriptions = listOf<SubscriptionObject>()

/* When */
val exception = shouldThrowUnit<BackendException> {
userBackendService.createUser("appId", identities, properties, subscriptions)
userBackendService.createUser("appId", identities, subscriptions)
}

/* Then */
Expand All @@ -48,11 +47,10 @@ class UserBackendServiceTests : FunSpec({
coEvery { spyHttpClient.post(any(), any()) } returns HttpResponse(202, "{identity:{onesignal_id: \"$osId\", aliasLabel1: \"aliasValue1\"}}")
val userBackendService = UserBackendService(spyHttpClient)
val identities = mapOf("aliasLabel1" to "aliasValue1")
val properties = PropertiesObject()
val subscriptions = listOf<SubscriptionObject>()

/* When */
val response = userBackendService.createUser("appId", identities, properties, subscriptions)
val response = userBackendService.createUser("appId", identities, subscriptions)

/* Then */
response.identities["onesignal_id"] shouldBe osId
Expand All @@ -79,12 +77,11 @@ class UserBackendServiceTests : FunSpec({
coEvery { spyHttpClient.post(any(), any()) } returns HttpResponse(202, "{identity:{onesignal_id: \"$osId\"}, subscriptions:[{id:\"subscriptionId1\", type:\"AndroidPush\"}]}")
val userBackendService = UserBackendService(spyHttpClient)
val identities = mapOf<String, String>()
val properties = PropertiesObject()
val subscriptions = mutableListOf<SubscriptionObject>()
subscriptions.add(SubscriptionObject("SHOULDNOTUSE", SubscriptionObjectType.ANDROID_PUSH))

/* When */
val response = userBackendService.createUser("appId", identities, properties, subscriptions)
val response = userBackendService.createUser("appId", identities, subscriptions)

/* Then */
response.identities["onesignal_id"] shouldBe osId
Expand All @@ -107,40 +104,6 @@ class UserBackendServiceTests : FunSpec({
}
}

test("create user with an alias and properties creates a new user") {
/* Given */
val osId = "11111111-1111-1111-1111-111111111111"
val spyHttpClient = mockk<IHttpClient>()
coEvery { spyHttpClient.post(any(), any()) } returns HttpResponse(202, "{identity:{onesignal_id: \"$osId\", aliasLabel1: \"aliasValue1\"}, properties: { tags: {tagKey1: tagValue1}}}")
val userBackendService = UserBackendService(spyHttpClient)
val identities = mapOf("aliasLabel1" to "aliasValue1")
val properties = PropertiesObject(tags = mapOf("tagkey1" to "tagValue1"))
val subscriptions = listOf<SubscriptionObject>()

/* When */
val response = userBackendService.createUser("appId", identities, properties, subscriptions)

/* Then */
response.identities["onesignal_id"] shouldBe osId
response.identities["aliasLabel1"] shouldBe "aliasValue1"
response.subscriptions.count() shouldBe 0
coVerify {
spyHttpClient.post(
"apps/appId/users",
withArg {
it.has("identity") shouldBe true
it.getJSONObject("identity").has("aliasLabel1") shouldBe true
it.getJSONObject("identity").getString("aliasLabel1") shouldBe "aliasValue1"
it.has("properties") shouldBe true
it.getJSONObject("properties").has("tags") shouldBe true
it.getJSONObject("properties").getJSONObject("tags").has("tagkey1") shouldBe true
it.getJSONObject("properties").getJSONObject("tags").getString("tagkey1") shouldBe "tagValue1"
it.has("subscriptions") shouldBe false
},
)
}
}

test("update user tags") {
/* Given */
val aliasLabel = "onesignal_id"
Expand Down
Loading