Setting Basic Auth in Mocha and SuperTest - javascript

I'm trying to set us a test to verify the username and password of a path blocked by the basic auth of a username and password.
it('should receive a status code of 200 with login', function(done) {
request(url)
.get("/staging")
.expect(200)
.set('Authorization', 'Basic username:password')
.end(function(err, res) {
if (err) {
throw err;
}
done();
});
});

Using the auth method
SuperTest is based on SuperAgent which provides the auth method to facilitate Basic Authentication:
it('should receive a status code of 200 with login', function(done) {
request(url)
.get('/staging')
.auth('the-username', 'the-password')
.expect(200, done);
});
Source: http://visionmedia.github.io/superagent/#basic-authentication
PS: You can pass done straight to any of the .expect() calls

The username:password part must be base64 encoded
You can use something like
.set("Authorization", "basic " + new Buffer("username:password").toString("base64"))

Related

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

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.

express, mocha testing always returns 404

My express POST route is:
app.post("/addPost", function(req, res) {
let newComment = { post: req.body.createP, comment: req.body.createC };
myDB.push(newComment);
res.render("index.ejs", { posts: myDB });
});
And my mocha test
describe("POST /", function() {
it("it ", function(done) {
supertest(myApp.app)
.post("/")
.expect(200)
.end(function(err, res) {
if (err) return done(err);
done();
});
});
});
Manually, the POST route works fine, but the mocha test always returns 404 instead of 200. Also, the mocha test for GET routes does work. Any ideas whats causing this?
Plus, how would one test html form data being sent via a POST request. Thanks in advance!

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();
});
});

Sending a POST request with chai sends an empty body?

I have the following setup right now
test.js
var user = {
username: 'test_user',
email: 'test#test.me',
password: 'you shall not pass',
address: 'No where street'
};
chai.request(app)
.post('/api/v1/users')
.send(user);
I'm handling the post request in my routes/user.js
router.post('/', function(req, res, next) {
console.log('body: ' + req.body);
queries.insertUser(req.body)
.then(function(id) {
return queries.getSingleUser(id);
})
.then(function(user) {
res.status(200).json(user);
})
.catch(function(err) {
next(err);
});
});
req.body ends up being undefined. Any clue as to what might be going wrong?
The code is live at https://ide.c9.io/burtonium/node-from-scratch if anybody wants to have a look.
req.body being undefined is generally caused by either not using the body-parser middleware in Express, or declaring it incorrectly (for instance, after the route that wants to access req.body).
Assuming that Chai sends JSON, add this to your Express app:
app.use(require('body-parser').json());
(before you declare the routers)

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