From: David ‘Bombe’ Roden Date: Thu, 4 Apr 2024 15:59:27 +0000 (+0200) Subject: 🚧 Add JSON filter X-Git-Tag: v2~3 X-Git-Url: https://git.pterodactylus.net/?p=rhynodge.git;a=commitdiff_plain;h=3dc17a61f9a05eff6ed71a67a4e2e898435a3c57 🚧 Add JSON filter --- 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 index 0000000..502a002 --- /dev/null +++ b/src/main/kotlin/net/pterodactylus/rhynodge/filters/JsonFilter.kt @@ -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 index 0000000..a37990a --- /dev/null +++ b/src/test/java/net/pterodactylus/rhynodge/filters/JsonFilterTest.kt @@ -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", "this is not 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() +}