SOAP UI - Return two different responses for two different POST Request Payloads for same REST API end point - groovy

I have a REST POST API end point - "abc/def".
It's request payload has (out of many other fields) a field "yourId" which can take either 1 or 2 as shown below:
{
"yourId":"1"
}
OR
{
"yourId":"2
}
On the basis of the value of "yourId", I need to return two different responses either 1. YOUR_RESPONSE_1 OR 2. YOUR_RESPONSE_2 for which I have written a groovy script as shown below:
def requestBody = mockRequest.getRequestContent()
log.info "Request body: " + requestBody
yourId="yourId"
id1="1"
id2="2"
if(requestBody.contains(yourId+":"+id1)){
return "YOUR_RESPONSE_1"
}else if(requestBody.contains(yourId+":"+id2)){
return "YOUR_RESPONSE_2"
}else return "ERROR_RESPONSE"
When I hit the end point "localhost:8080/abc/def" from postman, I get ERROR_RESPONSE. How can I fix it.

I would suggest you to use the JSONSlurper() as this avoids the use of escape characters and makes the script legible, Also it come in handy when the input JSON is complex
def requestBody = mockRequest.getRequestContent()
def parsedJson = new groovy.json.JsonSlurper().parseText(requestBody)
def ID = parsedJson.yourId
if(ID=="1"){
return "YOUR_RESPONSE_1"
}
else if(ID=="2"){
return "YOUR_RESPONSE_2"
}
else return "ERROR_RESPONSE"

Related

How to catch null value on http response

I have the following code method which is used to test for an existing user in MSGraph API
public String getGuestUserId(String AuthToken,String userEmail){
String _userId
def http = new HTTPBuilder(graph_base_user_url + "?")
http.request(GET) {
requestContentType = ContentType.JSON
//uri.query = [ $filter:"mail eq '$userEmail'"].toString()
uri.query=[$filter:"mail eq '$userEmail'"]
headers.'Authorization' = "Bearer " + AuthToken
response.success = { resp, json ->
//as the retunr json alue is an array collection we need to get the first element as we request all time one record from the filter
**_userId=json.value[0].id**
}
// user ID not found : error 404
response.'404' = { resp ->
_userId = 'Not Found'
}
}
_userId
}
This method works fine when the user is existing and will return properly from the success response the user ID property.
The issue I get is that if the user is not existing, the ID field is not existing either and the array is empty.
How can I handle efficiently that case and return a meaning full value to the caller like "User Does not exist"
I have try a catch exception in the response side but seems doe snot to work
Any idea how can I handle the test like if the array[0] is empty or does not contains any Id property, then return something back ?
Thanks for help
regards
It seems to be widely accepted practice not to catch NPE. Instead, one should check if something is null.
In your case:
You should check if json.value is not empty
You also should check if id is not null.
Please also note that handling exceptions in lambdas is always tricky.
You can change the code to:
http.request(GET) {
requestContentType = ContentType.JSON
uri.query=[$filter:"mail eq '$userEmail'"]
headers.'Authorization' = "Bearer " + AuthToken
if (json.value && json.value[0].id) {
response.success = { resp, json -> **_userId=json.value[0].id** }
} else {
// Here you can return generic error response, like the one below
// or consider more granular error reporting
response.'404' = { resp -> _userId = 'Not Found'}
}
}

Httpbuilder put examples for sending multiple query params groovy

I am using Httpbuilder 0.7.1 and groovy 1.8 to invoke the rest call.
I need to send the mutiple values for the same query parameter but it is not working.
I need to send values as below
https:///?action=test&group=grp1&group=grp2
I have tried with the code below and it is working as expected.
Map query = [:]
Map headerMap = [:]
headerMap["Accept"] = 'application/json'
headerMap["Authorization"] = authtoken
def groupsListArray=[]
if (group.contains(",")) {
def groupsList = group.split(",");
for ( singlegroup in groupsList) {
groupsListArray.add(singlegroup.toString())
}
query.put("group",groupListArray)
}
else{
query.put("group",group)
}
def http = new HTTPBuilder(baseUrl)
http.request(method) { req ->
uri.path = path
uri.query = query
headerMap.each { key, value ->
headers."${key}" = "${value}" }
}
Is there any other way, we can send multiple values for the same query parameter with httpbuilder?
Okie, the issue has been identified with the REST service and there is no issue with this code.Thanks for the help

How to print all assertion failure messages into HTML report of SoapUI

I am running test case and asserting data using groovy. I want to print each and every failed message to html junit generate report.
Example Code
import groovy.json.JsonSlurper
def ResponseMessage = messageExchange.response.responseContent
def jsonString = new JsonSlurper().parseText(ResponseMessage)
assert !(jsonString.isEmpty())
assert jsonString.code == 200
assert jsonString.status == "success"
def accountInfo = jsonString.data
assert !(accountInfo.isEmpty())
def inc=0
//CHECKING LANGUAGES IN RESPONSE
if(accountInfo.languages.id!=null)
{
log.info("Language added successfully")
}
else
{
log.info("Language NOT added.") //want to display this in html report
inc++
}
if(accountInfo.educations!=null)
{
log.info("Educations added successfully")
}
else
{
log.info("Educations NOT added.") //want to display this in html report
inc++
}
assert inc<=0,"API unable to return all parameters, Please check logs"
Scenario
What I am doing here is , IF test condition does not match and go to ELSE, I do increment of variable inc by 1. So at the end if fail my test if inc>0.
Report
In junit style html generated report, if test failed it display only one message called API unable to return all parameters, Please check logs
But what I want is to display each IF condition message into HTML report if for any condition goes into ELSE section.
Couple of pointers:
assert stops at first failure and only this failure message is part of junit report.
having said that, user will not know if there are any further verification failures for the current response.
the messages that are part of if..else are not part of junit report
in order to achieve that, need to collect all those messages and finally show the collected error messages.
below solution uses a variable, messages and appends each failure which allows to show them at the end. this way all failures can be shown in the report if that is desirable which OP requested for.
user can also show the messages in the report using below statement apart from assert statement
if (messages) throw new Error(messages.toString())
Script Assertion
import groovy.json.JsonSlurper
//check if the response is empty
assert context.response, 'Response is empty or null'
def jsonString = new JsonSlurper().parseText(context.response)
def messages = new StringBuffer()
jsonString.code == 200 ?: messages.append("Code does not match: actual[${jsonString.code}], expected[200]\n")
jsonString.status == "success" ?: messages.append("Status does not match: actual[${jsonString.status}], expected[success]\n")
def accountInfo = jsonString.data
accountInfo ?: messages.append('AccountInfo is empty or null\n')
def inc=0
//CHECKING LANGUAGES IN RESPONSE
if(accountInfo.languages.id) {
log.info('Language added successfully')
} else {
log.error('Language NOT added.') //want to display this in html report
messages.append('Language not added.\n')
inc++
}
if(accountInfo.educations) {
log.info('Educations added successfully')
} else {
log.error('Educations NOT added.') //want to display this in html report
messages.append('Educations NOT added.\n')
inc++
}
//inc<=0 ?: messages.append('API unable to return all parameters, Please check logs.')
//if(messages.toString()) throw new Error(messages.toString())
assert inc<=0, messages.append('API unable to return all parameters, Please check logs.').toString()

Spock: check the query parameter count in URI

I have just started with spock. I have one functionality. where the java function makes an http call. As per functionality, the URI used in http call, must contain "loc" parameter and it should be only once.
I am writing Spock test case. I have written below snippet.
def "prepareURI" () {
given: "Search Object"
URI uri = new URI();
when:
uri = handler.prepareURI( properties) // it will return URI like http://example.com?query=abc&loc=US
then:
with(uri)
{
def map = uri.getQuery().split('&').inject([:]) {map, kv-> def (key, value) = kv.split('=').toList(); map[key] = value != null ? URLDecoder.decode(value) : null; map }
assert map.loc != null
}
}
From above snippet, my 2 tests got passed like
It should be exists
It should not be null
I want to check the count of "loc" query parameter. It should be passed exactly once. With map as above, If I pass "loc" parameter twice, map overrides the old value with 2nd one.
Does any one knows, how to access the query parameters as list, and in list I want to search the count of Strings which starts with "loc"
Thanks in advance.
Perhaps an example would be the best start:
def uri = new URI('http://example.com?query=abc&loc=US')
def parsed = uri.query.tokenize('&').collect { it.tokenize('=') }
println "parsed to list: $parsed"
println "count of 'loc' params: " + parsed.count { it.first() == 'loc' }
println "count of 'bob' params: " + parsed.count { it.first() == 'bob' }
println "count of params with value 'abc': " + parsed.count { it.last() == 'abc' }
prints:
$ groovy test.groovy
parsed to list: [[query, abc], [loc, US]]
count of 'loc' params: 1
count of 'bob' params: 0
count of params with value 'abc': 1
the problem, as you correctly noted, is that you can not put your params into a map if your intent is to count the number of params with a certain name.
In the above, we parse the params in to a list of lists where the inner lists are key, value pairs. This way we can call it.first() to get the param names and it.last() to get the param values. The groovy List.count { } method lets us count the occurences of a certain item in the list of params.
As for your code, there is no need to call new URI() at the beginning of your test as you set the value anyway a few lines down.
Also the with(uri) call is unnecessary as you don't use any of the uri methods without prefixing them with uri. anyway. I.e. you can either write:
def uri = new URI('http://example.com?query=abc&loc=US')
def parsed = uri.query.tokenize('&').collect { it.tokenize('=') }
or:
def uri = new URI('http://example.com?query=abc&loc=US')
uri.with {
def parsed = query.tokenize('&').collect { it.tokenize('=') }
}
(note that we are using query directly in the second example)
but there is not much point in using with if you are still prefixing with uri..
The resulting test case might look something like:
def "prepareURI"() {
given: "Search Object"
def uri = handler.prepareURI( properties) // it will return URI like http://example.com?query=abc&loc=US
when:
def parsed = query.tokenize('&').collect { it.tokenize('=') }
then:
assert parsed.count { it.first() == 'loc' } == 1
}

JSON format list in couchDB

I am writing a list for couchDB. All the documentation I have read assumes you would want to return data in html or plain text. I, however, need it to be returned in JSON format, in exactly the same way that a view would return (the application I am writing relies on this).
What is the correct way to have a list return its data in JSON format?
Try toJSON(), see the example.
You need to format your output with send to mimmic a JSON output. Here is an example of how we do that in a real case:
function(head, req) {
start({"headers": {"Content-Type": "application/json"}});
var keys = {};
while (row = getRow()) {
//Code goes here
send("{\"rows\":[");
var init = true;
for (var key in keys) {
if (init) {
send("\n");
init = false;
}
else send(",\n");
send("{\"key\": " + key + ",\"value\":");
send("{\"first_val\":" + val1);
send(", \"second_val\":" + val2);
send(", \"third_val\":" + val3 + "}}");
}
send("\n]}");
}
In this way, the output of the list has the same format as the underlying view.

Resources