package com.zandero.rest; import com.zandero.rest.reader.*; import com.zandero.rest.test.TestPostRest; import com.zandero.rest.test.TestReaderRest; import com.zandero.rest.test.json.Dummy; import com.zandero.rest.test.json.ExtendedDummy; import com.zandero.rest.writer.TestCustomWriter; import com.zandero.utils.extra.JsonUtils; import io.vertx.core.buffer.Buffer; import io.vertx.ext.web.Router; import io.vertx.ext.web.codec.BodyCodec; import io.vertx.junit5.VertxExtension; import io.vertx.junit5.VertxTestContext; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.time.Instant; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; /** * */ @ExtendWith(VertxExtension.class) class CustomReaderTest extends VertxTest { @BeforeAll static void start() { before(); Router router = RestRouter.register(vertx, TestReaderRest.class); vertx.createHttpServer() .requestHandler(router) .listen(PORT); } @BeforeEach void cleanUp() { // clear all registered writers or reader and handlers RestRouter.getReaders().clear(); RestRouter.getWriters().clear(); RestRouter.getExceptionHandlers().clear(); RestRouter.getContextProviders().clear(); } @Test void testCustomInput(VertxTestContext context) { client.post(PORT, HOST, "/read/custom") .as(BodyCodec.string()) .sendBuffer(Buffer.buffer("The quick brown fox jumps over the red dog!"), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("brown,dog,fox,jumps,over,quick,red,the", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void testCustomInput_WithBuilder(VertxTestContext context) { client.post(PORT, HOST, "/read/custom") .as(BodyCodec.string()) .sendBuffer(Buffer.buffer("The quick brown fox jumps over the red dog!"), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("brown,dog,fox,jumps,over,quick,red,the", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void testCustomInput_2(VertxTestContext context) { RestRouter.getReaders() .register(List.class, CustomWordListReader.class); // all arguments that are List<> go through this reader ... (reader returns List<String> as output) client.post(PORT, HOST, "/read/registered") .as(BodyCodec.string()) .sendBuffer(Buffer.buffer("The quick brown fox jumps over the red dog!"), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("brown,dog,fox,jumps,over,quick,red,the", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void testExtendedReader(VertxTestContext context) { RestRouter.getReaders().register(Dummy.class, DummyBodyReader.class); RestRouter.getReaders().register(ExtendedDummy.class, ExtendedDummyBodyReader.class); // check if correct reader is used client.post(PORT, HOST, "/read/normal/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new Dummy("one", "dummy"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy", response.body()); // returns sorted list of unique words context.completeNow(); }))); // 2nd send extended dummy to same REST client.post(PORT, HOST, "/read/normal/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new ExtendedDummy("one", "dummy", "extra"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy", response.body()); // returns sorted list of unique words context.completeNow(); }))); // 3rd send extended dummy to extended REST client.post(PORT, HOST, "/read/extended/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new ExtendedDummy("one", "dummy", "extra"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy (extra)", response.body()); // returns sorted list of unique words context.completeNow(); }))); // 4th send normal dummy to extended REST client.post(PORT, HOST, "/read/extended/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new Dummy("one", "dummy"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy (null)", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void extendedContentTypeTest(VertxTestContext context) { RestRouter.getReaders().register(Dummy.class, DummyBodyReader.class); client.post(PORT, HOST, "/read/normal/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json;charset=UTF-8") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new Dummy("one", "dummy"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void extendedContentTypeByMediaType(VertxTestContext context) { // register reader afterwards - should still work RestRouter.getReaders().register("application/json", DummyBodyReader.class); client.post(PORT, HOST, "/read/normal/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new Dummy("one", "dummy"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void extendedContentTypeByAnnotatedMediaType(VertxTestContext context) { // register reader afterwards - should still work RestRouter.getReaders().register(DummyBodyReader.class); client.post(PORT, HOST, "/read/normal/dummy") .as(BodyCodec.string()) .putHeader("Content-Type", "application/json") .sendBuffer(Buffer.buffer(JsonUtils.toJson(new Dummy("one", "dummy"))), context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("one=dummy", response.body()); // returns sorted list of unique words context.completeNow(); }))); } @Test void incompatibleMimeTypeReaderTest() { // register application/json to IntegerReader RestRouter.getReaders().register("application/json", IntegerBodyReader.class); // bind rest that consumes application/json IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> RestRouter.register(vertx, TestPostRest.class)); assertEquals( "POST /post/json - Parameter type: 'class com.zandero.rest.test.json.Dummy' not matching reader type: " + "'class java.lang.Integer' in: 'class com.zandero.rest.reader.IntegerBodyReader'!", e.getMessage()); } @Test void incompatibleMimeTypeWriterTest() { // register application/json to String writer RestRouter.getWriters().register("application/json", TestCustomWriter.class); // bind rest that consumes application/json IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> RestRouter.register(vertx, TestPostRest.class)); assertEquals( "POST /post/json - Response type: 'class com.zandero.rest.test.json.Dummy' not matching writer type: " + "'class java.lang.String' in: 'class com.zandero.rest.writer.TestCustomWriter'!", e.getMessage()); } @Test void readTimeFromQuery(VertxTestContext context) { RestRouter.getReaders().register(Instant.class, InstantReader.class); client.get(PORT, HOST, "/read/time") .setQueryParam("is", "2020-08-19") .as(BodyCodec.string()) .send(context.succeeding(response -> context.verify(() -> { assertEquals(200, response.statusCode()); assertEquals("2020-08-19 00:00:00 +0000", response.body()); context.completeNow(); }))); } @Test void failToReadTimeFromQuery(VertxTestContext context) { RestRouter.getReaders().register(Instant.class, InstantReader.class); client.get(PORT, HOST, "/read/time") .setQueryParam("is", "2020-08-XX") .as(BodyCodec.string()) .send(context.succeeding(response -> context.verify(() -> { assertEquals(400, response.statusCode()); assertEquals("Invalid time stamp: '2020-08-XX', expected format: yyyy-MM-dd'T'hh:mm:ss", response.body()); context.completeNow(); }))); } }