I am trying to cover my API, protected by Auth0, with unit tests. Wrote the below:
'use strict';
const createJWKSMock = require('mock-jwks').default;
const startAuthServer = jwksServer => {
const jwks = createJWKSMock(jwksServer);
jwks.start();
return jwks;
};
const getToken = jwks => {
const token = jwks.token({
iss: `https://${process.env.AUTH0_DOMAIN}/`,
sub: 'testprovider|12345678',
aud: [
`${process.env.AUTH0_AUDIENCE}`,
`https://${process.env.AUTH0_DOMAIN}/userinfo`
],
iat: 1635891021,
exp: 1635977421,
azp: 'AndI...3oF',
scope: 'openid profile email'
});
return token;
};
const stopAuthServer = jwks => {
jwks.stop();
};
describe('/promoter/event/:id', () => {
let server, token, jwks;
beforeAll(() => {});
beforeEach(async () => {
jest.clearAllMocks();
jwks = startAuthServer(`https://${process.env.AUTH0_DOMAIN}`);
token = getToken(jwks);
server = require('../../../');
await server.ready();
});
afterEach(async () => {
stopAuthServer(jwks);
});
it('GET for a non-exising event returns 404', async () => {
const mockSelect = jest.fn();
mockSelect
.mockResolvedValueOnce({
rowCount: 1,
rows: [{ row_to_json: { id: 1 } }]
})
.mockResolvedValueOnce({
rowCount: 0,
rows: []
});
server.pg.query = mockSelect;
// const token = `eyJhb...u5WYA`;
const response = await server.inject({
method: 'GET',
url: '/promoter/event/25',
headers: { Authorization: `Bearer ${token}` }
});
expect(response.statusCode).toEqual(404);
});
});
If I run the code with a token I generate with getToken
the Auth0 plugin does not let the token pass, and I am getting 500
.
If I use/uncomment the token returned by Auth0
the tests pass. Hence, it is pretty clear that the problem is the token.
I decoded both tokens - those issued by Auth0
and those made by mock-jwks
and the only difference I noticed is the header in the tokens made by mock-jwks
is missing typ
property.
The ones made by Auth0
look like:
{
"alg": "RS256",
"typ": "JWT",
"kid": "Mk...OQ"
}
While those produced with mock-jwks
look like:
{
"alg": "RS256",
"kid": "Mk...OQ"
}
Internally, my server is using fastify-auth0-verify
to verify the tokens.
I have also tried mocking the auth server with nock
as below:
nock(`https://${process.env.AUTH0_DOMAIN}`)
.get('/.well-known/jwks.json')
.reply(200, nockReply);
It is not working either. The call never gets to it, and further, NodeJS prints a warning:
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
If I disable mock-jwks
, Jest
/tests exit just fine both with nock
and without nock
.
Suggestions?