🚧 Add JSON filter
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 4 Apr 2024 15:59:27 +0000 (17:59 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 4 Apr 2024 15:59:27 +0000 (17:59 +0200)
src/main/kotlin/net/pterodactylus/rhynodge/filters/JsonFilter.kt [new file with mode: 0644]
src/test/java/net/pterodactylus/rhynodge/filters/JsonFilterTest.kt [new file with mode: 0644]

diff --git a/src/main/kotlin/net/pterodactylus/rhynodge/filters/JsonFilter.kt b/src/main/kotlin/net/pterodactylus/rhynodge/filters/JsonFilter.kt
new file mode 100644 (file)
index 0000000..502a002
--- /dev/null
@@ -0,0 +1,28 @@
+package net.pterodactylus.rhynodge.filters
+
+import com.fasterxml.jackson.core.JsonParseException
+import com.fasterxml.jackson.databind.ObjectMapper
+import net.pterodactylus.rhynodge.Filter
+import net.pterodactylus.rhynodge.State
+import net.pterodactylus.rhynodge.states.FailedState
+import net.pterodactylus.rhynodge.states.HttpState
+import net.pterodactylus.rhynodge.states.JsonState
+
+class JsonFilter : Filter {
+
+       override fun filter(state: State): State {
+               if (state is FailedState) {
+                       return state
+               }
+               val httpState = state as? HttpState ?: throw IllegalArgumentException("state must be HttpState")
+               val jsonNode = try {
+                       objectMapper.readTree(httpState.rawResult())
+               } catch (jsonParseException: JsonParseException) {
+                       return FailedState(jsonParseException)
+               }
+               return JsonState(jsonNode)
+       }
+
+}
+
+private val objectMapper = ObjectMapper()
diff --git a/src/test/java/net/pterodactylus/rhynodge/filters/JsonFilterTest.kt b/src/test/java/net/pterodactylus/rhynodge/filters/JsonFilterTest.kt
new file mode 100644 (file)
index 0000000..a37990a
--- /dev/null
@@ -0,0 +1,71 @@
+package net.pterodactylus.rhynodge.filters
+
+import com.spotify.hamcrest.jackson.JsonMatchers.jsonArray
+import com.spotify.hamcrest.jackson.JsonMatchers.jsonDouble
+import com.spotify.hamcrest.jackson.JsonMatchers.jsonNull
+import com.spotify.hamcrest.jackson.JsonMatchers.jsonObject
+import com.spotify.hamcrest.jackson.JsonMatchers.jsonText
+import net.pterodactylus.rhynodge.Filter
+import net.pterodactylus.rhynodge.states.AbstractState
+import net.pterodactylus.rhynodge.states.FailedState
+import net.pterodactylus.rhynodge.states.HttpState
+import net.pterodactylus.rhynodge.states.JsonState
+import net.pterodactylus.rhynodge.states.StringState
+import org.hamcrest.MatcherAssert.assertThat
+import org.hamcrest.Matchers.contains
+import org.hamcrest.Matchers.instanceOf
+import org.junit.Assert
+import org.junit.Assert.assertThrows
+import org.junit.Test
+
+class JsonFilterTest {
+
+       @Test
+       fun `json filter is a filter implementation`() {
+               assertThat(JsonFilter(), instanceOf(Filter::class.java))
+       }
+
+       @Test
+       fun `http state can be turned into json state`() {
+               val httpState = HttpState("", 200, "application/json", "{\n  \"state\": \"foo\",\n  \"list\": [\n    \"value1\",\n    \"value2\"\n  ],\n  \"object\": {\n    \"foo\": \"bar\",\n    \"baz\": null,\n    \"quux\": 1.5\n  }\n}".encodeToByteArray())
+               val jsonState = filter.filter(httpState) as JsonState
+               val jsonNode = jsonState.jsonNode
+               assertThat(
+                       jsonNode, jsonObject()
+                               .where("state", jsonText("foo"))
+                               .where(
+                                       "list", jsonArray(
+                                               contains(
+                                                       jsonText("value1"),
+                                                       jsonText("value2")
+                                               )
+                                       )
+                               )
+                               .where(
+                                       "object", jsonObject()
+                                               .where("foo", jsonText("bar"))
+                                               .where("baz", jsonNull())
+                                               .where("quux", jsonDouble(1.5))
+                               )
+               )
+       }
+
+       @Test
+       fun `json filter returns failed state when json can not be parsed`() {
+               val httpState = HttpState("", 200, "application/json", "<json>this is not json</json>".encodeToByteArray())
+               assertThat(filter.filter(httpState), instanceOf(FailedState::class.java))
+       }
+
+       @Test
+       fun `json filter throws exception if given state is not an http state`() {
+               assertThrows(IllegalArgumentException::class.java) { filter.filter(StringState("foo")) }
+       }
+
+       @Test
+       fun `json filter returns a failed state when a failed state is given`() {
+               val newState = filter.filter(FailedState())
+               assertThat(newState, instanceOf(FailedState::class.java))
+       }
+
+       val filter = JsonFilter()
+}