frisby and read the response header with json response REST API - frisby.js

I am using frisby to automate the REST API testing. All of my REST API is based on json and return json response. In one of the requirement, I need to read the response header and fetch the response header and set it for next request. With json response, I am not able to read the response header. Following is sample code for my test.
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.afterJSON(function (response) {
//How to read session id from header
//var sessionId = res.headers[constants.SESSION_ID_HEADER_KEY];
var exist = response.exist;
expect(exist).toBe(true);
});
Please help.

You code was actually OK, you were just trying to use 'res' variable instead of response.
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.afterJSON(function (response) {
var sessionId = response.headers[constants.SESSION_ID_HEADER_KEY];
// Use the sessionId in other frisby.create(...) call
}).
toss();
Another alternative is to use after() as follows:
frisby.create("Check to make sure that user does exist")
.get(hostURL + "/api/users/checkusername/" + username, user, {json: true}, {headers: {'Content-Type': 'application/json'}})
.expectHeaderContains('content-type', 'application/json')
.after(function (err, res, body) {
var obj = JSON.parse(body);
var sessionId = obj.headers[constants.SESSION_ID_HEADER_KEY];
// Use the sessionId in other frisby.create(...) call
}).
toss();

Related

How to get a value from returned JSON in HTML?

My client side looks like this:
filename="random_filename.docx"
var response = await fetch("https://backend.wl.r.appspot.com/scriptstuff", {
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ file: filename })
});
var data = response.json();
console.log(data);
and my backend return looks like this
response = jsonify({'prediction': str(prob)})
response.headers['Access-Control-Allow-Origin'] = '*'
return response, 200
I receive a promise with the value of 'prediction', but I'm not sure how to access that or why the current code isn't working.
EDIT: adding await before response.json() works
You can execute a function upon a promise being fulfilled by appending a .then() to the fetch request. If you're already receiving the JSON object then the values can be accessed by data.some_key.
I'm not an expert but first store str(prob) into a variable and then create an object with it. I think jsonify() takes things very literally.

POSTing json to API with Angular 2/4

I am new to angular 4 and REST API development. I have developed a Login API in back-end and it works fine when I call it using Postman:
In the front-end application which is an Angular 4 project, I have created a service to call this login API. Here is the method I created in this service:
sendCredential(username: string, password: string) {
const url = 'http://localhost:8080/authenticate/user';
const body = '{"username": "' + username + '", "password": "' + password + '"}';
const headers = new Headers(
{
'Content-Type': 'application/json'
});
return this.http.post(url, body, {headers: headers});
}
My first question is:
Is this the correct way to pass the json object and call this API?
And I also created a component which calls the method in the service. Here is the method/event-handler I created in this component:
onSubmit(uname: string, pwd: string) {
this.loginService.sendCredential(uname, pwd).subscribe(
res => {
this.loggedIn = true;
localStorage.setItem('PortalAdminHasLoggedIn', 'true');
location.reload();
},
err => console.log(err)
);
}
My second question is:
How should I check whether a token is returned back or an error?
Question 1:
You do not need to stringify the body object when you do a http.post() in angular. Just use a normal object will do, and the Http class will help you parse it internally:
sendCredential(username: string, password: string) {
const url = 'http://localhost:8080/authenticate/user';
//do not need to stringify your body
const body = {
username, password
}
const headers = new Headers(
{
'Content-Type': 'application/json'
});
return this.http.post(url, body, {headers: headers});
}
Question 2:
As for your error, note that Angular also catch every http error. and by http error, it means that any status code that is <200 or >=300 will be an error. So only status codes that is in between 200 and 300 is considered successful. Upon an error received, angular will throw an Observable error, which you will need to handle explicitly (which you did it correctly):
onSubmit(uname: string, pwd: string) {
this.loginService.sendCredential(uname, pwd).subscribe(
res => {
//token should be in your res object
this.loggedIn = true;
localStorage.setItem('PortalAdminHasLoggedIn', 'true');
location.reload();
},
err => {
//handle your error here.
//there shouldn't be any token here
console.log(error);
}
);
}
With your above code, you should receive your token in your successful callback, and it will be in the res object. If there's an error, no token should be received and you should handle the error at the error callback.

I'm not using Express, but I'm trying extract POST data then to send a json as response, with no luck

I'm still very new to node.js so please bear with me.
I'm trying to extract POST data then sent a json as response, but I don't seem to be able to extract the data from the POST request and even worse I can't find the syntax for people who are NOT using Express to send the json. It keeps telling me res.json is not a function.
EDIT: I found out the problem for the json part, I was a dump. I finally remember what I was told, json are sent like strings.
var http = require('http');
var qs = require("querystring");
server = http.createServer(function (req, res) {
try {
var body = "";
var post = qs.parse("");
if (req.method == "POST") {
res.writeHeader(200, {"Content-Type": "application/json"});
req.on("data", function (data) {
body += data;
console.log(data); //It gives something like <Buffer xx xx xx ...>
if (body.length > 1e6)
req.connection.destroy();
});
req.on("end", function () {
post = qs.parse(body);
console.log(post.test); //It gives "undefined"
});
res.end(JSON.stringify({ a: 1 }));
} catch(err) {
console.dir(err);
res.writeHeader(200, {"Content-Type": "text/plain"});
res.end("Hi hi");
}
});
server.listen(8000);
console.log("http start #8000");
Any help? Thanks in advance.
below solves the date to string (i.e. converting buffer to string
res.on('data', function(chunk) {
var textChunk = chunk.toString('utf8');
// console.log(textChunk); // will give you a stream of text from data
});
you could store textChunk out of the ondata handler, to then use that if required (say returning relevant data to the user back again)

JSON object from HTTP response there but undefiend

In Node.js, I use request to post as such:
First I make the options
var ops = {
'user':'johnny',
'password':'password'
};
Then I make the request as such:
request.post({url: endpoint, formData: ops}, function(err, res, body){
console.log(res.body);
});
This then returns the data I want from an API:
{"user":"johnny","time":"2016-11-03T15:58:34.444Z"}
But then when I change the request to:
request.post({url: endpoint, formData: ops}, function(err, res, body){
console.log(res.body.user);
});
I get back "undefined".
Why can I access the res.body but not then then res.body.user when user is clearly an attribute of the object?
Thanks
Your response being a string, this will do the trick :
var data = JSON.parse(res.body);
console.log(data.user);

Is it possible to combine a GET and POST in Javascript?

I have javascript code that should login (ie send some information to the server) and then receive a reply JSON message. I know this is doable by first doing a post, and then in the asynchronous response, when it completes, do a get. This would require two callback functions and two messages.
I was just wondering whether there is any way to do a get and send JSON as part of the query, so that there is just a single request/response rather than two.
Here is a sample post I wrote:
function post(url, payload, callback) {
payload = JSON.stringify(payload);
var http = new XMLHttpRequest();
http.open("POST", location.pathname + url, true);
http.setRequestHeader("Content-type", "application/json");
http.onreadystatechange = function () {
if (http.readyState === 4 && http.status !== 200) {
callback(false, http.response);
} else if (http.readyState === 4 && http.status === 200) {
callback(true, http.response);
}
return;
};
http.send(payload);
}
If I want to get back JSON, what do I do?
Is it as simple as changing POST to GET and looking at:
http.responseText upon the return?
If you are doing any login functionality you should always use the HTTP POST method.
You could use AJAX (W3schools documentation about AJAX ) to handle sending your login form over POST and then handle the response in the same code block. bellow is an example.
$('#login-form').submit(function(e) {
e.preventDefault(); // Prevents the page from refreshing
// serializes the form data with id login-form
var formData = $(this).serialize();
$.ajax({
type: 'POST',
data: formData,
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
url: $(this).attr('action'),
//if your server sends a status OK message handle the response
//data will be the JSON response from the server
success: function(result,status,xhr) {
var jsonRes = JSON.parse(result); // parse the JSON object
console.log(jsonRes);
},
//if there was an error with your request the server will send
// an error response code and it is handled here
error: function(xhr,status,error) {
console.log(error);
}
});