From c7979b3b8e721fb2b14d2ad2b28c4d4455bfef46 Mon Sep 17 00:00:00 2001 From: O-sura Date: Tue, 26 Mar 2024 12:03:14 +0530 Subject: [PATCH] Adding cucmber tests for scope-validation,api-versioning and backend-support --- .../cucumber-tests/CRs/artifacts.yaml | 65 ++++++- .../integration/api/APIDeploymentSteps.java | 139 ++++++++++---- .../wso2/apk/integration/api/BaseSteps.java | 2 - .../apk/integration/api/SharedContext.java | 49 +++-- .../org/wso2/apk/integration/utils/Utils.java | 26 ++- .../definitions/cors-definition.json | 41 +++++ .../resources/artifacts/payloads/api1.json | 4 +- .../payloads/api_default_version.json | 20 +++ .../payloads/api_with_basic_auth.json | 56 ++++++ .../artifacts/payloads/cors_api.json | 58 ++++++ .../artifacts/payloads/gqlPayload.json | 2 +- .../artifacts/payloads/gql_cors.json | 72 ++++++++ .../payloads/gql_default_version.json | 31 ++++ .../payloads/gql_with_basic_auth.json | 75 ++++++++ .../payloads/gql_with_basic_auth2.json | 99 ++++++++++ .../artifacts/payloads/gql_with_scopes.json | 2 +- .../resources/tests/api/APIVersion.feature | 137 ++++++++++++++ .../tests/api/BackendSecurity.feature | 100 +++++++++++ .../tests/api/BackendSupport.feature | 108 +++++++++++ .../src/test/resources/tests/api/CORS.feature | 170 ++++++++++++++++++ .../tests/api/DefaultVersion.feature | 106 +++++++++++ .../resources/tests/api/Deployment.feature | 14 +- .../{ScopesEnabled.feature => Scopes.feature} | 14 +- 23 files changed, 1318 insertions(+), 72 deletions(-) create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/cors-definition.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_default_version.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_with_basic_auth.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/cors_api.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_cors.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_default_version.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth2.json create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/APIVersion.feature create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSecurity.feature create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSupport.feature create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/CORS.feature create mode 100644 test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/DefaultVersion.feature rename test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/{ScopesEnabled.feature => Scopes.feature} (93%) diff --git a/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml b/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml index 7eeb1b40ff..2754146b11 100644 --- a/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml +++ b/test/apim-apk-agent-test/cucumber-tests/CRs/artifacts.yaml @@ -257,4 +257,67 @@ spec: targetPort: 9002 protocol: TCP selector: - app: graphql-faker \ No newline at end of file + app: graphql-faker + +--- +apiVersion: v1 +kind: Service +metadata: + name: backend + namespace: apk +spec: + ports: + - name: http + port: 80 + targetPort: 80 + selector: + app: httpbin +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: httpbin + namespace: apk +spec: + replicas: 1 + selector: + matchLabels: + app: httpbin + template: + metadata: + labels: + app: httpbin + spec: + containers: + - image: docker.io/kennethreitz/httpbin:latest + imagePullPolicy: IfNotPresent + name: httpbin + ports: + - containerPort: 80 + resources: + requests: + memory: "200Mi" + cpu: "300m" + limits: + memory: "200Mi" + cpu: "300m" +--- +apiVersion: v1 +kind: Secret +metadata: + name: backend-creds + namespace: apk +data: + username: YWRtaW4= + password: YWRtaW4= +type: Opaque +--- +apiVersion: v1 +kind: Secret +metadata: + name: backend-creds-1 + namespace: apk +data: + username: ZHNmZHNmc2Rmc2Rm + password: YWRtaW4= +type: Opaque \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java index 90ac74e245..537d7c9266 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/APIDeploymentSteps.java @@ -36,6 +36,8 @@ import org.wso2.apk.integration.utils.Constants; import org.wso2.apk.integration.utils.Utils; import org.wso2.apk.integration.utils.clients.SimpleHTTPClient; +import java.nio.file.Files; +import java.nio.charset.StandardCharsets; import java.io.File; import java.io.IOException; @@ -83,17 +85,28 @@ public void iHaveTheDefinitionFile(String definitionFileName) throws IOException definitionFile = new File(url.getPath()); } - @When("make the import API Creation request") - public void make_import_api_creation_request() throws Exception { - logger.info("OAS URL: " + OASURL); - - // Create a MultipartEntityBuilder to build the request entity - MultipartEntityBuilder builder = MultipartEntityBuilder.create() - .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) - .addTextBody("url", OASURL, ContentType.TEXT_PLAIN) - .addPart("additionalProperties", new FileBody(payloadFile)); + @When("make the import API Creation request using OAS {string}") + public void make_import_api_creation_request(String definitionType) throws Exception { + MultipartEntityBuilder builder = null; + if(definitionType.equals("URL")){ + logger.info("OAS URL: " + OASURL); + builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addTextBody("url", OASURL, ContentType.TEXT_PLAIN) + .addPart("additionalProperties", new FileBody(payloadFile)); + + logger.info("Payload File: "+ new FileBody(payloadFile)); + } + if(definitionType.equals("File")){ + logger.info("OAS File: " + definitionFile.getName()); + builder = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) + .addPart("file", new FileBody(definitionFile)) + .addPart("additionalProperties", new FileBody(payloadFile)); + + logger.info("Payload File: "+ new FileBody(payloadFile)); + } - logger.info("Payload File: "+ new FileBody(payloadFile)); Map headers = new HashMap<>(); headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); @@ -194,26 +207,44 @@ public void make_generate_keys_request() throws Exception { String keyManagerUUID = sharedContext.getKeyManagerUUID(); logger.info("Key Manager UUID: " + keyManagerUUID); logger.info("Application UUID: " + applicationUUID); - String payload = "{\"keyType\":\"PRODUCTION\",\"grantTypesToBeSupported\":[\"password\",\"client_credentials\"]," + + String payloadForProdKeys = "{\"keyType\":\"PRODUCTION\",\"grantTypesToBeSupported\":[\"password\",\"client_credentials\"]," + "\"callbackUrl\":\"\",\"additionalProperties\":{\"application_access_token_expiry_time\":\"N/A\"," + "\"user_access_token_expiry_time\":\"N/A\",\"refresh_token_expiry_time\":\"N/A\"," + "\"id_token_expiry_time\":\"N/A\",\"pkceMandatory\":\"false\",\"pkceSupportPlain\":\"false\"," + "\"bypassClientCredentials\":\"false\"},\"keyManager\":\"" + keyManagerUUID +"\"," + "\"validityTime\":3600,\"scopes\":[\"default\"]}"; + + String payloadForSandboxKeys = "{\"keyType\":\"SANDBOX\",\"grantTypesToBeSupported\":[\"password\",\"client_credentials\"]," + + "\"callbackUrl\":\"\",\"additionalProperties\":{\"application_access_token_expiry_time\":\"N/A\"," + + "\"user_access_token_expiry_time\":\"N/A\",\"refresh_token_expiry_time\":\"N/A\"," + + "\"id_token_expiry_time\":\"N/A\",\"pkceMandatory\":\"false\",\"pkceSupportPlain\":\"false\"," + + "\"bypassClientCredentials\":\"false\"},\"keyManager\":\"" + keyManagerUUID +"\"," + + "\"validityTime\":3600,\"scopes\":[\"default\"]}"; + + Map headers = new HashMap<>(); headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getDevportalAccessToken()); headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); - logger.info("Payload: " + payload); - HttpResponse response = sharedContext.getHttpClient().doPost(Utils.getGenerateKeysURL(applicationUUID), - headers, payload, Constants.CONTENT_TYPES.APPLICATION_JSON); + headers, payloadForProdKeys, Constants.CONTENT_TYPES.APPLICATION_JSON); sharedContext.setResponse(response); sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); - sharedContext.setConsumerSecret(Utils.extractKeys(sharedContext.getResponseBody(), "consumerSecret")); - sharedContext.setConsumerKey(Utils.extractKeys(sharedContext.getResponseBody(), "consumerKey")); + sharedContext.setConsumerSecret(Utils.extractKeys(sharedContext.getResponseBody(), "consumerSecret"), "production"); + sharedContext.setConsumerKey(Utils.extractKeys(sharedContext.getResponseBody(), "consumerKey"), "production"); + sharedContext.setKeyMappingID(Utils.extractKeys(sharedContext.getResponseBody(), "keyMappingId"), "production"); + Thread.sleep(3000); + + HttpResponse response2 = sharedContext.getHttpClient().doPost(Utils.getGenerateKeysURL(applicationUUID), + headers, payloadForSandboxKeys, Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setResponse(response2); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + sharedContext.setConsumerSecret(Utils.extractKeys(sharedContext.getResponseBody(), "consumerSecret"), "sandbox"); + sharedContext.setConsumerKey(Utils.extractKeys(sharedContext.getResponseBody(), "consumerKey"), "sandbox"); + sharedContext.setKeyMappingID(Utils.extractKeys(sharedContext.getResponseBody(), "keyMappingId"), "sandbox"); Thread.sleep(3000); } @@ -237,10 +268,10 @@ public void make_subscription_request() throws Exception { Thread.sleep(3000); } - @When("I get oauth keys for application") - public void get_oauth_keys_for_application() throws Exception { + @When("I get {string} oauth keys for application") + public void get_oauth_keys_for_application(String type) throws Exception { String applicationUUID = sharedContext.getApplicationUUID(); - + String keyType = (type.equals("production")) ? "production" : "sandbox"; Map headers = new HashMap<>(); headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getDevportalAccessToken()); headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); @@ -250,18 +281,22 @@ public void get_oauth_keys_for_application() throws Exception { sharedContext.setResponse(response); sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); - sharedContext.setOauthKeyUUID(Utils.extractOAuthMappingID(sharedContext.getResponseBody())); + sharedContext.setOauthKeyUUID(Utils.extractOAuthMappingID(sharedContext.getResponseBody(), sharedContext.getKeyMappingID(keyType))); Thread.sleep(3000); } - @When("make the Access Token Generation request") - public void make_access_token_generation_request() throws Exception { + @When("make the Access Token Generation request for {string}") + public void make_access_token_generation_request(String type) throws Exception { String applicationUUID = sharedContext.getApplicationUUID(); String oauthKeyUUID = sharedContext.getOauthKeyUUID(); - String consumerKey = sharedContext.getConsumerKey(); - String consumerSecret = sharedContext.getConsumerSecret(); - logger.info("Oauth Key UUID: " + oauthKeyUUID); + String keyType = (type.equals("production")) ? "production" : "sandbox"; + logger.info("Generating keys for: " + keyType); + String consumerKey = sharedContext.getConsumerKey(keyType); + String consumerSecret = sharedContext.getConsumerSecret(keyType); + logger.info("Application UUID: " + applicationUUID); + logger.info("Oauth Key UUID: " + oauthKeyUUID); + String payload = "{\"consumerSecret\":\"" + consumerSecret + "\",\"validityPeriod\":3600,\"revokeToken\":null," + "\"scopes\":[\"write:pets\",\"read:pets\",\"query:hero\"],\"additionalProperties\":{\"id_token_expiry_time\":3600," + "\"application_access_token_expiry_time\":3600,\"user_access_token_expiry_time\":3600,\"bypassClientCredentials\":false," + @@ -285,10 +320,13 @@ public void make_access_token_generation_request() throws Exception { public void make_access_token_generation_request_without_scopes() throws Exception { String applicationUUID = sharedContext.getApplicationUUID(); String oauthKeyUUID = sharedContext.getOauthKeyUUID(); - String consumerKey = sharedContext.getConsumerKey(); - String consumerSecret = sharedContext.getConsumerSecret(); - logger.info("Oauth Key UUID: " + oauthKeyUUID); + String keyType = "production"; //Use the same ternary logic above if both sandbox and production routes need to be tested + String consumerKey = sharedContext.getConsumerKey(keyType); + String consumerSecret = sharedContext.getConsumerSecret(keyType); + logger.info("Application UUID: " + applicationUUID); + logger.info("Oauth Key UUID: " + oauthKeyUUID); + String payload = "{\"consumerSecret\":\"" + consumerSecret + "\",\"validityPeriod\":3600,\"revokeToken\":null," + "\"scopes\":[],\"additionalProperties\":{\"id_token_expiry_time\":3600," + "\"application_access_token_expiry_time\":3600,\"user_access_token_expiry_time\":3600,\"bypassClientCredentials\":false," + @@ -355,8 +393,6 @@ public void makeAPIDeploymentFromOrganization(String organization) throws Except Thread.sleep(3000); } - - // @When("I undeploy the API whose ID is {string}") // public void i_undeploy_the_api_whose_id_is(String apiID) throws Exception { @@ -398,7 +434,6 @@ public void makeAPIDeploymentFromOrganization(String organization) throws Except // sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); // } - //New steps @Given("a valid graphql definition file") public void iHaveValidGraphQLDefinition() throws Exception { @@ -449,6 +484,21 @@ public void make_import_gqlapi_creation_request() throws Exception { Thread.sleep(3000); } + @Then("I update the GQL API settings") + public void make_update_gql_request() throws Exception { + String fileContent = new String(Files.readAllBytes(payloadFile.toPath()), StandardCharsets.UTF_8); + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + HttpResponse response = sharedContext.getHttpClient().doPut(Utils.getAPIUnDeployerURL(sharedContext.getApiUUID()), headers, fileContent ,Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + sharedContext.setApiUUID(Utils.extractID(sharedContext.getResponseBody())); + Thread.sleep(3000); + } + @Then("I delete the application {string} from devportal") public void make_application_deletion_request(String applicationName) throws Exception { logger.info("Fetching the applications"); @@ -491,14 +541,39 @@ public void find_api_uuid_using_name(String apiName) throws Exception { @When("I undeploy the selected API") public void i_undeploy_the_api() throws Exception { + logger.info("API UUID to be deleted: " + sharedContext.getApiUUID()); Map headers = new HashMap<>(); headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); - + HttpResponse response = sharedContext.getHttpClient().doDelete(Utils.getAPIUnDeployerURL(sharedContext.getApiUUID()), headers); sharedContext.setResponse(response); sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); Thread.sleep(3000); } + + @When("I create the new version {string} of the same API with default version set to {string}") + public void create_new_version_of_the_api(String newVersion, String isDefaultVersion) throws Exception { + String apiUUID = sharedContext.getApiUUID(); + + Map headers = new HashMap<>(); + headers.put(Constants.REQUEST_HEADERS.AUTHORIZATION, "Bearer " + sharedContext.getPublisherAccessToken()); + headers.put(Constants.REQUEST_HEADERS.HOST, Constants.DEFAULT_API_HOST); + + // Create query parameters + List queryParams = new ArrayList<>(); + queryParams.add(new BasicNameValuePair("newVersion", newVersion)); + queryParams.add(new BasicNameValuePair("defaultVersion", isDefaultVersion)); + queryParams.add(new BasicNameValuePair("apiId", apiUUID)); + + URI uri = new URIBuilder(Utils.getAPINewVersionCreationURL()).addParameters(queryParams).build(); + + HttpResponse response = sharedContext.getHttpClient().doPost(uri.toString(), headers,"",Constants.CONTENT_TYPES.APPLICATION_JSON); + + sharedContext.setResponse(response); + sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); + sharedContext.setApiUUID(Utils.extractID(sharedContext.getResponseBody())); + Thread.sleep(3000); + } } diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java index bae41d5c33..1a6a515aa9 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/BaseSteps.java @@ -134,8 +134,6 @@ public void sendHttpRequest(String httpMethod, String url, String body) throws I } else if (CurlOption.HttpMethod.POST.toString().toLowerCase().equals(httpMethod.toLowerCase())) { sharedContext.setResponse(httpClient.doPost(url, sharedContext.getHeaders(), body, null)); sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); - logger.info("Post Response: " + sharedContext.getResponse()); - logger.info("Post Response Body: " + sharedContext.getResponseBody()); } else if (CurlOption.HttpMethod.PUT.toString().toLowerCase().equals(httpMethod.toLowerCase())) { sharedContext.setResponse(httpClient.doPut(url, sharedContext.getHeaders(), body, null)); sharedContext.setResponseBody(SimpleHTTPClient.responseEntityBodyToString(sharedContext.getResponse())); diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java index 1f446fd6ff..edca76227e 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/api/SharedContext.java @@ -43,6 +43,10 @@ public class SharedContext { private String oauthKeyUUID; private String consumerSecret; private String consumerKey; + private String sandboxConsumerSecret; + private String sandboxConsumerKey; + private String prodKeyMappingID; + private String sandboxKeyMappingID; private String apiAccessToken; private Boolean definitionValidStatus; private HashMap valueStore = new HashMap<>(); @@ -175,24 +179,49 @@ public void setOauthKeyUUID(String oauthKeyUUID) { this.oauthKeyUUID = oauthKeyUUID; } - public String getConsumerSecret() { - - return consumerSecret; + public String getConsumerSecret(String keyType) { + if ("production".equals(keyType)) + return consumerSecret; + else if ("sandbox".equals(keyType)) + return sandboxConsumerSecret; + return ""; } - public void setConsumerSecret(String consumerSecret) { - - this.consumerSecret = consumerSecret; + public void setConsumerSecret(String consumerSecret, String keyType) { + if ("production".equals(keyType)) + this.consumerSecret = consumerSecret; + else if ("sandbox".equals(keyType)) + this.sandboxConsumerSecret = consumerSecret; } - public String getConsumerKey() { + public String getConsumerKey(String keyType) { + if ("production".equals(keyType)) + return consumerKey; + else if ("sandbox".equals(keyType)) + return sandboxConsumerKey; + return ""; + } - return consumerKey; + public void setConsumerKey(String consumerKey, String keyType) { + if ("production".equals(keyType)) + this.consumerKey = consumerKey; + else if ("sandbox".equals(keyType)) + this.sandboxConsumerKey = consumerKey; } - public void setConsumerKey(String consumerKey) { + public void setKeyMappingID(String keyMappingID, String keyType){ + if ("production".equals(keyType)) + this.prodKeyMappingID = keyMappingID; + else if ("sandbox".equals(keyType)) + this.sandboxKeyMappingID = keyMappingID; + } - this.consumerKey = consumerKey; + public String getKeyMappingID(String keyType){ + if ("production".equals(keyType)) + return prodKeyMappingID; + else if ("sandbox".equals(keyType)) + return sandboxKeyMappingID; + return ""; } public String getApiAccessToken() { diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java index 64b616d0e0..8564e72f54 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/java/org/wso2/apk/integration/utils/Utils.java @@ -140,6 +140,11 @@ public static String getAPISearchEndpoint(String queryValue) { + Constants.DEFAULT_API_DEPLOYER + "search?query=content:" + queryValue; } + public static String getAPINewVersionCreationURL() { + return "https://" + Constants.DEFAULT_API_HOST + ":" + Constants.DEFAULT_GW_PORT + "/" + + Constants.DEFAULT_API_DEPLOYER + "apis/copy-api"; + } + public static String extractID(String payload) throws IOException { JSONParser parser = new JSONParser(); @@ -187,18 +192,21 @@ public static String extractKeyManagerID(String payload) throws IOException { } } - public static String extractOAuthMappingID(String payload) throws IOException { - + public static String extractOAuthMappingID(String payload, String keyMappingID) throws IOException { JSONParser parser = new JSONParser(); try { - // Parse the JSON string JSONObject jsonObject = (JSONObject) parser.parse(payload); - - // Get the value of the "id" attribute - JSONArray idValue = (JSONArray)jsonObject.get("list"); - JSONObject keyManager = (JSONObject) idValue.get(0); - String keyManagerId = (String) keyManager.get("keyMappingId"); - return keyManagerId; + JSONArray list = (JSONArray) jsonObject.get("list"); + + for (Object obj : list) { + JSONObject keyManager = (JSONObject) obj; + String currentKeyMappingId = (String) keyManager.get("keyMappingId"); + if (keyMappingID.equals(currentKeyMappingId)) { + return currentKeyMappingId; + } + } + return null; + } catch (ParseException e) { throw new IOException("Error while parsing the JSON payload: " + e.getMessage()); } diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/cors-definition.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/cors-definition.json new file mode 100644 index 0000000000..29a7ce15a3 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/definitions/cors-definition.json @@ -0,0 +1,41 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "test-cors", + "description": "A simple HTTP Request & Response Service", + "version": "2.0.0" + }, + "servers": [ + { + "url": "https://httpbin.org" + } + ], + "tags": [ + { + "name": "HTTP Methods", + "description": "Testing different HTTP verbs" + }, + { + "name": "Auth", + "description": "Auth methods" + } + ], + "paths": { + "/anything": { + "get": { + "tags": [ + "Anything" + ], + "summary": "Returns anything passed in request data.", + "responses": { + "200": { + "description": "Anything passed in request", + "content": {} + } + } + } + } + }, + "components": {} +} + diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json index 289b5f5d6a..2ab7363da8 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api1.json @@ -6,10 +6,10 @@ "endpointConfig":{ "endpoint_type":"http", "sandbox_endpoints":{ - "url":"https://petstore3.swagger.io/api/v3" + "url":"http://backend:80/anything" }, "production_endpoints": { - "url":"https://petstore3.swagger.io/api/v3" + "url":"http://backend:80/anything" } }, "policies": [ diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_default_version.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_default_version.json new file mode 100644 index 0000000000..6bb9d02d2b --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_default_version.json @@ -0,0 +1,20 @@ +{ + "name":"SwaggerPetstore", + "version":"1.0.0", + "context":"/petstore", + "isDefaultVersion": true, + "gatewayType":"wso2/apk", + "endpointConfig":{ + "endpoint_type":"http", + "sandbox_endpoints":{ + "url":"http://backend:80/anything" + }, + "production_endpoints": { + "url":"http://backend:80/anything" + } + }, + "policies": [ + "Gold", + "Unlimited" + ] + } \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_with_basic_auth.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_with_basic_auth.json new file mode 100644 index 0000000000..b96664d784 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/api_with_basic_auth.json @@ -0,0 +1,56 @@ +{ + "name": "SwaggerPetstore", + "context": "/petstore", + "version": "1.0.0", + "provider": "admin", + "type": "HTTP", + "transport": [ + "http", + "https" + ], + "tags": [], + "policies": [ + "Unlimited" + ], + "authorizationHeader": "Authorization", + "apiKeyHeader": "ApiKey", + "securityScheme": [ + "oauth_basic_auth_api_key_mandatory", + "oauth2" + ], + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "http://backend:80/anything" + }, + "production_endpoints": { + "url": "http://backend:80/anything" + }, + "endpoint_security": { + "production": { + "enabled": true, + "type": "BASIC", + "username": "admin", + "password": "admin", + "grantType": "", + "tokenUrl": "", + "clientId": null, + "clientSecret": null, + "customParameters": {} + }, + "sandbox": { + "enabled": false, + "type": "NONE", + "username": "", + "password": null, + "grantType": "", + "tokenUrl": "", + "clientId": null, + "clientSecret": null, + "customParameters": {} + } + } + }, + "gatewayVendor": "wso2", + "gatewayType":"wso2/apk" +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/cors_api.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/cors_api.json new file mode 100644 index 0000000000..0f2f168522 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/cors_api.json @@ -0,0 +1,58 @@ + { + "name": "test-cors", + "context": "/test_cors", + "version": "2.0.0", + "type": "HTTP", + "transport": [ + "http", + "https" + ], + "policies": [ + "Unlimited", + "Gold" + ], + "corsConfiguration": { + "corsConfigurationEnabled": true, + "accessControlAllowOrigins": [ + "abc.com" + ], + "accessControlAllowCredentials": true, + "accessControlAllowHeaders": [ + "authorization", + "Content-Type" + ], + "accessControlAllowMethods": [ + "GET", + "PUT", + "POST", + "DELETE" + ] + }, + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "https://httpbin.org" + }, + "production_endpoints": { + "url": "https://httpbin.org" + } + }, + "endpointImplementationType": "ENDPOINT", + "scopes": [], + "operations": [ + { + "id": "", + "target": "/anything", + "verb": "GET", + "authType": "Application \u0026 Application User", + "throttlingPolicy": "Unlimited", + "scopes": [], + "usedProductIds": [], + "operationPolicies": { + "request": [], + "response": [], + "fault": [] + } + } + ] +} diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gqlPayload.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gqlPayload.json index 0cf90bf8e5..fb0a8d7e3c 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gqlPayload.json +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gqlPayload.json @@ -2,7 +2,7 @@ "name": "StarwarsAPI", "version": "3.14", "context": "/graphql", - "gatewayType": "Regular", + "gatewayType":"wso2/apk", "policies": ["Unlimited"], "operations": [ { diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_cors.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_cors.json new file mode 100644 index 0000000000..355f8a0cf6 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_cors.json @@ -0,0 +1,72 @@ +{ + "name": "StarWarsAPI", + "context": "/test_cors", + "version": "2.0.0", + "provider": "admin", + "type": "GRAPHQL", + "audience": null, + "transport": [ + "http", + "https" + ], + "tags": [], + "policies": [ + "Unlimited" + ], + "apiThrottlingPolicy": null, + "authorizationHeader": "Authorization", + "apiKeyHeader": "ApiKey", + "securityScheme": [ + "oauth_basic_auth_api_key_mandatory", + "oauth2" + ], + "corsConfiguration": { + "corsConfigurationEnabled": true, + "accessControlAllowOrigins": [ + "abc.com" + ], + "accessControlAllowCredentials": true, + "accessControlAllowHeaders": [ + "authorization", + "Access-Control-Allow-Origin" + ], + "accessControlAllowMethods": [ + "GET", + "PUT", + "POST", + "DELETE" + ] + }, + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "http://backend:80/anything" + }, + "production_endpoints": { + "url": "http://backend:80/anything" + } + }, + "endpointImplementationType": "ENDPOINT", + "scopes": [], + "operations": [ + { + "id": "", + "target": "anything", + "verb": "QUERY", + "authType": "Application & Application User", + "throttlingPolicy": "Unlimited", + "scopes": [], + "usedProductIds": [], + "amznResourceName": null, + "amznResourceTimeout": null, + "amznResourceContentEncode": null, + "payloadSchema": null, + "uriMapping": null, + "operationPolicies": { + "request": [], + "response": [], + "fault": [] + } + } + ] +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_default_version.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_default_version.json new file mode 100644 index 0000000000..116c5b2e0e --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_default_version.json @@ -0,0 +1,31 @@ +{ + "name": "StarwarsAPI", + "version": "3.14", + "context": "/graphql", + "gatewayType":"wso2/apk", + "policies": ["Unlimited"], + "isDefaultVersion": true, + "operations": [ + { + "id": "0", + "target": "hero", + "verb": "QUERY", + "authType": "Any", + "throttlingPolicy": null, + "scopes": [], + "usedProductIds": [], + "amznResourceName": null, + "amznResourceTimeout": null, + "amznResourceContentEncode": null, + "payloadSchema": null, + "uriMapping": null, + "operationPolicies": null + } + ], + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { "url": "http://graphql-faker-service:9002/graphql" }, + "production_endpoints": { "url": "http://graphql-faker-service:9002/graphql" } + } + } + \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth.json new file mode 100644 index 0000000000..f177625c62 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth.json @@ -0,0 +1,75 @@ +{ + "name": "StarWarsAPI", + "context": "/gql_basic_auth", + "version": "2.0.0", + "type": "GRAPHQL", + "transport": [ + "http", + "https" + ], + "tags": [], + "policies": [ + "Unlimited" + ], + "authorizationHeader": "Authorization", + "apiKeyHeader": "ApiKey", + "securityScheme": [ + "oauth_basic_auth_api_key_mandatory", + "oauth2" + ], + "corsConfiguration": { + "corsConfigurationEnabled": false, + "accessControlAllowOrigins": [ + "*" + ], + "accessControlAllowCredentials": false, + "accessControlAllowHeaders": [ + "authorization", + "Access-Control-Allow-Origin", + "Content-Type", + "SOAPAction" + ], + "accessControlAllowMethods": [ + "GET", + "PUT", + "POST", + "DELETE", + "PATCH", + "OPTIONS" + ] + }, + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "http://backend:80/anything" + }, + "production_endpoints": { + "url": "http://backend:80/anything" + } + }, + "endpointImplementationType": "ENDPOINT", + "scopes": [], + "operations": [ + { + "id": "", + "target": "hero", + "verb": "QUERY", + "authType": "Application & Application User", + "throttlingPolicy": "Unlimited", + "scopes": [], + "usedProductIds": [], + "amznResourceName": null, + "amznResourceTimeout": null, + "amznResourceContentEncode": null, + "payloadSchema": null, + "uriMapping": null, + "operationPolicies": { + "request": [], + "response": [], + "fault": [] + } + } + ], + "gatewayVendor": "wso2", + "gatewayType": "wso2/apk" +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth2.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth2.json new file mode 100644 index 0000000000..a1d376bff5 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_basic_auth2.json @@ -0,0 +1,99 @@ +{ + "name": "StarWarsAPI", + "context": "/gql_basic_auth", + "version": "2.0.0", + "type": "GRAPHQL", + "transport": [ + "http", + "https" + ], + "tags": [], + "policies": [ + "Unlimited" + ], + "authorizationHeader": "Authorization", + "apiKeyHeader": "ApiKey", + "securityScheme": [ + "oauth_basic_auth_api_key_mandatory", + "oauth2" + ], + "corsConfiguration": { + "corsConfigurationEnabled": false, + "accessControlAllowOrigins": [ + "*" + ], + "accessControlAllowCredentials": false, + "accessControlAllowHeaders": [ + "authorization", + "Access-Control-Allow-Origin", + "Content-Type", + "SOAPAction" + ], + "accessControlAllowMethods": [ + "GET", + "PUT", + "POST", + "DELETE", + "PATCH", + "OPTIONS" + ] + }, + "endpointConfig": { + "endpoint_type": "http", + "endpoint_security": { + "production": { + "enabled": true, + "type": "BASIC", + "username": "admin", + "password": "admin", + "grantType": "", + "tokenUrl": "", + "clientId": null, + "clientSecret": null, + "customParameters": {} + }, + "sandbox": { + "enabled": false, + "type": "NONE", + "username": "", + "password": null, + "grantType": "", + "tokenUrl": "", + "clientId": null, + "clientSecret": null, + "customParameters": {} + } + }, + "sandbox_endpoints": { + "url": "http://backend:80/anything" + }, + "production_endpoints": { + "url": "http://backend:80/anything" + } + }, + "endpointImplementationType": "ENDPOINT", + "scopes": [], + "operations": [ + { + "id": "", + "target": "hero", + "verb": "QUERY", + "authType": "Application & Application User", + "throttlingPolicy": "Unlimited", + "scopes": [], + "usedProductIds": [], + "amznResourceName": null, + "amznResourceTimeout": null, + "amznResourceContentEncode": null, + "payloadSchema": null, + "uriMapping": null, + "operationPolicies": { + "request": [], + "response": [], + "fault": [] + } + } + ], + "gatewayVendor": "wso2", + "gatewayType": "wso2/apk" +} \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_scopes.json b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_scopes.json index 18a2f9757b..93765ea854 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_scopes.json +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/artifacts/payloads/gql_with_scopes.json @@ -365,6 +365,6 @@ "vendor": "WSO2" }, "gatewayVendor": "wso2", - "gatewayType": "wso2/synapse", + "gatewayType":"wso2/apk", "asyncTransportProtocols": [] } \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/APIVersion.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/APIVersion.feature new file mode 100644 index 0000000000..b0372a3c84 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/APIVersion.feature @@ -0,0 +1,137 @@ +Feature: Creating new versions of the APIs + Background: + Given The system is ready + Scenario: Create a new version of a REST API and try to invoke both old and newer versions + And I have a DCR application + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/api1.json" + And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" + And make the import API Creation request using OAS "URL" + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "SampleApp" + Then the response status code should be 201 + And the response body should contain "SampleApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" + And I eventually receive 200 response code, not accepting + |429| + And I create the new version "2.0.0" of the same API with default version set to "false" + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And the response body should contain "2.0.0" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + # And make the Subscription request + # Then the response status code should be 201 + # And the response body should contain "Unlimited" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/2.0.0/pet/4" with body "" + And I eventually receive 200 response code, not accepting + |429| + + Scenario: Undeploy the created REST APIs + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "SampleApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "1.0.0" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" + And the response status code should be 404 + Then I find the apiUUID of the API created with the name "2.0.0" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/2.0.0/pet/4" with body "" + And the response status code should be 404 + + + Scenario: Create a new version of a GraphQL API and try to invoke both old and newer versions + And I have a DCR application + And I have a valid Publisher access token + When the definition file "artifacts/definitions/schema_graphql.graphql" + Given a valid graphql definition file + Then the response should be given as valid + When I use the Payload file "artifacts/payloads/gql_with_scopes.json" + Then I make the import GraphQLAPI Creation request + Then the response status code should be 201 + And the response body should contain "StarWarsAPI" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "TestApp" + Then the response status code should be 201 + And the response body should contain "TestApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" + Then the response status code should be 200 + And I eventually receive 200 response code, not accepting + | 404 | + | 401 | + And I create the new version "3.2" of the same API with default version set to "true" + Then the response status code should be 201 + And the response body should contain "StarWarsAPI" + And the response body should contain "3.2" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.2" with body "{\"query\":\"{ hero { name } }\"}" + And I eventually receive 200 response code, not accepting + |429| + + Scenario: Undeploying the created GraphQL APIs + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "TestApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "3.14" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" + And I eventually receive 404 response code, not accepting + |200| + Then I find the apiUUID of the API created with the name "3.2" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.2" with body "{\"query\":\"{ hero { name } }\"}" + And I eventually receive 404 response code, not accepting + |200| \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSecurity.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSecurity.feature new file mode 100644 index 0000000000..12bc7f5c5e --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSecurity.feature @@ -0,0 +1,100 @@ +Feature: Backend Security for APIs + Background: + Given The system is ready + Scenario: Enable basic auth for endpoint and verfy the authorization for REST API + And I have a DCR application + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/api_with_basic_auth.json" + And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" + And make the import API Creation request using OAS "URL" + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "SampleApp" + Then the response status code should be 201 + And the response body should contain "SampleApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + Then the response status code should be 200 + And the response body should contain "\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"" + + Scenario: Undeploying an already existing REST API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "SampleApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "SwaggerPetstore" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/basic-auth/3.14/employee/" with body "" + And I eventually receive 404 response code, not accepting + |200| + + Scenario: Enable basic auth for endpoint and verfy the authorization for REST API for a GraphQL API + And I have a DCR application + And I have a valid Publisher access token + When the definition file "artifacts/definitions/schema_graphql.graphql" + Given a valid graphql definition file + Then the response should be given as valid + When I use the Payload file "artifacts/payloads/gql_with_basic_auth.json" + Then I make the import GraphQLAPI Creation request + Then the response status code should be 201 + And the response body should contain "StarWarsAPI" + Then I use the Payload file "artifacts/payloads/gql_with_basic_auth2.json" + And I update the GQL API settings + Then the response status code should be 200 + And the response body should contain "StarWarsAPI" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "TestApp" + Then the response status code should be 201 + And the response body should contain "TestApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "POST" request to "https://default.gw.wso2.com:9095/gql_basic_auth/2.0.0/" with body "{\"query\":\"{ hero { id } }\"}" + Then the response status code should be 200 + And the response body should contain "\"Authorization\": \"Basic YWRtaW46YWRtaW4=\"" + + Scenario: Undeploying an already existing GraphQL API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "TestApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "StarWarsAPI" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "POST" request to "https://default.gw.wso2.com:9095/gql_basic_auth/2.0.0/" with body "{\"query\":\"{ hero { id } }\"}" + And I eventually receive 404 response code, not accepting + |200| \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSupport.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSupport.feature new file mode 100644 index 0000000000..5b8ed644f6 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/BackendSupport.feature @@ -0,0 +1,108 @@ +Feature: Backend Support for APIs + Background: + Given The system is ready + Scenario: Make endpoint alterations in the REST API deployment and verfy the functionality + And I have a DCR application + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/api1.json" + And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" + And make the import API Creation request using OAS "URL" + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "SampleApp" + Then the response status code should be 201 + And the response body should contain "SampleApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + Then the response status code should be 200 + And I get "sandbox" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "sandbox" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "GET" request to "https://sandbox.default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + Then the response status code should be 200 + + Scenario: Undeploying an already existing REST API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "SampleApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "SwaggerPetstore" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://sandbox.default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + And I eventually receive 404 response code, not accepting + |200| + + Scenario: Make endpoint alterations in the GRaphQL API deployment and verfy the functionality + And I have a DCR application + And I have a valid Publisher access token + When the definition file "artifacts/definitions/schema_graphql.graphql" + Given a valid graphql definition file + Then the response should be given as valid + When I use the Payload file "artifacts/payloads/gqlPayload.json" + Then I make the import GraphQLAPI Creation request + Then the response status code should be 201 + And the response body should contain "StarwarsAPI" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "TestApp" + Then the response status code should be 201 + And the response body should contain "TestApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" + Then the response status code should be 200 + And I get "sandbox" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "sandbox" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "POST" request to "https://sandbox.default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" + Then the response status code should be 200 + + Scenario: Undeploying an already existing GraphQL API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "TestApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "StarwarsAPI" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "POST" request to "https://sandbox.default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" + And I eventually receive 404 response code, not accepting + |200| \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/CORS.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/CORS.feature new file mode 100644 index 0000000000..61519e3ea9 --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/CORS.feature @@ -0,0 +1,170 @@ +Feature: CORS Policy handling + Background: + Given The system is ready + Scenario: Testing CORS Policy for a REST API + And I have a DCR application + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/cors_api.json" + When the definition file "artifacts/definitions/cors-definition.json" + And make the import API Creation request using OAS "File" + Then the response status code should be 201 + And the response body should contain "test-cors" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "SampleApp" + Then the response status code should be 201 + And the response body should contain "SampleApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/anything/" with body "" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should not contain + | Access-Control-Allow-Origin | + | Access-Control-Allow-Credentials | + | Access-Control-Allow-Methods | + | Access-Control-Allow-Headers | + | Access-Control-Max-Age | + Then I set headers + | Origin | test.domain.com | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/anything/" with body "" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should not contain + | Access-Control-Allow-Origin | + | Access-Control-Allow-Credentials | + | Access-Control-Allow-Methods | + | Access-Control-Allow-Headers | + | Access-Control-Max-Age | + Then I set headers + | Origin | abc.com | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/anything/" with body "" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should contain + | Access-Control-Allow-Origin | abc.com | + | Access-Control-Allow-Credentials | true | + Then I set headers + | Origin | abc.com | + | Access-Control-Request-Method | GET | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/anything/" with body "" + And I eventually receive 200 response code, not accepting + | 429 | + And the response headers should contain + | Access-Control-Allow-Origin | abc.com | + | Access-Control-Allow-Credentials | true | + | Access-Control-Allow-Methods | GET, PUT, POST, DELETE | + | Access-Control-Allow-Headers | authorization, Content-Type | + + Scenario: Undeploying an already existing REST API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "SampleApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "cors" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/anything/" with body "" + And I eventually receive 404 response code, not accepting + |200| + + Scenario: Testing CORS Policy for a GraphQL API + And I have a DCR application + And I have a valid Publisher access token + When the definition file "artifacts/definitions/schema_graphql.graphql" + Given a valid graphql definition file + Then the response should be given as valid + When I use the Payload file "artifacts/payloads/gql_cors.json" + Then I make the import GraphQLAPI Creation request + Then the response status code should be 201 + And the response body should contain "StarWarsAPI" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "TestApp" + Then the response status code should be 201 + And the response body should contain "TestApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/" with body "{\"query\":\"{ anything }\"}" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should not contain + | Access-Control-Allow-Origin | + | Access-Control-Allow-Credentials | + | Access-Control-Allow-Methods | + | Access-Control-Allow-Headers | + | Access-Control-Max-Age | + Then I set headers + | Origin | test.domain.com | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/" with body "{\"query\":\"{ anything }\"}" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should not contain + | Access-Control-Allow-Origin | + | Access-Control-Allow-Credentials | + | Access-Control-Allow-Methods | + | Access-Control-Allow-Headers | + | Access-Control-Max-Age | + Then I set headers + | Origin | abc.com | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/" with body "{\"query\":\"{ anything }\"}" + And I eventually receive 204 response code, not accepting + | 429 | + And the response headers should contain + | Access-Control-Allow-Origin | abc.com | + | Access-Control-Allow-Credentials | true | + Then I set headers + | Origin | abc.com | + | Access-Control-Request-Method | GET | + And I send "OPTIONS" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/" with body "{\"query\":\"{ anything }\"}" + And I eventually receive 200 response code, not accepting + | 429 | + And the response headers should contain + | Access-Control-Allow-Origin | abc.com | + | Access-Control-Allow-Credentials | true | + | Access-Control-Allow-Methods | GET, PUT, POST, DELETE | + | Access-Control-Allow-Headers | authorization, Access-Control-Allow-Origin | + + + + Scenario: Undeploying an already existing GraphQL API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "TestApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "StarWarsAPI" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/test_cors/2.0.0/" with body "{\"query\":\"{ anything }\"}" + And I eventually receive 404 response code, not accepting + |200| \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/DefaultVersion.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/DefaultVersion.feature new file mode 100644 index 0000000000..63cc188c6b --- /dev/null +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/DefaultVersion.feature @@ -0,0 +1,106 @@ +Feature: API Default Version + Background: + Given The system is ready + Scenario: Checking the default version property for the REST API + And I have a DCR application + And I have a valid Publisher access token + When I use the Payload file "artifacts/payloads/api_default_version.json" + And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" + And make the import API Creation request using OAS "URL" + Then the response status code should be 201 + And the response body should contain "SwaggerPetstore" + And make the API Revision Deployment request + Then the response status code should be 201 + And make the Change Lifecycle request + Then the response status code should be 200 + And I have a valid Devportal access token + And make the Application Creation request with the name "SampleApp" + Then the response status code should be 201 + And the response body should contain "SampleApp" + And I have a KeyManager + And make the Generate Keys request + Then the response status code should be 200 + And the response body should contain "consumerKey" + And the response body should contain "consumerSecret" + And make the Subscription request + Then the response status code should be 201 + And the response body should contain "Unlimited" + And I get "production" oauth keys for application + Then the response status code should be 200 + And make the Access Token Generation request for "production" + Then the response status code should be 200 + And the response body should contain "accessToken" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" + And I eventually receive 200 response code, not accepting + |429| + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/pet/4" with body "" + And I eventually receive 200 response code, not accepting + |429| + + Scenario: Undeploying an already existing REST API + And I have a DCR application + And I have a valid Devportal access token + Then I delete the application "SampleApp" from devportal + Then the response status code should be 200 + And I have a valid Publisher access token + Then I find the apiUUID of the API created with the name "SwaggerPetstore" + Then I undeploy the selected API + Then the response status code should be 200 + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" + And I eventually receive 404 response code, not accepting + |200| + +# Scenario: Checking the default version property for the GraphQL API +# And I have a DCR application +# And I have a valid Publisher access token +# When the definition file "artifacts/definitions/schema_graphql.graphql" +# Given a valid graphql definition file +# Then the response should be given as valid +# When I use the Payload file "artifacts/payloads/gql_default_version.json" +# Then I make the import GraphQLAPI Creation request +# Then the response status code should be 201 +# And the response body should contain "StarwarsAPI" +# And make the API Revision Deployment request +# Then the response status code should be 201 +# And make the Change Lifecycle request +# Then the response status code should be 200 +# And I have a valid Devportal access token +# And make the Application Creation request with the name "TestApp" +# Then the response status code should be 201 +# And the response body should contain "TestApp" +# And I have a KeyManager +# And make the Generate Keys request +# Then the response status code should be 200 +# And the response body should contain "consumerKey" +# And the response body should contain "consumerSecret" +# And make the Subscription request +# Then the response status code should be 201 +# And the response body should contain "Unlimited" +# And I get "production" oauth keys for application +# Then the response status code should be 200 +# And make the Access Token Generation request for "production" +# Then the response status code should be 200 +# And the response body should contain "accessToken" +# And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" +# Then the response status code should be 200 +# And I eventually receive 200 response code, not accepting +# | 404 | +# | 401 | +# And I send "POST" request to "https://default.gw.wso2.com:9095/graphql" with body "{\"query\":\"{ hero { name } }\"}" +# Then the response status code should be 200 +# And I eventually receive 200 response code, not accepting +# | 404 | +# | 401 | + +# Scenario: Undeploying an already existing GraphQL API +# And I have a DCR application +# And I have a valid Devportal access token +# Then I delete the application "TestApp" from devportal +# Then the response status code should be 200 +# And I have a valid Publisher access token +# Then I find the apiUUID of the API created with the name "StarwarsAPI" +# Then I undeploy the selected API +# Then the response status code should be 200 +# And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" +# And I eventually receive 404 response code, not accepting +# |200| \ No newline at end of file diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature index 2b87975994..d380eda36d 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Deployment.feature @@ -6,7 +6,7 @@ Feature: API Deployment And I have a valid Publisher access token When I use the Payload file "artifacts/payloads/api1.json" And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" - And make the import API Creation request + And make the import API Creation request using OAS "URL" Then the response status code should be 201 And the response body should contain "SwaggerPetstore" And make the API Revision Deployment request @@ -25,12 +25,12 @@ Feature: API Deployment And make the Subscription request Then the response status code should be 201 And the response body should contain "Unlimited" - And I get oauth keys for application + And I get "production" oauth keys for application Then the response status code should be 200 - And make the Access Token Generation request + And make the Access Token Generation request for "production" Then the response status code should be 200 And the response body should contain "accessToken" - And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" And I eventually receive 200 response code, not accepting |429| @@ -43,7 +43,7 @@ Feature: API Deployment Then I find the apiUUID of the API created with the name "SwaggerPetstore" Then I undeploy the selected API Then the response status code should be 200 - And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" And I eventually receive 404 response code, not accepting |200| @@ -73,9 +73,9 @@ Feature: API Deployment And make the Subscription request Then the response status code should be 201 And the response body should contain "Unlimited" - And I get oauth keys for application + And I get "production" oauth keys for application Then the response status code should be 200 - And make the Access Token Generation request + And make the Access Token Generation request for "production" Then the response status code should be 200 And the response body should contain "accessToken" And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}" diff --git a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/ScopesEnabled.feature b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Scopes.feature similarity index 93% rename from test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/ScopesEnabled.feature rename to test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Scopes.feature index 83bdafdf83..f88068ec81 100644 --- a/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/ScopesEnabled.feature +++ b/test/apim-apk-agent-test/cucumber-tests/src/test/resources/tests/api/Scopes.feature @@ -6,7 +6,7 @@ Feature: Invoking APIs with scopes enabled And I have a valid Publisher access token When I use the Payload file "artifacts/payloads/api1.json" And I use the OAS URL "https://petstore3.swagger.io/api/v3/openapi.json" - And make the import API Creation request + And make the import API Creation request using OAS "URL" Then the response status code should be 201 And the response body should contain "SwaggerPetstore" And make the API Revision Deployment request @@ -25,18 +25,18 @@ Feature: Invoking APIs with scopes enabled And make the Subscription request Then the response status code should be 201 And the response body should contain "Unlimited" - And I get oauth keys for application + And I get "production" oauth keys for application Then the response status code should be 200 - And make the Access Token Generation request + And make the Access Token Generation request for "production" Then the response status code should be 200 And the response body should contain "accessToken" - And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" And I eventually receive 200 response code, not accepting |429| Then I make Access Token Generation request without scopes Then the response status code should be 200 And the response body should contain "accessToken" - And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/5" with body "" + And I send "GET" request to "https://default.gw.wso2.com:9095/petstore/1.0.0/pet/4" with body "" Then the response status code should be 403 Scenario: Undeploy the created REST API @@ -75,9 +75,9 @@ Feature: Invoking APIs with scopes enabled And make the Subscription request Then the response status code should be 201 And the response body should contain "Unlimited" - And I get oauth keys for application + And I get "production" oauth keys for application Then the response status code should be 200 - And make the Access Token Generation request + And make the Access Token Generation request for "production" Then the response status code should be 200 And the response body should contain "accessToken" And I send "POST" request to "https://default.gw.wso2.com:9095/graphql/3.14" with body "{\"query\":\"{ hero { name } }\"}"