This is an automated email from the ASF dual-hosted git repository.

jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git


The following commit(s) were added to refs/heads/main by this push:
     new 1aa650f  Add additional test coverage for REST DSL methods
1aa650f is described below

commit 1aa650f3677032499af8640cca2fc5e9062b2c9a
Author: James Netherton <[email protected]>
AuthorDate: Wed Sep 1 07:12:00 2021 +0100

    Add additional test coverage for REST DSL methods
    
    Fixes #3036
---
 .../component/openapijava/it/OpenApiRoutes.java    | 116 +++++++++++++++++-
 .../component/openapijava/it/OpenApiTest.java      | 130 +++++++++++++++++++++
 .../quarkus/component/rest/it/RestRoutes.java      |  72 ++++++++++--
 .../camel/quarkus/component/rest/it/RestTest.java  |  76 +++++++++---
 4 files changed, 365 insertions(+), 29 deletions(-)

diff --git 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
index beb1dc7..ee15121 100644
--- 
a/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
+++ 
b/integration-tests/openapi-java/src/main/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiRoutes.java
@@ -23,21 +23,127 @@ import java.util.Set;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.rest.CollectionFormat;
+import org.apache.camel.model.rest.RestParamType;
 import org.apache.camel.quarkus.component.openapijava.it.model.Fruit;
 
 public class OpenApiRoutes extends RouteBuilder {
     @Override
     public void configure() throws Exception {
-        Set<Fruit> fruits = 
Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>()));
-        fruits.add(new Fruit("Apple", "Winter fruit"));
-        fruits.add(new Fruit("Pineapple", "Tropical fruit"));
 
         rest()
                 .get("/fruits/list")
                 .id("list")
                 .produces(MediaType.APPLICATION_JSON)
                 .route()
-                .setBody().constant(fruits)
-                .marshal().json();
+                .setBody().constant(getFruits())
+                .marshal().json()
+                .endRest()
+
+                .get("/operation/spec")
+                .param()
+                .type(RestParamType.header)
+                .name("header_number")
+                .dataType("integer")
+                .required(true)
+                .allowableValues("1", "2", "3")
+                .defaultValue("1")
+                .description("Header Param Number")
+                .endParam()
+                .param()
+                .type(RestParamType.query)
+                .name("query_letter")
+                .dataType("string")
+                .required(false)
+                .allowableValues("A", "B", "C")
+                .defaultValue("B")
+                .description("Query Param Letter")
+                .collectionFormat(CollectionFormat.multi)
+                .endParam()
+                .responseMessage()
+                .code(418)
+                .message("I am a teapot")
+                .responseModel(Integer.class)
+                .header("rate")
+                .description("API Rate Limit")
+                .dataType("integer")
+                .endHeader()
+                .endResponseMessage()
+                .responseMessage()
+                .code("error")
+                .message("Response Error")
+                .endResponseMessage()
+                .route()
+                .setBody().constant("GET: /operation/spec")
+                .endRest()
+
+                .get("/security/scopes")
+                .security("OAuth2", "scope1,scope2,scope3")
+                .route()
+                .setBody().constant("GET: /security/scopes")
+                .endRest()
+
+                .get("/security/api/key")
+                .route()
+                .setBody().constant("GET: /security/api/key/header")
+                .endRest()
+                .securityDefinitions()
+                .apiKey("X-API-Key", "The API key")
+                .withHeader("X-API-KEY")
+                .end()
+                .end()
+
+                .get("/security/basic/auth")
+                .route()
+                .setBody().constant("/security/basic/auth")
+                .endRest()
+                .securityDefinitions()
+                .basicAuth("basicAuth", "Basic Authentication")
+                .end()
+
+                .get("/security/bearer/token")
+                .route()
+                .setBody().constant("/security/bearer/token")
+                .endRest()
+                .securityDefinitions()
+                .bearerToken("bearerAuth", "Bearer Token Authentication")
+                .end()
+
+                .get("/security/mutual/tls")
+                .route()
+                .setBody().constant("/security/mutual/tls")
+                .endRest()
+                .securityDefinitions()
+                .mutualTLS("mutualTLS")
+                .end()
+
+                .get("/security/oauth2")
+                .route()
+                .setBody().constant("/security/oauth2")
+                .endRest()
+                .securityDefinitions()
+                .oauth2("oauth2", "OAuth2 Authentication")
+                .flow("implicit")
+                
.authorizationUrl("https://secure.apache.org/fake/oauth2/authorize";)
+                .withScope("scope1", "Scope 1")
+                .withScope("scope2", "Scope 2")
+                .withScope("scope3", "Scope 3")
+                .end()
+                .end()
+
+                .get("/security/openid")
+                .route()
+                .setBody().constant("/security/openid")
+                .endRest()
+                .securityDefinitions()
+                .openIdConnect("openId", 
"https://secure.apache.org/fake/openid-configuration";)
+                .end();
+    }
+
+    private Set<Fruit> getFruits() {
+        Set<Fruit> fruits = 
Collections.newSetFromMap(Collections.synchronizedMap(new LinkedHashMap<>()));
+        fruits.add(new Fruit("Apple", "Winter fruit"));
+        fruits.add(new Fruit("Pineapple", "Tropical fruit"));
+        return fruits;
     }
 }
diff --git 
a/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiTest.java
 
b/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiTest.java
index 7da09f1..205f176 100644
--- 
a/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiTest.java
+++ 
b/integration-tests/openapi-java/src/test/java/org/apache/camel/quarkus/component/openapijava/it/OpenApiTest.java
@@ -21,6 +21,7 @@ import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
 import org.junit.jupiter.api.Test;
 
+import static org.hamcrest.Matchers.contains;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.hasKey;
 import static org.hamcrest.Matchers.is;
@@ -51,4 +52,133 @@ class OpenApiTest {
                         "paths.'/fruits/list'.get.operationId", is("list"));
     }
 
+    @Test
+    public void openApiEndpointSecurity() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "paths.'/security/scopes'", hasKey("get"),
+                        "paths.'/security/scopes'.get.security[0].OAuth2", 
contains("scope1", "scope2", "scope3"));
+
+    }
+
+    @Test
+    public void openApiKeySecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("X-API-Key"),
+                        "components.securitySchemes.X-API-Key.type", 
is("apiKey"),
+                        "components.securitySchemes.X-API-Key.description", 
is("The API key"),
+                        "components.securitySchemes.X-API-Key.name", 
is("X-API-KEY"),
+                        "components.securitySchemes.X-API-Key.in", 
is("header"));
+
+    }
+
+    @Test
+    public void openApiBasicAuthSecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("basicAuth"),
+                        "components.securitySchemes.basicAuth.scheme", 
is("basic"),
+                        "components.securitySchemes.basicAuth.type", 
is("http"),
+                        "components.securitySchemes.basicAuth.description", 
is("Basic Authentication"));
+
+    }
+
+    @Test
+    public void openApiBearerAuthSecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("bearerAuth"),
+                        "components.securitySchemes.bearerAuth.scheme", 
is("bearer"),
+                        "components.securitySchemes.bearerAuth.type", 
is("http"),
+                        "components.securitySchemes.bearerAuth.bearerFormat", 
is("Bearer Token Authentication"));
+    }
+
+    @Test
+    public void openApiMutualTlsSecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("mutualTLS"),
+                        "components.securitySchemes.mutualTLS.type", 
is("mutualTLS"));
+    }
+
+    @Test
+    public void openApiOauth2SecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("oauth2"),
+                        
"components.securitySchemes.oauth2.flows.implicit.authorizationUrl",
+                        is("https://secure.apache.org/fake/oauth2/authorize";),
+                        
"components.securitySchemes.oauth2.flows.implicit.scopes.scope1", is("Scope 1"),
+                        
"components.securitySchemes.oauth2.flows.implicit.scopes.scope2", is("Scope 2"),
+                        
"components.securitySchemes.oauth2.flows.implicit.scopes.scope3", is("Scope 
3"));
+    }
+
+    @Test
+    public void openApiOpenIdSecurityDefinition() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "components.securitySchemes", hasKey("openId"),
+                        "components.securitySchemes.openId.openIdConnectUrl",
+                        
is("https://secure.apache.org/fake/openid-configuration";),
+                        "components.securitySchemes.openId.type", 
is("openIdConnect"));
+    }
+
+    @Test
+    public void openApiOperationSpecification() {
+        RestAssured.given()
+                .get("/openapi.json")
+                .then()
+                .contentType(ContentType.JSON)
+                .statusCode(200)
+                .body(
+                        "paths.'/operation/spec'", hasKey("get"),
+                        "paths.'/operation/spec'.get.parameters[0].name", 
is("header_number"),
+                        
"paths.'/operation/spec'.get.parameters[0].description", is("Header Param 
Number"),
+                        
"paths.'/operation/spec'.get.parameters[0].schema.default", is("1"),
+                        
"paths.'/operation/spec'.get.parameters[0].schema.enum", contains("1", "2", 
"3"),
+                        
"paths.'/operation/spec'.get.parameters[0].schema.type", is("integer"),
+                        "paths.'/operation/spec'.get.parameters[0].in", 
is("header"),
+                        "paths.'/operation/spec'.get.parameters[0].required", 
is(true),
+                        "paths.'/operation/spec'.get.parameters[1].style", 
is("multi"),
+                        "paths.'/operation/spec'.get.parameters[1].name", 
is("query_letter"),
+                        
"paths.'/operation/spec'.get.parameters[1].description", is("Query Param 
Letter"),
+                        
"paths.'/operation/spec'.get.parameters[1].schema.default", is("B"),
+                        
"paths.'/operation/spec'.get.parameters[1].schema.enum", contains("A", "B", 
"C"),
+                        
"paths.'/operation/spec'.get.parameters[1].schema.type", is("string"),
+                        "paths.'/operation/spec'.get.parameters[1].in", 
is("query"),
+                        "paths.'/operation/spec'.get.parameters[1].required", 
is(false),
+                        
"paths.'/operation/spec'.get.responses.418.headers.rate.schema.type", 
is("integer"),
+                        
"paths.'/operation/spec'.get.responses.418.headers.rate.description", is("API 
Rate Limit"),
+                        
"paths.'/operation/spec'.get.responses.418.description", is("I am a teapot"),
+                        
"paths.'/operation/spec'.get.responses.error.description", is("Response 
Error"));
+    }
 }
diff --git 
a/integration-tests/rest/src/main/java/org/apache/camel/quarkus/component/rest/it/RestRoutes.java
 
b/integration-tests/rest/src/main/java/org/apache/camel/quarkus/component/rest/it/RestRoutes.java
index 88189f2..5342994 100644
--- 
a/integration-tests/rest/src/main/java/org/apache/camel/quarkus/component/rest/it/RestRoutes.java
+++ 
b/integration-tests/rest/src/main/java/org/apache/camel/quarkus/component/rest/it/RestRoutes.java
@@ -16,34 +16,67 @@
  */
 package org.apache.camel.quarkus.component.rest.it;
 
+import java.util.Map;
+
+import javax.activation.DataHandler;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.attachment.AttachmentMessage;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.model.rest.RestBindingMode;
 import org.apache.camel.model.rest.RestParamType;
 
 public class RestRoutes extends RouteBuilder {
 
+    private static final String PERSON_JSON = "{\"firstName\": \"John\", 
\"lastName\": \"Doe\", \"age\": 64}";
+    private static final String PERSON_XML = "<person firstName=\"John\" 
lastName=\"Doe\" age=\"64\"/>";
+
     @Override
     public void configure() {
-        final String personJson = "{\"firstName\": \"John\", \"lastName\": 
\"Doe\", \"age\": 64}";
-        final String personXml = "<person firstName=\"John\" lastName=\"Doe\" 
age=\"64\"/>";
         restConfiguration()
                 .enableCORS(true)
                 .corsAllowCredentials(true)
-                .corsHeaderProperty("Access-Control-Allow-Methods", "GET, 
POST");
+                .corsHeaderProperty("Access-Control-Allow-Methods", "GET, 
POST")
+                .endpointProperty("fileNameExtWhitelist", ".txt");
 
         rest("/rest")
-                .get("/get")
+                .delete()
+                .produces("text/plain")
+                .route()
+                .setBody(constant("DELETE: /rest"))
+                .endRest()
+
+                .get()
+                .produces("text/plain")
+                .route()
+                .setBody(constant("GET: /rest"))
+                .endRest()
+
+                .head()
+                .route()
+                .setHeader(Exchange.CONTENT_TYPE).constant("text/plain")
+                .endRest()
+
+                .patch()
+                .consumes("text/plain")
+                .produces("text/plain")
                 .route()
-                .setBody(constant("GET: /rest/get"))
+                .setBody(simple("${body}: /rest"))
                 .endRest()
 
-                .post("/post")
-                .consumes("text/plain").produces("text/plain")
+                .post()
+                .consumes("text/plain")
+                .produces("text/plain")
                 .route()
-                .setBody(constant("POST: /rest/post"))
+                .setBody(simple("${body}: /rest"))
+                .endRest()
+
+                .put()
+                .consumes("text/plain")
+                .produces("text/plain")
+                .route()
+                .setBody(simple("${body}: /rest"))
                 .endRest()
 
                 .post("/validation")
@@ -72,7 +105,7 @@ public class RestRoutes extends RouteBuilder {
 
                 .get("/binding/json/producer")
                 .route()
-                .setBody(constant(personJson))
+                .setBody(constant(PERSON_JSON))
                 .endRest()
 
                 .post("/pojo/binding/xml")
@@ -86,12 +119,31 @@ public class RestRoutes extends RouteBuilder {
 
                 .get("/binding/xml/producer")
                 .route()
-                .setBody(constant(personXml))
+                .setBody(constant(PERSON_XML))
                 .endRest()
 
                 .post("/log")
                 .route()
                 .log("Hello ${body}")
+                .endRest()
+
+                .verb("head", "/custom/verb")
+                .route()
+                .setHeader(Exchange.CONTENT_TYPE, constant("text/plain"))
+                .endRest()
+
+                .post("/multipart/upload")
+                .route()
+                .process(exchange -> {
+                    AttachmentMessage attachmentMessage = 
exchange.getMessage(AttachmentMessage.class);
+                    Map<String, DataHandler> attachments = 
attachmentMessage.getAttachments();
+                    if (attachments != null) {
+                        int size = attachments.size();
+                        exchange.getMessage().setBody(String.valueOf(size));
+                    } else {
+                        exchange.getMessage().setBody("0");
+                    }
+                })
                 .endRest();
     }
 }
diff --git 
a/integration-tests/rest/src/test/java/org/apache/camel/quarkus/component/rest/it/RestTest.java
 
b/integration-tests/rest/src/test/java/org/apache/camel/quarkus/component/rest/it/RestTest.java
index be25dca..7f9d59e 100644
--- 
a/integration-tests/rest/src/test/java/org/apache/camel/quarkus/component/rest/it/RestTest.java
+++ 
b/integration-tests/rest/src/test/java/org/apache/camel/quarkus/component/rest/it/RestTest.java
@@ -16,11 +16,18 @@
  */
 package org.apache.camel.quarkus.component.rest.it;
 
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
 import io.quarkus.test.junit.QuarkusTest;
 import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
+import io.restassured.response.ValidatableResponse;
 import org.apache.camel.component.platform.http.PlatformHttpConstants;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.Matchers.is;
@@ -40,21 +47,27 @@ class RestTest {
                 .body("component", 
is(PlatformHttpConstants.PLATFORM_HTTP_COMPONENT_NAME));
     }
 
-    @Test
-    public void rest() {
-        RestAssured.get("/rest/get")
+    @ParameterizedTest
+    @ValueSource(strings = { "DELETE", "GET", "HEAD", "PATCH", "POST", "PUT" })
+    public void rest(String method) {
+        String body = method.matches("PATCH|POST|PUT") ? method : "";
+
+        ValidatableResponse response = RestAssured.given()
+                .body(body)
+                .request(method, "/rest")
                 .then()
                 .header("Access-Control-Allow-Headers", 
matchesPattern(".*Access-Control.*"))
                 .header("Access-Control-Allow-Methods", matchesPattern("GET, 
POST"))
-                .header("Access-Control-Allow-Credentials", equalTo("true"))
-                .body(equalTo("GET: /rest/get"));
-
-        RestAssured.given()
-                .contentType(ContentType.TEXT)
-                .post("/rest/post")
-                .then()
-                .statusCode(200)
-                .body(equalTo("POST: /rest/post"));
+                .header("Access-Control-Allow-Credentials", equalTo("true"));
+
+        if (method.equals("HEAD")) {
+            // Response body is ignored for HEAD so verify response headers
+            response.statusCode(204);
+            response.header("Content-Type", ContentType.TEXT.toString());
+        } else {
+            response.statusCode(200);
+            response.body(is(method + ": /rest"));
+        }
     }
 
     @Test
@@ -178,7 +191,7 @@ class RestTest {
     }
 
     @Test
-    public void lightweight() throws Throwable {
+    public void lightweight() {
         RestAssured.when()
                 .get("/rest/inspect/camel-context/lightweight")
                 .then()
@@ -187,7 +200,7 @@ class RestTest {
     }
 
     @Test
-    public void restLog() throws Throwable {
+    public void restLog() {
         String message = "Camel Quarkus Platform HTTP";
         RestAssured.given()
                 .contentType(ContentType.TEXT)
@@ -198,4 +211,39 @@ class RestTest {
                 .statusCode(200)
                 .body(is(message));
     }
+
+    @Test
+    public void customVerb() {
+        RestAssured.given()
+                .head("/rest/custom/verb")
+                .then()
+                .statusCode(204)
+                .header("Content-Type", is(ContentType.TEXT.toString()));
+    }
+
+    @Test
+    public void multiPartUpload() throws IOException {
+        Path txtFile = Files.createTempFile("multipartUpload", ".txt");
+        Path csvFile = Files.createTempFile("multipartUpload", ".csv");
+
+        try {
+            RestAssured.given()
+                    .multiPart(txtFile.toFile())
+                    .post("/rest/multipart/upload")
+                    .then()
+                    .statusCode(200)
+                    .body(is("1"));
+
+            // fileNameExtWhitelist config will only allow the txt file 
extension
+            RestAssured.given()
+                    .multiPart(csvFile.toFile())
+                    .post("/rest/multipart/upload")
+                    .then()
+                    .statusCode(200)
+                    .body(is("0"));
+        } finally {
+            Files.deleteIfExists(txtFile);
+            Files.deleteIfExists(csvFile);
+        }
+    }
 }

Reply via email to