Skip to content

Commit

Permalink
Add complex payload unit tests for HTTP Post functions
Browse files Browse the repository at this point in the history
  • Loading branch information
shanggeeth committed Aug 14, 2024
1 parent ce935a3 commit f431671
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import java.util.Map;

import static org.apache.http.HttpHeaders.CONTENT_TYPE;

import static org.wso2.carbon.identity.conditional.auth.functions.common.utils.CommonUtils.getPayloadDataMap;

/**
* Implementation of the {@link HTTPPostFunction}
Expand Down Expand Up @@ -111,20 +111,22 @@ public void httpPost(String endpointURL, Object... params) {
setHeaders(request, headers);

if (MapUtils.isNotEmpty(payloadData)) {

Map<String, Object> payloadDataMap = getPayloadDataMap(payloadData);
/*
For the header "Content-Type : application/x-www-form-urlencoded" request body data is set to
UrlEncodedFormEntity format. For the other cases request body data is set to StringEntity format.
*/
if (TYPE_APPLICATION_FORM_URLENCODED.equals(headers.get(CONTENT_TYPE))) {
List<NameValuePair> entities = new ArrayList<>();
for (Map.Entry<String, Object> dataElements : payloadData.entrySet()) {
for (Map.Entry<String, Object> dataElements : payloadDataMap.entrySet()) {
String value = (dataElements.getValue() != null) ? dataElements.getValue().toString() : null;
entities.add(new BasicNameValuePair(dataElements.getKey(), value));
}
request.setEntity(new UrlEncodedFormEntity(entities, StandardCharsets.UTF_8));
} else {
JSONObject jsonObject = new JSONObject();
jsonObject.putAll(payloadData);
jsonObject.putAll(payloadDataMap);
request.setEntity(new StringEntity(jsonObject.toJSONString(), StandardCharsets.UTF_8));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

package org.wso2.carbon.identity.conditional.auth.functions.http;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JOSEObjectType;
import com.nimbusds.jose.JWSAlgorithm;
Expand Down Expand Up @@ -94,6 +96,8 @@ public class HTTPPostFunctionImplTest extends JsSequenceHandlerAbstractTest {
private static final String ALLOWED_DOMAIN = "abc";
private static final String AUTHORIZATION = "Authorization";
private static final String API_KEY_HEADER = "X-API-KEY";
public static final String HTTP_POST_PAYLOAD = "http-post-payload.json";
public static final String HTTP_POST_PAYLOAD_TEST_SP = "http-post-payload-test-sp.xml";
private HTTPPostFunctionImpl httpPostFunction;

@InjectMicroservicePort
Expand Down Expand Up @@ -229,6 +233,20 @@ public void testHttpPostMethodWithClientCredentialAuthConfig() throws JsTestExce
result);
}

/**
* Test httpPost method with payload.
* Check if the payload data is sent with the request.
*
* @throws JsTestException
*/
@Test
public void testHttpPostMethodWithPayload() throws JsTestException {

String result = executeHttpPostFunction("dummy-post-with-payload", HTTP_POST_PAYLOAD_TEST_SP);
assertEquals(result, SUCCESS, "The http post request was not successful. Result from request: "
+ result);
}

/**
* Tests the behavior of the httpPost function when provided with null headers.
*
Expand Down Expand Up @@ -291,7 +309,7 @@ private String executeHttpPostFunction(String path, String adaptiveAuthScript) t
return context.getSelectedAcr();
}

private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) {
private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) throws JsTestException {

LocalAndOutboundAuthenticationConfig localAndOutboundAuthenticationConfig =
sp.getLocalAndOutBoundAuthenticationConfig();
Expand All @@ -303,7 +321,7 @@ private void updateSPAuthScriptRequestUrl(ServiceProvider sp, String path) {
sp.setLocalAndOutBoundAuthenticationConfig(localAndOutboundAuthenticationConfig);
}

private String getFormattedScript(String script, String path) {
private String getFormattedScript(String script, String path) throws JsTestException {
switch (path) {
case "dummy-post":
return String.format(script, getRequestUrl("dummy-post"));
Expand All @@ -318,6 +336,9 @@ private String getFormattedScript(String script, String path) {
case "dummy-post-with-clientcredential-auth-config":
return String.format(script, getRequestUrl("dummy-post-with-clientcredential-auth-config"),
getRequestUrl("dummy-token-endpoint"));
case "dummy-post-with-payload":
JsonObject Payload = sequenceHandlerRunner.loadJson(HTTP_POST_PAYLOAD, this);
return String.format(script, Payload.toString(), getRequestUrl("dummy-post-with-payload"));
default:
return null;
}
Expand Down Expand Up @@ -466,6 +487,28 @@ public Map<String, String> dummyPostWithClientCredentialAuthConfig(@HeaderParam(
return response;
}

@POST
@Path("/dummy-post-with-payload")
@Consumes("application/json")
@Produces("application/json")
public Map<String, Object> dummyPostWithPayload(Map<String, Object> data) throws JsTestException {

JsonObject expectedPayload = sequenceHandlerRunner.loadJson(HTTP_POST_PAYLOAD, this);
Gson gson = new Gson();
String dataStr = gson.toJson(data);
JsonObject actualPayload = gson.fromJson(dataStr, JsonObject.class);
Map<String, Object> response = new HashMap<>();
response.put(STATUS, SUCCESS);
response.put("data", dataStr);

if (expectedPayload.equals(actualPayload)) {
return response;
} else {
throw new JsTestException("Payloads do not match. " +
String.format("Expected payload: %s, Actual payload: %s", expectedPayload, actualPayload));
}
}

/**
* Dummy token endpoint to test the http post function with clientcredential auth config.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<!--
~ Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org).
~
~ 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.
-->
<ServiceProvider>
<ApplicationID>1</ApplicationID>
<ApplicationName>default</ApplicationName>
<Description>Default Service Provider</Description>
<InboundAuthenticationConfig>
<InboundAuthenticationRequestConfigs>
<InboundAuthenticationRequestConfig>
<InboundAuthKey>default</InboundAuthKey>
<InboundAuthType></InboundAuthType>
<Properties></Properties>
</InboundAuthenticationRequestConfig>
</InboundAuthenticationRequestConfigs>
</InboundAuthenticationConfig>
<LocalAndOutBoundAuthenticationConfig>
<AuthenticationSteps>
<AuthenticationStep>
<StepOrder>1</StepOrder>
<LocalAuthenticatorConfigs>
<LocalAuthenticatorConfig>
<Name>BasicMockAuthenticator</Name>
<DisplayName>basicauth</DisplayName>
<IsEnabled>true</IsEnabled>
</LocalAuthenticatorConfig>
</LocalAuthenticatorConfigs>
<SubjectStep>true</SubjectStep>
<AttributeStep>true</AttributeStep>
</AuthenticationStep>
</AuthenticationSteps>
<AuthenticationScript type="application/javascript" enabled="true"><![CDATA[
function onLoginRequest(context) {
var comprehensivePayload = %s;
httpPost('%s', comprehensivePayload, {
onSuccess : function(context, data) {
Log.info('httpPost call success');
context.selectedAcr = data.status;
executeStep(1);
}, onFail : function(context, data) {
Log.info('httpPost call failed');
context.selectedAcr = 'FAILED';
executeStep(1);
}
});
}
]]></AuthenticationScript>
<AuthenticationType>flow</AuthenticationType>
</LocalAndOutBoundAuthenticationConfig>
<RequestPathAuthenticatorConfigs></RequestPathAuthenticatorConfigs>
<InboundProvisioningConfig></InboundProvisioningConfig>
<OutboundProvisioningConfig></OutboundProvisioningConfig>
<ClaimConfig>
<AlwaysSendMappedLocalSubjectId>true</AlwaysSendMappedLocalSubjectId>
</ClaimConfig>
<PermissionAndRoleConfig></PermissionAndRoleConfig>
</ServiceProvider>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"stringKey": "stringValue",
"numberKey": 123,
"booleanKey": true,
"arrayKey": [
"arrayString",
456,
false,
{
"nestedObjectInArrayKey": "nestedObjectValue",
"nestedArrayInArrayKey": ["nestedArrayValue1", "nestedArrayValue2"]
}
],
"objectKey": {
"objectStringKey": "objectStringValue",
"objectNumberKey": 789,
"objectBooleanKey": false,
"nestedObjectKey": {
"nestedObjectStringKey": "nestedObjectStringValue",
"nestedObjectArrayKey": [
"nestedArrayValue1",
101112,
true
]
},
"arrayOfObjectsKey": [
{
"arrayOfObjectsStringKey": "arrayOfObjectsStringValue1",
"arrayOfObjectsNumberKey": 131415,
"arrayOfObjectsBooleanKey": true
},
{
"arrayOfObjectsStringKey": "arrayOfObjectsStringValue2",
"arrayOfObjectsNumberKey": 161718,
"arrayOfObjectsBooleanKey": false
}
]
}
}

0 comments on commit f431671

Please sign in to comment.