Repository: eclipse/microprofile-open-api
Pull request #129 (2017-12-07 18:12:22)

Added TCK tests for @Server, @Operation, @Parameter, @Explode, @SecuyityRequirement and @SecuritySchema
PR for issue #69 

Signed-off-by: Navid Shakibapour <navid.shakibapour@gmail.com>


Patch:
diff --git a/tck/pom.xml b/tck/pom.xml
index 0800db1..76fa985 100644
--- a/tck/pom.xml
+++ b/tck/pom.xml
@@ -127,6 +127,13 @@
              <scope>compile</scope>
          </dependency>
 
+         <dependency>
+             <groupId>org.hamcrest</groupId>
+             <artifactId>java-hamcrest</artifactId>
+             <version>2.0.0.0</version>
+             <scope>compile</scope>
+         </dependency>
+
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
index 74c403e..3c929dd 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/JAXRSApp.java
@@ -68,7 +68,7 @@ import org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource;
         termsOfService = "http://airlinesratingapp.com/terms", 
         contact = @Contact(
             name = "AirlinesRatingApp API Support",
-            url = "https://github.com/microservices-api/oas3-airlines",
+            url = "http://exampleurl.com/contact",
             email = "techsupport@airlinesratingapp.com"),
         license = @License(
             name = "Apache 2.0",
@@ -76,10 +76,13 @@ import org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource;
         security = @SecurityRequirement(name = "airlinesRatingApp_auth"),
         servers = {
                 @Server(url = "https://{username}.gigantic-server.com:{port}/{basePath}", description = "The production API server",
-                        variables = { @ServerVariable(name = "username", description = "Reviews of the app by users", defaultValue = "reviews"),
-                                @ServerVariable(name = "port", description = "Booking data", enumeration = { "8443", "443" }, defaultValue = "8443"),
+                        variables = {
+                                @ServerVariable(name = "username", description = "Reviews of the app by users", defaultValue = "user1",
+                                        enumeration = { "user1", "user2" }),
+                                @ServerVariable(name = "port", description = "Booking data", defaultValue = "8443"),
                                 @ServerVariable(name = "user", description = "User data", defaultValue = "user"),
-                                @ServerVariable(name = "basePath", defaultValue = "v2") }) },
+                                @ServerVariable(name = "basePath", defaultValue = "v2") }),
+                @Server(url = "https://test-server.com:80/basePath", description = "The test API server") },
         components = @Components(
                 schemas = { 
                         @Schema(name = "Bookings", type = SchemaType.ARRAY, implementation = Booking.class),
@@ -132,7 +135,7 @@ import org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource;
     description = "APIs for booking and managing air flights",
     externalDocs = @ExternalDocumentation(
         description = "For more information, see the link.",
-        url = "https://github.com/janamanoharan/airlinesratingapp")
+        url = "http://exampleurl.com/schema")
     )
 public class JAXRSApp extends Application {
     @Override
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/BookingResource.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/BookingResource.java
index 17b0778..4e0d73f 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/BookingResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/BookingResource.java
@@ -30,6 +30,7 @@ import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType;
 import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
 import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement;
 import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme;
+import org.eclipse.microprofile.openapi.annotations.servers.Server;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -61,6 +62,8 @@ import org.eclipse.microprofile.openapi.apps.airlines.model.Booking;
     description = "Security Scheme for booking resource",
     openIdConnectUrl = "http://openidconnect.com/testurl"
 )
+@Server(description = "Secure server", url = "https://gigantic-server.com:443")
+@Server(description = "Unsecure server", url = "http://gigantic-server.com:80")
 public class BookingResource {
     private Map<Integer, Booking> bookings = new ConcurrentHashMap<Integer, Booking>();
     private volatile int currentId = 0;
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/ReviewResource.java b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/ReviewResource.java
index 47d3e17..c259df5 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/ReviewResource.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/apps/airlines/resources/ReviewResource.java
@@ -65,9 +65,9 @@ import org.eclipse.microprofile.openapi.apps.airlines.model.User;
 @Path("/reviews")
 @Servers({ @Server(description = "Secure server", url = "https://gigantic-server.com:443"),
         @Server(description = "Unsecure server", url = "http://gigantic-server.com:80") })
-@Server(url = "https://gigantic-server.com:{port}",
+@Server(url = "{protocol}://test-server.com",
         description = "The production API server",
-        variables = { @ServerVariable(name = "port", description = "Review data", enumeration = { "9080", "9443" }, defaultValue = "9080") })
+        variables = { @ServerVariable(name = "protocol", enumeration = { "http", "https" }, defaultValue = "https") })
 @SecurityScheme(
     securitySchemeName = "reviewoauth2",
     type = SecuritySchemeType.OAUTH2,
@@ -371,16 +371,10 @@ public class ReviewResource {
         operationId = "createReview",
         tags = {"Reviews"},
         servers = {
-            @Server(
-                url = "localhost:9080/oas3-airlines/reviews/{id}",
-                description = "view of all the reviews",
-                variables = {
-                    @ServerVariable(
-                        name = "id",
-                        description = "id of the review",
-                        defaultValue = "1")
-            })
-        },
+                @Server(url = "localhost:9080/{proxyPath}/reviews/id",
+                        description = "view of all the reviews",
+                        variables = { @ServerVariable(name = "proxyPath", description = "Base path of the proxy", defaultValue = "proxy") }),
+                @Server(url = "http://random.url/reviews", description = "random text") },
         security = @SecurityRequirement(
                      name = "reviewoauth2",
                      scopes = "write:reviews"),


Test patch:
diff --git a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
index 2858613..c411caa 100644
--- a/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
+++ b/tck/src/main/java/org/eclipse/microprofile/openapi/tck/EndpointTest.java
@@ -17,15 +17,27 @@
 package org.eclipse.microprofile.openapi.tck;
 
 import static io.restassured.RestAssured.given;
+import static org.hamcrest.Matchers.both;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.either;
+import static org.hamcrest.Matchers.empty;
 import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.hamcrest.collection.IsMapWithSize.aMapWithSize;
 
 import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.eclipse.microprofile.openapi.tck.utils.YamlToJsonConverterServlet;
-import org.hamcrest.Matchers;
 import org.jboss.arquillian.container.test.api.Deployment;
 import org.jboss.arquillian.container.test.api.RunAsClient;
 import org.jboss.arquillian.junit.Arquillian;
@@ -76,11 +88,12 @@ public class EndpointTest {
             RestAssured.authentication = RestAssured.basic(userName, password);
             RestAssured.useRelaxedHTTPSValidation();
         }
+        RestAssured.defaultParser = Parser.JSON;
     }
-    
+
     @Before
     public void setUpTest() {
-        vr = given().when().get("/proxy").then().parser("", Parser.JSON).statusCode(200);
+        vr = given().when().get("/proxy").then().statusCode(200);
     }
 
     @Deployment(name = "proxy")
@@ -94,14 +107,15 @@ public class EndpointTest {
                 .addAsLibraries(new File("./lib/jackson-databind-2.9.2.jar"))
                 .addAsLibraries(new File("./lib/jackson-annotations-2.9.1.jar"))
                 .addAsLibraries(new File("./lib/snakeyaml-1.18.jar"))
-                .addAsLibraries(new File("./lib/commons-logging-1.2.jar"));
+                .addAsLibraries(new File("./lib/commons-logging-1.2.jar"))
+                .addAsLibraries(new File("./lib/commons-lang3-3.4.jar"));
     }
 
     @Deployment(name = "airlines")
     public static WebArchive createDeployment() {
         return ShrinkWrap.create(WebArchive.class, "airlines.war")
                 .addPackages(true, "org.eclipse.microprofile.openapi.apps.airlines")
-                .addAsManifestResource("openapi.yaml", "openapi.yaml");
+                .addAsManifestResource("openapi.yaml", "openapi/openapi.yaml");
     }
 
     @Test
@@ -122,7 +136,7 @@ public class EndpointTest {
     @RunAsClient
     public void testContact() {
         vr.body("info.contact.name", equalTo("AirlinesRatingApp API Support"));
-        vr.body("info.contact.url", equalTo("https://github.com/microservices-api/oas3-airlines"));
+        vr.body("info.contact.url", equalTo("http://exampleurl.com/contact"));
         vr.body("info.contact.email", equalTo("techsupport@airlinesratingapp.com"));
     }
 
@@ -143,6 +157,324 @@ public class EndpointTest {
     @Test
     @RunAsClient
     public void testServer() {
-        vr.body("servers[*]", Matchers.hasSize(8));
+        vr.body("servers", hasSize(2));
+        vr.body("servers.url", hasSize(2));
+
+        String url = "https://{username}.gigantic-server.com:{port}/{basePath}";
+        String serverPath = "servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("The production API server"));
+        vr.body(serverPath + ".variables", aMapWithSize(4));
+        vr.body(serverPath + ".variables.username.description", equalTo("Reviews of the app by users"));
+        vr.body(serverPath + ".variables.username.default", equalTo("user1"));
+        vr.body(serverPath + ".variables.username.enum", containsInAnyOrder("user1", "user2"));
+        vr.body(serverPath + ".variables.port.description", equalTo("Booking data"));
+        vr.body(serverPath + ".variables.port.default", equalTo("8443"));
+        vr.body(serverPath + ".variables.user.description", equalTo("User data"));
+        vr.body(serverPath + ".variables.user.default", equalTo("user"));
+        vr.body(serverPath + ".variables.basePath.default", equalTo("v2"));
+
+        url = "https://test-server.com:80/basePath";
+        serverPath = "servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("The test API server"));
+
+        // Testing @Servers and @Server defined on top of a class with @Server
+        // defined in an operation
+        // org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource
+        vr.body("paths.'/reviews/{id}'.delete.servers", hasSize(3));
+        vr.body("paths.'/reviews/{id}'.delete.servers.url", hasSize(3));
+
+        url = "https://gigantic-server.com:443";
+        serverPath = "paths.'/reviews/{id}'.delete.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("Secure server"));
+
+        url = "http://gigantic-server.com:80";
+        serverPath = "paths.'/reviews/{id}'.delete.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("Unsecure server"));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
+
+        url = "{protocol}://test-server.com";
+        serverPath = "paths.'/reviews/{id}'.delete.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("The production API server"));
+        vr.body(serverPath + ".variables", aMapWithSize(1));
+        vr.body(serverPath + ".variables.proxyPath.description", equalTo("Base path of the proxy"));
+        vr.body(serverPath + ".variables.proxyPath.default", equalTo("http"));
+        vr.body(serverPath + ".variables.proxyPath.enum", containsInAnyOrder("http", "https"));
+
+        // Testing two @Server defined in an @operation annotation on a method
+        // org.eclipse.microprofile.openapi.apps.airlines.resources.ReviewResource.createReview(Review)
+        vr.body("paths.'/reviews'.post.servers", hasSize(2));
+        vr.body("paths.'/reviews'.post.servers.url", hasSize(2));
+        url = "localhost:9080/{proxyPath}/reviews/id";
+        serverPath = "paths.'/reviews'.post.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("view of all the reviews"));
+        vr.body(serverPath + ".variables", aMapWithSize(1));
+        vr.body(serverPath + ".variables.proxyPath.description", equalTo("Base path of the proxy"));
+        vr.body(serverPath + ".variables.proxyPath.default", equalTo("proxy"));
+        url = "http://random.url/reviews";
+        serverPath = "paths.'/reviews'.post.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("random text"));
+
+        // Testing two @Server defined on top of a class
+        // org.eclipse.microprofile.openapi.apps.airlines.resources.BookingResource
+        vr.body("paths.'/bookings'.get.servers", hasSize(2));
+        vr.body("paths.'/bookings'.get.servers.url", hasSize(2));
+
+        url = "https://gigantic-server.com:80";
+        serverPath = "paths.'/bookings'.get.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("Secure server"));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
+
+        url = "https://gigantic-server.com:443";
+        serverPath = "paths.'/bookings'.get.servers.find { it.url == '" + url + "' }";
+        vr.body(serverPath + ".description", equalTo("Unsecure server"));
+        vr.body(serverPath + ".variables", either(not(empty())).or(notNullValue()));
+    }
+
+    @Test
+    @RunAsClient
+    public void testOperationAirlinesResource() {
+        vr.body("paths.'/'.get.summary", equalTo("Retrieve all available airlines"));
+        vr.body("paths.'/'.get.operationId", equalTo("getAirlines"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testOperationAvailabilityResource() {
+        vr.body("paths.'/availability'.get.summary", equalTo("Retrieve all available flights"));
+        vr.body("paths.'/availability'.get.operationId", equalTo("getFlights"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testOperationBookingResource() {
+        vr.body("paths.'/bookings'.get.summary", equalTo("Retrieve all bookings for current user"));
+        vr.body("paths.'/bookings'.get.operationId", equalTo("getAllBookings"));
+
+        vr.body("paths.'/bookings'.post.summary", equalTo("Create a booking"));
+        vr.body("paths.'/bookings'.post.description", equalTo("Create a new booking record with the booking information provided."));
+        vr.body("paths.'/bookings'.post.operationId", equalTo("createBooking"));
+
+        vr.body("paths.'/bookings/{id}'.get.summary", equalTo("Get a booking with ID"));
+        vr.body("paths.'/bookings/{id}'.get.operationId", equalTo("getBookingById"));
+
+        vr.body("paths.'/bookings/{id}'.put.summary", equalTo("Update a booking with ID"));
+        vr.body("paths.'/bookings/{id}'.put.operationId", equalTo("updateBookingId"));
+
+        vr.body("paths.'/bookings/{id}'.delete.summary", equalTo("Delete a booking with ID"));
+        vr.body("paths.'/bookings/{id}'.delete.operationId", equalTo("deleteBookingById"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testOperationReviewResource() {
+        vr.body("paths.'/reviews'.get.summary", equalTo("get all the reviews"));
+        vr.body("paths.'/reviews'.get.operationId", equalTo("getAllReviews"));
+
+        vr.body("paths.'/reviews'.post.summary", equalTo("Create a Review"));
+        vr.body("paths.'/reviews'.post.operationId", equalTo("createReview"));
+
+        vr.body("paths.'/reviews/{id}'.get.summary", equalTo("Get a review with ID"));
+        vr.body("paths.'/reviews/{id}'.get.operationId", equalTo("getReviewById"));
+
+        vr.body("paths.'/reviews/{id}'.delete.summary", equalTo("Delete a Review with ID"));
+        vr.body("paths.'/reviews/{id}'.delete.operationId", equalTo("deleteReview"));
+
+        vr.body("paths.'/reviews/{user}'.get.summary", equalTo("Get all reviews by user"));
+        vr.body("paths.'/reviews/{user}'.get.operationId", equalTo("getReviewByUser"));
+
+        vr.body("paths.'/reviews/{airline}'.get.summary", equalTo("Get all reviews by airlines"));
+        vr.body("paths.'/reviews/{airline}'.get.operationId", equalTo("getReviewByAirline"));
+
+        vr.body("paths.'/reviews/{user}/{airlines}'.get.summary", equalTo("Get all reviews for an airline by User"));
+        vr.body("paths.'/reviews/{user}/{airlines}'.get.operationId", equalTo("getReviewByAirlineAndUser"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testOperationUserResource() {
+        vr.body("paths.'/user'.post.summary", equalTo("Create user"));
+        vr.body("paths.'/user'.post.description", equalTo("This can only be done by the logged in user."));
+        vr.body("paths.'/user'.post.operationId", equalTo("createUser"));
+
+        vr.body("paths.'/user/createWithArray'.post.summary", equalTo("Creates list of users with given input array"));
+        vr.body("paths.'/user/createWithArray'.post.operationId", equalTo("createUsersFromArray"));
+
+        vr.body("paths.'/user/createWithList'.post.summary", equalTo("Creates list of users with given input list"));
+        vr.body("paths.'/user/createWithList'.post.operationId", equalTo("createUsersFromList"));
+
+        vr.body("paths.'/user/{username}'.put.summary", equalTo("Update user"));
+        vr.body("paths.'/user/{username}'.put.description", equalTo("This can only be done by the logged in user."));
+        vr.body("paths.'/user/{username}'.put.operationId", equalTo("updateUser"));
+
+        vr.body("paths.'/user/{username}'.delete.summary", equalTo("Delete user"));
+        vr.body("paths.'/user/{username}'.delete.description", equalTo("This can only be done by the logged in user."));
+        vr.body("paths.'/user/{username}'.delete.operationId", equalTo("deleteUser"));
+
+        vr.body("paths.'/user/{username}'.get.summary", equalTo("Get user by user name"));
+        vr.body("paths.'/user/{username}'.get.operationId", equalTo("getUserByUserName"));
+
+        vr.body("paths.'/user/{id}'.get.summary", equalTo("Get user by id"));
+        vr.body("paths.'/user/{id}'.get.operationId", equalTo("getUserById"));
+
+        vr.body("paths.'/user/login'.get.summary", equalTo("Logs user into the system"));
+        vr.body("paths.'/user/login'.get.operationId", equalTo("logInUser"));
+
+        vr.body("paths.'/user/logout'.get.summary", equalTo("Logs out current logged in user session"));
+        vr.body("paths.'/user/logout'.get.operationId", equalTo("logOutUser"));
+    }
+
+    @Test
+    @RunAsClient
+    public void testParameter() throws InterruptedException {
+        testAvailabilityGetParamater(vr);
+        testBookingIdMethods(vr);
+        testReviewIdMethods(vr);
+        testUserLoginMethods(vr);
+    }
+
+    private void testUserLoginMethods(ValidatableResponse vr2) {
+        String reviewParameters = "paths.'/user/login'.get.parameters";
+        vr.body(reviewParameters, hasSize(2));
+        vr.body(reviewParameters + ".findAll { it }.name", hasItems("username", "password"));
+        List<String[]> list = new ArrayList<String[]>();
+        list.add(new String[] { "username", "The user name for login" });
+        list.add(new String[] { "password", "The password for login in clear text" });
+
+        for (int i = 0; i < list.size(); i++) {
+            String currentParam = list.get(i)[0];
+            String query = reviewParameters + ".findAll { it.name == '" + currentParam + "' }";
+
+            vr.body(query + ".in", both(hasSize(1)).and(contains("query")));
+            vr.body(query + ".description", both(hasSize(1)).and(contains(list.get(i)[1])));
+            vr.body(query + ".required", both(hasSize(1)).and(contains(true)));
+            vr.body(query + ".schema.type", both(hasSize(1)).and(contains("string")));
+        }
+    }
+
+    private void testReviewIdMethods(ValidatableResponse vr2) {
+        String reviewParameters = "paths.'/reviews/{id}'.get.parameters";
+        vr.body(reviewParameters, hasSize(1));
+        vr.body(reviewParameters + ".findAll { it }.name", contains("id"));
+        vr.body(reviewParameters + ".findAll { it.name == 'id' }.in", both(hasSize(1)).and(contains("path")));
+        // vr.body(reviewParameters + ".findAll { it.name == 'id' }.description", both(hasSize(1)).and(contains("ID of the booking")));
+        vr.body(reviewParameters + ".findAll { it.name == 'id' }.required", both(hasSize(1)).and(contains(true)));
+        vr.body(reviewParameters + ".findAll { it.name == 'id' }.content.'*/*'.schema.type", both(hasSize(1)).and(contains("integer")));
+    }
+
+    private void testBookingIdMethods(ValidatableResponse vr) {
+        String bookingParameters = "paths.'/bookings/{id}'.%s.parameters";
+
+        for (String method : new String[] { "get", "put", "delete" }) {
+            bookingParameters = String.format(bookingParameters, method);
+
+            vr.body(bookingParameters, hasSize(1));
+            vr.body(bookingParameters + ".findAll { it }.name", contains("id"));
+
+            vr.body(bookingParameters + ".findAll { it.name == 'id' }.in", both(hasSize(1)).and(contains("path")));
+            // TODO
+            vr.body(bookingParameters + ".findAll { it.name == 'id' }.description", both(hasSize(1)).and(contains("ID of the booking")));
+            vr.body(bookingParameters + ".findAll { it.name == 'id' }.required", both(hasSize(1)).and(contains(true)));
+            vr.body(bookingParameters + ".findAll { it.name == 'id' }.schema.type", both(hasSize(1)).and(contains("integer")));
+        }
+    }
+
+    private void testAvailabilityGetParamater(ValidatableResponse vr) {
+        String availabilityParameters = "paths.'/availability'.get.parameters";
+
+        vr.body(availabilityParameters, hasSize(6));
+        vr.body(availabilityParameters + ".findAll { it }.name",
+                hasItems("departureDate", "airportFrom", "returningDate", "airportTo", "numberOfAdults", "numberOfChildren"));
+
+        List<String[]> list = new ArrayList<String[]>();
+        list.add(new String[] { "departureDate", "Customer departure date" });
+        list.add(new String[] { "airportFrom", "Airport the customer departs from" });
+        list.add(new String[] { "returningDate", "Customer return date" });
+        list.add(new String[] { "airportTo", "Airport the customer returns to" });
+        list.add(new String[] { "numberOfAdults", "Number of adults on the flight" });
+        list.add(new String[] { "numberOfChildren", "Number of children on the flight" });
+
+        for (int i = 0; i < list.size(); i++) {
+            String currentParam = list.get(i)[0];
+            String query = availabilityParameters + ".findAll { it.name == '" + currentParam + "' }";
+
+            vr.body(query + ".in", both(hasSize(1)).and(contains("query")));
+            vr.body(query + ".description", both(hasSize(1)).and(contains(list.get(i)[1])));
+            vr.body(query + ".required", both(hasSize(1)).and(contains(true)));
+            vr.body(query + ".schema.type", both(hasSize(1)).and(contains("string")));
+        }
+
+        vr.body(availabilityParameters + ".findAll { it.name == 'numberOfAdults' }.schema.minimum", both(hasSize(1)).and(contains(0)));
+        vr.body(availabilityParameters + ".findAll { it.name == 'numberOfChildren' }.schema.minimum", both(hasSize(1)).and(contains(0)));
+    }
+
+    @Test
+    @RunAsClient
+    public void testExplode() throws InterruptedException {
+        String explode = "paths.'/user/{username}'.put.responses.'200'.content.'application/xml'.encoding.password.explode";
+        vr.body(explode, equalTo(true));
+        explode = "paths.'/user/{username}'.put.responses.'200'.content.'application/xml'.encoding.password.explode";
+        vr.body(explode, equalTo(true));
+    }
+
+    @Test
+    @RunAsClient
+    public void testSecurityRequirement() throws InterruptedException {
+        vr.body("security.airlinesRatingApp_auth[0][0]", equalTo(null));
+
+        vr.body("paths.'/reviews'.post.security.reviewoauth2[0][0]", equalTo("write:reviews"));
+        vr.body("paths.'/reviews'.post.security.reviewoauth2", hasSize(1));
+
+        vr.body("paths.'/user'.post.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user'.post.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/createWithArray'.post.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/createWithArray'.post.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/createWithList'.post.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/createWithList'.post.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/{username}'.get.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/{username}'.get.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/{username}'.put.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/{username}'.put.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/{username}'.delete.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/{username}'.delete.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/{id}'.get.security.httpTestScheme[0][0]", equalTo("write:users"));
+        vr.body("paths.'/user/{id}'.get.security.httpTestScheme", hasSize(1));
+
+        vr.body("paths.'/user/{login}'.get.security.httpTestScheme[0][0]", equalTo(null));
+        vr.body("paths.'/user/{logout}'.get.security.httpTestScheme[0][0]", equalTo(null));
+    }
+
+    @Test
+    @RunAsClient
+    public void testSecuritySchemesInComponents() throws InterruptedException {
+        String s = "components.securitySchemes";
+        vr.body(s, hasKey("httpTestScheme"));
+        vr.body(s, hasKey("airlinesRatingApp_auth"));
+        vr.body(s, hasKey("reviewoauth2"));
+
+        vr.body(s + ".httpTestScheme.type", equalTo("http"));
+        vr.body(s + ".httpTestScheme.description", equalTo("user security scheme"));
+        vr.body(s + ".httpTestScheme.name", equalTo("httpTestScheme"));
+        vr.body(s + ".httpTestScheme.scheme", equalTo("testScheme"));
+
+        vr.body(s + ".airlinesRatingApp_auth.type", equalTo("apiKey"));
+        vr.body(s + ".airlinesRatingApp_auth.description", equalTo("authentication needed to access Airlines app"));
+        vr.body(s + ".airlinesRatingApp_auth.name", equalTo("airlinesRatingApp_auth"));
+        vr.body(s + ".airlinesRatingApp_auth.in", equalTo("header"));
+
+        vr.body(s + ".reviewoauth2.type", equalTo("oauth2"));
+        vr.body(s + ".reviewoauth2.description", equalTo("authentication needed to create and delete reviews"));
+        vr.body(s + ".reviewoauth2.name", equalTo("reviewoauth2"));
+
+        String t = "components.securitySchemes.reviewoauth2.flows";
+        vr.body(t + ".implicit.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(t + ".implicit.scopes.'write:reviews'", equalTo("create a review"));
+        vr.body(t + ".authorizationCode.authorizationUrl", equalTo("https://example.com/api/oauth/dialog"));
+        vr.body(t + ".authorizationCode.tokenUrl", equalTo("https://example.com/api/oauth/token"));
     }
 }