Joi.attempt(config, Schema.schwifty) validation fails in Jest tests
kmenshov opened this issue · comments
I'm getting a Joi validation error on configuration object inside the internals.schwifty
when trying to create a server inside Jest tests. Everywhere else (including NODE_ENV=test npm start
) the server is being created just fine. The error disappears if I don't export any models.
Details and steps to reproduce:
// package.json
"scripts": {
"test:jest": "NODE_ENV=test jest",
}
In any Jest test file:
// example.test.js
const Glue = require('glue');
const Manifest = require('../server/config/manifest');
const createServer = Glue.compose(Manifest.get('/'));
test('some test', async () => {
const server = await createServer;
});
the command npm run test:jest -- example.test.js
fails with the following:
ValidationError: {
"knex": {
"debug": false,
"client": "pg",
"connection": {
"host": "127.0.0.1",
"user": "user",
"password": "password",
"database": "db_test"
}
},
"models": [
function Users() {\n _classCallCheck(this, Users);\n\n return _possibleConstructorReturn(this, _getPrototypeOf(Users).apply(this, arguments));\n } [2]
],
"migrationsDir": "/server/config/migrations",
"value" [1]: -- missing --
}
[1] "value" must be a Function
[2] "0" must be a class
at Object.<anonymous>.exports.process (node_modules/joi/lib/errors.js:203:19)
at Object.<anonymous>.internals.Alternatives._validateWithOptions (node_modules/joi/lib/types/any/index.js:764:31)
at Object.<anonymous>.module.exports.internals.Any.root.validate (node_modules/joi/lib/index.js:147:23)
at Object.<anonymous>.module.exports.internals.Any.root.attempt (node_modules/joi/lib/index.js:177:29)
at Object.<anonymous>.internals.schwifty (node_modules/schwifty/lib/index.js:190:18)
at Object.register (node_modules/schwifty/lib/index.js:79:19)
at Object.<anonymous>.internals.Server.register (node_modules/hapi/lib/server.js:453:35)
but if I transform the test file into a plain JS script:
// example.js
const Glue = require('glue');
const Manifest = require('../server/config/manifest');
const createServer = Glue.compose(Manifest.get('/'));
(async () => {
const server = await createServer;
console.log(server);
})();
and run it with NODE_ENV=test node example.js
everything works fine and I see the server object being printed to stdout without any errors.
The error also disappears if I export an empty array for models:
// /server/models/index.js
const Users = require('./Users');
module.exports = [
// Users,
];
I'm using Schwifty 4.2.0
Curious! Is jest configured to use any sort of transpilation (e.g. via babel)?
Ah, why didn't I think about it! Indeed it is:
// test/jest.setup.js
require('@babel/polyfill');
But without it I get the ReferenceError: regeneratorRuntime is not defined
in tests. :(
Yep, seems like it's mutually exclusive. I've tried to replace babel polyfill with regenerator-runtime:
// test/jest.setup.js
// require('@babel/polyfill');
require('regenerator-runtime/runtime');
and got the same Joi validation error as described in the first post.
Can maybe the Joi schema be made less restrictive?
// schwifty/lib/schema.js
// internals.model = Joi.func().class();
internals.model = Joi.func();
There's really no need to transpile classes away in nodejs, and I highly suggest testing the code you're going to run in production, which I hope is not transpiled for a variety of reasons. I think the fix here is to your project's test suite. Mostly likely the polyfill itself is not responsible for the transpilation of classes to functions—you likely have @babel/preset-env setup somewhere, and you can try to configure that to omit certain transformations, or to only transpile your client-side directories.
I was wrong, sorry for bothering you. :) For anyone facing the same problem: indeed, the solution is just to exclude the server (but not the client) code from being transpiled altogether:
// jest.config.js
transformIgnorePatterns: ['<rootDir>/server/', '<rootDir>/node_modules/'],
See details here: https://jestjs.io/docs/en/configuration#transformignorepatterns-array-string
Glad you got it sorted out!