Assertion for Xml in Rest Assured - java

I finally figured out how to get the List out of the XML. The Rest Assured site however didn't go over how to make a assertion for the list I got. How do I assert This movie has bruce willis as a actor with the rest assured format of given, when, then? Do I use the List in the given()?
#Test
public void verifyBruceWillisIsInDieHard() {
String xmlPath = get(
"http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml")
.andReturn().body().asString();
XmlPath actor = new XmlPath(xmlPath);
actor.setRoot("movie");
List<String> nameOfFirstActor = actor.getList("movie.#actors");
System.out.println(nameOfFirstActor);

Something like this perhaps?
when().
get("http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml").
then().
body("movie.#actors", hasItem("bruce willis"));

With a little tweaking to your answer this worked.
when().
get("http://www.omdbapi.com/?t=Die+Hard&y=&plot=short&r=xml").
then().
body("root.movie.#actors", containsString("Bruce Willis"));

Related

How to save a value from an XML-MvcResult into a variable with xpath

I have an integration test, to test two rest services with content-type application/xml. The first endpoint is called by an post request to create a person, and return a revision id. This ID is generated via a sql sequence in a H2 SQL database, so this id can differ. Now I want to delete the entry and call the second endpoint. The test should test the second endpoint. The problem is, I need the value of the revision id from the first call.
Here is my test:
String revisionID;
mvc.perform(post("url/create")
.contentType(MediaType.APPLICATION_XML)
.content(readXML("person")).accept("application/xml"))
.andExpect(status().isCreated())
// here I can do some tests, but I need to store the id value
// I have no idea to store the node in revisionId
.andExpect(xpath("/context/revisionId/text()").exist());
mvc.perform(delete("url/remove/revision/" + revisionId) // I need to know the id here
.contentType(MediaType.APPLICATION_XML)
.andExpect(status().isOk());
Testing values or counts of nodes in this way works perfectly, but I could not find a simple solution to extract/store a value with xpath. My plan B is to use java.xml.Xpath or JAXB, but I can't belive that there is no spring way with the MockMvc framework.
I can not use json, because it is an old system that use this rest enpoints.
Thanks in advance
I used my plan B and wrote an xpath method
public String getXpathValue( MvcResult xmlResult, String xpath) throws UnsupportedEncodingException, XPathExpressionException {
String content = xmlResult.getResponse().getContentAsString();
XPath xPathInstace = XPathFactory.newInstance().newXPath();
InputSource inputXML = new InputSource(new StringReader(content));
String result = xPathInstace.evaluate(xpath, inputXML);
return result;
}
and I use it like:
AtomicReference<Long> longAtomicReference = new AtomicReference<>();
mvc.perform(post("url/create")
.contentType(MediaType.APPLICATION_XML)
.content(readXML("person")).accept("application/xml"))
.andExpect(status().isCreated())
.andExpect(xpath("/context/revisionId/text()").exist())
.andDo(xmlResult -> {
longAtomicReference.set(Long.parseLong(getXpathValue(xmlResult, "//revisionId")));
});
Long revisionId = longAtomicReference.get();

Rest Assured code not allowing to use println

I am trying to automate twitter API. when tried to print "js.get("text") using
System.out.println(js.get("text")); I am getting error as
"The method println(boolean) is ambiguous for the type PrintStream"
I downloaded jars and passed in Build path as well "scribejava-apis-2.5.3" and "scribejava-core-4.2.0"
Below code is not allowing me use println for ------>js.get("text")
public class Basicfunc {
String Consumerkeys= "**************";
String Consumersecretkeys="*******************";
String Token="*******************";
String Tokensecret="***************************";
#Test
public void getLatestTweet(){
RestAssured.baseURI = "https://api.twitter.com/1.1/statuses";
Response res = given().auth().oauth(Consumerkeys, Consumersecretkeys, Token, Tokensecret).
queryParam("count","1").
when().get("/home_timeline.json").then().extract().response();
String response = res.asString();
System.out.println(response);
JsonPath js = new JsonPath(response);
System.out.println(js.get("text"));
}
}
Use System.out.println(js.getString("text")); instead of System.out.println(js.get("text"));, because get returns any primitive value.
I think your problem is that your twitter response is actually a list.
Try to use System.out.println(js.getList()[0].get("text")); and be aware that you are only using the first [0] entry and ignoring the rest.

How to use OpenFeign to get a pojo array?

I’m trying to use a OpenFeign client to hit an API, get some JSON, and convert it to a POJO array.
Previously I was simply getting a string of JSON and using Gson to convert it to the array like so
FeignInterface {
String get(Request req);
}
String json = feignClient.get(request);
POJO[] pojoArray = new Gson().fromJson(json, POJO[].class);
This was working. I would like to eliminate the extra step and have feign auto decode the JSON and return a POJO directly though, so I am trying this
FeignInterface {
POJO[] get(Request req);
}
POJO[] pojoArray = feignClient.getJsonPojo(request);`
I am running into this error
feign.codec.DecodeException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 2 path $
Both methods used the same builder
feignClient = Feign.builder()
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.target(FeignInterface.class, apiUrl);
Anyone have any ideas?
You have broken JSON payload. Before serialising you need to remove all unsupported characters. Feign allows this:
If you need to pre-process the response before give it to the Decoder,
you can use the mapAndDecode builder method. An example use case is
dealing with an API that only serves jsonp, you will maybe need to
unwrap the jsonp before send it to the Json decoder of your choice:
public class Example {
public static void main(String[] args) {
JsonpApi jsonpApi = Feign.builder()
.mapAndDecode((response, type) -> jsopUnwrap(response, type), new GsonDecoder())
.target(FeignInterface.class, apiUrl);
}
}
So, you need to do the same in your configuration and:
trim response and remove all whitespaces at the beginning and end of payload.
remove all new_line characters like: \r\n, \r, \n
Use online tool to be sure your JSON payload is valid and ready to be deserialised .

Null token returned

I'm testing API endpoints. The problem is when I check on Swagger, it returns a valid token, but in my testing it returns NULL. Can you point out where I'm doing the wrong thing?
public static void createOrganization() {
Map<String, String> org = new HashMap();
org.put("directorName", "name");
org.put("email", "email#gmail.com");
org.put("website", "www.site.com");
org.put("phoneNumber", "000111");
String registrationToken = given().
contentType("application/json").
body(org).
when().
post("/v3/organizations").
then().
extract().path("registrationToken");
System.out.println("Token: "+ registrationToken);
Output: Token: null
UPDATE:
Maybe I'm using extract() incorrectly, maybe there's a different solution to use the generated values later. Since for registerDevice() I'm getting NULL as well.
public static void registerDevice(){
String clientDeviceId =
given().
param("phoneNumber", "000111").
param("model", "samsung").
param("platform", "0").
param("push_token",SenimEnvironmentVars.testPushToken).
param("uuid", SenimEnvironmentVars.testUUID).
param("version", "7.1").
when().
post("/v3/user-devices").
then().
contentType("application/json").
extract().path("clientDeviceId");
System.out.println("Device ID: "+ clientDeviceId); //also prints NULL
}
Is there any other ways to generate tokens, device IDs etc. and use them later?
As documentation says
You can extract values from the response or return the response
instance itself after you've done validating the response by using the
extract method
So try to write after then some validating method like contentType(JSON).

How to construct QueryBuilder from JSON DSL when using Java API in ElasticSearch?

I'm using ElasticSearch as a search service in Spring Web project which using Transport Client to communicate with ES.
I'm wondering if there exists a method which can construct a QueryBuilder from a JSON DSL. for example, convert this bool query DSL JSON to a QueryBuilder.
{
"query" : {
"bool" : {
"must" : { "match" : {"content" : "quick"},
"should": { "match": {"content" : "lazy"}
}
}
}
I need this method because I have to receive user's bool string input from web front-side, and parse this bool string to a QueryBuilder. However it not suit to use QueryBuilders.boolQuery().must(matchQB).should(shouldQB).must_not(mustNotQB). Because we may need several must or non must query.
If there exist a method can construct a QueryBuilder from JSON DSL or there exists alternative solutions, it will much easier.
PS: I have found two method which can wrap a DSL String to a QueryBuilder for ES search.
One is WrapperQueryBuilder, see details here. http://javadoc.kyubu.de/elasticsearch/HEAD/org/elasticsearch/index/query/WrapperQueryBuilder.html
Another is QueryBuilders.wrapperQuery(String DSL).
You can use QueryBuilders.wrapperQuery(jsonQueryString);
You can use setQuery, which can receive a json format string.
/**
* Constructs a new search source builder with a raw search query.
*/
public SearchRequestBuilder setQuery(String query) {
sourceBuilder().query(query);
return this;
}
Note this: only part of the DSL is needed, the {"query": } part is omitted, like this:
SearchResponse searchResponse = client.prepareSearch(indices).setQuery("{\"term\": {\"id\": 1}}").execute().actionGet();
It might be worth investigating low level rest client. With this you can do:
RestClient esClient = RestClient.builder(new HttpHost("localhost", 9200, "http")).build();
Request request = new Request("POST", "/INDEX_NAME/_doc/_search");
request.setJsonEntity(yourJsonQueryString);
Response response = esClient.performRequest(request);
String jsonResponse = EntityUtils.toString(response.getEntity());

Categories