Protractor : How to Call Rest API POST with header and body - protractor

I have setup steps before running my e2e test in which I have to create users before I execute my test. I am using Protractor's Request API to make REST API POST calls but I'm not sure how can I pass data (body) and headers in the request. My request should look like this:
URL : 'rest/users', Headers : {'Content-Type' : 'application/json'}, body: {"userName": "user1", "domain": "1", "password": "password1", "userID": "1"}
I am trying to do something like this:
var request = require('request');
function createuser(url){
console.log("complete url = ", browser.baseUrl+url);
request({
method: 'POST',
uri: browser.baseUrl+url,
multipart: [
{'Content-Type': 'application/json'},
{body: {
'userName': 'test3',
'tenantKey': '0',
'password': 'Test3',
'userID': '3'}
}
],
function(error, response, body) {
if (error) {
return console.error('User Creation failed:', error);
}
console.log('User Creation successful! Server responded with:', body);
}
})
};
createuser('rest/1.0/dev/users');
It's throwing the following error (I'm not sure what am I doing wrong):
Error: Body attribute missing in multipart.
Stack:
Error: Body attribute missing in multipart.
at C:\code\ui\dgui\node_modules\request\lib\multipart.js:35:36
at Array.forEach (native)
at Multipart.isChunked (C:\code\ui\dgui\node_modules\request\lib\multipart.js:33:11)
at Multipart.onRequest (C:\code\ui\dgui\node_modules\request\lib\multipart.js:104:22)
at Request.multipart (C:\code\ui\dgui\node_modules\request\request.js:1176:19)
at Request.init (C:\code\ui\dgui\node_modules\request\request.js:424:10)
at new Request (C:\code\ui\dgui\node_modules\request\request.js:142:8)
at request (C:\code\ui\dgui\node_modules\request\index.js:55:10)
at createuser (C:\code\ui\dgui\tests\e2e\TestSuites\_BVT\_CreateNewUsers2.js:36:2)
at Suite.<anonymous> (C:\code\ui\dgui\tests\e2e\TestSuites\_BVT\_CreateNewUsers2.js:49:3)

I am able to achieve this using 'superagent', this is how I am using:
CallRestAPI:
var request = require( "superagent" );
var PostUrl = browser.baseUrl + 'rest/1.0/dev/users';
exports.CreateUsers = function(body){
console.log("Executing CreateUsers");
var data = '{' +body + '}';
console.log("Send data in post request = ", data);
request.post( PostUrl ).set('Content-Type', 'application/json').send(data).end(function(err,res){
if(err){
console.log("CreateUsers post error= ", err )
} else{
console.log("CreateUsers post response = ", res.status)
}
});
};
Using this Function as:
var Common = require('../.././helpers/CallRestAPI');
Common.CreateUsers('"userName": "test1", "tenantKey": "0", "password": "Test1", "userID": "1"');

Have managed it in my code with request validation when eg. access token is wrong or app do not respond. Imo it's better approach because your proposition always passes test what can give false positive.
exports.authorize = function (login, pass) {
var action = function () {
return getToken().then(function (token) {
var dfd = protractor.promise.defer();
req.post(getBackendUrl() + '/authorize/authenticate')
.set('Content-Type', 'application/json').set('RequestId', uuid.v4()).set('Authorization', token)
.send({"login": login, "pass": pass})
.end(function (err, res) {
if (err) {
dfd.reject(res)
} else {
dfd.fulfill(res.body);
}
});
return dfd.promise;
})
};
return browser.controlFlow().execute(action);
};
Endpoint authorize returns 200 status code for both - valid and not valid credentials so in specific test it can be distincted by simple jasmine expect like:
var Initialize = require('..initialize');
var successResponse = {status: 'success'};
expect(Initialize.authorize('some_login', 'some_password')).toEqual(successResponse);

var request = require('request');
var options = {
method: 'POST',
url: 'https://sbx-office-api.b2bcloud.com/rmi/v1/books/list?type=fetchall',
headers: {
'Accept': 'application/json, text/plain, */*',
'Authorization': 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IlFrTTFRemt6UlVJNE5UazNSVVJGTUVVNU5rTXlNVVpFT0RJek5EQTNPRFkyTVVaRVFrVXdSZyJ9.eyJodHRwczovL21hcnZlbC5zaGFycC5jb20vdGVuYW50aWQiOiJkNTA4Yjc3NC01NjBlLTRlNTktYTk3Yy1mODQxYjhmYjVkN2QiLCJodHRwczovL21hcnZlbC5zaGFycC5jb20vY29ubmVjdGlvbiI6InNoYXJwc29mdHdhcmVkZXYtd2FhZCIsImh0dHBzOi8vbWFydmVsLnNoYXJwLmNvbS9lbWFpbCI6InJhbWVzaHRAU2hhcnBzb2Z0d2FyZWRldi5vbm1pY3Jvc29mdC5jb20iLCJodHRwczovL21hcnZlbC5zaGFycC5jb20vbmFtZSI6IlJhbWVzaCBUIiwiaHR0cHM6Ly9tYXJ2ZWwuc2hhcnAuY29tL3JvbGUiOiJCQSB1c2VyIiwiaXNzIjoiaHR0cHM6Ly9zYnguYXV0aDAuY29tLyIsInN1YiI6IndhYWR8VGVFbVNzNGpnRGpXeTRVX0ItWlo4SDRobFZielVUdzM4djNmb2MzNXVzWSIsImF1ZCI6WyJodHRwczovL3NieC5hdXRoMC5jb20vYXBpL3YyLyIsImh0dHBzOi8vc2J4LmF1dGgwLmNvbS91c2VyaW5mbyJdLCJpYXQiOjE1NjY5NzY4MzIsImV4cCI6MTU2Njk4NDAzMiwiYXpwIjoiQW1zeU9UbHI3akg5eFU5azZlem15ODJNZDV4NDUyZFIiLCJzY29wZSI6Im9wZW5pZCBwcm9maWxlIn0.D5MoBVJ2lWZ7b3FCZtMQkmdMxJot8SCR1-Oso-wponPtF2y6kLxKK5dUftI_yzydvaJsZ9mwjVvZIAHESlrwkjVizYGXTFchjasT81hMZtJgt6iW8sA7Nu5qx7MVsc2z7UAS0mGhV2a_NEvZaYQ1A0dC19wG2A6bNJIMNEy46oJXlUe8nxb1ezkh4CkO3jUnVIPBo4rney_uwcXj-wc5hiE3a6m7jeHphyy70zDBFD_YRiizZaXzI-LTPGvhuRb7UtfcZuOomQqOuH6xebaoe3OzX9aA7CfWCHIJDhjQJwC-5BR5HQ9k7FCae3L4pWfmUVUOTZEFViJtxazLxOjM_w',
'Content-Type':'application/json',
'Sec-Fetch-Mode': 'cors',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36'
},
body: '{ "headers":{"normalizedNames":{},"lazyUpdate":null}}'
};
it('Should reach testsite', done => {
request(options, function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
done();
});
});

Related

Unable to receive mail sent via sendgrid

I'm creating a contact form using Nextjs and SendGrid, according to this header status
202
{
server: 'nginx',
date: 'Thu, 08 Dec 2022 16:29:25 GMT',
'content-length': '0',
connection: 'close',
'x-message-id': 'CaVdpVAURza6JrUF7yIQQA',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-
of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason':
'https://sendgrid.com/docs/Classroom/Basics/API/cors.html',
'strict-transport-security': 'max-age=600; includeSubDomains'
}
the email is sent but I find nothing in my inbox,
and this error occurs in the terminal
API resolved without sending a response for /api/contact, this may result in stalled requests.
I don't know what mistake I've done but. I invite you to look at my code bellow:
API :
import sgMail from "#sendgrid/mail";
export default function handler(req, res) {
if (req.method !== "POST") {
res.status(405).json({ message: "INVALID_METHOD" });
return;
}
// Variables from the client side
var name = req.body.name;
var email= req.body.email;
var subject= req.body.subject;
var content = req.body.content;
// auto line break message
const message = content
.replace(/\n/g, "<br>")
.replace(/\r/g, "<br>")
.replace(/\t/g, "<br>")
.replace(/<(?!br\s*\/?)[^>]+>/g, "");
// giving the api key API
sgMail.setApiKey(process.env.KEY_SENDGRID);
// Creating message
const sendGridMail = {
to: "arotiana4612#gmail.com",
from: "kaspersky2mahanaima#gmail.com",
subject: subject,
templateId: "d-b48909edf062437e8442f861a4c8be29",
dynamic_template_data: {
name: name,
email: email,
subject: subject,
content: message,
},
};
// SENDING MESSAGE VIA SENDGRID
(async () => {
try {
await sgMail.send(sendGridMail)
.then((response) => {
console.log(response[0].statusCode)
console.log(response[0].headers)
})
.catch((error) => {
console.error(error)
})
} catch (err){
console.error(err);
res.status(500).json({
error:JSON.stringify(err),
message: "ERROR_WITH_SENDGRID",
});
}
})();
}
And this is the method from the client side that from which I get the data:
const onSubmit: SubmitHandler<Inputs> = async (formData) => {
if (!isLoading) {
setIsLoading(true);
const response = await fetch("/api/contact", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(formData),
});
const result = await response.json();
setIsLoading(false);
if (!response.ok) {
console.log("error sending email:",result);
} else {
console.log("ok");
}
return result;
}
};
I want to receive the mail in my inbox. Your help would be very appreciated, I'm strugling

HTTP 400 on IBM Cloud (Cloud Foundry) with Node.js an Express

I have a simple app with two routes, which I use locally and on IBM Cloud/Cloud Foundry (512 M RAM)
/
returns "Hello World!" & 200 locally and on the IBM Cloud
/getData
returns some data locally & 200
on cloud it returns 400, no logs
Edit:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
var cors = require("cors"); // Cors
app.use(cors());
var port = process.env.PORT || 3000;
app.get('/', (req, res) => res.send('Hello World!'))
// *************** GETDATA ***************************************
app.get('/getData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "GET",
url: req.headers.route,
headers: httpHeaderOptions
};
// console.log("headers: " + JSON.stringify(req.headers));
// console.log("GET DOCS: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
console.log(typeof (body));
body_json = JSON.parse(body);
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body);
res.status(200).json(body_json);
}
});
});
// *************** POST DOC ***************************************
app.post('/postData', function (req, res) {
var request = require("request");
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
apikey: req.headers.apikey
};
var restoptions = {
method: "POST",
url: req.headers.route,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("headers: " + JSON.stringify(req.headers));
console.log("POST DOC: \n", JSON.stringify(restoptions));
request(restoptions, function (error, response, body) {
if (typeof (body) == 'object' && Object.keys(body).length === 0) {
// unknown error, empty resposne
res.status(400).json(body);
} else {
console.log("body: " + JSON.stringify(body));
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", JSON.stringify(body));
res.status(200).json(body);
}
}
});
});
// *********************
app.post('/watsonAssistant', function (req, res) {
var request = require("request");
var reqURL = "https://hackathon-jps.eu-de.mybluemix.net/watsonAssistant";
console.log("URL: \n", reqURL);
console.log("POST Body: \n", JSON.stringify(req.body));
var httpHeaderOptions = {
accept: "application/json",
"content-type": "application/json",
};
var restoptions = {
method: "POST",
url: reqURL,
headers: httpHeaderOptions,
body: req.body,
json: true
};
console.log("send request \n");
request(restoptions, function (error, response, body) {
console.log("in request \n");
if (error) {
console.error("Failed: %s", error.message);
body = {
"error": error.message
};
res.status(400).json(body);
} else {
console.log("Success: \n", body[0]);
res.status(200).json(body[0]);
}
});
});
// Start the server
app.listen(port, function () {
console.log('simple forward server is running')
});
link to the code
This will be because whatever req.headers.route is set to, is not visible to the app when it is running in the cloud. Your first check should be on error. Your second check should be if body is not null, and an object instead you immediately JSON.parse body, which may be throwing a parsing exception.

Angular 2 http post is returning 200 but no response is returned

My http call is returning 200 but no response is captured. My code inside subscribe is not being hit. The API is returning data when I test in postman. Here is my code.
getToken(authcode: string) {
var data = 'client_id=InspectWebApp_client&code=' + authcode + '&redirect_uri=http://localhost:3000&grant_type=authorization_code';
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
this.http.post('https://fedloginqa.test.com/as/token.oauth2', data, options)
.subscribe((res: Response) => {
var resultsToken = res.json();
localStorage.setItem("access_token",resultsToken.access_token)
//return this.inspections;
})
}
I was also facing the same problem. The problem was solved using the map function on Observables. Here is my implementation:
login(Username:string, Password:string) : Observable<Response>{
let headers = new Headers();
headers.append("Authorization", "Basic " + btoa(Username + ":" + Password));
headers.append("Content-Type", "application/x-www-form-urlencoded");
return this._http.post(this._baseUrl+"auth/login", " " , {headers: headers} )
.map((response: Response) => {
return response;
}).catch(this.handleError);
}
Here the handleError is a function to catch the excceptions generated. This is a function in login.service.ts that sends the username and password to the api to get data. You can see that I am returning response from the map function in this service. Now, this returned response can be caught in subscribe function in following way:
this._loginService.login(this.username, this.password)
.subscribe(
(response) => {
//Here you can map the response to a type.
this.apiResult = <IUser>response.json();
},
(err) => {
//Here you can catch the error
},
() => {this.router.navigate(['home'])}
);

How do I POST JSON in Angular 2?

I don't understand what I am doing wrong, my server returns "undefined" when I try to get the json.
POST(url, data) {
var headers = new Headers(), authtoken = localStorage.getItem('authtoken');
headers.append("Content-Type", 'application/json');
if (authtoken) {
headers.append("Authorization", 'Token ' + authtoken)
}
headers.append("Accept", 'application/json');
var requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: this.apiURL + url,
headers: headers,
body: data
})
return this.http.request(new Request(requestoptions))
.map((res: Response) => {
if (res) {
return { status: res.status, json: res.json() }
}
});
}
And my function:
login(username, password) {
this.POST('login/', {test: 'test'}).subscribe(data => {
console.log(data)
})
}
When I try this, the request body looks like this:
So instead of sending actual json, it just sends "[object Object]".
Instead of "Request payload" it should be "JSON". What am I doing wrong?
I have been looking for a visual answer to the question of posting json data in Angular for a while, to no avail. Now that I eventually have something working, let's share:
Inlined
Let's assume you expect a json response body of type T.
const options = {headers: {'Content-Type': 'application/json'}};
this.http.post<T>(url, JSON.stringify(data), options).subscribe(
(t: T) => console.info(JSON.stringify(t))
);
Official doc
Extendable class
import { HttpClient, HttpHeaders } from '#angular/common/http';
export class MyHttpService {
constructor(protected http: HttpClient) {}
headers = new HttpHeaders({
'Content-Type': 'application/json'
});
postJson<T>(url: string, data: any): Observable<T> {
return this.http.post<T>(
url,
JSON.stringify(data),
{headers: this.headers}
)
}
The gist
In the beginning I missed this sort of 'nested' way to pass in the content-type:
{headers:{'Content-Type': 'application/json'}}
You need to stringify the payload
var requestoptions = new RequestOptions({
method: RequestMethod.Post,
url: this.apiURL + url,
headers: headers,
body: JSON.stringify(data)
})
The header should be
'Content-Type': 'application/json'
and
body: data
should be
body: JSON.stringify(data);

Facebook authentication with nodejs

I'm trying to authenticate user in facebook:
var querystring = require('querystring');
var http = require('http');
var fs = require('fs');
getCookies(function(cookies){
logIn(cookies);
});
function logIn(cookies) {
var post_data = querystring.stringify({
'email': 'email#domain',
'pass': 'password'
});
var post_options = {
host: 'www.facebook.com',
port: '80',
path: '/login.php?login_attempt=1',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': post_data.length,
'user-agent': 'Mozilla/5.0',
'set-cookie': cookies[0]
}
};
var post_req = http.request(post_options, function(res) {
res.setEncoding('utf8');
console.log(res.statusCode);
var data = '';
res.on('data', function (chunk) {
data += chunk;
});
res.on('end', function () {
fs.writeFile("C:\\Users\\user\\Desktop\\fb.html", data, function(err) {
if(err) {
console.log(err);
} else {
console.log("The file was saved!");
}
});
});
});
post_req.write(post_data);
post_req.end();
}
function getCookies(callback){
var get_options = {
host: 'www.facebook.com',
port: '80',
path: '/',
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'user-agent': 'Mozilla/5.0'
}
};
var get_req = http.request(get_options, function(res) {
var cookies = res.headers['set-cookie'];
res.on('end', function (chunk) {
callback(cookies);
});
});
get_req.write('');
get_req.end();
}
But the response is that cookies in my browser are not enabled. Please don't suggest using existing libraries for connecting to facebook, I'm learning... Thanks for help in advance
Facebook uses OAuth authentication to authenticate an user. I have used oAuth module to get access to the Linkedin APIs at http://nabaruns.blogspot.in/2013/01/linkedin-api-call-using-nodejs-oauth.html. You can try the same and see if you can call graph facebook apis.
Hope this helps