Serenity screenplay rest extract value from response - java

I'm trying to extract class Header from response but can't find solution to that can please anyone guide me on this ?
Actor actor = Actor.named("ADMIN").whoCan(CallAnApi.at(baseUrl));
actor.attemptsTo(Get.resource("headers/" + rsplId).with(request -> request.header("Content-Type", "application/json")
.relaxedHTTPSValidation()
.cookies(cookies)));
actor.should(seeThatResponse(response -> response.assertThat().statusCode(200)
.extract().response().as(Header.class)
));
actor.should is void and when I tried to find anything inside seeThatResponse static method returning ReponseConsequence and see the message only thing I found inside was message that it was succesfull.
My method is returning Header but I don't know how to return this extracted Header inside response -> response.

I found solution with this approach maybe it'll help someone in the future.
actor.should(seeThatResponse(response -> response.assertThat().statusCode(200)));
return SerenityRest.lastResponse().as(Header.class);

Related

trying to return pdf or json with ByteArrayResource in webflux Mono

New to webflux and got a task. I am returning pdf right now with ByteArrayResource. Downstream service can also provide json in times. If any error occurred.
Right now I have :
public Mono<ByteArrayResource> downloadReport(){
return reactiveClient
.get(uriBuilder -> uriBuilder.queryParam("userId",userId)
.build(requestId))
.uri()
.accept(APPLICATION_PDF, APPLICATION_JSON)
.retrive()
.bodyToMono(ByteArrayResource.class);
}
With this code in postman error comes in json format but contentType is shown as application/octet-stream. Any idea how to get application/json?
Any suggestion??? Help is greatly appreciated.

How to handle 500 error code using retrieve in webclient

I've read quite a few documentations and other stackoverflow questions regarding this matter but I can't seem to get my code working.
So essentially I have a WebClient making a POST request.
IF the response status is 200, then I make another call to another endpoint using a different WebClient. After second webclient call, return a string.
ELSE I just return a String from the method e.g. "failed to create order.".
Simple enough. (this is all done in a seperate thread fyi, not the main thread.)
But I've noticed that if i do get back a 500 error code, WebClient throws an exception. What I want to do is capture the exception and handle that gracefully and return a String like "Error calling first endpoint etc."
This is what I have so far:
private String generateOrder(ImportedOrderDetails importedOrderDetails)
{
Order requestBody = generateRequestBody(importedOrderDetails);
OrderResponse responseForCreatingOrder = orderWebClient()
.post()
.body(Mono.just(requestBody), Order.class)
.retrieve()
.bodyToMono(OrderResponse.class)
.block();
if (responseForCreatingOrder.getResponseStatus().equals(SUCCESS))
{...other call using different webclient}
else{ return "Error creating order."}
This works fine when the response status is 200 but when its 500 it blows up.
OrderResponse is a custom object. orderWebClient() is just a method that returns a prebuilt WebClient containing the baseUrl and headers etc.
I came across this:
Spring WebClient - How to handle error scenarios I did try implementing it but couldn't figure out where to put the block method since I kept on getting the following:
reactor.core.Exceptions$ReactiveException: java.lang.Exception
at reactor.core.Exceptions.propagate(Exceptions.java:393)
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:97)
at reactor.core.publisher.Mono.block(Mono.java:1680)
I had to edit my code a bit to try and implement the answer to that question:
private Mono<? extends Throwable> handleError(String message) {
log.error("====---"+message);
return Mono.error(Exception::new);
}
private String generateOrder(ImportedOrderDetails importedOrderDetails)
{
Order requestBody = generateRequestBody(importedOrderDetails);
Mono<OrderResponse> responseForCreatingDemo = orderWebClient()
.post()
.body(Mono.just(requestBody), Order.class)
.retrieve()
.onStatus(
(HttpStatus::is5xxServerError),
(it -> handleError(it.statusCode().getReasonPhrase()))
)
.bodyToMono(OrderResponse.class);
System.out.println("-=-"+responseForCreatingDemo);
if (responseForCreatingOrder != null && responseForCreatingOrder.block().getHeader().getResponseStatus().equals(SUCCESS)){...}
The error was coming from the .block part in the if condition. I believe this is something pretty trivial and missing the big picture.
Any suggestions?
It seems you have two kinds of statuses:
Http status, defined by the protocol itself (see HTTP response status codes)
Something specific to the application you're working on, encapsulated into the OrderResponse class.
So you have to handle two "errors" instead of one, one of the possible solutions might look like
.retrieve()
.bodyToMono(OrderResponse.class)
// 4xx, 5xx errors and return "Unable to create order" String instead
.onErrorContinue(WebClientResponseException.class, (ex, v) ->
Mono.just("Unable to create order"))
// if application specific status is not "ok" return "Unable to create order"
.map(it -> it.ok ? "Ok response" : "Unable to create order")
.block();
Please note that this code sample ignores exception and does not even log it

restAssured - cannot master post method

fellow stackoverflowians :)
I've been for quit time to make a Post call using Gmail API.
Been trying to use createDraft and createLabel.
Now I guess I've found how to do this correctly (mostly) but I get this error:
java.lang.AssertionError: 1 expectation failed.
Expected status code <200> but was <400>.
I realise that this error occurs because I make incorrect request.
Could You, guys, help me with this?
Here's my code:
import io.restassured.RestAssured.*
import io.restassured.http.ContentType
import io.restassured.matcher.RestAssuredMatchers.*
import org.hamcrest.Matchers.*
import org.testng.annotations.Test
class RestAPIAutoTestPost {
#Test
fun createLabelInGoogleMail() {
RestAssured.baseURI = "https://www.googleapis.com/gmail/v1/users/me"
val accessToken = "ya29.Glw7BEv6***"
val jsonAsMap = HashMap<String, Any>()
jsonAsMap.put("id", "labelAPITestNameID")
jsonAsMap.put("labelListVisibility", "labelShow")
jsonAsMap.put("messageListVisibility", "show")
jsonAsMap.put("messagesTotal", "0")
jsonAsMap.put("messagesUnread", "0")
jsonAsMap.put("name", "labelAPITestName")
jsonAsMap.put("threadsTotal", "0")
jsonAsMap.put("threadsUnread", "0")
jsonAsMap.put("type", "user")
given().
contentType(ContentType.JSON).
body(jsonAsMap).
`when`()
post("/labels?access_token=$accessToken").
then().
statusCode(200)
}
}
I suppose I use HashMap incorrectly or I use some incorrect body fields.
I've only started to learn restAssured so I beg my pardons for newby question.
Thanks!
P.S. I'd really appreciate for any help with Post methods and puting data into body
I think your use of RestAssured and HashMap is correct. I think you are getting a 400 from this API because you are specifying the id property. By playing with this in Google's API Explorer, I was able to generate 400 errors by doing that. According to the documentation, the only things you need to specify for a POST/Create are: labelListVisibility, messageListVisibility, and name. The id is returned to you as part of the response.
A good feature in RestAssured is that you can have it log what it sends or receives when there is an error or all the time.
Log all requests:
given().log().all()
Log all responses:
`when`().log().all()
Or just when validations fail:
`when`().log().ifValidationFails()
Using that will give you a more precise reason why your interaction with the API is failing because it will show whatever Google is sending back. So we can see for sure if I'm right about the id.
And since you seem to be using Kotlin for this, you might want to take advantage of its great multiline string capabilities and just create the JSON payload manually:
val body = """
{
"labelListVisibility": "labelShow",
"messageListVisibility": "show",
"name": "ThisIsATest"
}
"""

Is it possible to extract the method name from the response object?

I'm using REST-Assured in Java and here's how I'm getting my response object:
Response response = RestAssured.given().contentType(ContentType.JSON).header(header_name).get();
I want to know if there's any way to extract the method name used (GET in this case) from the response object.
Incase if you're interested in knowing the requested method say GET or POST, below code will print the method on the console
given().log().method()
.when()
.get("https://www.google.co.in/").then().statusCode(200);
Hope this helps

How do I get Rest Assured to return the text (non-encrypted or streamed) value in my REST response?

I recently moved over to Java and am attempting to write some REST tests against the netflix REST service.
I'm having an issue in that my response using rest assured either wants to send a gzip encoded response or "InputStream", neither of which provide the actual XML text in the content of the response. I discovered the "Accept-Encoding" header yet making that blank doesn't seem to be the solution. With .Net I never had to mess with this and I can't seem to find the proper means of returning a human readable response.
My code:
RestAssured.baseURI = "http://api-public.netflix.com";
RestAssured.port = 80;
Response myResponse = given().header("Accept-Encoding", "").given().auth().oauth(consumerKey, consumerSecret, accessToken, secretToken).param("term", "star wars").get("/catalog/titles/autocomplete");
My response object has a "content" value with nothing but references to buffers, wrapped streams etc. Trying to get a ToString() of the response doesn't work. None of the examples I've seen seem to work in my case.
Any suggestions on what I'm doing wrong here?
This has worked for me:
given().config(RestAssured.config().decoderConfig(DecoderConfig.decoderConfig().noContentDecoders())).get(url)
I guess in Java land everything is returned as an input stream. Using a stream reader grabbed me the data I needed.
Until its version 1.9.0, Rest-assured has been providing by default in the requests the header "Accept-Encoding:gzip,deflate" with no way of changing it.
See
https://code.google.com/p/rest-assured/issues/detail?id=154
It works for me:
String responseJson = get("/languages/").asString();

Categories