From 60525302144c5532c66f6c50699830ad2ed04b8c Mon Sep 17 00:00:00 2001 From: Sergio del Amo Date: Mon, 26 Feb 2024 17:03:55 +0100 Subject: [PATCH 1/2] tck: JsonError test --- .../tck/tests/hateoas/JsonErrorTest.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java diff --git a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java new file mode 100644 index 00000000000..8d6fed8ea23 --- /dev/null +++ b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.tests.hateoas; + +import io.micronaut.core.value.OptionalMultiValues; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.http.hateoas.GenericResource; +import io.micronaut.http.hateoas.Link; +import io.micronaut.http.hateoas.Resource; +import io.micronaut.http.hateoas.VndError; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import static io.micronaut.http.tck.TestScenario.asserts; +import static org.junit.jupiter.api.Assertions.*; + + +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class JsonErrorTest { + private static final String SPEC_NAME = "JsonErrorTest"; + + /** + * @throws IOException Exception thrown while getting the server under test. + */ + @Test + public void responseCanBeBoundToJsonError() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET("/jsonError"), + (server, request) -> { + Executable e = () -> server.exchange(request, VndError.class); + HttpClientResponseException ex = Assertions.assertThrows(HttpClientResponseException.class, e); + Optional vndErrorOptional = ex.getResponse().getBody(VndError.class); + assertTrue(vndErrorOptional.isPresent()); + VndError vndError = vndErrorOptional.get(); + assertEquals("Not Found", vndError.getMessage()); + OptionalMultiValues links = vndError.getLinks(); + assertFalse(links.isEmpty()); + links.getFirst("self").ifPresent(link -> { + assertEquals("/jsonError", link.getHref()); + assertFalse(link.isTemplated()); + }); + OptionalMultiValues resourceOptionalMultiValues = vndError.getEmbedded(); + assertFalse(resourceOptionalMultiValues.isEmpty()); + + Optional> errorsOptional = resourceOptionalMultiValues.get("errors"); + assertTrue(errorsOptional.isPresent()); + List resources = errorsOptional.get(); + Optional genericResourceOptional = resources.stream() + .filter(resource -> resource instanceof GenericResource) + .map(GenericResource.class::cast) + .findFirst(); + assertTrue(genericResourceOptional.isPresent()); + assertEquals("Page Not Found", genericResourceOptional.get().getAdditionalProperties().get("message")); + }); + } +} From 85f8b243b522af403480c4b844afaabdcd60e6d1 Mon Sep 17 00:00:00 2001 From: Sergio del Amo Date: Mon, 11 Mar 2024 12:28:49 +0100 Subject: [PATCH 2/2] add reflect-config.json --- .../tck/tests/hateoas/JsonErrorTest.java | 19 ++--- .../tck/tests/hateoas/VndErrorTest.java | 79 +++++++++++++++++++ .../reflect-config.json | 35 ++++++++ 3 files changed, 122 insertions(+), 11 deletions(-) create mode 100644 http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/VndErrorTest.java create mode 100644 http/src/main/resources/META-INF/native-image/io.micronaut.http.hateoas/reflect-config.json diff --git a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java index 8d6fed8ea23..37123b9cd72 100644 --- a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java +++ b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/JsonErrorTest.java @@ -18,10 +18,7 @@ import io.micronaut.core.value.OptionalMultiValues; import io.micronaut.http.HttpRequest; import io.micronaut.http.client.exceptions.HttpClientResponseException; -import io.micronaut.http.hateoas.GenericResource; -import io.micronaut.http.hateoas.Link; -import io.micronaut.http.hateoas.Resource; -import io.micronaut.http.hateoas.VndError; +import io.micronaut.http.hateoas.*; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; @@ -50,19 +47,19 @@ public void responseCanBeBoundToJsonError() throws IOException { asserts(SPEC_NAME, HttpRequest.GET("/jsonError"), (server, request) -> { - Executable e = () -> server.exchange(request, VndError.class); + Executable e = () -> server.exchange(request, JsonError.class); HttpClientResponseException ex = Assertions.assertThrows(HttpClientResponseException.class, e); - Optional vndErrorOptional = ex.getResponse().getBody(VndError.class); - assertTrue(vndErrorOptional.isPresent()); - VndError vndError = vndErrorOptional.get(); - assertEquals("Not Found", vndError.getMessage()); - OptionalMultiValues links = vndError.getLinks(); + Optional jsonErrorOptional = ex.getResponse().getBody(JsonError.class); + assertTrue(jsonErrorOptional.isPresent()); + JsonError jsonError = jsonErrorOptional.get(); + assertEquals("Not Found", jsonError.getMessage()); + OptionalMultiValues links = jsonError.getLinks(); assertFalse(links.isEmpty()); links.getFirst("self").ifPresent(link -> { assertEquals("/jsonError", link.getHref()); assertFalse(link.isTemplated()); }); - OptionalMultiValues resourceOptionalMultiValues = vndError.getEmbedded(); + OptionalMultiValues resourceOptionalMultiValues = jsonError.getEmbedded(); assertFalse(resourceOptionalMultiValues.isEmpty()); Optional> errorsOptional = resourceOptionalMultiValues.get("errors"); diff --git a/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/VndErrorTest.java b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/VndErrorTest.java new file mode 100644 index 00000000000..a5c74a410c8 --- /dev/null +++ b/http-server-tck/src/main/java/io/micronaut/http/server/tck/tests/hateoas/VndErrorTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2017-2023 original authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.micronaut.http.server.tck.tests.hateoas; + +import io.micronaut.core.value.OptionalMultiValues; +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.exceptions.HttpClientResponseException; +import io.micronaut.http.hateoas.GenericResource; +import io.micronaut.http.hateoas.Link; +import io.micronaut.http.hateoas.Resource; +import io.micronaut.http.hateoas.VndError; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import static io.micronaut.http.tck.TestScenario.asserts; +import static org.junit.jupiter.api.Assertions.*; + + +@SuppressWarnings({ + "java:S5960", // We're allowed assertions, as these are used in tests only + "checkstyle:MissingJavadocType", + "checkstyle:DesignForExtension" +}) +public class VndErrorTest { + private static final String SPEC_NAME = "VndErrorTest"; + + /** + * @throws IOException Exception thrown while getting the server under test. + */ + @Test + public void responseCanBeBoundToVndError() throws IOException { + asserts(SPEC_NAME, + HttpRequest.GET("/vndError"), + (server, request) -> { + Executable e = () -> server.exchange(request, VndError.class); + HttpClientResponseException ex = Assertions.assertThrows(HttpClientResponseException.class, e); + Optional vndErrorOptional = ex.getResponse().getBody(VndError.class); + assertTrue(vndErrorOptional.isPresent()); + VndError vndError = vndErrorOptional.get(); + assertEquals("Not Found", vndError.getMessage()); + OptionalMultiValues links = vndError.getLinks(); + assertFalse(links.isEmpty()); + links.getFirst("self").ifPresent(link -> { + assertEquals("/vndError", link.getHref()); + assertFalse(link.isTemplated()); + }); + OptionalMultiValues resourceOptionalMultiValues = vndError.getEmbedded(); + assertFalse(resourceOptionalMultiValues.isEmpty()); + + Optional> errorsOptional = resourceOptionalMultiValues.get("errors"); + assertTrue(errorsOptional.isPresent()); + List resources = errorsOptional.get(); + Optional genericResourceOptional = resources.stream() + .filter(resource -> resource instanceof GenericResource) + .map(GenericResource.class::cast) + .findFirst(); + assertTrue(genericResourceOptional.isPresent()); + assertEquals("Page Not Found", genericResourceOptional.get().getAdditionalProperties().get("message")); + }); + } +} diff --git a/http/src/main/resources/META-INF/native-image/io.micronaut.http.hateoas/reflect-config.json b/http/src/main/resources/META-INF/native-image/io.micronaut.http.hateoas/reflect-config.json new file mode 100644 index 00000000000..0591488abdd --- /dev/null +++ b/http/src/main/resources/META-INF/native-image/io.micronaut.http.hateoas/reflect-config.json @@ -0,0 +1,35 @@ +[ + { + "name": "io.micronaut.http.hateoas.GenericResource", + "queryAllDeclaredMethods": true, + "allDeclaredFields": true, + "queryAllDeclaredConstructors": true, + "methods": [ + { + "name": "addProperty", + "parameterTypes": [ + "java.lang.String", + "java.lang.Object" + ] + } + ] + }, + { + "name": "io.micronaut.http.hateoas.Resource", + "queryAllDeclaredMethods": true, + "methods": [ + { + "name": "deserialize", + "parameterTypes": [ + "io.micronaut.http.hateoas.GenericResource" + ] + } + ] + }, + { + "name": "io.micronaut.http.hateoas.JsonError", + "queryAllDeclaredMethods": true, + "allDeclaredFields": true, + "queryAllDeclaredConstructors": true + } +] \ No newline at end of file