I am trying to test a Nodejs application that uses express and passport.js.
So in my main app.js file I am requiring passportConfig file like this:
const passport = require('passport');
const passportConfig = require('./routes/passport.js');
// Configure global passport object
passportConfig(passport);
This is what my custom passport.js file looks like:
// load all the things we need
const LocalStrategy = require('passport-local').Strategy;
const sha = require('sha256');
const sql = require('mssql');
const fs = require('fs');
const path = require('path');
const connection = require('../middleware/database');
// expose this function to our app using module.exports
module.exports = async function (passport) {
const pool = await connection;
.......
.......
As you can see I am obtaining the passport object passed into this module from app.js and loading various strategies to it. Within this function I have:
passport.use('admin-login', new LocalStrategy(
{
// by default, local strategy uses username and password, we will override with email
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true, // allows us to pass back the entire request to the callback
},
((req, name, password, done) => { // callback with name and password from our form
async function verifyAdminAuth() {
Everything is working node and express wise. Express makes the global passport object and all of the strategies are available everywhere.
Now, my login route file login.js for admin login looks like this:
const passport = require('passport');
router.post('/login/admin', bouncer.block, passport.authenticate('admin-login', {
successRedirect: '/',
failureRedirect: '/failure',
}), (req, res) => {
});
As you can see above, I am loading passport.js straight from the node_modules library so it should not have the custom strategies I implemented. However, with the magic of express, since express caches the library it loads with all of the custom strategies that I have added event though was in the app.js file.
I can use my browser to send a post request with username and password params to /admin/login and everything works fine. But when doing the same thing from jest using supertest, it throws an error saying :
POST /login/admin 500 28.396 ms - 7976 console.log
{ status: 500, message: 'Unknown authentication strategy "admin-login"',
This is what my test file looks like:
const request = require('supertest');
const { app } = require('../app');
/* eslint-env jest */
// Info on Mocking: https://jestjs.io/docs/en/mock-functions.html
describe('POST /postNewBook', () => {
test('should return status 200 ', async () => {
const agent = request.agent(app);
// This route requires an authenticated user. So lets create an authenticated agent
// we will just piggyback off of it and make further requests.
const res = await agent.post('/login/admin').send({ username: 'Admin', password: 'MyAdminPassword' });
// Before moving on lets check if agent is authenticated
console.log(res.body);
expect(res.status).toEqual(200);
});
I am very new to both jest and supertest. My understanding was that supertest will load the Nodejs server exactly like just running the node server yourself using the command line. I have been able to do other simple get and post route testing with it with success. But there seems to something that I am missing when it comes to testing authenticated routes. Why does supertest not recognize that "admin-login" authentication strategy has been added already. Yes it is not in the same file as login.js but if it is running everything the same why is it failing here?
from message: 'Unknown authentication strategy "admin-login"' jest testing using supertest
No comments:
Post a Comment