Skip to content

Commit

Permalink
fix: adjust data deserializer to return correct type
Browse files Browse the repository at this point in the history
- Changed the DataDeserializer to return Any? instead of JsonNode to fix type mismatch errors
  in 'data'field deserialization.
- Changed the user agent field from `agent` to `user_agent` to match specificiations.
  • Loading branch information
jboix committed Nov 5, 2024
1 parent db13a05 commit 8bc123f
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ data class EventRequest(
*
* If the `browser.agent` field is not present, the deserializer returns the node unmodified.
*/
private class DataDeserializer : JsonDeserializer<JsonNode?>() {
private class DataDeserializer : JsonDeserializer<Any?>() {
companion object {
private val userAgentAnalyzer =
UserAgentAnalyzer
Expand All @@ -67,14 +67,14 @@ private class DataDeserializer : JsonDeserializer<JsonNode?>() {
override fun deserialize(
parser: JsonParser,
ctxt: DeserializationContext,
): JsonNode {
): Any? {
val node: JsonNode = parser.codec.readTree(parser)
val browserNode = (node as? ObjectNode)?.get("browser")
val userAgent =
(browserNode as? ObjectNode)
?.get("agent")
?.get("user_agent")
?.asText()
?.let(userAgentAnalyzer::parse) ?: return node
?.let(userAgentAnalyzer::parse) ?: return parser.codec.treeToValue(node, Any::class.java)

node.set<ObjectNode>(
"browser",
Expand All @@ -100,7 +100,7 @@ private class DataDeserializer : JsonDeserializer<JsonNode?>() {
},
)

return node
return parser.codec.treeToValue(node, Any::class.java)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package ch.srgssr.pillarbox.monitoring.event.model

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ObjectNode
import com.fasterxml.jackson.module.kotlin.readValue
import io.kotest.core.spec.style.ShouldSpec
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import org.springframework.boot.test.context.SpringBootTest

@SpringBootTest
Expand All @@ -23,7 +21,7 @@ class EventRequestTest(
"version": 1,
"data": {
"browser": {
"agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
}
}
}
Expand All @@ -33,22 +31,18 @@ class EventRequestTest(
val eventRequest = objectMapper.readValue<EventRequest>(jsonInput)

// Then: The user agent data should have been resolved
val dataNode = eventRequest.data as? ObjectNode
dataNode shouldNotBe null
val dataNode = eventRequest.data as Map<*, *>

val browserNode = dataNode?.get("browser") as? ObjectNode
browserNode shouldNotBe null
browserNode?.get("name")?.asText() shouldBe "Chrome"
browserNode?.get("version")?.asText() shouldBe "129"
val browserNode = dataNode["browser"] as Map<*, *>
browserNode["name"] shouldBe "Chrome"
browserNode["version"] shouldBe "129"

val deviceNode = dataNode?.get("device") as? ObjectNode
deviceNode shouldNotBe null
deviceNode?.get("name")?.asText() shouldBe "Apple Macintosh"
val deviceNode = dataNode["device"] as Map<*, *>
deviceNode["name"] shouldBe "Apple Macintosh"

val osNode = dataNode?.get("os") as? ObjectNode
osNode shouldNotBe null
osNode?.get("name")?.asText() shouldBe "Mac OS"
osNode?.get("version")?.asText() shouldBe ">=10.15.7"
val osNode = dataNode["os"] as Map<*, *>
osNode["name"] shouldBe "Mac OS"
osNode["version"] shouldBe ">=10.15.7"
}

should("retain existing data when deserializing an event without user agent") {
Expand All @@ -73,15 +67,13 @@ class EventRequestTest(
val eventRequest = objectMapper.readValue<EventRequest>(jsonInput)

// Then: The data for browser, os and device should not have been modified
val dataNode = eventRequest.data as? ObjectNode
dataNode shouldNotBe null
val dataNode = eventRequest.data as Map<*, *>

val browserNode = dataNode?.get("browser") as? ObjectNode
browserNode shouldNotBe null
browserNode?.get("name")?.asText() shouldBe "Firefox"
browserNode?.get("version")?.asText() shouldBe "2.0"
val browserNode = dataNode["browser"] as Map<*, *>
browserNode["name"] shouldBe "Firefox"
browserNode["version"] shouldBe "2.0"

dataNode?.get("device") shouldBe null
dataNode?.get("os") shouldBe null
dataNode["device"] shouldBe null
dataNode["os"] shouldBe null
}
})

0 comments on commit 8bc123f

Please sign in to comment.