Feathers: "Authentication strategy 'local' is not registered" when using supertest

Created on 6 Sep 2017  路  4Comments  路  Source: feathersjs/feathers

Steps to reproduce

Create a new feathers app with authentication using the CLI.

# use the default value for each prompt
feathers g app
feathers g authentication

Install supertest as a dev dependency.

npm i -D supertest

Add the following file at test/services/authentication.test.js:

const supertest = require('supertest');
const app = require('../../src/app');
const config = require('../../config/default.json');

const testUser = {
  email: '[email protected]',
  password: 'password1234',
};

describe('POST /authentication', () => {
  beforeEach(() => {
    // delete all users then create the test user
    return app.service('users').remove(null)
      .then(() => app.service('users').create(Object.assign({}, testUser)));
  });

  afterEach(() => {
    // delete all users
    return app.service('users').remove(null);
  });

  it.only('creates a valid JWT', () => {
    return supertest(app)
      .post('/authentication')
      .type('json')
      .send(Object.assign({strategy: 'local'}, testUser))
      .expect(201)
      .then(res => {
        return app.passport.verifyJWT(res.body.accessToken, {
          secret: config.authentication.secret,
        });
      });
  });
});

Run the test.

npm test

Expected behavior

The test should pass.

Actual behavior

The test fails with the following output:

  POST /authentication
info: after: users - Method: remove
info: after: users - Method: create
info: error: authentication - Method: create: Authentication strategy 'local' is not registered.
error:  BadRequest: Authentication strategy 'local' is not registered.
    at Error.BadRequest (D:\Users\Jordan\Desktop\feathers-test-test2\node_modules\feathers-errors\lib\index.js:93:17)
    at Object.<anonymous> (D:\Users\Jordan\Desktop\feathers-test-test2\node_modules\feathers-authentication\lib\hooks\authenticate.js:62:29)
    at process._tickCallback (internal/process/next_tick.js:109:7)
    1) creates a valid JWT
info: after: users - Method: remove


  0 passing (381ms)
  1 failing

  1) POST /authentication creates a valid JWT:
     Error: expected 201 "Created", got 400 "Bad Request"
      at Test._assertStatus (node_modules\supertest\lib\test.js:266:12)
      at Test._assertFunction (node_modules\supertest\lib\test.js:281:11)
      at Test.assert (node_modules\supertest\lib\test.js:171:18)
      at Server.assert (node_modules\supertest\lib\test.js:131:12)
      at emitCloseNT (net.js:1552:8)
      at _combinedTickCallback (internal/process/next_tick.js:77:11)
      at process._tickCallback (internal/process/next_tick.js:104:9)

System configuration

Module versions:

{
  "dependencies": {
    "body-parser": "^1.17.2",
    "compression": "^1.7.0",
    "cors": "^2.8.4",
    "feathers": "^2.2.0",
    "feathers-authentication": "^1.2.7",
    "feathers-authentication-hooks": "^0.1.4",
    "feathers-authentication-jwt": "^0.3.2",
    "feathers-authentication-local": "^0.4.4",
    "feathers-configuration": "^0.4.1",
    "feathers-errors": "^2.9.1",
    "feathers-hooks": "^2.0.2",
    "feathers-hooks-common": "^3.7.2",
    "feathers-nedb": "^2.7.0",
    "feathers-rest": "^1.8.0",
    "feathers-socketio": "^2.0.0",
    "helmet": "^3.8.1",
    "nedb": "^1.8.0",
    "serve-favicon": "^2.4.3",
    "winston": "^2.3.1"
  },
  "devDependencies": {
    "eslint": "^4.6.1",
    "mocha": "^3.5.0",
    "request": "^2.81.0",
    "request-promise": "^4.2.1",
    "supertest": "^3.0.0"
  }
}

NodeJS version: v6.11.2

Most helpful comment

If you don't call app.listen you have to call app.setup(server) manually. A lot of plugins (including authentication) are using the setup method to set themselves up after everything else (like middleware and services) have been registered.

All 4 comments

Maybe this issue belongs to feathers-authentication, but I believe this is a timing issue native to feathers as a whole. It seems that the app starts listening before it has fully initialized.

If you don't call app.listen you have to call app.setup(server) manually. A lot of plugins (including authentication) are using the setup method to set themselves up after everything else (like middleware and services) have been registered.

Thank you. That was the issue. I assumed that supertest calls app.listen, however it calls http.createServer(app).listen. Here's the workaround I've come up with:

const supertest = require('supertest');
const app = require('../../src/app');
const config = require('../../config/default.json');

const testUser = {
  email: '[email protected]',
  password: 'password1234',
};

describe('POST /authentication', () => {
  let server;

  beforeEach(done => {
    // start the app
    server = app.listen(0, done);
  });

  beforeEach(() => {
    // delete all users then create the test user
    return app.service('users').remove(null)
      .then(() => app.service('users').create(Object.assign({}, testUser)));
  });

  afterEach(() => {
    // delete all users
    return app.service('users').remove(null);
  });

  afterEach(done => {
    // stop the app
    server.close(done);
  });

  it('creates a valid JWT', () => {
    return supertest(server)
      .post('/authentication')
      .type('json')
      .send(Object.assign({strategy: 'local'}, testUser))
      .expect(201)
      .then(res => {
        return app.passport.verifyJWT(res.body.accessToken, {
          secret: config.authentication.secret,
        });
      });
  });
});

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue with a link to this issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rrubio picture rrubio  路  4Comments

NetOperatorWibby picture NetOperatorWibby  路  4Comments

Mattchewone picture Mattchewone  路  4Comments

huytran0605 picture huytran0605  路  3Comments

eric-burel picture eric-burel  路  3Comments