-
Notifications
You must be signed in to change notification settings - Fork 376
chore: merge 5.3.0 beta into main and resolve conflict #2525
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+1,556
−5
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
2c50fa8
Merge pull request #2403 from OneSignal/kotlin1.9-update
jkasten2 bd3ac8b
Merge pull request #2389 from OneSignal/chore/add_session_listener_tests
jinliu9508 ca0ee23
Merge pull request #2501 from OneSignal/fg/wrapper-prs
fadi-george 038ac65
test coverage test (#2409)
abdulraqeeb33 bfa2e34
add: custom event API and internal data model
jinliu9508 1bc4a1f
add: backend service for custom events
jinliu9508 e60e157
add: unit tests for custom events
jinliu9508 58a9ad3
fixup: removed CustomEvent and updated comparison keys
jinliu9508 d335b1b
chore: update sdkVersion reference; add tests for JSONUtils
jinliu9508 25071ca
address detekt failure
jinliu9508 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -163,4 +163,59 @@ object JSONUtils { | |
| `object` | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Check if an object is JSON-serializable. | ||
| * Recursively check each item if object is a map or a list. | ||
| */ | ||
| fun isValidJsonObject(value: Any?): Boolean { | ||
| return when (value) { | ||
| null, | ||
| is Boolean, | ||
| is Number, | ||
| is String, | ||
| is JSONObject, | ||
| is JSONArray, | ||
| -> true | ||
| is Map<*, *> -> value.keys.all { it is String } && value.values.all { isValidJsonObject(it) } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you please write a unit test for this?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added more tests for JSONUtils.kt |
||
| is List<*> -> value.all { isValidJsonObject(it) } | ||
| else -> false | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Recursively convert a JSON-serializable map into a JSON-compatible format, handling | ||
| * nested Maps and Lists appropriately. | ||
| */ | ||
| fun mapToJson(map: Map<String, Any>): JSONObject { | ||
| val json = JSONObject() | ||
| for ((key, value) in map) { | ||
| json.put(key, convertToJson(value)) | ||
| } | ||
| return json | ||
| } | ||
|
|
||
| /** | ||
| * Recursively converts maps and lists into JSON-compatible objects, transforming maps with | ||
| * String keys into JSON objects, lists into JSON arrays, and leaving primitive values unchanged to support safe JSON serialization. | ||
| */ | ||
| fun convertToJson(value: Any): Any { | ||
| return when (value) { | ||
| is Map<*, *> -> { | ||
| val subMap = | ||
| value.entries | ||
| .filter { it.key is String } | ||
| .associate { | ||
| it.key as String to convertToJson(it.value!!) | ||
| } | ||
| mapToJson(subMap) | ||
| } | ||
| is List<*> -> { | ||
| val array = JSONArray() | ||
| value.forEach { array.put(convertToJson(it!!)) } | ||
| array | ||
| } | ||
| else -> value | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
...core/src/main/java/com/onesignal/user/internal/customEvents/ICustomEventBackendService.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| package com.onesignal.user.internal.customEvents | ||
|
|
||
| import com.onesignal.core.internal.operations.ExecutionResponse | ||
| import com.onesignal.user.internal.customEvents.impl.CustomEventMetadata | ||
|
|
||
| /** | ||
| * The backend service for custom events. | ||
| */ | ||
| interface ICustomEventBackendService { | ||
| /** | ||
| * Send an custom event to the backend and return the response. | ||
| * | ||
| * @param customEvent The custom event to send up. | ||
| */ | ||
| suspend fun sendCustomEvent( | ||
| appId: String, | ||
| onesignalId: String, | ||
| externalId: String?, | ||
| timestamp: Long, | ||
| eventName: String, | ||
| eventProperties: String?, | ||
| metadata: CustomEventMetadata, | ||
| ): ExecutionResponse | ||
| } |
8 changes: 8 additions & 0 deletions
8
...nal/core/src/main/java/com/onesignal/user/internal/customEvents/ICustomEventController.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package com.onesignal.user.internal.customEvents | ||
|
|
||
| interface ICustomEventController { | ||
| fun sendCustomEvent( | ||
| name: String, | ||
| properties: Map<String, Any>?, | ||
| ) | ||
| } |
53 changes: 53 additions & 0 deletions
53
.../src/main/java/com/onesignal/user/internal/customEvents/impl/CustomEventBackendService.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| package com.onesignal.user.internal.customEvents.impl | ||
|
|
||
| import com.onesignal.common.DateUtils | ||
| import com.onesignal.common.exceptions.BackendException | ||
| import com.onesignal.core.internal.http.IHttpClient | ||
| import com.onesignal.core.internal.operations.ExecutionResponse | ||
| import com.onesignal.core.internal.operations.ExecutionResult | ||
| import com.onesignal.user.internal.customEvents.ICustomEventBackendService | ||
| import org.json.JSONArray | ||
| import org.json.JSONObject | ||
| import java.util.TimeZone | ||
|
|
||
| internal class CustomEventBackendService( | ||
| private val httpClient: IHttpClient, | ||
| ) : ICustomEventBackendService { | ||
| override suspend fun sendCustomEvent( | ||
| appId: String, | ||
| onesignalId: String, | ||
| externalId: String?, | ||
| timestamp: Long, | ||
| eventName: String, | ||
| eventProperties: String?, | ||
| metadata: CustomEventMetadata, | ||
| ): ExecutionResponse { | ||
| val body = JSONObject() | ||
| body.put("name", eventName) | ||
| body.put("onesignal_id", onesignalId) | ||
| externalId?.let { body.put("external_id", it) } | ||
| body.put( | ||
| "timestamp", | ||
| DateUtils.iso8601Format().apply { | ||
| timeZone = TimeZone.getTimeZone("UTC") | ||
jinliu9508 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }.format( | ||
| timestamp, | ||
| ), | ||
| ) | ||
|
|
||
| val payload = eventProperties?.let { JSONObject(it) } ?: JSONObject() | ||
|
|
||
| payload.put("os_sdk", metadata.toJSONObject()) | ||
|
|
||
| body.put("payload", payload) | ||
| val jsonObject = JSONObject().put("events", JSONArray().put(body)) | ||
|
|
||
| val response = httpClient.post("apps/$appId/custom_events", jsonObject) | ||
|
|
||
| if (!response.isSuccess) { | ||
| throw BackendException(response.statusCode, response.payload, response.retryAfterSeconds) | ||
| } | ||
|
|
||
| return ExecutionResponse(ExecutionResult.SUCCESS) | ||
| } | ||
| } | ||
32 changes: 32 additions & 0 deletions
32
...core/src/main/java/com/onesignal/user/internal/customEvents/impl/CustomEventController.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.onesignal.user.internal.customEvents.impl | ||
|
|
||
| import com.onesignal.common.JSONUtils | ||
| import com.onesignal.core.internal.config.ConfigModelStore | ||
| import com.onesignal.core.internal.operations.IOperationRepo | ||
| import com.onesignal.core.internal.time.ITime | ||
| import com.onesignal.user.internal.customEvents.ICustomEventController | ||
| import com.onesignal.user.internal.identity.IdentityModelStore | ||
| import com.onesignal.user.internal.operations.TrackCustomEventOperation | ||
|
|
||
| class CustomEventController( | ||
| private val identityModelStore: IdentityModelStore, | ||
| private val configModelStore: ConfigModelStore, | ||
| private val time: ITime, | ||
| private val opRepo: IOperationRepo, | ||
| ) : ICustomEventController { | ||
| override fun sendCustomEvent( | ||
| name: String, | ||
| properties: Map<String, Any>?, | ||
| ) { | ||
| val op = | ||
| TrackCustomEventOperation( | ||
| configModelStore.model.appId, | ||
| identityModelStore.model.onesignalId, | ||
| identityModelStore.model.externalId, | ||
| time.currentTimeMillis, | ||
| name, | ||
| properties?.let { JSONUtils.mapToJson(it).toString() }, | ||
| ) | ||
| opRepo.enqueue(op) | ||
| } | ||
| } |
39 changes: 39 additions & 0 deletions
39
...l/core/src/main/java/com/onesignal/user/internal/customEvents/impl/CustomEventMetadata.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| package com.onesignal.user.internal.customEvents.impl | ||
|
|
||
| import com.onesignal.common.putSafe | ||
| import org.json.JSONException | ||
| import org.json.JSONObject | ||
|
|
||
| class CustomEventMetadata( | ||
| val deviceType: String?, | ||
| val sdk: String?, | ||
| val appVersion: String?, | ||
| val type: String?, | ||
| val deviceModel: String?, | ||
| val deviceOS: String?, | ||
| ) { | ||
| @Throws(JSONException::class) | ||
| fun toJSONObject(): JSONObject { | ||
| val json = JSONObject() | ||
| json.putSafe(SDK, sdk) | ||
| json.putSafe(APP_VERSION, appVersion) | ||
| json.putSafe(TYPE, type) | ||
| json.putSafe(DEVICE_TYPE, deviceType) | ||
| json.putSafe(DEVICE_MODEL, deviceModel) | ||
| json.putSafe(DEVICE_OS, deviceOS) | ||
| return json | ||
| } | ||
|
|
||
| override fun toString(): String { | ||
| return toJSONObject().toString() | ||
| } | ||
|
|
||
| companion object { | ||
| private const val DEVICE_TYPE = "device_type" | ||
jinliu9508 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| private const val SDK = "sdk" | ||
| private const val APP_VERSION = "app_version" | ||
| private const val TYPE = "type" | ||
| private const val DEVICE_MODEL = "device_model" | ||
| private const val DEVICE_OS = "device_os" | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about finite checks?