nodejs supertest express test prior to invoking external API - node.js

Not sure if this is possible but Id like to run a test without invoking an external API POST request.
Whats currently happening is ive got a test confirming the post data sent to my server API is processed correctly, as it needs to add some basic additional information to the BODY before sending it to the external API, and then the server makes another POST request to an external API with this modified BODY.
This is all done in the below function.
createUser(req,res){
...
// schema validation,
// adding fields
// external server post request
}
Is it possible to have my test ignore the external API call?
the test looks like
it('POST users --> 200 Successful Post', () => {
return request(app).post('/api/users').send(........ my json .......)
.expect('Content-Type', /json/)
.expect(200)
.then((response) => {
expect(response.body).toEqual(
......
)
})
});

You can use nock to intercept and mock requests for testings.
On your test, you can setup your mocking object like this:
const nock = require("nock");
const scope = nock("https://api.github.com")
.get("/repos/atom/atom/license")
.reply(200);
It will intercept an HTTPS GET requests to /repos/atom/atom/license.
How to Test Node.js Apps That Interact With External APIs

Related

Post a simple react form - node, axios, nodemailer, backend, postman

I've set up a react form running on http://localhost:3000/about and I've the backend running on port 5000 (localhost:5000). On react's package.json I set up "proxy":"localhost:5000:.
When I use postman and I send the post to localhost:5000/api/contact, the email is sent correctly (I send the data as JSON - name, email and message). Status 200
When I use the react form, the data is well prepared as json but I can't figure out the baseURL to send correctly the method post. status 404. I tried:
localhost:3000/about/api/contact;
localhost:3000/api/contact;
localhost:3000/api.... None works...
FYI
the server is set up with the following middleware and is working ok:
app.use('/api',contactRoute)
the controller is imported and coded as following:
router.post('/contact', (req, res)=>{
const data = req.body;
The React part is not posting correctly with axios and is coded as following:
onSubmit: async (values) => {
//values.preventDefault();
try {
const data = (JSON.stringify(values, null, 2))
setLoader(true);
console.log(data)
await axios.post('/contact', data);
The method post in react is never completed, when I check the console.log of data, is correctly structured as JSON...status 404
use the post parameter in your axois request {port: 5000} then It will use your actual backend port.
By default, axios uses the base path from the URL. So, here when an API request is made.
await axios.post('/contact', data);
It is actually making the post request on localhost:3000 rather than your backend server at localhost:5000. Also, "api" should also be prepended.
One simple way is to use absolute URL which should work.
await axios.post('http://localhost:5000/api/contact', data);

NodeJs Express how to handle items(params) that sent from frontend?

Im new in backend development (using NodeJs Express).
Its very basic question (I didn't find any good tutorial about it)
Question is:
I have this line of code:
app.get('/test', function (req ,res){
res.send('test');
});
What I wanna do is: BackEnd only sends res to FrontEnd, if FrontEnd send some JSON first.
Like Backend will show Something to FrontEnd, only if FrontEnd send JSON first;
How to handle it? What code to write?
Or what to type in google search to find this kind of tutorial
You are building a REST API with node. In REST we don't keep states. When we receive a request we process and respond. In the Front end, you can do wait until the response is received. use promises, async-await or callbacks to wait until the response in the Front end. Use these methods to connect with back end from front-end axios, fetch. To process the incoming JSON body use body-parser. Based on the request body you can process and send the response. PS: Every request should be given a response. That's how REST behaves.
In Query
yourbackend.com/test?message=welcomeToStackOverflow
This is how you can access with in query:
const {message} = req.query;
console.log(message);
// welcomeToStackOverflow
In Params
yourbackend.com/test/:message
This is how you can access with in params :
const {message} = req.params;
console.log(message);
// welcomeToStackOverflow
Here you have working example : https://codesandbox.io/s/trusting-rosalind-37brf?file=/routes/test.js

Making an http request using NodeJS and access the returned cookies

I am querying a remote API using NodeJS. I am currently using Axios to make the request, but I am willing to use another package if required.
Using NodeJS, I make a request to a remote API.
Axios.post("http://remote.api/getCookie")
.then(value => {
console.log(value);
});
The API returns a number of cookies (this can be seen in the spec, and when I test it in a browser). How can I access these cookies from the value returned by Axios.
Just get them from the Set-Cookie header:
Axios.post("http://<url>").then(response => {
const cookies = response.headers["set-cookie"];
// do whatever you want
}
You can then parse the header by yourself or use a library like cookie or set-cookie-parser

How to add facebook authentication to my react app?

I'm using express as backend. I implemented facebook authentication at the backend.
router.get('/login/facebook',
passport.authenticate('facebook',{scope:['email']}));
router.get('/login/facebook/callback',
passport.authenticate('facebook',{
successRedirect : '/home',
failureRedirect:'/'
})
);
Now I want to call this through my react app, so that when the user lands up at home page, first he should be authenticated by facebook then only he can see homepage. How can I do this ?
I tried using react-router, but I can't understand how to call backend using react-router.
I also fetched /login/facebook using fetch command :
componentDidMount(){
fetch("127.0.0.1:3001/login/facebook");
But it gave me CORS error.
My react app is at 127.0.0.1:3000 and express server at 127.0.0.1:3001.
If this issue is only in dev mode, then Daniel's answer is correct.
In any case, I recommend to avoid calling the :3001 api directly from the :3000 app. Here's what I would do.
I will edit the fetch call as follows,
componentDidMount(){
fetch("/login/facebook");
}
This call will be received by the backend which serves the react application.
Now there are three cases,
Case 1: Your file serving app will have a proxy method which can forward requests to an API. For example read it here
Case 2 This is my Recommended approach. I would simply write the authentication logic in the :3000 server and only use the :3001 API for handling business logic of the app.
Case 3: If you have a backend app (:3000), say written using expressJs, you can forward the request to the :3001 API. Here is a sample code for that,
client.send({
method: req.method,
path: req.url,
data: req.body,
params: req.params
}).then( (response) => {
// Something
}).catch( (err) => {
// Handle error
});
Here the client is a module which uses the request module to make HTTP calls.
You can implement the above call as an express middleware to use it for all HTTP calls.
There are several options:
If you are using webpack dev server, you can set up a proxy to your api. See here
You can temporary disable cors validation during development. See here

Nodejs- Trying to retrieve API request details using nodejs script

I am trying to fetch nodejs API request details like request header, response details, response time etc using nodejs script
request
.post('http://localhost:3000/api/pet')
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.end(function(err, res){
// Calling the end function will send the request
});
I have tried with the packages like node-monitor- https://github.com/shunanya/Node.js-monitoring but it returns request details of all requests and need to pass server details and options
I was trying to use native node js functions and modules to get request and response details of API request for any request made using express, hapi, request, http
Basically I am trying to trigger one notification script when any http API request occurs from node application

Resources