I have an app that is using Express and Passport. I am using the Google OAuth2 Strategy with Passport. I have a few routes that require a login through this strategy.
I'm doing integration tests with Mocha and Chai currently, but I'm unsure how to bypass or work with the OAuth2 authentication that is required for some of my routes.
For instance, here is one of my tests:
it("should list a single item on /items/<id> GET", function(done) {
chai.request(server)
.get('/items/' + id)
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json;
res.body.should.be.a('object');
res.body.should.have.property('description');
done();
});
});
My route for /items/:id
router.get('/items/:id', auth.isLoggedIn, function(req, res) {
var item = getItem();
res.json(item);
});
/items/:id
requires a login. Is there a way to bypass the login for testing, or mock a user to that my integration testing will work?
I was able to test github OAuth/passport with mocha chai chai-http nock and nock-github-oauth
nock-github-oauth
stubs out the token urls
Also manually nocked the github user and email api calls with samples from the GitHub API docs
This is my auth_controller_spec.js
//During the test the env variable is set to test
process.env.NODE_ENV = 'test';
var chai = require('chai');
var chaiHttp = require('chai-http');
var should = chai.should();
var expect = chai.expect
var User = require.main.require('models/User');
// https://gist.github.com/branneman/8048520#7-the-wrapper
var app = require.main.require('app');
chai.use(chaiHttp);
function nockGitHubUserAPI(nock) {
/**
* Intercept `https://api.github.com:443/user` API Call.
*/
nock('https://api.github.com:443')
.filteringPath(/\/user.+/, '/user')
.get('/user')
.reply(200,
{
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false,
"name": "monalisa octocat",
"company": "GitHub",
"blog": "https://github.com/blog",
"location": "San Francisco",
"email": "[email protected]",
"hireable": false,
"bio": "There once was...",
"public_repos": 2,
"public_gists": 1,
"followers": 20,
"following": 0,
"created_at": "2008-01-14T04:33:35Z",
"updated_at": "2008-01-14T04:33:35Z"
}
);
/**
* Intercept `https://api.github.com:443/user/emails` API Call.
*/
nock('https://api.github.com:443')
.filteringPath(/\/user\/emails.+/, '/user/emails')
.get('/user/emails')
.reply(200,
[
{
"email": "[email protected]",
"verified": true,
"primary": true
}
]
);
}
describe('Auth Controller', (done) => {
var user, nock, github, mockToken, githubHost;
before((done) => {
nock = require('nock');
nock.enableNetConnect('127.0.0.1');
github = require('nock-github-oauth');
nockGitHubUserAPI(nock)
github.nock(done);
})
beforeEach((done) => { //Before each test we reset the database
User.query().del().then(() => {
var params = {name: 'bonzo', authtype: 'github', authid: '12345678'}
// Create a user so the db isn't empty
// May help us uncover odd bugs
new User(params).save()
.then((bonzo) => {
user = bonzo;
done();
})
})
});
after(function(done) {
nock.cleanAll();
done();
});
describe('github link', () => {
it('it should redirect to github.com login / approve page', (done) => {
chai.request(app)
.get('/auth/github')
.redirects(0)
.end((err, res) => {
expect(res.headers['location']).to.match(/^https:\/\/github.com\/login\/oauth\/authorize/);
done();
});
});
});
describe('github callback', () => {
it(' should poll github api for details, upsert the user and log them in', (done) => {
var agent = chai.request.agent(app)
agent.get('/auth/github/callback')
.query({code : '9835b716e83875665b21' })
.end((err, res) => {
// If successful layout displays username on page in (brackets)
expect(res.text).to.match(/\(octocat\)/);
done();
});
});
});
describe('logout', () => {
it('it should end the session and show login', (done) => {
chai.request(app)
.get('/auth/logout')
.end((err, res) => {
expect(res.redirects[0]).to.match(/\/$/);
// If successful layout displays Login links
expect(res.text).to.match(/Login/);
done();
});
});
});
});
Full Source code here: https://github.com/stujo/node-express-gamebase
I figured out how to make this work by mocking isAuthenticated in the request object within my mocha test.
var chai = require('chai');
var chaiHttp = require('chaiHttp');
var server = require('../app');
var should = chai.should();
chai.use(chaiHttp);
// Allows the middleware to think we're already authenticated.
server.request.isAuthenticated = function() {
return true;
}
describe('Items', function() {
it('should list all items on / GET', function(done) {
chai.request(server)
.get('/')
.end(function(err, res) {
res.should.have.status(200);
res.should.be.json;
// more tests...
done();
});
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With