From a8b64eb5943192382d98eb3179428ca3c4cab956 Mon Sep 17 00:00:00 2001 From: TheRasanjana Date: Mon, 3 May 2021 14:50:46 +0530 Subject: [PATCH 1/7] Add Prototype endpoint test cases --- .../prototype/PrototypedAPITestcase.java | 228 ++++++++++++++++++ .../src/test/resources/testng.xml | 1 + 2 files changed, 229 insertions(+) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java new file mode 100644 index 0000000000..1827e824cd --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -0,0 +1,228 @@ +/* + * + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.wso2.am.integration.tests.prototype; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import javax.ws.rs.core.Response; +import javax.xml.xpath.XPathExpressionException; + +import com.google.gson.Gson; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import org.wso2.am.integration.clients.publisher.api.v1.dto.APIDTO; +import org.wso2.am.integration.clients.publisher.api.v1.dto.APIListDTO; +import org.wso2.am.integration.clients.publisher.api.v1.dto.WorkflowResponseDTO; +import org.wso2.am.integration.test.impl.RestAPIPublisherImpl; +import org.wso2.am.integration.test.impl.RestAPIStoreImpl; +import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException; +import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest; +import org.wso2.am.integration.test.utils.bean.APILifeCycleAction; +import org.wso2.am.integration.test.utils.bean.APILifeCycleState; +import org.wso2.am.integration.test.utils.bean.APIRequest; +import org.wso2.am.integration.test.utils.generic.APIMTestCaseUtils; +import org.wso2.am.integration.test.utils.http.HTTPSClientUtils; +import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; + +public class PrototypedAPITestcase extends APIMIntegrationBaseTest { + + private final String apiVersion = "1.0.0"; + private String apiProvider; + private String apiName; + private String apiEndPointUrl; + private String apiID; + private APIIdentifier apiIdentifier; + + @BeforeClass(alwaysRun = true) + public void setEnvironment() throws APIManagerIntegrationTestException, XPathExpressionException { + + super.init(); + + String apiPrototypeEndpointPostfixUrl = "am/sample/pizzashack/v1/api/menu"; + apiEndPointUrl = gatewayUrlsWrk.getWebAppURLHttp() + apiPrototypeEndpointPostfixUrl; + + restAPIPublisher = new RestAPIPublisherImpl(publisherContext.getContextTenant().getContextUser().getUserName(), + publisherContext.getContextTenant().getContextUser().getPassword(), + publisherContext.getContextTenant().getDomain(), publisherURLHttps); + + restAPIStore = new RestAPIStoreImpl(storeContext.getContextTenant().getContextUser().getUserName(), + storeContext.getContextTenant().getContextUser().getPassword(), + storeContext.getContextTenant().getDomain(), storeURLHttps); + + apiProvider = publisherContext.getContextTenant().getContextUser().getUserName(); + } + + @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint and invoke") + public void testPrototypedAPIEndpoint() throws Exception { + + apiName = "APIMPrototypedEndpointAPI1"; + String apiContext = "pizzashack-prototype"; + String apiTags = "pizza, order, pizza-menu"; + String apiDescription = "Pizza API:Allows to manage pizza orders " + + "(create, update, retrieve orders)"; + + apiIdentifier = new APIIdentifier(apiProvider, apiName, apiVersion); + APIRequest apiRequest = new APIRequest(apiName, apiContext, new URL(apiEndPointUrl)); + apiRequest.setVersion(apiVersion); + apiRequest.setDescription(apiDescription); + apiRequest.setTags(apiTags); + apiRequest.setVisibility(APIDTO.VisibilityEnum.PUBLIC.getValue()); + + HttpResponse addAPIResponse = restAPIPublisher.addAPI(apiRequest); + assertEquals(addAPIResponse.getResponseCode(), Response.Status.CREATED.getStatusCode(), + "Invalid Response Code"); + apiID = addAPIResponse.getData(); + + //Deployed API as a Prototyped API & check the status + WorkflowResponseDTO lcChangeResponse = restAPIPublisher.changeAPILifeCycleStatus(apiID, + APILifeCycleAction.DEPLOY_AS_PROTOTYPE.getAction()); + + HttpResponse response = restAPIPublisher.getAPI(apiID); + Gson g = new Gson(); + APIDTO apidto = g.fromJson(response.getData(), APIDTO.class); + String endPointString = "{\"implementation_status\":\"prototyped\",\"endpoint_type\":\"http\"," + + "\"production_endpoints\":{\"config\":null," + + "\"url\":\"" + apiEndPointUrl + "\"}," + + "\"sandbox_endpoints\":{\"config\":null,\"url\":\"" + apiEndPointUrl + "\"}}"; + + JSONParser parser = new JSONParser(); + JSONObject endpoint = (JSONObject) parser.parse(endPointString); + apidto.setEndpointConfig(endpoint); + + restAPIPublisher.updateAPI(apidto); + + assertTrue(lcChangeResponse.getLifecycleState().getState().equals("Prototyped"), + apiName + " status not updated as Prototyped"); + Thread.sleep(15000); + + // Create a revision and Deploy the API + createAPIRevisionAndDeployUsingRest(apiID, restAPIPublisher); + + //Check whether Prototype API is available in publisher + APIListDTO getAllAPIsResponse = restAPIPublisher.getAllAPIs(); + assertTrue(APIMTestCaseUtils.isAPIAvailable(apiIdentifier, getAllAPIsResponse), + "Implemented" + apiName + " Api is not visible in API Publisher."); + Thread.sleep(15000); + + //Check whether Prototype API is available under the Prototyped API + org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore + .getPrototypedAPIs(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + assertTrue(APIMTestCaseUtils.isAPIAvailableInStore(apiIdentifier, prototypedAPIs), + apiName + " is not visible as Prototyped API"); + + Map requestHeaders = new HashMap<>(); + requestHeaders.put("accept", "application/json"); + + //Invoke the Prototype endpoint and validate + HttpResponse response1 = HTTPSClientUtils + .doGet(getAPIInvocationURLHttps(apiContext, apiVersion) + + "", requestHeaders); + Assert.assertEquals(response1.getResponseCode(), 200); + Assert.assertTrue(response1.getData().contains("BBQ Chicken Bacon")); + } + + @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint, demote to created and invoke") + public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { + + apiName = "APIMPrototypedEndpointAPI2"; + String apiContext = "pizzashack-prototype2"; + String apiTags = "pizza, order, pizza-menu"; + String apiDescription = "Pizza API:Allows to manage pizza orders " + + "(create, update, retrieve orders)"; + + apiIdentifier = new APIIdentifier(apiProvider, apiName, apiVersion); + APIRequest apiRequest = new APIRequest(apiName, apiContext, new URL(apiEndPointUrl)); + apiRequest.setVersion(apiVersion); + apiRequest.setDescription(apiDescription); + apiRequest.setTags(apiTags); + apiRequest.setVisibility(APIDTO.VisibilityEnum.PUBLIC.getValue()); + + HttpResponse addAPIResponse = restAPIPublisher.addAPI(apiRequest); + assertEquals(addAPIResponse.getResponseCode(), Response.Status.CREATED.getStatusCode(), + "Invalid Response Code"); + apiID = addAPIResponse.getData(); + + //Deployed API as a Prototyped API & check the status + WorkflowResponseDTO lcChangeResponse = restAPIPublisher.changeAPILifeCycleStatus(apiID, + APILifeCycleAction.DEPLOY_AS_PROTOTYPE.getAction()); + + HttpResponse response = restAPIPublisher.getAPI(apiID); + Gson g = new Gson(); + APIDTO apidto = g.fromJson(response.getData(), APIDTO.class); + String endPointString = "{\"implementation_status\":\"prototyped\",\"endpoint_type\":\"http\"," + + "\"production_endpoints\":{\"config\":null," + + "\"url\":\"" + apiEndPointUrl + "\"}," + + "\"sandbox_endpoints\":{\"config\":null,\"url\":\"" + apiEndPointUrl + "\"}}"; + + JSONParser parser = new JSONParser(); + JSONObject endpoint = (JSONObject) parser.parse(endPointString); + apidto.setEndpointConfig(endpoint); + + //Update the API with Prototype endpoint + restAPIPublisher.updateAPI(apidto); + + assertTrue(lcChangeResponse.getLifecycleState().getState().equals("Prototyped"), + apiName + " status not updated as Prototyped"); + Thread.sleep(15000); + + // Create a revision and Deploy the API + createAPIRevisionAndDeployUsingRest(apiID, restAPIPublisher); + + //Check whether Prototype API is available in publisher + APIListDTO getAllAPIsResponse = restAPIPublisher.getAllAPIs(); + assertTrue(APIMTestCaseUtils.isAPIAvailable(apiIdentifier, getAllAPIsResponse), + "Implemented" + apiName + " Api is not visible in API Publisher."); + Thread.sleep(15000); + + //Check whether Prototype API is available under the Prototyped API + org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore + .getPrototypedAPIs(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + assertTrue(APIMTestCaseUtils.isAPIAvailableInStore(apiIdentifier, prototypedAPIs), + apiName + " is not visible as Prototyped API"); + + //Change the status PROTOTYPED to CREATED + restAPIPublisher.changeAPILifeCycleStatus(apiID, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); + assertTrue(APILifeCycleState.CREATED.getState().equals(restAPIPublisher.getLifecycleStatus(apiID).getData()), + apiName + "status not updated as CREATED"); + //Wait for the changes to be applied after demoting to Created. + Thread.sleep(15000); + + Map requestHeaders = new HashMap<>(); + requestHeaders.put("accept", "application/json"); + + //Invoke the Prototype endpoint + HttpResponse response2 = HTTPSClientUtils + .doGet(getAPIInvocationURLHttps(apiContext, apiVersion) + + "", requestHeaders); + + Assert.assertEquals(response2.getResponseCode(), 401, "User was able to invoke the API demoted to CREATED from PROTOTYPE"); + } + +} diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml index 5ab3148d88..8f670248b1 100755 --- a/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/testng.xml @@ -175,6 +175,7 @@ + From ba7fa06ff6cb27c252532c8f3d70de7740445d5b Mon Sep 17 00:00:00 2001 From: TheRasanjana Date: Tue, 4 May 2021 21:28:38 +0530 Subject: [PATCH 2/7] Add tenant user mode for execution --- .../prototype/PrototypedAPITestcase.java | 54 +++++++++++-------- 1 file changed, 33 insertions(+), 21 deletions(-) diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 1827e824cd..39091a5ab9 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -34,12 +34,12 @@ import org.json.simple.parser.JSONParser; import org.testng.Assert; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; import org.testng.annotations.Test; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIListDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.WorkflowResponseDTO; -import org.wso2.am.integration.test.impl.RestAPIPublisherImpl; -import org.wso2.am.integration.test.impl.RestAPIStoreImpl; import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException; import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest; import org.wso2.am.integration.test.utils.bean.APILifeCycleAction; @@ -48,8 +48,8 @@ import org.wso2.am.integration.test.utils.generic.APIMTestCaseUtils; import org.wso2.am.integration.test.utils.http.HTTPSClientUtils; import org.wso2.carbon.apimgt.api.model.APIIdentifier; +import org.wso2.carbon.automation.engine.context.TestUserMode; import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; -import org.wso2.carbon.utils.multitenancy.MultitenantConstants; public class PrototypedAPITestcase extends APIMIntegrationBaseTest { @@ -57,31 +57,37 @@ public class PrototypedAPITestcase extends APIMIntegrationBaseTest { private String apiProvider; private String apiName; private String apiEndPointUrl; - private String apiID; private APIIdentifier apiIdentifier; + @Factory(dataProvider = "userModeDataProvider") + public PrototypedAPITestcase(TestUserMode userMode) { + + this.userMode = userMode; + } + + @DataProvider + public static Object[][] userModeDataProvider() { + + return new Object[][]{ + new Object[]{TestUserMode.SUPER_TENANT_ADMIN}, + new Object[]{TestUserMode.TENANT_ADMIN} + }; + } + @BeforeClass(alwaysRun = true) public void setEnvironment() throws APIManagerIntegrationTestException, XPathExpressionException { - super.init(); + super.init(userMode); + apiProvider = user.getUserName(); String apiPrototypeEndpointPostfixUrl = "am/sample/pizzashack/v1/api/menu"; apiEndPointUrl = gatewayUrlsWrk.getWebAppURLHttp() + apiPrototypeEndpointPostfixUrl; - - restAPIPublisher = new RestAPIPublisherImpl(publisherContext.getContextTenant().getContextUser().getUserName(), - publisherContext.getContextTenant().getContextUser().getPassword(), - publisherContext.getContextTenant().getDomain(), publisherURLHttps); - - restAPIStore = new RestAPIStoreImpl(storeContext.getContextTenant().getContextUser().getUserName(), - storeContext.getContextTenant().getContextUser().getPassword(), - storeContext.getContextTenant().getDomain(), storeURLHttps); - - apiProvider = publisherContext.getContextTenant().getContextUser().getUserName(); } @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint and invoke") public void testPrototypedAPIEndpoint() throws Exception { + String apiID; apiName = "APIMPrototypedEndpointAPI1"; String apiContext = "pizzashack-prototype"; String apiTags = "pizza, order, pizza-menu"; @@ -94,6 +100,7 @@ public void testPrototypedAPIEndpoint() throws Exception { apiRequest.setDescription(apiDescription); apiRequest.setTags(apiTags); apiRequest.setVisibility(APIDTO.VisibilityEnum.PUBLIC.getValue()); + apiRequest.setProvider(apiProvider); HttpResponse addAPIResponse = restAPIPublisher.addAPI(apiRequest); assertEquals(addAPIResponse.getResponseCode(), Response.Status.CREATED.getStatusCode(), @@ -133,7 +140,7 @@ public void testPrototypedAPIEndpoint() throws Exception { //Check whether Prototype API is available under the Prototyped API org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore - .getPrototypedAPIs(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + .getPrototypedAPIs(user.getUserDomain()); assertTrue(APIMTestCaseUtils.isAPIAvailableInStore(apiIdentifier, prototypedAPIs), apiName + " is not visible as Prototyped API"); @@ -146,11 +153,15 @@ public void testPrototypedAPIEndpoint() throws Exception { "", requestHeaders); Assert.assertEquals(response1.getResponseCode(), 200); Assert.assertTrue(response1.getData().contains("BBQ Chicken Bacon")); + + restAPIPublisher.changeAPILifeCycleStatus(apiID, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); + restAPIPublisher.deleteAPI(apiID); } - @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint, demote to created and invoke") + @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint, demote to created and invoke", dependsOnMethods = {"testPrototypedAPIEndpoint"}) public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { + String apiID; apiName = "APIMPrototypedEndpointAPI2"; String apiContext = "pizzashack-prototype2"; String apiTags = "pizza, order, pizza-menu"; @@ -163,6 +174,7 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { apiRequest.setDescription(apiDescription); apiRequest.setTags(apiTags); apiRequest.setVisibility(APIDTO.VisibilityEnum.PUBLIC.getValue()); + apiRequest.setProvider(apiProvider); HttpResponse addAPIResponse = restAPIPublisher.addAPI(apiRequest); assertEquals(addAPIResponse.getResponseCode(), Response.Status.CREATED.getStatusCode(), @@ -203,7 +215,7 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { //Check whether Prototype API is available under the Prototyped API org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore - .getPrototypedAPIs(MultitenantConstants.SUPER_TENANT_DOMAIN_NAME); + .getPrototypedAPIs(user.getUserDomain()); assertTrue(APIMTestCaseUtils.isAPIAvailableInStore(apiIdentifier, prototypedAPIs), apiName + " is not visible as Prototyped API"); @@ -211,9 +223,9 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { restAPIPublisher.changeAPILifeCycleStatus(apiID, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); assertTrue(APILifeCycleState.CREATED.getState().equals(restAPIPublisher.getLifecycleStatus(apiID).getData()), apiName + "status not updated as CREATED"); + //Wait for the changes to be applied after demoting to Created. Thread.sleep(15000); - Map requestHeaders = new HashMap<>(); requestHeaders.put("accept", "application/json"); @@ -221,8 +233,8 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { HttpResponse response2 = HTTPSClientUtils .doGet(getAPIInvocationURLHttps(apiContext, apiVersion) + "", requestHeaders); - Assert.assertEquals(response2.getResponseCode(), 401, "User was able to invoke the API demoted to CREATED from PROTOTYPE"); - } + restAPIPublisher.deleteAPI(apiID); + } } From 94e8c6bee7d0f23a516a23cb8ab189ba1886e56a Mon Sep 17 00:00:00 2001 From: theRasanjanana Date: Fri, 7 May 2021 03:11:25 +0530 Subject: [PATCH 3/7] Add Inline prototype tests --- .../test/impl/RestAPIPublisherImpl.java | 19 ++++ .../prototype/PrototypedAPITestcase.java | 95 +++++++++++++--- .../v3/prototype/additionalProperties.json | 60 ++++++++++ .../oas/v3/prototype/oas_import.json | 96 ++++++++++++++++ .../oas/v3/prototype/updatedMockOas.json | 104 ++++++++++++++++++ 5 files changed, 359 insertions(+), 15 deletions(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/additionalProperties.json create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/oas_import.json create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/updatedMockOas.json diff --git a/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java b/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java index ef79b8fd2c..27866605bb 100644 --- a/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java +++ b/modules/integration/tests-common/integration-test-utils/src/main/java/org/wso2/am/integration/test/impl/RestAPIPublisherImpl.java @@ -71,6 +71,7 @@ import org.wso2.am.integration.clients.publisher.api.v1.dto.LifecycleHistoryDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.LifecycleStateDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.MediationListDTO; +import org.wso2.am.integration.clients.publisher.api.v1.dto.MockResponsePayloadListDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.OpenAPIDefinitionValidationResponseDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.PatchRequestBodyDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.PostRequestBodyDTO; @@ -587,6 +588,24 @@ public HttpResponse deleteAPI(String apiId) throws ApiException { return response; } + public HttpResponse generateMockScript(String apiId) throws ApiException { + ApiResponse mockResponse = apIsApi.generateMockScriptsWithHttpInfo(apiId, null); + HttpResponse response = null; + if (mockResponse.getStatusCode() == 200) { + response = new HttpResponse("Successfully generated MockScript", 200); + } + return response; + } + + public HttpResponse getGenerateMockScript(String apiId) throws ApiException { + ApiResponse mockResponse = apIsApi.getGeneratedMockScriptsOfAPIWithHttpInfo(apiId, null); + HttpResponse response = null; + if (mockResponse.getStatusCode() == 200) { + response = new HttpResponse(mockResponse.getData().toString(), 200); + } + return response; + } + /** * Remove document * diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 39091a5ab9..8bb4b894fb 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -23,6 +23,9 @@ import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -30,6 +33,7 @@ import javax.xml.xpath.XPathExpressionException; import com.google.gson.Gson; +import org.apache.commons.io.IOUtils; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.testng.Assert; @@ -40,6 +44,7 @@ import org.wso2.am.integration.clients.publisher.api.v1.dto.APIDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.APIListDTO; import org.wso2.am.integration.clients.publisher.api.v1.dto.WorkflowResponseDTO; +import org.wso2.am.integration.test.Constants; import org.wso2.am.integration.test.utils.APIManagerIntegrationTestException; import org.wso2.am.integration.test.utils.base.APIMIntegrationBaseTest; import org.wso2.am.integration.test.utils.bean.APILifeCycleAction; @@ -57,6 +62,8 @@ public class PrototypedAPITestcase extends APIMIntegrationBaseTest { private String apiProvider; private String apiName; private String apiEndPointUrl; + private String resourcePath; + private String apiID; private APIIdentifier apiIdentifier; @Factory(dataProvider = "userModeDataProvider") @@ -70,7 +77,7 @@ public static Object[][] userModeDataProvider() { return new Object[][]{ new Object[]{TestUserMode.SUPER_TENANT_ADMIN}, - new Object[]{TestUserMode.TENANT_ADMIN} +// new Object[]{TestUserMode.TENANT_ADMIN} }; } @@ -79,7 +86,6 @@ public void setEnvironment() throws APIManagerIntegrationTestException, XPathExp super.init(userMode); apiProvider = user.getUserName(); - String apiPrototypeEndpointPostfixUrl = "am/sample/pizzashack/v1/api/menu"; apiEndPointUrl = gatewayUrlsWrk.getWebAppURLHttp() + apiPrototypeEndpointPostfixUrl; } @@ -87,7 +93,6 @@ public void setEnvironment() throws APIManagerIntegrationTestException, XPathExp @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint and invoke") public void testPrototypedAPIEndpoint() throws Exception { - String apiID; apiName = "APIMPrototypedEndpointAPI1"; String apiContext = "pizzashack-prototype"; String apiTags = "pizza, order, pizza-menu"; @@ -127,7 +132,7 @@ public void testPrototypedAPIEndpoint() throws Exception { assertTrue(lcChangeResponse.getLifecycleState().getState().equals("Prototyped"), apiName + " status not updated as Prototyped"); - Thread.sleep(15000); + waitForAPIDeployment(); // Create a revision and Deploy the API createAPIRevisionAndDeployUsingRest(apiID, restAPIPublisher); @@ -136,7 +141,7 @@ public void testPrototypedAPIEndpoint() throws Exception { APIListDTO getAllAPIsResponse = restAPIPublisher.getAllAPIs(); assertTrue(APIMTestCaseUtils.isAPIAvailable(apiIdentifier, getAllAPIsResponse), "Implemented" + apiName + " Api is not visible in API Publisher."); - Thread.sleep(15000); + waitForAPIDeployment(); //Check whether Prototype API is available under the Prototyped API org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore @@ -161,7 +166,6 @@ public void testPrototypedAPIEndpoint() throws Exception { @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint, demote to created and invoke", dependsOnMethods = {"testPrototypedAPIEndpoint"}) public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { - String apiID; apiName = "APIMPrototypedEndpointAPI2"; String apiContext = "pizzashack-prototype2"; String apiTags = "pizza, order, pizza-menu"; @@ -197,39 +201,39 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { JSONObject endpoint = (JSONObject) parser.parse(endPointString); apidto.setEndpointConfig(endpoint); - //Update the API with Prototype endpoint + // Update the API with Prototype endpoint restAPIPublisher.updateAPI(apidto); assertTrue(lcChangeResponse.getLifecycleState().getState().equals("Prototyped"), apiName + " status not updated as Prototyped"); - Thread.sleep(15000); + waitForAPIDeployment(); // Create a revision and Deploy the API createAPIRevisionAndDeployUsingRest(apiID, restAPIPublisher); - //Check whether Prototype API is available in publisher + // Check whether Prototype API is available in publisher APIListDTO getAllAPIsResponse = restAPIPublisher.getAllAPIs(); assertTrue(APIMTestCaseUtils.isAPIAvailable(apiIdentifier, getAllAPIsResponse), "Implemented" + apiName + " Api is not visible in API Publisher."); - Thread.sleep(15000); + waitForAPIDeployment(); - //Check whether Prototype API is available under the Prototyped API + // Check whether Prototype API is available under the Prototyped API org.wso2.am.integration.clients.store.api.v1.dto.APIListDTO prototypedAPIs = restAPIStore .getPrototypedAPIs(user.getUserDomain()); assertTrue(APIMTestCaseUtils.isAPIAvailableInStore(apiIdentifier, prototypedAPIs), apiName + " is not visible as Prototyped API"); - //Change the status PROTOTYPED to CREATED + // Change the status PROTOTYPED to CREATED restAPIPublisher.changeAPILifeCycleStatus(apiID, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); assertTrue(APILifeCycleState.CREATED.getState().equals(restAPIPublisher.getLifecycleStatus(apiID).getData()), apiName + "status not updated as CREATED"); - //Wait for the changes to be applied after demoting to Created. - Thread.sleep(15000); + // Wait for the changes to be applied after demoting to Created. + waitForAPIDeployment(); Map requestHeaders = new HashMap<>(); requestHeaders.put("accept", "application/json"); - //Invoke the Prototype endpoint + // Invoke the Prototype endpoint HttpResponse response2 = HTTPSClientUtils .doGet(getAPIInvocationURLHttps(apiContext, apiVersion) + "", requestHeaders); @@ -237,4 +241,65 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { restAPIPublisher.deleteAPI(apiID); } + + + @Test(groups = { "wso2.am" }, description = "Create an inline protoype API with OAS3 and Generate mock") + public void testInlinePrototypeWithMock() throws Exception { + + resourcePath = "oas" + File.separator + "v3" + File.separator; + String originalDefinition = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "oas_import.json"), + "UTF-8"); + String additionalProperties = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "additionalProperties.json"), + "UTF-8"); + String updatedMock = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "updatedMockOas.json"), + "UTF-8"); + org.json.JSONObject additionalPropertiesObj = new org.json.JSONObject(additionalProperties); + additionalPropertiesObj.put("provider", user.getUserName()); + org.json.JSONObject updatedMockObj = new org.json.JSONObject(updatedMock); + updatedMockObj.put("provider", user.getUserName()); + File file = geTempFileWithContent(originalDefinition); + // Create an api by importing OAS3 file + APIDTO apidto = restAPIPublisher.importOASDefinition(file, additionalPropertiesObj.toString()); + String apiImportId = apidto.getId(); + + // Change the lifecycle status to Prototype + restAPIPublisher.changeAPILifeCycleStatus(apiImportId, Constants.DEPLOY_AS_PROTOTYPE); + + // Generate mock Script for Prototype Implementation + HttpResponse mockgenResponse = restAPIPublisher.generateMockScript(apiImportId); + Assert.assertEquals( mockgenResponse.getResponseCode(), 200); + + // Retrieve and validate the generated mock script + HttpResponse mockedGetResponse = restAPIPublisher.getGenerateMockScript(apiImportId); + Assert.assertTrue(mockedGetResponse.getData().contains("/pets")); + Assert.assertTrue(mockedGetResponse.getData().contains("/pets/{petId}")); + Assert.assertTrue(mockedGetResponse.getData().contains("/oldpets")); + + // Create a revision and Deploy the API + createAPIRevisionAndDeployUsingRest(apiImportId, restAPIPublisher); + + Map requestHeaders = new HashMap<>(); + requestHeaders.put("accept", "application/json"); + waitForAPIDeployment(); + //Invoke the Prototype endpoint and validate + HttpResponse response1 = HTTPSClientUtils + .doGet(getAPIInvocationURLHttps("SwaggerPetstorev3import", "1.0.0") + + "/pets/1", requestHeaders); + Assert.assertEquals(response1.getResponseCode(), 200); + + restAPIPublisher.changeAPILifeCycleStatus(apiImportId, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); + restAPIPublisher.deleteAPI(apiImportId); + } + + private File geTempFileWithContent(String swagger) throws Exception { + File temp = File.createTempFile("swagger", ".json"); + temp.deleteOnExit(); + BufferedWriter out = new BufferedWriter(new FileWriter(temp)); + out.write(swagger); + out.close(); + return temp; + } } diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/additionalProperties.json b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/additionalProperties.json new file mode 100644 index 0000000000..213a422540 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/additionalProperties.json @@ -0,0 +1,60 @@ +{ + "id": "71889e16-773e-471b-bc53-251569efff64", + "name": "SwaggerPetstore_v3_import", + "description": null, + "context": "/SwaggerPetstorev3import", + "version": "1.0.0", + "provider": "admin", + "lifeCycleStatus": "PUBLISHED", + "wsdlInfo": null, + "responseCachingEnabled": false, + "cacheTimeout": 300, + "hasThumbnail": null, + "isDefaultVersion": false, + "enableSchemaValidation": false, + "type": "HTTP", + "transport": ["http", "https"], + "tags": [], + "policies": ["Unlimited"], + "apiThrottlingPolicy": "Unlimited", + "authorizationHeader": null, + "securityScheme": ["oauth2", "oauth_basic_auth_mandatory"], + "maxTps": null, + "visibility": "PUBLIC", + "visibleRoles": [], + "visibleTenants": [], + "mediationPolicies": [], + "subscriptionAvailability": "ALL_TENANTS", + "subscriptionAvailableTenants": [], + "additionalProperties": [], + "monetization": null, + "accessControl": "NONE", + "accessControlRoles": [], + "businessInformation": { + "businessOwner": null, + "businessOwnerEmail": null, + "technicalOwner": null, + "technicalOwnerEmail": null + }, + "corsConfiguration": { + "corsConfigurationEnabled": true, + "accessControlAllowOrigins": ["*"], + "accessControlAllowCredentials": false, + "accessControlAllowHeaders": ["authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction"], + "accessControlAllowMethods": ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"] + }, + "workflowStatus": null, + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "https://localhost:9443/publisher-new/apis/create/openapi" + }, + "production_endpoints": { + "url": "https://localhost:9443/publisher-new/apis/create/openapi" + } + }, + "endpointImplementationType": "INLINE", + "scopes": [], + "operations": [], + "threatProtectionPolicies": null +} \ No newline at end of file diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/oas_import.json b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/oas_import.json new file mode 100644 index 0000000000..ea8ad265db --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/oas_import.json @@ -0,0 +1,96 @@ +{ + "openapi" : "3.0.1", + "info" : { + "title" : "SwaggerPetstore_v3", + "version" : "1.0.0" + }, + "servers" : [ { + "url" : "/" + } ], + "security" : [ { + "default" : [ ] + } ], + "paths" : { + "/pets" : { + "get" : { + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ "SwaggerPetstore_imp_v3" ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + }, + "/pets/{petId}" : { + "get" : { + "parameters" : [ { + "name" : "petId", + "in" : "path", + "required" : true, + "style" : "simple", + "explode" : false, + "schema" : { + "type" : "string" + } + } ], + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + }, + "/oldpets" : { + "delete" : { + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ "SwaggerPetstore_imp_v3" ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + } + }, + "components" : { + "securitySchemes" : { + "default" : { + "type" : "oauth2", + "flows" : { + "implicit" : { + "authorizationUrl" : "https://test.com", + "scopes" : { + "SwaggerPetstore_imp_v3" : "SwaggerPetstore_imp_v3" + }, + "x-scopes-bindings" : { + "SwaggerPetstore_imp_v3" : "admin" + } + } + } + } + } + }, + "x-throttling-tier" : "Unlimited", + "x-wso2-cors" : { + "corsConfigurationEnabled" : true, + "accessControlAllowOrigins" : [ "*" ], + "accessControlAllowCredentials" : false, + "accessControlAllowHeaders" : [ "authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction" ], + "accessControlAllowMethods" : [ "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS" ] + }, + "x-wso2-production-endpoints" : "https://localhost:9443/publisher-new/apis/create/openapi", + "x-wso2-sandbox-endpoints" : "https://localhost:9443/publisher-new/apis/create/openapi", + "x-wso2-basePath" : "/SwaggerPetstorev3/1.0.0" +} \ No newline at end of file diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/updatedMockOas.json b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/updatedMockOas.json new file mode 100644 index 0000000000..c8fbfee7df --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v3/prototype/updatedMockOas.json @@ -0,0 +1,104 @@ +{ + "openapi": "3.0.1", + "info": { + "title": "SwaggerPetstore_v3", + "version": "1.0.0" + }, + "servers": [ + { + "url": "/" + } + ], + "security": [ + { + "default": [] + } + ], + "paths": { + "/pets": { + "get": { + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "default": [ + "SwaggerPetstore_imp_v3" + ] + } + ], + "x-auth-type": "Application & Application User", + "x-throttling-tier": null, + "x-mediation-script": "var accept = mc.getProperty('AcceptHeader');\nvar responseCode = mc.getProperty('query.param.responseCode');\nvar responseCodeSC;\nvar responses = [];\nif (!responses[200]) {\n responses[200] = [];\n}\nresponses[200][\"application/json\"] = \"\";\nresponses[200][\"application/xml\"] = \"\";\n\n\nresponses[501] = [];\nresponses[501][\"application/json\"] = {\n\"code\" : 501,\n\"description\" : \"Not Implemented\"}\nresponses[501][\"application/xml\"] = 501Not Implemented;\n\nif (responseCode == null) {\n responseCode = 200;\n}\n\nif (!responses[responseCode]) {\n if (responses[\"default\"]) {\n responseCode = \"default\"\n } else {\n responseCode = 501;\n }\n}\nif (responseCode === \"default\") {\n responseCodeSC = mc.getProperty('query.param.responseCode');\n} else {\n responseCodeSC = responseCode;\n}\nif (accept == null || !responses[responseCode][accept]) {\n accept = \"application/json\";\n}\n\nif (accept == \"application/json\") {\n mc.setProperty('CONTENT_TYPE', 'application/json');\n mc.setProperty('HTTP_SC', responseCodeSC + \"\");\n mc.setPayloadJSON(responses[responseCode][\"application/json\"]);\n} else if (accept == \"application/xml\") {\n mc.setProperty('CONTENT_TYPE', 'application/xml');\n mc.setProperty('HTTP_SC', responseCodeSC + \"\");\n mc.setPayloadXML(responses[responseCode][\"application/xml\"]);\n}" + } + }, + "/pets/{petId}": { + "get": { + "parameters": [ + { + "name": "petId", + "in": "path", + "required": true, + "style": "simple", + "explode": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "default": [] + } + ], + "x-auth-type": "Application & Application User", + "x-throttling-tier": null, + "x-mediation-script": "var accept = mc.getProperty('AcceptHeader');\nvar responseCode = mc.getProperty('query.param.responseCode');\nvar responseCodeSC;\nvar responses = [];\nif (!responses[200]) {\n responses[200] = [];\n}\nresponses[200][\"application/json\"] = \"\";\nresponses[200][\"application/xml\"] = \"\";\n\n\nresponses[501] = [];\nresponses[501][\"application/json\"] = {\n\"code\" : 501,\n\"description\" : \"Not Implemented\"}\nresponses[501][\"application/xml\"] = 501Not Implemented;\n\nif (responseCode == null) {\n responseCode = 200;\n}\n\nif (!responses[responseCode]) {\n if (responses[\"default\"]) {\n responseCode = \"default\"\n } else {\n responseCode = 501;\n }\n}\nif (responseCode === \"default\") {\n responseCodeSC = mc.getProperty('query.param.responseCode');\n} else {\n responseCodeSC = responseCode;\n}\nif (accept == null || !responses[responseCode][accept]) {\n accept = \"application/json\";\n}\n\nif (accept == \"application/json\") {\n mc.setProperty('CONTENT_TYPE', 'application/json');\n mc.setProperty('HTTP_SC', responseCodeSC + \" Nirons mock Start \");\n mc.setPayloadJSON(responses[responseCode][\"application/json\"]);\n} else if (accept == \"application/xml\") {\n mc.setProperty('CONTENT_TYPE', 'application/xml');\n mc.setProperty('HTTP_SC', responseCodeSC + \"\");\n mc.setPayloadXML(responses[responseCode][\"application/xml\"]);\n}" + } + }, + "/oldpets": { + "delete": { + "responses": { + "200": { + "description": "OK" + } + }, + "security": [ + { + "default": [ + "SwaggerPetstore_imp_v3" + ] + } + ], + "x-auth-type": "Application & Application User", + "x-throttling-tier": null, + "x-mediation-script": "var accept = mc.getProperty('AcceptHeader');\nvar responseCode = mc.getProperty('query.param.responseCode');\nvar responseCodeSC;\nvar responses = [];\nif (!responses[200]) {\n responses[200] = [];\n}\nresponses[200][\"application/json\"] = \"\";\nresponses[200][\"application/xml\"] = \"\";\n\n\nresponses[501] = [];\nresponses[501][\"application/json\"] = {\n\"code\" : 501,\n\"description\" : \"Not Implemented\"}\nresponses[501][\"application/xml\"] = 501Not Implemented;\n\nif (responseCode == null) {\n responseCode = 200;\n}\n\nif (!responses[responseCode]) {\n if (responses[\"default\"]) {\n responseCode = \"default\"\n } else {\n responseCode = 501;\n }\n}\nif (responseCode === \"default\") {\n responseCodeSC = mc.getProperty('query.param.responseCode');\n} else {\n responseCodeSC = responseCode;\n}\nif (accept == null || !responses[responseCode][accept]) {\n accept = \"application/json\";\n}\n\nif (accept == \"application/json\") {\n mc.setProperty('CONTENT_TYPE', 'application/json');\n mc.setProperty('HTTP_SC', responseCodeSC + \"\");\n mc.setPayloadJSON(responses[responseCode][\"application/json\"]);\n} else if (accept == \"application/xml\") {\n mc.setProperty('CONTENT_TYPE', 'application/xml');\n mc.setProperty('HTTP_SC', responseCodeSC + \"\");\n mc.setPayloadXML(responses[responseCode][\"application/xml\"]);\n}" + } + } + }, + "components": { + "securitySchemes": { + "default": { + "type": "oauth2", + "flows": { + "implicit": { + "authorizationUrl": "https://test.com", + "scopes": { + "SwaggerPetstore_imp_v3": "SwaggerPetstore_imp_v3" + }, + "x-scopes-bindings": { + "SwaggerPetstore_imp_v3": "admin" + } + } + } + } + } + } +} \ No newline at end of file From f52794cd907684a821e70b993fe6c8cdd4bd333b Mon Sep 17 00:00:00 2001 From: theRasanjanana Date: Fri, 7 May 2021 10:02:56 +0530 Subject: [PATCH 4/7] Reformatting code --- .../tests/prototype/PrototypedAPITestcase.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 8bb4b894fb..59e4bf1cf1 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -242,19 +242,18 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { restAPIPublisher.deleteAPI(apiID); } - - @Test(groups = { "wso2.am" }, description = "Create an inline protoype API with OAS3 and Generate mock") + @Test(groups = {"wso2.am"}, description = "Create an inline protoype API with OAS3 and Generate mock") public void testInlinePrototypeWithMock() throws Exception { resourcePath = "oas" + File.separator + "v3" + File.separator; String originalDefinition = IOUtils.toString( - getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "oas_import.json"), + getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "oas_import.json"), "UTF-8"); String additionalProperties = IOUtils.toString( - getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "additionalProperties.json"), + getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "additionalProperties.json"), "UTF-8"); String updatedMock = IOUtils.toString( - getClass().getClassLoader().getResourceAsStream(resourcePath +"prototype" + File.separator + "updatedMockOas.json"), + getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "updatedMockOas.json"), "UTF-8"); org.json.JSONObject additionalPropertiesObj = new org.json.JSONObject(additionalProperties); additionalPropertiesObj.put("provider", user.getUserName()); @@ -270,7 +269,7 @@ public void testInlinePrototypeWithMock() throws Exception { // Generate mock Script for Prototype Implementation HttpResponse mockgenResponse = restAPIPublisher.generateMockScript(apiImportId); - Assert.assertEquals( mockgenResponse.getResponseCode(), 200); + Assert.assertEquals(mockgenResponse.getResponseCode(), 200); // Retrieve and validate the generated mock script HttpResponse mockedGetResponse = restAPIPublisher.getGenerateMockScript(apiImportId); @@ -295,6 +294,7 @@ public void testInlinePrototypeWithMock() throws Exception { } private File geTempFileWithContent(String swagger) throws Exception { + File temp = File.createTempFile("swagger", ".json"); temp.deleteOnExit(); BufferedWriter out = new BufferedWriter(new FileWriter(temp)); From 86665fa39f66611934865c150706764bc606a942 Mon Sep 17 00:00:00 2001 From: theRasanjanana Date: Fri, 7 May 2021 15:26:52 +0530 Subject: [PATCH 5/7] Add inline prototype for OAS2 --- .../prototype/PrototypedAPITestcase.java | 50 ++++++++++- .../v2/prototype/additionalProperties.json | 60 +++++++++++++ .../oas/v2/prototype/oas_import.json | 86 +++++++++++++++++++ 3 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/additionalProperties.json create mode 100644 modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/oas_import.json diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 59e4bf1cf1..2f9c0ea6c6 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -243,7 +243,7 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { } @Test(groups = {"wso2.am"}, description = "Create an inline protoype API with OAS3 and Generate mock") - public void testInlinePrototypeWithMock() throws Exception { + public void testOAS3InlinePrototypeWithMock() throws Exception { resourcePath = "oas" + File.separator + "v3" + File.separator; String originalDefinition = IOUtils.toString( @@ -293,6 +293,54 @@ public void testInlinePrototypeWithMock() throws Exception { restAPIPublisher.deleteAPI(apiImportId); } + @Test(groups = {"wso2.am"}, description = "Create an inline protoype API with OAS2 and Generate mock") + public void testOAS2InlinePrototypeWithMock() throws Exception { + + resourcePath = "oas" + File.separator + "v2" + File.separator; + String originalDefinition = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "oas_import.json"), + "UTF-8"); + String additionalProperties = IOUtils.toString( + getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "additionalProperties.json"), + "UTF-8"); + + org.json.JSONObject additionalPropertiesObj = new org.json.JSONObject(additionalProperties); + additionalPropertiesObj.put("provider", user.getUserName()); + + File file = geTempFileWithContent(originalDefinition); + // Create an api by importing OAS3 file + APIDTO apidto = restAPIPublisher.importOASDefinition(file, additionalPropertiesObj.toString()); + String apiImportId = apidto.getId(); + + // Change the lifecycle status to Prototype + restAPIPublisher.changeAPILifeCycleStatus(apiImportId, Constants.DEPLOY_AS_PROTOTYPE); + + // Generate mock Script for Prototype Implementation + HttpResponse mockgenResponse = restAPIPublisher.generateMockScript(apiImportId); + Assert.assertEquals(mockgenResponse.getResponseCode(), 200); + + // Retrieve and validate the generated mock script + HttpResponse mockedGetResponse = restAPIPublisher.getGenerateMockScript(apiImportId); + Assert.assertTrue(mockedGetResponse.getData().contains("/pets")); + Assert.assertTrue(mockedGetResponse.getData().contains("/pets/{petId}")); + Assert.assertTrue(mockedGetResponse.getData().contains("/oldpets")); + + // Create a revision and Deploy the API + createAPIRevisionAndDeployUsingRest(apiImportId, restAPIPublisher); + + Map requestHeaders = new HashMap<>(); + requestHeaders.put("accept", "application/json"); + waitForAPIDeployment(); + //Invoke the Prototype endpoint and validate + HttpResponse response1 = HTTPSClientUtils + .doGet(getAPIInvocationURLHttps("SwaggerPetstorev2import", "1.0.0") + + "/pets/1", requestHeaders); + Assert.assertEquals(response1.getResponseCode(), 200); + + restAPIPublisher.changeAPILifeCycleStatus(apiImportId, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); + restAPIPublisher.deleteAPI(apiImportId); + } + private File geTempFileWithContent(String swagger) throws Exception { File temp = File.createTempFile("swagger", ".json"); diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/additionalProperties.json b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/additionalProperties.json new file mode 100644 index 0000000000..ed4ade325c --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/additionalProperties.json @@ -0,0 +1,60 @@ +{ + "id": "71889e16-773e-471b-bc53-251569efff64", + "name": "SwaggerPetstore_v2_import", + "description": null, + "context": "/SwaggerPetstorev2import", + "version": "1.0.0", + "provider": "admin", + "lifeCycleStatus": "PUBLISHED", + "wsdlInfo": null, + "responseCachingEnabled": false, + "cacheTimeout": 300, + "hasThumbnail": null, + "isDefaultVersion": false, + "enableSchemaValidation": false, + "type": "HTTP", + "transport": ["http", "https"], + "tags": [], + "policies": ["Unlimited"], + "apiThrottlingPolicy": "Unlimited", + "authorizationHeader": null, + "securityScheme": ["oauth2", "oauth_basic_auth_mandatory"], + "maxTps": null, + "visibility": "PUBLIC", + "visibleRoles": [], + "visibleTenants": [], + "mediationPolicies": [], + "subscriptionAvailability": "ALL_TENANTS", + "subscriptionAvailableTenants": [], + "additionalProperties": [], + "monetization": null, + "accessControl": "NONE", + "accessControlRoles": [], + "businessInformation": { + "businessOwner": null, + "businessOwnerEmail": null, + "technicalOwner": null, + "technicalOwnerEmail": null + }, + "corsConfiguration": { + "corsConfigurationEnabled": true, + "accessControlAllowOrigins": ["*"], + "accessControlAllowCredentials": false, + "accessControlAllowHeaders": ["authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction"], + "accessControlAllowMethods": ["GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS"] + }, + "workflowStatus": null, + "endpointConfig": { + "endpoint_type": "http", + "sandbox_endpoints": { + "url": "https://localhost:9443/publisher-new/apis/create/openapi" + }, + "production_endpoints": { + "url": "https://localhost:9443/publisher-new/apis/create/openapi" + } + }, + "endpointImplementationType": "INLINE", + "scopes": [], + "operations": [], + "threatProtectionPolicies": null +} \ No newline at end of file diff --git a/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/oas_import.json b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/oas_import.json new file mode 100644 index 0000000000..012227bed6 --- /dev/null +++ b/modules/integration/tests-integration/tests-backend/src/test/resources/oas/v2/prototype/oas_import.json @@ -0,0 +1,86 @@ +{ + "swagger" : "2.0", + "info" : { + "version" : "1.0.0", + "title" : "SwaggerPetstore_v2" + }, + "security" : [ { + "default" : [ ] + } ], + "paths" : { + "/pets" : { + "get" : { + "parameters" : [ ], + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ "SwaggerPetstore_imp_v2" ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + }, + "/pets/{petId}" : { + "get" : { + "parameters" : [ { + "name" : "petId", + "in" : "path", + "required" : true, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + }, + "/oldpets" : { + "delete" : { + "parameters" : [ ], + "responses" : { + "200" : { + "description" : "OK" + } + }, + "security" : [ { + "default" : [ "SwaggerPetstore_imp_v2" ] + } ], + "x-auth-type" : "Application & Application User", + "x-throttling-tier" : null + } + } + }, + "securityDefinitions" : { + "default" : { + "type" : "oauth2", + "authorizationUrl" : "https://test.com", + "flow" : "implicit", + "scopes" : { + "SwaggerPetstore_imp_v2" : "SwaggerPetstore_imp_v2" + }, + "x-scopes-bindings" : { + "SwaggerPetstore_imp_v2" : "admin" + } + } + }, + "x-throttling-tier" : "Unlimited", + "x-wso2-cors" : { + "corsConfigurationEnabled" : true, + "accessControlAllowOrigins" : [ "*" ], + "accessControlAllowCredentials" : false, + "accessControlAllowHeaders" : [ "authorization", "Access-Control-Allow-Origin", "Content-Type", "SOAPAction" ], + "accessControlAllowMethods" : [ "GET", "PUT", "POST", "DELETE", "PATCH", "OPTIONS" ] + }, + "x-wso2-production-endpoints" : "https://localhost:9443/publisher-new/apis/create/openapi", + "x-wso2-sandbox-endpoints" : "https://localhost:9443/publisher-new/apis/create/openapi", + "x-wso2-basePath" : "/SwaggerPetstorev2/1.0.0" +} \ No newline at end of file From c2d1a1cc70d36dc2d2bdfeb0257dc0a9f0cd0c41 Mon Sep 17 00:00:00 2001 From: theRasanjanana Date: Sat, 8 May 2021 19:02:08 +0530 Subject: [PATCH 6/7] Add tenant mode and fix the PR comments --- .../prototype/PrototypedAPITestcase.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 2f9c0ea6c6..828dcf8d63 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -37,6 +37,7 @@ import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.testng.Assert; +import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; @@ -55,6 +56,7 @@ import org.wso2.carbon.apimgt.api.model.APIIdentifier; import org.wso2.carbon.automation.engine.context.TestUserMode; import org.wso2.carbon.automation.test.utils.http.client.HttpResponse; +import org.wso2.carbon.utils.multitenancy.MultitenantConstants; public class PrototypedAPITestcase extends APIMIntegrationBaseTest { @@ -77,7 +79,7 @@ public static Object[][] userModeDataProvider() { return new Object[][]{ new Object[]{TestUserMode.SUPER_TENANT_ADMIN}, -// new Object[]{TestUserMode.TENANT_ADMIN} + new Object[]{TestUserMode.TENANT_USER} }; } @@ -158,9 +160,6 @@ public void testPrototypedAPIEndpoint() throws Exception { "", requestHeaders); Assert.assertEquals(response1.getResponseCode(), 200); Assert.assertTrue(response1.getData().contains("BBQ Chicken Bacon")); - - restAPIPublisher.changeAPILifeCycleStatus(apiID, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); - restAPIPublisher.deleteAPI(apiID); } @Test(groups = {"wso2.am"}, description = "Create an API with a prototype endpoint, demote to created and invoke", dependsOnMethods = {"testPrototypedAPIEndpoint"}) @@ -238,13 +237,12 @@ public void testDemotedPrototypedEndpointAPItoCreated() throws Exception { .doGet(getAPIInvocationURLHttps(apiContext, apiVersion) + "", requestHeaders); Assert.assertEquals(response2.getResponseCode(), 401, "User was able to invoke the API demoted to CREATED from PROTOTYPE"); - - restAPIPublisher.deleteAPI(apiID); } @Test(groups = {"wso2.am"}, description = "Create an inline protoype API with OAS3 and Generate mock") public void testOAS3InlinePrototypeWithMock() throws Exception { + String context = "/SwaggerPetstorev3import"; resourcePath = "oas" + File.separator + "v3" + File.separator; String originalDefinition = IOUtils.toString( getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "oas_import.json"), @@ -257,6 +255,10 @@ public void testOAS3InlinePrototypeWithMock() throws Exception { "UTF-8"); org.json.JSONObject additionalPropertiesObj = new org.json.JSONObject(additionalProperties); additionalPropertiesObj.put("provider", user.getUserName()); + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(user.getUserDomain())) { + context = "/t/" + user.getUserDomain() + context; + } + additionalPropertiesObj.put("context", context); org.json.JSONObject updatedMockObj = new org.json.JSONObject(updatedMock); updatedMockObj.put("provider", user.getUserName()); File file = geTempFileWithContent(originalDefinition); @@ -287,15 +289,14 @@ public void testOAS3InlinePrototypeWithMock() throws Exception { HttpResponse response1 = HTTPSClientUtils .doGet(getAPIInvocationURLHttps("SwaggerPetstorev3import", "1.0.0") + "/pets/1", requestHeaders); - Assert.assertEquals(response1.getResponseCode(), 200); - restAPIPublisher.changeAPILifeCycleStatus(apiImportId, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); - restAPIPublisher.deleteAPI(apiImportId); + Assert.assertEquals(response1.getResponseCode(), 200); } @Test(groups = {"wso2.am"}, description = "Create an inline protoype API with OAS2 and Generate mock") public void testOAS2InlinePrototypeWithMock() throws Exception { + String context = "/SwaggerPetstorev2import"; resourcePath = "oas" + File.separator + "v2" + File.separator; String originalDefinition = IOUtils.toString( getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "oas_import.json"), @@ -303,12 +304,15 @@ public void testOAS2InlinePrototypeWithMock() throws Exception { String additionalProperties = IOUtils.toString( getClass().getClassLoader().getResourceAsStream(resourcePath + "prototype" + File.separator + "additionalProperties.json"), "UTF-8"); - + if (!MultitenantConstants.SUPER_TENANT_DOMAIN_NAME.equals(user.getUserDomain())) { + context = "/t/" + user.getUserDomain() + context; + } org.json.JSONObject additionalPropertiesObj = new org.json.JSONObject(additionalProperties); additionalPropertiesObj.put("provider", user.getUserName()); + additionalPropertiesObj.put("context", context); File file = geTempFileWithContent(originalDefinition); - // Create an api by importing OAS3 file + // Create an api by importing OAS2 file APIDTO apidto = restAPIPublisher.importOASDefinition(file, additionalPropertiesObj.toString()); String apiImportId = apidto.getId(); @@ -336,9 +340,12 @@ public void testOAS2InlinePrototypeWithMock() throws Exception { .doGet(getAPIInvocationURLHttps("SwaggerPetstorev2import", "1.0.0") + "/pets/1", requestHeaders); Assert.assertEquals(response1.getResponseCode(), 200); + } + + @AfterClass(alwaysRun = true) + public void destroyAPIs() throws Exception { - restAPIPublisher.changeAPILifeCycleStatus(apiImportId, APILifeCycleAction.DEMOTE_TO_CREATE.getAction()); - restAPIPublisher.deleteAPI(apiImportId); + super.cleanUp(); } private File geTempFileWithContent(String swagger) throws Exception { From ec2f39f39071abfd8d9510b30c8b1a68d6367d78 Mon Sep 17 00:00:00 2001 From: theRasanjanana Date: Wed, 12 May 2021 19:01:25 +0530 Subject: [PATCH 7/7] Reformat code --- .../integration/tests/prototype/PrototypedAPITestcase.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java index 828dcf8d63..eee6285deb 100644 --- a/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java +++ b/modules/integration/tests-integration/tests-backend/src/test/java/org/wso2/am/integration/tests/prototype/PrototypedAPITestcase.java @@ -261,7 +261,7 @@ public void testOAS3InlinePrototypeWithMock() throws Exception { additionalPropertiesObj.put("context", context); org.json.JSONObject updatedMockObj = new org.json.JSONObject(updatedMock); updatedMockObj.put("provider", user.getUserName()); - File file = geTempFileWithContent(originalDefinition); + File file = getTempFileWithContent(originalDefinition); // Create an api by importing OAS3 file APIDTO apidto = restAPIPublisher.importOASDefinition(file, additionalPropertiesObj.toString()); String apiImportId = apidto.getId(); @@ -311,7 +311,7 @@ public void testOAS2InlinePrototypeWithMock() throws Exception { additionalPropertiesObj.put("provider", user.getUserName()); additionalPropertiesObj.put("context", context); - File file = geTempFileWithContent(originalDefinition); + File file = getTempFileWithContent(originalDefinition); // Create an api by importing OAS2 file APIDTO apidto = restAPIPublisher.importOASDefinition(file, additionalPropertiesObj.toString()); String apiImportId = apidto.getId(); @@ -348,7 +348,7 @@ public void destroyAPIs() throws Exception { super.cleanUp(); } - private File geTempFileWithContent(String swagger) throws Exception { + private File getTempFileWithContent(String swagger) throws Exception { File temp = File.createTempFile("swagger", ".json"); temp.deleteOnExit();