Forum Discussion

sonya_m's avatar
sonya_m
SmartBear Alumni (Retired)
4 years ago
Solved

[TechCorner Challenge #2] A Dispatching script to get responses based on the values in Request Body

Hi Community!

 

You are already adding so much value to the ReadyAPI Community and all fellow ReadyAPI users are grateful for this! Here’s your chance to contribute more to our TechCorner tag - a collection of helpful ReadyAPI scripts, code samples, tips and other useful content.

 

Today, I’d like us to focus on ServiceV which is part of ReadyAPI that allows creating virtual services and mock to test things in a sandbox.

 

Quite often, QA testers need to be able to get certain responses based on parameters in the body. To parse data of an incoming request, you can use a dispatching script. Your task today is to create such a script.

Difficulty

 

The steps to follow to complete the task:

  1. Create a REST virtual service from the Petstore Swagger specification (https://petstore.swagger.io/v2/swagger.json)

  2. Add two responses - ‘OK’ and ‘Bad Request’ for the "POST /v2/pet" operation (VirtAction). 

  3. Add a dispatching script for the "POST /v2/pet" operation (VirtAction). 

The dispatching conditions:

  • If "name" property contains more than 3 characters and the "status" value is one of {available, pending or sold}

     return the "OK" response (HTTP status code is 200, body is "{"result": "OK"}" or "<result>OK</result>" depending on the media type of the request)

  • Otherwise, return the "Bad Request" response (HTTP status code is 400, body is "{"error": "Invalid Request"}" or "<error>Invalid Request</error>" depending on the media type of the request).

A sample request:

JSON

XML

{
"id" : 0,
"category" : {
"id" : 0,
"name" : "string"
},
"name" : "doggie",
"photoUrls" : [ "string" ],
"tags" : [ {
"id" : 0,
"name" : "string"
} ],
"status" : "available"
}

<Pet>
<id>0</id>
<Category>
<id>0</id>
<name>string</name>
</Category>
<name>doggie</name>
<photoUrl>
<photoUrls>string</photoUrls>
</photoUrl>
<tag>
<Tag>
<id>0</id>
<name>string</name>
</Tag>
</tag>
<status>available</status>
</Pet>

 

Good luck!

  • Task: Quite often, QA testers need to be able to get certain responses based on parameters in the body. To parse data of an incoming request, you can use a dispatching script. Your task today is to create such a script.

     

    This is a solution created for [TechCorner Challenge #2]

     

    Here is the Script dispatch for the given conditions.

     

    Also note that if user provides Media Type other than "application/xml" or "application/json", will send a different error response..

     

    User will receive the response either xml or json based on the request header "accept", will send a different error response otherwise.

     

    Used response names in predefined naming convention as shown in the picture which will simplify the code.

     

    Code for Script Dispatch below. Please follow the in-line comments

     

     

     

    //Constants
    def APPLICATION_XML = 'application/xml'
    def APPLICATION_JSON = 'application/json'
    def ACCEPT = 'Accept'
    def CONTENT_TYPE = 'Content-Type'
    
    //Closure to validate request content type and accept type
    def isValidDocType = { it in [APPLICATION_XML, APPLICATION_JSON]}
    
    //Closure to validate the input status in the request
    def isValidStatus = { it in ['available', 'pending', 'sold'] }
    
    //Map for the response document to send as response; prefix will be identified at run time down the line
    def responseSuffixMap = [200: 'Response_200', 400: 'Response_BadRequest']
    
    //Closure to find xml request and decide whether 200 or 400 status to send in response
    def getXmlResultCode = {	
    	def xml = new XmlSlurper().parseText(it)
    	xml?.name?.text().size() > 3 && isValidStatus(xml?.status?.text()) ? 200 : 400
    }
    
    //Closure to find json request and decide whether 200 or 400 status to send in response
    def getJsonResultCode = {
    	def json = new groovy.json.JsonSlurper().parseText(it)
    	json?.name?.size() > 3 && isValidStatus(json?.status) ? 200 : 400
    }
    
    //Method to read the request headers
    def getHeaderValue(key) { 
    	mockRequest.requestHeaders.get(key).first() 
    }
    
    //Handle invalid documents using headers
    if (!isValidDocType(getHeaderValue(CONTENT_TYPE))) {
    	return "UnknownContentType"
    }
    if (!isValidDocType(getHeaderValue(ACCEPT))) {
    	return "UnknownAccept"
    }
    
    //Identify the response prefix based on the user request
    def responsePrefix = getHeaderValue(ACCEPT).split('/')[1]
    
    //Actual logic
    def resultCode = 400
    switch (getHeaderValue(CONTENT_TYPE)) {
    	case APPLICATION_XML:
    		resultCode = getXmlResultCode(mockRequest.getRequestContent())
    		break;
    	case APPLICATION_JSON:
    		resultCode = getJsonResultCode(mockRequest.getRequestContent())
    		break;
    	default:
    		break;
    }
    
    return responsePrefix + responseSuffixMap[resultCode]

     

     

     

     

    NOTE: Have created a sample project for the same in SoapUI Free edition 5.4.0.

    If you are interested, you can have a look at

    https://github.com/nmrao/sample-soapui-projects/tree/master/scriptDispatch

     

     

     

2 Replies

  • nmrao's avatar
    nmrao
    Champion Level 3

    Task: Quite often, QA testers need to be able to get certain responses based on parameters in the body. To parse data of an incoming request, you can use a dispatching script. Your task today is to create such a script.

     

    This is a solution created for [TechCorner Challenge #2]

     

    Here is the Script dispatch for the given conditions.

     

    Also note that if user provides Media Type other than "application/xml" or "application/json", will send a different error response..

     

    User will receive the response either xml or json based on the request header "accept", will send a different error response otherwise.

     

    Used response names in predefined naming convention as shown in the picture which will simplify the code.

     

    Code for Script Dispatch below. Please follow the in-line comments

     

     

     

    //Constants
    def APPLICATION_XML = 'application/xml'
    def APPLICATION_JSON = 'application/json'
    def ACCEPT = 'Accept'
    def CONTENT_TYPE = 'Content-Type'
    
    //Closure to validate request content type and accept type
    def isValidDocType = { it in [APPLICATION_XML, APPLICATION_JSON]}
    
    //Closure to validate the input status in the request
    def isValidStatus = { it in ['available', 'pending', 'sold'] }
    
    //Map for the response document to send as response; prefix will be identified at run time down the line
    def responseSuffixMap = [200: 'Response_200', 400: 'Response_BadRequest']
    
    //Closure to find xml request and decide whether 200 or 400 status to send in response
    def getXmlResultCode = {	
    	def xml = new XmlSlurper().parseText(it)
    	xml?.name?.text().size() > 3 && isValidStatus(xml?.status?.text()) ? 200 : 400
    }
    
    //Closure to find json request and decide whether 200 or 400 status to send in response
    def getJsonResultCode = {
    	def json = new groovy.json.JsonSlurper().parseText(it)
    	json?.name?.size() > 3 && isValidStatus(json?.status) ? 200 : 400
    }
    
    //Method to read the request headers
    def getHeaderValue(key) { 
    	mockRequest.requestHeaders.get(key).first() 
    }
    
    //Handle invalid documents using headers
    if (!isValidDocType(getHeaderValue(CONTENT_TYPE))) {
    	return "UnknownContentType"
    }
    if (!isValidDocType(getHeaderValue(ACCEPT))) {
    	return "UnknownAccept"
    }
    
    //Identify the response prefix based on the user request
    def responsePrefix = getHeaderValue(ACCEPT).split('/')[1]
    
    //Actual logic
    def resultCode = 400
    switch (getHeaderValue(CONTENT_TYPE)) {
    	case APPLICATION_XML:
    		resultCode = getXmlResultCode(mockRequest.getRequestContent())
    		break;
    	case APPLICATION_JSON:
    		resultCode = getJsonResultCode(mockRequest.getRequestContent())
    		break;
    	default:
    		break;
    }
    
    return responsePrefix + responseSuffixMap[resultCode]

     

     

     

     

    NOTE: Have created a sample project for the same in SoapUI Free edition 5.4.0.

    If you are interested, you can have a look at

    https://github.com/nmrao/sample-soapui-projects/tree/master/scriptDispatch

     

     

     

    • sonya_m's avatar
      sonya_m
      SmartBear Alumni (Retired)

      nmrao thank you for providing this great script. Works perfectly 👍