How to test for Empty array value in Unirest json Response - groovy

I have the following code snipet used in Jira Script Runner cloud
String _userId
def result = get(graph_base_user_url + "?")
.header("Authorization","Bearer " + AuthToken )
.queryString("\$filter","mail eq '$userEmail'")
.asJson()
if (result.getStatus().toString() =="200")
{
**if (result.getBody().value){ // <<<<< is Value is not empty ???
_userId=result.getBody().value[0].id
}**
else
_userId="-1" // user does not exist
}
// user ID not found : error 404
if (result.getStatus().toString()=="404")
_userId="User not found"
This code is returning in the result.getBody() the following output
{"#odata.context":"https://graph.microsoft.com/v1.0/$metadata#users","value":[]}
What I am trying to achieve is to test if the value array of the response is empty or not and if not empty I need to fetch the first element item as value[0].Id, but I could not get it correctly
How can I define my code in BOLD above to perform my correct test ?
Error I get from my code is : " Value is not a property of JsonNode object
Thanks for help
regards

from official doc http://kong.github.io/unirest-java/#responses
String result = Unirest.get("http://some.json.com")
.asJson()
.getBody()
.getObject()
.getJSONObject("car")
.getJSONArray("wheels")
.get(0)
so, something like this should work for you:
def a = result.getBody().getObject().getJSONArray("value")
if(a.length()>0) _userId = a.get(0).get("id")

Related

Groovy OkHttpBuilder with GET Method - getting groovy.json.JsonException

Hi I'm using Groovy HTTPBuilder to make a GET call with request body similar like this:
def obj = [:]
// add the data in map - obj
def http = OkHttpBuilder.configure {
request.uri = "URL"
request.uri.path = "/path"
request.headers.put("Authorization", "token value")
request.cookie("fingerprint", "fingerprint value")
request.accept ="application/json"
request.headers.put("Content-Type", "application/json;")
def jsonBody = JsonOutput.toJson(obj)
request.body = jsonBody
response.failure { FromServer fromServer, Object body ->
assertHttpFailure(fromServer, body)
}
}
http.get()
But, getting an groovy.json.JsonException with below details
Unable to determine the current character, it is not a string, number, array, or object
The current character read is 'R' with an int value of 82
Unable to determine the current character, it is not a string, number, array, or object
line number 1
index number 0
Required request body is missing: public org.springframework.http.ResponseEntity<java.util.List
Any suggestions ? why request body says missing

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'}
}
}

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

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"

How can i simplify checking if a value exist in Json doc

Here is my scenario, i am parsing via javascript a webpage and then post the result to an restApi to store the json in a db. The code works fine as long as all fields i defined in my script are send. Problem is over time they website might change names for fields and that would cause my code to crash.
Originally i used code like this
const mySchool = new mls.School();
mySchool.highSchoolDistrict = data["HIGH SCHOOL DISTRICT"].trim();
mySchool.elementary = data.ELEMENTARY.trim();
mySchool.elementaryOther = data["ELEMENTARY OTHER"].trim();
mySchool.middleJrHigh = data["MIDDLE/JR HIGH"].trim();
mySchool.middleJrHighOther = data["MIDDLE/JR HIGH OTHER"].trim();
mySchool.highSchool = data["HIGH SCHOOL"].trim();
mySchool.highSchoolOther = data["HIGH SCHOOL OTHER"].trim();
newListing.school = mySchool;
but when the element does not exist it complains about that it can not use trim of undefined. So to fix this i came up with this
if (data["PATIO/PORCH"]) {
newExterior.patioPorch = data["PATIO/PORCH"].trim();
}
this works but i am wondering if there is a more global approach then to go and check each field if it is defined ?
You could leverage a sort of helper function to check first if the item is undefined, and if not, return a trim()-ed version of the string.
var data = Array();
data["HIGH SCHOOL DISTRICT"] = " 123 ";
function trimString(inputStr) {
return (inputStr != undefined && typeof inputStr == "string") ? inputStr.trim() : undefined;
}
console.log(trimString(data["HIGH SCHOOL DISTRICT"]));
console.log(trimString(data["ELEMENTARY OTHER"]));

Mockito returning null value for Future

I am unit-testing a controller in a play-framework application.
The controller uses a repository and I am mocking the repository as follows
val mockUserRepository = mock(classOf[UsersRepository])
when(mockUserRepository.findOne(userKeys)).thenReturn(Future{Some(user)})
when(mockUserRepository.save(user)).thenReturn(Future(Some(user)))
Then I run the following test. In the test, controller.signupUser(request) calls the findOne method of the repository as follows
val findUserFuture: Future[Option[User]] = userRepo.findOne(userKeys)
println("user future is ",findUserFuture)
findUserFuture.flatMap { (userOption: Option[User]) => //this crashes because findUserFuture is null)
But findOne returns a null instead of a dummy Future{user}
"User signup request with body" should {
"return OK and user profile if the signup profile data is correct" in {
val jsonBody = Json.parse(
"""
{
"external-profile":{
"email":"test#test.com",
"firstname":"fn",
"lastname":"ln",
"password":"aA1!1111"
}
}
""")
//val jsonBody = Json.toJson(signupInfo)
val request: Request[AnyContentAsJson] = FakeRequest("POST", "ws/users/signup",Headers(("someH"->"someV")),new AnyContentAsJson(jsonBody))
println("sending sign up request ", request)
//request.body = signupInfo
val response: Future[Result] = controller.signupUser(request)
val responseBodyAsJsValue:JsValue = contentAsJson(response)
println("received response of sign up ", responseBodyAsJsValue)
}
}
error
received profile
UserProfile(None,ExternalUserProfile(test#test.com,fn,ln,Some(aA1!1111)))
checking if the user with the following details exists LoginInfo(credentials,test#test.com)
returning id 116 for name test#test.com
(user future is ,null)
java.lang.NullPointerException was thrown.
java.lang.NullPointerException
at controllers.UserController.$anonfun$signupUser$1(UserController.scala:116)
What I might be doing wrong?
The issue apparently was the I wasn't using when correctly.
I read that "
Mockito allows to configure the return values of its mocks via a fluent API. Unspecified method calls return "empty" values:
null for objects
0 for numbers
false for boolean
empty collections for collections
Mocks can return different values depending on arguments passed into a method. The when(…​.).thenReturn(…​.) method chain is used to specify a a return value for a method call with pre-defined parameters.
"
when expects the method as well as the exact arguments. So if I want to call findUser(userkey) where userkey's value is say 1 in the actual call then I need to write when(findUser(1)) or userKey=1; findUser(userKey)).
In my wrong implementation, I had set userkey as
UserKeys(1,"test#test.com",loginInfo,"","")
but the call to findUser was with value
UserKeys(116,"d#d.com",loginInfo,"fn","ln")
I changed the userkey value in test and it worked
val userKeys = UserKeys(utilities.bucketIDFromEmail(email)/*returns 116*/,"d#d.com",loginInfo,"fn","ln")
when(mockUserRepository.findOne(userKeys)).thenReturn(Future{Some(user)})
when(mockUserRepository.save(user)).thenReturn(Future(Some(user)))

Resources