How to test req.query using supertest node.js? - javascript

I have this code on supertest framework for tests:
it('GET normal pending transfer with receiverId', (done) => {
supertest(app)
.get('/transfers/pending')
.set('Accept', 'application/json')
.expect(200)
.query({
senderId: clientSenderId,
})
.expect('Content-Type', 'application/json; charset=utf-8')
.then((res) => {
console.log('res.body', res.body);
done();
})
.catch(done);
});
This endpoint - /transfers/pending takes query this way:
const { receiverId, senderId } = req.query;
As you can see, this is req.query and I want to send this query in my test's code.
I was trying to use this:
.get('/transfers/pending?senderId=${clientSenderId}')
And this:
.query({
senderId: clientSenderId,
})
And nothing of this isn't working. I mean, I got 500 and, the most important, I get an error in message, that belongs to other endpoint. It looks like my code triggers other endpoint, not that /transfers/pending.
My question is, how can I send queries in tests. With params and bodies everything works just fine, but not with queries.

Related

getting error 405 'Method not Allowed' When trying to send request to my node server

Its my first time using Express and MongoDB, i have created my Node server and connected it to my mongoDB database, but when i try to send an request from my html page to the server i get Error 405 method not allowed, following is my node.js server code
mongoose.connect('mongodb://localhost/userdatabase' ,{
useNewUrlParser: true,
useUnifiedTopology: true
})
const app = express()
app.use('/', express.static(path.join(__dirname, 'static')))
app.use(bodyParser.json())
const port = 5500
app.listen(port, () => {
console.log(`server is up at ${port}`)
})
app.post('/api/register', async(req, res) => {
const {username, password} = req.body
res.json({status: 'ok'})
try{
const response = await User.create({
username,
password
})
console.log('User created succesfully' , response)
}catch(error){
console.log(error)
}
})
and here is the function im trying to call to do the post request
const form = document.querySelector('#register')
form.addEventListener('submit', registerUser)
async function registerUser(event){
event.preventDefault()
const username = document.getElementById('username').value
const password = document.getElementById('password').value
const result = await fetch('/api/register', {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}, body: JSON.stringify({
username,
password
})
}).then(res => res.json())
}
basically i am creating an login system and try to register users, but for some reason i keep getting the error 405 when trying to call the Server, Note that for some reason it worked 3 times when i was trying earlier, I havent changed almost anything in the code but it just wont work, what it can be ? thanks in advance
You should tell in which port mongoDB would run.
const mongoose = require('mongoose');
main().catch(err => console.log(err));
async function main() {
await mongoose.connect('mongodb://localhost:27017/test');
}
I think you have to declare the server and port while calling the axios. The axios call should be - await fetch('localhost:5500/api/register'). It's searching for '/api/register' but didn't find anything. Hope this will solve your issue.
Issue solved : the html file wasn't in the folder 'static' 😅 probably i have moved it and didn't noticed, sorry for the question guys, if anyone have the same problem make sure to check it

How do I make a live search result in node.js and mongoDb

I am trying to implement a feature where I have an input on this route to make a live search of employees in the database
app.get('/delete' , isLoggedIn , (req , res) => {
res.render('pages/delete')
})
This route serves the search input. How do I create a live search based on a keyup event listener that sends the data to mongoDb/mongoose to search and return the results on the page?
I know how to do the event listener to get what is typed like so which is in the delete.js file
const deleteSearchInput = document.querySelector('#search-input');
deleteSearchInput.addEventListener('keyup' , (e) => {
let search = e.target.value.trim()
})
How do I send the value "e" to a post route to do the search and return it to the page
AJAX (using the JavaScript fetch API). AJAX allows JavaScript to send requests to the server without reloading.
const deleteSearchInput = document.querySelector('#search-input');
deleteSearchInput.addEventListener('keyup' , (e) => {
let search = e.target.value.trim();
fetch('/delete', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({search})
}).then(res =>
res.json()
).then(data => {
console.log(data.result); // <-- success!
}).catch(err => {
alert('error!');
console.error(err);
});
});
Then you have changes to make to the server side. Since you're sending a POST request, you need to create a handler to POST:
app.post('/delete', isLoggedIn, (req, res) => {
res.send('success!');
});
This will handle post requests, and only post requests. Now to get the value of whatever you sent to the server, we need to use an npm package called body-parser, which parses the incoming request. Run the following command in shell:
npm i body-parser
Then at the top of your server file before declaring your routes import and use the body-parser library:
const bodyParser = require('body-parser');
app.use(bodyParser.json()); // <-- add the JSON parser
Finally change your handler again:
app.post('/delete', isLoggedIn, (req, res) => {
const { search } = req.body;
console.log(search);
// ... do whatever you want and send a response, e.g.:
const result = 'my awesome message';
res.json({ result });
});
And that's how you do it.

How to send Headers ('Authorization','Bearer token') in Mocha Test cases

I am writing a test case to test my API . When I try to test for any open API, it is working fine. But When I try to send Authorization Token along with my API, it is not working. Here is the code:
The way i am sending headers is:
.set("Authorization", "Bearer " + token)
Is it the correct way of sending?
I have tried to send the Authorization token in Auth. But not able to get the same. But when I tried to consume same in Postman, it is working fine.
it("Get some random Info", function(done) {
chai
.request(baseUrl)
.get("/someRandomApi")
.set("Authorization", "Bearer " + token)
.end(function(err, res) {
expect(res).to.have.status(200);
done();
});
});
I like to set up my tests in the following way:
let baseUrl = 'http://localhost:9090'
let token = 'some_authorization_token'
First I would instantiate my variables baseUrl and token at the very top of the test, right after use() part.
Next to come is the setup of the test.
it("Get some random Info", function(done) {
chai.request(baseUrl)
.get('/someRandomApi')
.set({ "Authorization": `Bearer ${token}` })
.then((res) => {
expect(res).to.have.status(200)
const body = res.body
// console.log(body) - not really needed, but I include them as a comment
done();
}).catch((err) => done(err))
});
Now, .set() doesn't necessarily have to be like mine, works in your case as well.
You can use the auth function to set the Authorization header.
it("Get some random Info", function(done) {
chai
.request(baseUrl)
.get("/someRandomApi")
.auth(token, { type: 'bearer' })
.end(function(err, res) {
expect(res).to.have.status(200);
done();
});
});
chai-http has auth function to send the Authorization Bearer token.
Accroding to chai-http code on Github, token can be pass using:
.auth(accessToken, { type: 'bearer' })
The code would be like:
it("Get some random Info", function(done) {
chai.request(baseUrl)
.get('/someRandomApi')
.set(token,{ type: 'bearer' }) //token is actual token data
.then((res) => {
expect(res).to.have.status(200)
done();
}).catch((err) => done(err))
});
Try calling .get() after you call .set():
it("Get some random Info", function(done) {
chai
.request(baseUrl)
.set("Authorization", "Bearer " + token) //set the header first
.get("/someRandomApi") //then get the data
.end(function(err, res) {
expect(res).to.have.status(200);
done();
});
});

React Native Fetch Requests are not getting sent to my Node Js backend for some users

I've built a react native app that has a Node js backend. Users can sign In, sign up and view a profile page.
All my users can sign In but some of them can't view the profile page.
When I look at the request made to my backend, I get:
POST /UserRouter/SignIn 200 212.537 ms - 130342
Signing in works, it finds the user, returns the JWT token. When it's in the app no other requests are made. I get JSON Parse error: Unexpected EOF
Once you sign in, its supposed to immediately make a request to get your profile. With some accounts, this doesn't happen
My initial hypothesis of this problem is that the token for some users has expired, so they are not able to access protected routes. I use p***assport-jwt*** for my tokens. Hence, the backend not registering any requests.
Please find my code below:
_fetchData = () => {
AsyncStorage.getItem('jwt', (err, token) => {
fetch(`${backendUri }/UserRouter/Profile`, {
method: 'GET',
headers: {
Accept: 'application/json',
Authorization: token
}
})
.then((response) => response.json())
.then((json) => {
this.setState({name:json.name})
})
.catch((error) => {
console.log(error)
alert('There was an error ')
})
.done()
})
}
Here is my node JS code
app.get('/UserRouter/profile', passport.authenticate('jwt1', { session: false }), function (req, res) {
const token = req.headers.authorization
const decoded = jwt.decode(token.substring(4), config.secret)
User.findOne({
_id: decoded._id
},
function (err, user) {
if (err) throw err
res.json({ email: user.email, name: user.fName})
})
})
Thank you
This was the answer: https://stackoverflow.com/a/33617414/6542299
Turns out I was encoding my token with the users' document. the users' document was too large. so I just needed to reduce it

Strongloop Loopback remote hooks not triggered with supertest?

We are testing our loopback API code using spec.js files like this:
Require libs:
var app = rewire('../..');
var request = require('supertest');
var assert = require('chai').assert;
json helper method to standardize headers and content type:
function json(verb, url) {
return request(app)[verb](url)
.set('Content-Type', 'application/json')
.set('Accept', 'application/json')
.expect('Content-Type', /json/);
}
A test of a custom remote method that requires auth:
describe("Order remote methods", function() {
var accessTokenId, userId;
// authenticate before each test and save token
before(function(done) {
json('post', '/api/People/login')
.send({ email: 'user#email.com', password: 'password' })
.expect(200)
.end(function(err, res) {
accessTokenId = res.body.id;
userId = res.body.userId;
assert(res.body.id);
assert(res.body.userId);
done();
});
});
it("should fetch user orders", function(done) {
json('get', '/api/Orders/specialOrders')
.set('Authorization', accessTokenId)
.send({id: userId})
.expect(200)
.end(function(err, res) {
var orders = res.body.orders;
assert(Array.isArray(orders), "Orders should be an array");
// more asserts for explicit data values
done();
});
});
});
/api/Orders/specialOrders is a custom remote method that does a custom query on the Order model, which works as expected. But when I add a beforeRemote hook for this model, it does not get triggered by running the test. Is this expected or is my test setup not complete?
Remote hook:
Order.beforeRemote('specialOrders', function(ctx, unused, next) {
console.log('[userOrders]');
console.log('ctx req token: ', ctx.req.accessToken.userId);
console.log('ctx args: ', ctx.req.params.id);
// prevent remote method from being called
// even without a next(), remote is executed!
next(new Error('testing error'));
});
Running the same custom method via the Explorer UI, the beforeRemote hook is triggered as expected, and reports the custom error (or hangs when the next() is not present).
Is it possible to get supertest to trigger remote hooks in tests like this or am I missing some app setup in the spec file?

Categories