how to take only JSON response from SOAPUI - web-services

I am working on project which is giving XML and JSON type of response. I need to take only JSON response from SOAPUI to process for next step.
Is there any SOAPUI api available to get only JSON type of response by groovy script.
Thanks in advance.

Please check this response SoapUI Groovy Script’s JSON Responses Is Empty When Using Testrunner
import groovy.json.JsonSlurper
//provide the correct rest test step name
def stepName='testStepForPing'
def step = context.testCase.getTestStepByName(stepName)
def response = new String(step.testRequest.messageExchange.response.responseContent)
log.info response
def json = new JsonSlurper().parseText(response)

Assuming it's a REST service, by default this approach will fetch the response in JSON format.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def response = groovyUtils.getXmlHolder("RequestStepName#Response")
// as a string -> def response = context.expand('${RequestStepName#Response}')
You can get it as xml using #ResponseAsXml.

In the SOAPUI Javascript context I developed this algorithm.
var xmlHolder = com.eviware.soapui.support.XmlHolder(messageExchange.responseContent);
var nodes = xmlHolder.getDomNodes("//SOAP-ENV:Envelope/SOAP-ENV:Body/ns:xxxxxx");
var obj = {};
toJsonObject(nodes[0], obj);
function toJsonObject(xmlObject, jsonObject) {
for (var i = 0; i < xmlObject.getLength(); i++) {
var node = xmlObject.item(i);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
if (node.getLength() == 1) {
if (node.hasChildNodes()) {
jsonObject[node.getNodeName()] = String(node.item(0).getNodeValue());
}
} else {
if (node.hasChildNodes()) {
jsonObject[node.getNodeName()] = {};
jsonObject[node.getNodeName()] = toJsonObject(node, jsonObject[node.getNodeName()]);
}
}
}
}
return jsonObject;
}
log.info(JSON.stringify(obj));
context.setProperty('JSON: ', JSON.stringify(obj));

Related

nswag generated service has no return logic

I have a asp.net WebAPI service for user login that takes an email and password. The api method has the following signature. LoginDto has two fileds, Email and password.
public async Task<IActionResult> Login(LoginDto dto)
Once the user is authenticated, WebAPI returns an object that has token and Id:
return Ok(new { Token = GenerateJwtTokenFromClaims(claims), Id=user.Id });
On the client side (Blazor app), I used nswag command line tool by running nswag run and it "successfully" generated the Service and Contract files. Everything complies. nswag generated code is pasted below.
When I want to use the login nswag Service, I have the following method (I also have an overloaded method with CancellationToken but I only use this method):
public System.Threading.Tasks.Task Login2Async(LoginDto body)
{
return Login2Async(body, System.Threading.CancellationToken.None);
}
The question that I have is that how do I get the response out of the nswag-generated-code that the WebAPI login sent back to the client? When I try to assign a var to the method, I get Cannot assign void to an implicitly-typed variable which makes sense since I don't see a return type. I also don't see any logic in the nswag generated service file to return the response to the caller. How do I get the response back from the nswag generated API call? Is there an option I have to set in nswag run to get a response object back? Thanks in advance.
public async System.Threading.Tasks.Task Login2Async(LoginDto body, System.Threading.CancellationToken cancellationToken)
{
var urlBuilder_ = new System.Text.StringBuilder();
urlBuilder_.Append(BaseUrl != null ? BaseUrl.TrimEnd('/') : "").Append("/api/Account/Login");
var client_ = _httpClient;
var disposeClient_ = false;
try
{
using (var request_ = new System.Net.Http.HttpRequestMessage())
{
var content_ = new System.Net.Http.StringContent(Newtonsoft.Json.JsonConvert.SerializeObject(body, _settings.Value));
content_.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");
request_.Content = content_;
request_.Method = new System.Net.Http.HttpMethod("POST");
PrepareRequest(client_, request_, urlBuilder_);
var url_ = urlBuilder_.ToString();
request_.RequestUri = new System.Uri(url_, System.UriKind.RelativeOrAbsolute);
PrepareRequest(client_, request_, url_);
var response_ = await client_.SendAsync(request_, System.Net.Http.HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
var disposeResponse_ = true;
try
{
var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value);
if (response_.Content != null && response_.Content.Headers != null)
{
foreach (var item_ in response_.Content.Headers)
headers_[item_.Key] = item_.Value;
}
ProcessResponse(client_, response_);
var status_ = (int)response_.StatusCode;
if (status_ == 200)
{
return;
}
else
if (status_ == 400)
{
var objectResponse_ = await ReadObjectResponseAsync<ProblemDetails>(response_, headers_).ConfigureAwait(false);
throw new ApiException<ProblemDetails>("Bad Request", status_, objectResponse_.Text, headers_, objectResponse_.Object, null);
}
else
{
var responseData_ = response_.Content == null ? null : await response_.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new ApiException("The HTTP status code of the response was not expected (" + status_ + ").", status_, responseData_, headers_, null);
}
}
finally
{
if (disposeResponse_)
response_.Dispose();
}
}
}
finally
{
if (disposeClient_)
client_.Dispose();
}
}
Big thanks to the NSwag team, the issue is resolved. I was returning anonymous object from the WebAPI method. The correct way to do is the following. Notice that IActionResult was changed to ActionResult passing a concrete object to return to the caller.
public async Task<ActionResult<LoginDtoResponse>> Login(LoginDto dto)
then returning
return Ok(new LoginDtoResponse { Token = GenerateJwtTokenFromClaims(claims), Id=user.Id });
After that I did that, the following code was generated:
if (status_ == 200)
{
var objectResponse_ = await ReadObjectResponseAsync<LoginDtoResponse>(response_, headers_).ConfigureAwait(false);
return objectResponse_.Object;
}

Why is flask jsonify returning unidentified?

I am using fetch on the frontend to send data to my flask backend in order to make a movie seat booking. The whole process works fine until the client awaits the response, which is "undefined" . So , basically the database saves the data , the only problem is the response which is sent to the client. I used jsonify which usually works fine. Can anybody tell me what I am missing? Thanks in advance.
Here is the JS code :
function sendReservationToServer() {
const selectedSeats = sessionStorage.getItem('selectedSeats')
const reservation = { userId, selectedSeats, showTimeId, movieHallId }
fetch('/bookSeats', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(reservation)
}).then(response => {
response.json()
}).then(data => {
theatreHall.innerHTML = `${data} <br> <a href='/home'>Back to main menu</a>`
console.log(`${data}`)
}).catch(err => infoMsg.textContent = err)
sessionStorage.clear()
}
And this is the flask controller which handles the request:
#app.route("/bookSeats", methods=["POST"])
def book_seats():
selected_seats = request.json
user_id = selected_seats.get('userId')
seats = json.loads(selected_seats.get('selectedSeats'))
movie_hall_id = selected_seats.get('movieHallId')
seat_ids = []
showtime_id = selected_seats.get('showTimeId')
for seat in seats:
seat_ids.append(db.session.query(Seat).filter(
Seat.seat_number == seat).filter(Seat.movie_hall_id == movie_hall_id).all()[0].stid)
for seat in seat_ids:
reserved_seat = ReservedSeat(
seat_id=seat, show_time=showtime_id, user=user_id)
db.session.add(reserved_seat)
db.session.commit()
reservation = Reservation(
user=user_id, show_time=showtime_id, number_of_tickets=len(seat_ids))
db.session.add(reservation)
db.session.commit()
message = f'{seats} booked successfully'
return jsonify(message)
data is undefined because the first then does not return anything. Either make it return response.json() or move everything in the second then to the first and replace data with response.json().

Flutter sending a post request to a Django API with a file as the body

I have a Django API where a user is able to upload a file through a post request with the following body:
{
"file": *attached file*
}
In Django, the file is gathered from the request with request.FILES['file']
The request has to be sent from flutter (dart) code. I have tried a few ways, this is the function from my latest attempt which shows an error - because the "file" is not in the correct format.
static void uploadProfilePhoto(File file, String fileId) async {
Uint8List fileBytes = file.readAsBytesSync();
var response = http.post(
globals.baseURL() + "/upload/",
//headers: {"Content-Type": "application/json"},
body: {
"file":base64Encode(fileBytes)
}
).then((v)=>print("v: "+v.body));
}
Any idea in what format the "file" should be sent from flutter? Else is there any other method which might work? Thank you in advance.
in flutter use
import 'dart:convert' as convert;
import 'dart:io';
import 'package:http/http.dart' as http;
#override
Future<Map<String, dynamic>> sendFiletodjango(
{File file,
}) async {
var endPoint = url;
Map data = {};
String base64file = base64Encode(file.readAsBytesSync());
String fileName = file.path.split("/").last;
data['name']=fileName;
data['file']= base64file;
try {
var response = await http.post(endPoint,headers: yourRequestHeaders, body:convert.json.encode(data));
} catch (e) {
throw (e.toString());
}
}
in python django use
from django.core.files.base import ContentFile
file = response.data.get("file")
name = response.data.get("name")
your_file = ContentFile(base64.b64decode(file),name)
model.fileField = your_file
model.save()
You can try multipart/form-data to upload files from Flutter to the Django server using HTTP post request.
From flutter, you can send multipart/form-data request in the below shown way.
Future<Response> uploadFile(File file) async {
Response response;
var uri = Uri.parse(url);
var request = http.MultipartRequest('POST', uri);
request.files.add(await http.MultipartFile.fromPath('file', file.path));
var response = await request.send();
if (response.statusCode == 200 || response.statusCode == 201) {
print('Uploaded!');
}
return response;
}
You can find more about it here Dart MultipartRequest.

How to create dict in the django?

I want to get an JSON response from the API and give a response with the selected field. I have fetched the response but I am not able to create a response with the new value. I am very new to python world and in learning stage.
def search(request):
if request.method == 'POST':
searchQry = request.POST.get("searchQry","")
nodeIP = settings.NODEIP
params = {'search':searchQry}
apiResponse = requests.get(url = nodeIP, params = params)
data = apiResponse.json()
newArray = {}
nodeName = 'RPID'
if nodeName == 'RPID':
for x in data:
newArray['cphNumber'] = x["data"]["cphNumber"]
newArray['farmName'] = x['data']['farmName']
newArray['addressLine1'] = x['data']['addressLine1']
return HttpResponse(json.dumps(newArray))
else:
return HttpResponse('Unauthrozed Access')
My response array looks likes this :
[{"data": {"cphNumber": "321","farmName": "313","addressLine1": "13","addressLine2": "13","region": "13", "postalCode": "13"},"id": "4c1b935664e6f684e89ee363f473ce3567599d4b9da0f5889565d5b6f0b84440"},{"data": {"cphNumber": "321","farmName": "313","addressLine1": "13","addressLine2": "13","region": "13","postalCode": "13"},"id": "7cbe7be9797896545410ed6c4dcc18064525037bc19fbe9272f9baabbb3216ec"},{"data": { "cphNumber": "321","farmName": "313","addressLine1": "13","addressLine2": "13","region": "13","postalCode": "13"},"id": "7df10c0b7b84434d5ace6811a1b2752a5e5bca13b691399ccac2a6ee79d17797"}]
In response I am getting only one array. I know I have to do something like newArray[0]['cphNumber'] But I am getting an error. Can you please help me to solve this .

How can I simulate server for Unit test in Grails (Spock)?

I have written this simple service for doing subrequest via HTTPBuilder, to get instance of class representing obtained page for further use:
package cmspage
import groovyx.net.http.HTTPBuilder
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.HTML
class CmsPageService {
static transactional = false
final String SUBREQUEST_HOST = "www.mydomainforsubrequest.com"
CmsPage getCmsPageInstance(Object request) {
String host = request.getServerName()
String url = request.getRequestURI()
HashMap queryMap = this.queryStringToMap(request.getQueryString())
return this.subRequest(host, url, queryMap)
}
CmsPage getCmsPageInstance(String host, String url, String queryString = null) {
HashMap queryMap = queryStringToMap(queryString)
return this.subRequest(host, url, queryMap)
}
private CmsPage subRequest(String host, String url, HashMap queryMap = null) {
CmsPage cmsPageInstance = new CmsPage()
HTTPBuilder http = new HTTPBuilder()
http.request("http://" + SUBREQUEST_HOST, GET, HTML) { req ->
uri.path = url
uri.query = queryMap
headers.'X-Original-Host' = 'www.mydomain.com'
response.success = { resp, html ->
cmsPageInstance.responseStatusCode = resp.status
if (resp.status < 400) {
cmsPageInstance.html = html
}
}
response.failure = { resp ->
cmsPageInstance.responseStatusCode = resp.status
return null
}
}
return cmsPageInstance
}
private HashMap queryStringToMap(String queryString) {
if (queryString) {
queryString = queryString.replace("?", "")
String[] splitToParameters = queryString.split("&")
HashMap queryMap = new HashMap()
splitToParameters.each {
String[] split = it.split("=")
for (int i = 0; i < split.length; i += 2) {
queryMap.put(split[i], split[i + 1])
}
}
return queryMap
} else return null
}
}
Now I need to write unit test for this service. I would like to use some simple html document to test it instead of testing some "live" site. But I do not know how?
Can anybody help me?
Jadler should suite you well. Check its documentation and this post on basic usage.