My client is asking me to perform test for api where the body of the request should one in raw instead of header or something else.
He showed me how to do it in postman, but samething I want to simulate through automation which is in Java and rest assured.
Then How to approach the same in java becasue I can do it through get or post in java and restassured but dont know how to do it with raw.
GET-
#Test
public void mytest() {
Map<String, String> paramSample = new HashMap<>();
paramSample.put("v", "X.X");
paramSample.put("headers", "X");
paramSample.put("local", "X");
paramSample.put("method", "xxxxx");
paramSample.put("json", CreateJSON(ExecutionConfig.xxxx,0,0,ExecutionConfig.xxxxx,"Mex"));
paramSample.put("sender", ExecutionConfig.xxxx);
paramSample.put("api_key", ExecutionConfig.xxx);
paramSample.put("format", "json");
RequestSpecification request = given();
Response responseSample = request.params(paramSample).get(ExecutionConfig.Mxxxxx).then().extract().response();
Related
#Test(description = "Verify that user is able to login and get the offer details for a particular promo code", dependsOnGroups = "getAuthKey")
public void verify_offers_with_login_with_promo_code() {
Map<String, String> headers = InputRequestHelper.setHeaders("auth_api_key", auth_api_key);
**// Have to remove the below set path parameters later in the code**
requestSpecification.pathParam("promocode", "1909");
Response response = InputRequestHelper.createGetRequest(requestSpecification, captor,
Constants.OFFER_PROMOCODE_PATH, headers, "com.dhani/schemas/offers/offersPromocode.json");
CommonHelper.writeRequestAndResponseInReport(writer.toString(), response.prettyPrint());
JSONObject jsonObject = new JSONObject(response.getBody().asString());
AssertionHelper.assertNotNull(ParseDynamicJson.getKey(jsonObject, "data"), "data");
AssertionHelper.assertFieldValue(ParseDynamicJson.getKey(jsonObject, "message"), "success", "message");
}
There is no way remove config in RequestSpecification --> shouldn't re-use this. You have to create new instance of this class for every request.
Similar situation here: https://stackoverflow.com/a/69569031/7574461
I'm trying to call an get api which is hosted in aws api gateway via rest-assured
I'm able to sign the request and make a call. But to sign the request, I need to pass the full url to AWS to generate the Authorization Header.
For Ex. If I'm going to access an an endpoint
https://my-aws-api.com/basepath/v1/request/123
I need to sign the request via AWSSigner which needs the full endpoint to do so.
My current approach
String baseURI="https://my-aws-api.com";
String basePath="basepath/v1";
String requestPath="request/123";
String endpoint=baseURI+"/"+basePath+"/"+requestPath;
Map<String,String> signedHeaders= aws4sign(endpoint,defaultHeaders);
given()
.log().ifValidationFails()
.headers(signedHeaders)
.when()
.get(endpoint)
.then()
.log().ifValidationFails()
.statusCode(200);
If I do that , then I cant use RestAssured's baseURI, basePath and path params
I want to access it like
RestAssured.baseURI="https://my-aws-api.com";
RestAssured.basePath="basepath/v1";
given()
.log().ifValidationFails()
.pathParam("reqID", "123")
.when()
.get("request/{reqID}")
.then()
.log().ifValidationFails()
.statusCode(200);
AwsSigner
public static Map<String, String> aws4Sign(String endpoint, Map<String, String> headers) throws URISyntaxException {
String serviceName = "execute-api";
AWS4Signer aws4Signer = new AWS4Signer();
aws4Signer.setRegionName(EU_WEST_1.getName());
aws4Signer.setServiceName(serviceName);
DefaultRequest defaultRequest = new DefaultRequest(serviceName);
URI uri = new URI(endpoint);
defaultRequest.setEndpoint(new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), "", "", ""));
defaultRequest.setHttpMethod(HttpMethodName.GET);
defaultRequest.setResourcePath(uri.getRawPath());
defaultRequest.setHeaders(headers);
aws4Signer.sign(defaultRequest, DefaultAWSCredentialsProviderChain.getInstance().getCredentials());
return defaultRequest.getHeaders();
}
So My question is there any way, I can intercept the RestAssured's request before it makes the call, so that I can get the fully generated end point and add the aws signed header to the call.
I am not familiar with this library but from briefly reading its documentation and Javadoc, you should be able to use a RequestFilter to inspect and alter a request before it is sent out.
Take a look at the Filter section of the user guide.
Thanks to #Ashaman.
The Filter Section is what I'm looking for
You can get the uri and other headers that were passed with requests from RequestSpec and then send it to the function to sign them and remove the old headers and put the new headers. Then forward the request
#BeforeAll
public void init() {
RestAssured.baseURI = "https://my-aws-api.com";
RestAssured.filters((requestSpec, responseSpec, ctx) -> {
Map<String, String> headers = requestSpec.getHeaders()
.asList()
.stream()
.collect(Collectors.toMap(Header::getName, Header::getValue));
Map<String, String> signedHeaders = aws4sign(requestSpec.getURI(), headers);
requestSpec.removeHeaders();
requestSpec.headers(signedHeaders);
return ctx.next(requestSpec, responseSpec);
});
}
And for the tests I can use the features of Rest Assured normally
given()
.log().ifValidationFails()
.pathParam("reqID", "123")
.when()
.get("request/{reqID}")
.then()
.log().ifValidationFails()
.statusCode(200);
Am trying the reuse the restassured get call in the testng api tests, but the restassured instance in using the cookies received from the previous response.
Tried RestAssured.reset(); but this doesn't help in flushing the cookies we got from earlier request/response.
Reason for this question - As the get endpoint behaves differently if there is a session cookie exist on the request.
#Test // TestNG test
public void test_1(){
//Set Cookie
Cookie cookie = new Cookie.Builder("COOKIENAME","COOKIEVALUE").setDomain("*.com").setPath("/").setExpiryDate(SOMELATERDATE).build();
RestAssured.baseURI = https://ENV_URL;
Response response = RestAssured.given().log().all()
.cookies(new Cookies(cookie)).when().get("/END_POINT").then().extract().response().prettyPeek();
RestAssured.reset();
}
#Test // TestNG test
public void test_2(){
//Set Cookie
Cookie cookie = new Cookie.Builder("COOKIENAME", "COOKIEVALUE").setDomain("*.com").setPath("/").setExpiryDate(SOMELATERDATE).build();
RestAssured.baseURI = https://ENV_URL;
// Still Reuses the cookie received from previous response
Response response = RestAssured.given().log().all()
.cookies(new Cookies(cookie)).when().get("/END_POINT").then().extract().response().prettyPeek();
RestAssured.reset();
}
Use CookieFilter. If you want to exclude the a particular cookie you can use the following code.
#Test
public void sampletest(){
CookieFilter cookieFilter = new CookieFilter();
Response response = RestAssured.given().
cookie("foo", "bar").
filter(cookieFilter). // Reuse the same cookie filter
// if "foo" is stored in cookieFilter it won't be applied because it's already applied explicitly
expect().
statusCode(200).
when().
get("/y");
}
I want to send http notifications with query params with Spring web client. I tried this:
WebClient client;
public Mono<Response> execute(String url) {
MultiValueMap map = new MultiValueMap<>();
map.add("some_key", "some_value");
return client.post().uri(builder -> builder
.host("http://www.test.com/notification")
.queryParams(map).build())
.accept(MediaType.APPLICATION_XML)
.contentType(MediaType.APPLICATION_XML)
.retrieve()
.bodyToMono(Response.class);
}
But I have several issues:
When I try to use MultiValueMap I get error Cannot instantiate the type MultiValueMap
Also how I can get the notification result? I don't want to send any payload or get any payload. I only want to get OK for response.
EDIT:
public Mono<String> execute(String url) {
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("some_key", "some_value");
return client.post().uri(builder -> builder
.queryParams(map).build())
.accept(MediaType.APPLICATION_XML)
.contentType(MediaType.APPLICATION_XML)
.retrieve()
.bodyToMono(String.class);
}
MultiValueMap
MultiValueMap is an interface from org.springframework.util
You are trying to instantiate it the following way:
MultiValueMap map = new MultiValueMap<>();
This won't work as you need to provide an implementation of the interface. If you really want to instantiate it this way then maybe try using one of the implementations of the MultiValueMap, like LinkedMultiValueMap.
OK for response
If you are only interested in the result (i.e. the status code) of the request, you could try to do the following:
client.post().uri(builder -> builder
.host("http://www.test.com/notification")
.queryParams(map).build())
.accept(MediaType.APPLICATION_XML)
.contentType(MediaType.APPLICATION_XML)
.exchange()
.map(ClientResponse::statusCode);
The last call to map(...) will return an instance of Mono<HttpStatus>.
Hope this helps.
I need to invoke a form-data typed API using Rest Assured. Here is my code.
private Map<String, String> getFormParamsMap() {
Map<String, String> formParams = new HashMap<>();
formParams.put("creatorId", "Instructor1");
formParams.put("creatorPlatform", "Web");
formParams.put("creatoredSource", "File");
formParams.put("creatoredType", "Auto");
formParams.put("deckId", "5a605b472e02d86561172dad");
formParams.put("userId", "kind");
return formParams;
}
public void invoke() {
response = given()
.header("Content-Type", "application/form-data")
.header(AUTHORIZATION_HEADER_NAME, accessToken) //Some API contains access token to run with the API
.headers(headers)
.formParams(getFormParamsMap()) // requestParamsMap here.
.when()
.post(invokingEndpoint);
}
When I execute this, I am getting the below error.
Message: java.lang.IllegalArgumentException: Don't know how to encode creatorPlatform=Web&creatoredType=Auto&deckId=5a605b472e02d86561172dad&creatorId=Instructor1&creatoredSource=File&userId=kind as a byte stream.
Please use EncoderConfig (EncoderConfig#encodeContentTypeAs) to specify how to serialize data for this content-type.
For example: "given().config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))). .."
Stack Trace:
io.restassured.internal.http.EncoderRegistry.encodeStream(EncoderRegistry.java:130)
When I use .config(RestAssured.config().encoderConfig(encoderConfig().encodeContentTypeAs("application/form-data", ContentType.TEXT))) in the invoke() method, it gives the result as below.
{
"status": 400,
"message": "Content type 'application/x-www-form-urlencoded;charset=ISO-8859-1' not supported",
"error": "Bad Request",
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException"
}
My request is not x-www-form-urlencoded type, it is form-data type. I can execute it using postman.
Appreciate your support on this.
Thanks.
I have solve this issue by using encodeContentTypeAs("multipart/form-data", ContentType.TEXT)
Ex:-
public void invoke() {
response = given()
.config(
RestAssured.config()
.encoderConfig(
encoderConfig()
.encodeContentTypeAs("multipart/form-data", ContentType.TEXT)))
.headers(headers)
.formParams(formParams)
.when()
.post(oAuthBaseURI).then().extract().response();
}
Please add the consumer as well.
See here for the encoders available for Rest Assured.
This might be causing the problem -
encodeContentTypeAs("application/form-data", ContentType.TEXT)
You can also try this -
.encoderConfig(encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false).encodeContentTypeAs("application/form-data", ContentType.TEXT));
As far as I can tell, headers(headers) method replaces all headers, and then RestAssured uses x-www-form-urlencoded content type as default.
Try adding "Content-Type" header after the call to headers(headers).