wiremock stub with query params not working - java

I am trying to match this url path -
/abc-service/abc?param1=value1&param2=VALUE_2
This gets matched with a json file as below
{
"request": {
"method": "GET",
"urlPathPattern": "/abc-service/abc(.*)"
},
"response": {
"headers": {
"Content-Type": "application/json"
},
"jsonBody": [],
"status": 200
}
}
But if I remove this and use stubFor() as below, it doesn't work.
WireMock.stubFor(
WireMock.get(WireMock.urlPathMatching("/abc-service/abc(.*)"))
.willReturn(okJson("[]")));
I even tried adding query params as below, that doesn't work either.
final Map<String, StringValuePattern> stringStringValuePatternMap = new HashMap<>();
stringStringValuePatternMap.put("param1", matching("value1"));
stringStringValuePatternMap.put("param2", matching("VALUE2"));
WireMock.stubFor(
WireMock.get(WireMock.urlPathEqualTo("/abc-service/abc"))
.withQueryParams(stringStringValuePatternMap)
.willReturn(
aResponse()
.withStatus(HttpStatus.OK.value())
.withHeader(
HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON_VALUE)));
What am I doing wrong?

Related

how to escape part of json loaded as object

I'm not fluent in API testing hence my question. I have a body to POST (mock) that will consist of:
{
"request":
{
"urlPath": "path/to/",
"method": "POST",
"bodyPatterns":[{
"equalToJson" : "{\n\"query\": [\n{\n\"name\": \"name1\",\n\"value\": \"123\"\n },\n{\n\"name\": \"name2\",\n\"value\": \"345\"\n},\n{\n\"name\": \"name3\",\n\"value\": \"someName\"\n}\n],\n\"anotherItem\": [],\n\"side\": 77,\n\"pageSize\": 44\n}", "jsonCompareMode": "LENIENT"
}]
},
"response":
{
"status": 200,
"headers":
{
"Content-Type" : "application/json"
},
"body": "{"items\": [\n{\n\"item\": 1,\n
\"item2\": 2,\n
etc
"\n}\n]\n}"
}
}
I want to use some pojo classes to separately create Request and Response:
public Request initRequest() {
BodyPattern bodyPat = new BodyPattern();
Query query = new Query();
Query query2 = new Query();
Query query3 = new Query();
EqualToJson equalToJ = new EqualToJson();
query.setName("name1");
query.setValue("123");
query2.setName("name2");
query2.setValue("345");
query3.setName("name2");
query3.setValue("someName");
List<Query> queryList = new ArrayList<>();
queryList.add(query);
queryList.add(query2);
queryList.add(query3);
equalToJ.setQuery(queryList);
List<Filter> filtersList = new ArrayList<>();
equalToJ.setFilter(filtersList);
equalToJ.setSide(77);
equalToJ.setPageSize(44);
List<EqualToJson> eqList = new ArrayList<>();
eqList.add(equalToJ);
req.setUrlPath(URL + "/Test001");
req.setMethod("POST");
bodyPat.setEqualToJson(eqList);
bodyPat.setJsonCompareMode("LENIENT");
List<BodyPattern> bodyPatList = new ArrayList<>();
bodyPatList.add(bodyPat);
req.setBodyPatterns(bodyPatList);
return req;
}
To see it in more user-friendly view, here you go:
{
"request": {
"urlPath": "/path/to",
"method": "POST",
"bodyPatterns": [
{
"equalToJson": {
"query": [
{
"name": "name1",
"value": "123"
},
{
"name": "name2",
"value": "345"
},
{
"name": "name3",
"value": "someName"
}
],
"filter": [
],
"side": 77,
"pageSize": 44
},
"jsonCompareMode": "LENIENT"
}
]
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"body": {
"side": 77,
"pageSize": 44,
"items": [
{
"name1": "123",
"name2": "345",
"name3": "someName"
etc...
}
]
}
}
}
Similarly, I do with Response.
My question is, how can I make to have just a part of this json (BodyPatters) as escaped signs? Mock is created this way that it only accepts escaped characters in this part of json.
I can of course hardcode this payload, but I want to have control over those fields' values and steer them, as parameters.
I really have no idea how to handle this.
You can use objectmapper of jackson to convert Object to String. For example:
void name2() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Query query = new Query("name1", "123");
EqualToJson equalToJson = new EqualToJson();
equalToJson.setQuery(Arrays.asList(query));
BodyPattern bodyPattern = new BodyPattern();
bodyPattern.setEqualToJson(mapper.writeValueAsString(equalToJson));
String bodyPatternText = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(bodyPattern);
System.out.println(bodyPatternText);
}
#Data
#AllArgsConstructor
static class Query{
private String name;
private String value;
}
#Data
static class EqualToJson {
private List<Query> query;
}
#Data
static class BodyPattern {
private String equalToJson;
}
This is a result:
{
"equalToJson" : "{\"query\":[{\"name\":\"name1\",\"value\":\"123\"}]}"
}

Java Spring response JSON String unescaped

I have the following Spring Method :
#RequestMapping(value = "/product/{productId}", method = RequestMethod.GET ,produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> getProductById(
//ProductDTO database query in order to retrieve productg by ID and population
final ObjectMapper objectMapper = new ObjectMapper();
final String json = objectMapper.writeValueAsString(productDTO);
return new ResponseEntity<>(json, HttpStatus.OK);
That returns a product representation in JSON format, the problem that I have is when I return this JSON , in the response I get it escaped like this:
"{\"uid\":\"test\",\"type\":\"Fragrance\",\"modifiedtime\":1575379505000,\"name\":\"test
name\",\"otherProperties\":{\"container\":false,\" ETC...``
I would need it unescaped in the response , how can I achieve this?
The reason I transform the DTO manually is because if I just return the DTO in the ResponseEntity the representation of the JSON handled by Spring is not the same as the one I get using objectMapper.writeValueAsString method , instead of getting this:
"name": "nombre de prueba",
"otherProperties": {
"container": false,
"onlineExclusive": false,
"sizeGuide": "size guide",etc..
I get this:
"name": "nombre de prueba",
"otherProperties": [
{
"key": "container",
"value": {
"type": "boolean",
"value": false
}
},
{
"key": "onlineExclusive",
"value": {
"type": "boolean",
"value": false
}
},
{
"key": "sizeGuide",
"value": {
"type": "string",
"value": "size guide"
}
},
```

URL Path Pattern Matching in WireMocks (pattern matching)

I am using wiremock for REST API testing and I am facing the below problem.
I have the following 2 json requests created.
REQUEST 1:
{
"request": {
"method": "GET",
"urlPattern": "/api/v1/user/2158634832/ishop.*",
"headers": {
"Accept": {
"contains": "application/json"
},
"X-RequestId": {
"matches": ".*"
},
"X-SecurityToken": {
"matches": "valid_secure_token"
}
}
},
"response": {
"status": 200,
"jsonBody": {
"user": {
"ID": "5cc1b131-8858-4870-a7ce-fd37aa805ebf",
"info": [
{
"kid": "2f0ad36a-9f23-427c-9a15-16d240385b87",
"cid": 10962435,
"pid": "V",
"contactid": 11812026,
"created": "2017-04-26T00:08:25.926",
"lastModified": "2017-04-27T00:01:45.047",
}
]
}
},
"headers": {
"Content-Type": "application/json"
}
}
}
My Get Request for the above wiremock looks something like this
**/api/v1/user/2158634832/ishop?ID=9879cfde-e353-4722-a91e-f22d29d8195c**
Request 2 :
{
"request": {
"method": "GET",
"urlPattern": "/api/v1/user/2158634832/ishop/status.*",
"headers": {
"Accept": {
"contains": "application/json"
},
"X-RequestId": {
"matches": ".*"
},
"X-SecurityToken": {
"matches": "valid_secure_token"
}
}
},
"response": {
"status": 200,
"jsonBody": {
"userstatus": {
"id": "5cc1b131-8858-4870-a7ce-fd37aa805ebf",
"type": "ishop",
"status" : "active",
"lastModifiedTime": "2017-04-27T00:01:45.047",
"allowedChange": "true"
}
},
"headers": {
"Content-Type": "application/json"
}
}
}
my Get request for the above looks something like this
/api/v1/user/2158634832/ishop/status?ID=9879cfde-e353-4722-a91e-f22d29d8195c
the problem here is that at times due to the similar URL Pattern for Request 1 and Request 2 what is happening is at times
When I submit a request for Request 1, I am getting the response which is of Request 2.
Can anyone suggest me a workaround how can i fix this ? I am hoping something to do with matches and urlPattern and somehow i can eleminate the status call in the first request i can do it, but not sure how.
any suggestions ?
Since one of your request URLs contains the other, a regex matching the shorter one will also match the longer one. I suspect this is why the shorter one is being matched when you'd prefer the longer one.
I suggest being more specific with your URL matches e.g.
"urlPath": "/api/v1/user/2158634832/ishop" in the first stub and
"urlPath": "/api/v1/user/2158634832/ishop/status" in the second
These will still match despite you not specifying the ID query param. WireMock treats extra headers or query parameters without match parameters as "don't care, match anyway".
Well i fixed it in the following way
Request 1 changed from
"urlPattern": "/api/v1/user/2158634832/ishop.*",
to
"urlPath": "/api/v1/user/2158634832/ishop",
Request 2 changed from
"urlPattern": "/api/v1/user/2158634832/ishop/status.*",
to
"urlPath": "/api/v1/user/2158634832/ishop/status",
A better solution is to use stub priority:
http://wiremock.org/docs/stubbing/#stub-priority
This way you can still use urlPatten
{
"priority" : 2,
"request": {
"method": "GET",
"urlPattern": "/api/v1/user/2158634832/ishop.*",
"headers": {
...
and:
{
"priority" : 1,
"request": {
"method": "GET",
"urlPattern": "/api/v1/user/2158634832/ishop/status.*",
"headers": {
...

swagger io consume json on post

Using swagger editor I created a post call to consume a json object that I want to simply load into a db but when I run the call I get an empty json object.
This is the parameters portion of my json swagger for the post
"parameters": [
{
"in": "body",
"name": "body",
"description": "Add question to collection",
"required": true,
"schema": { "type" : "object", "additionalProperties" : {}
}
}
],
It then creates a "Body" model, but I am not able to see the json that was part of the post:
#javax.annotation.Generated(value = "class io.swagger.codegen.languages.JaxRSServerCodegen", date = "2016-01-22T20:49:03.229Z")
public class Body {
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Body body = (Body) o;
return true;
}
#Override
public int hashCode() {
return Objects.hash();
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("class Body {\n");
sb.append("}");
return sb.toString();
}
/**
* Convert the given object to string with each line indented by 4 spaces
* (except the first line).
*/
private String toIndentedString(Object o) {
if (o == null) {
return "null";
}
return o.toString().replace("\n", "\n ");
}
}
If I remove the text/json from consume and generated my code again and I still see an issue with the body model and being able to pull in json.
If you look at the toString method it shows hard coded values, so I dont see how I can pull the json from the post with the post method only taking in the Body and securitycontext.
I am a little confused about the http accept, when using this swagger snippet:
"post": {
"tags": [
"AskGrey"
],
"summary": "Create new askgrey.com question",
"operationId": "postAskGrey",
"consumes": [
"application/json",
"text/json"
],
"produces": [
"application/json"
],
"parameters": [
{
"in": "body",
"name": "body",
"description": "Add question to collection",
"required": true,
"schema": { "type" : "object", "additionalProperties" : {}
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object"
}
}
},
"deprecated": false
}
The method generated is the following:
#Override
#POST
#Consumes("application/json")
public Response postAskGrey(Body body,SecurityContext securityContext)
throws NotFoundException {
So based on all this I am not sure how to pull in the post body info, normally I would grab what I need from the http request but with swagger I cant seem to figure out how that gets used.
Before you send your data you should check HTTP ACCEPT method which you set in swagger when you send your data.
There should be Several Accept method which their behaviour distinct from each other when sending data to server.
Thus for application/JSON : Data are part of body.
form-data and x-www-form-urlencoded : Data are part of header.
I haven't adaquate Java experience to give correct code to obtain json into related jSON Object but How to convert HTTP Request Body into JSON Object in Java this answer could help.
Please Check following RFCs for further information
form-data related RFC https://www.rfc-editor.org/rfc/rfc7578
x-www-form-urlencoded related RFC https://datatracker.ietf.org/doc/html/draft-hoehrmann-urlencoded-01
application/JSON related rfc https://www.ietf.org/rfc/rfc4627.txt
UPDATED
Related curl command : I get the command from swagger live demo http://petstore.swagger.io/#/pet paste your json to it and change url, secret key give it a try!
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"name": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}' 'http://petstore.swagger.io/v2/pet?api_key=special-key'

Parsing Facebook Graph API response

I'm working on Facebook Scores API for an android app. I query for the user score by accessing the user graph:
https://graph.facebook.com/user_id/scores&access_token={user_access_token}
I get a response like:
{
"data": [
{
"user": {
"name": "Michał Szydłowski",
"id": "100001699654797"
},
"score": 1200,
"application": {
"name": "QuizzlePeople",
"namespace": "quizzlepeople",
"id": "176694722487191"
}
},
{
"user": {
"name": "Michał Szydłowski",
"id": "100001699654797"
},
"score": 1,
"application": {
"name": "Friend Smash!",
"namespace": "friendsmashsample",
"id": "480369938658210"
}
},
{
"user": {
"name": "Michał Szydłowski",
"id": "100001699654797"
},
"score": 0,
"application": {
"name": "Wordox",
"namespace": "wordox-the-game",
"id": "227993680602156"
}
},
{
"user": {
"name": "Michał Szydłowski",
"id": "100001699654797"
},
"score": 0,
"application": {
"name": "SongPop",
"namespace": "songpop",
"id": "323595464361460"
}
}
]
}
How do I extract useful data from this?
I'm trying to take something as a JSONObject, using:
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("https://graph.facebook.com/me?fields=score&access_token=" + token);
HttpResponse resp = client.execute(get);
Log.i("info1", resp.toString());
// Parse the response
HttpEntity responseEntity = resp.getEntity();
String response = EntityUtils.toString(responseEntity);
Log.i("info1", response);
JSONObject result = new JSONObject(response);
JSONArray arr = result.getJSONArray("data");
Log.i("info2", arr.toString());
just to see if I can take anything, say, the array named 'data'. Yet the logcat does not show me anything. It shows the first 2 logs, but not the 3rd. Any ideas?
That looks like JSONObject. You can loop thru it and do whatever you wish with the data.
Have a look at http://json.org/ for documentation for a specific language (I presume you need java so click on the java link).
I appended the data to a table to give you an idea ( jquery / javascript ):
fiddle:http://jsfiddle.net/H8LNB/4/

Categories