Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit testing validators #55

Closed
juliancoleman opened this issue Nov 15, 2017 · 8 comments
Closed

Unit testing validators #55

juliancoleman opened this issue Nov 15, 2017 · 8 comments
Labels

Comments

@juliancoleman
Copy link

  • node version - 8.9.0
  • celebrate version - ^7.0.1
  • joi version (via npm ls --depth=0 | grep joi) -^13.0.2

Am I to be using Joi.validate(), or does Celebrate expose its own custom validator?

@juliancoleman juliancoleman changed the title How should I go about writing my unit tests? Unit testing validators Nov 15, 2017
@giltho
Copy link
Contributor

giltho commented Nov 15, 2017

Celebrate exposes his own version of joi
So basically

{ Joi } = require('celebrate');
Joi.validate(objectToValidate);

I am not entirely sure it answers to your question though

@juliancoleman
Copy link
Author

Great. Thanks for the quick reply! That's all I needed to know.

@juliancoleman
Copy link
Author

juliancoleman commented Nov 20, 2017

Perhaps that wasn't the solution. I'll outline my code below. What I'm trying to do is accomplish the same result as Joi.validate(payload, validator);

// validator.js
const { celebrate, Joi } = require('celebrate');

const Validator = celebrate({
  params : Joi.object().keys({
    eventKey : Joi.string().required(),
  }).unknown(false),
});

module.exports = Validator;
// validator_test.js
const { Joi } = require('celebrate');
const R = require('ramda');

const Validator = require('./validator');
const helpers = require('./helpers');

const validPayload = {
  params : {
    eventKey : 'testKey',
  },
};

describe('DeleteEventsValidator', () => {
  it(' does not allow unknown keys', () => {
    const payload = helpers.mergeObjectWithValidPayload(R.lensProp('params'), { unknownKey : 'hello' }, validPayload);
    const result = Joi.validate(payload, Validator);
    const { error } = result;

    expect(error).to.not.be.null;
    expect(R.prop('details', error)).to.have.length(1);

    expect(error.message).to.eql('"unknownKey" is not allowed');
  });
});

helpers.mergeObjectWithValidPayload is just a deep object merge. It will merge { unknownKey : 'hello' } into validPayload.params.

Anyway, this throws the following error:

1) DeleteEventsValidator does not allow unknown keys:
   TypeError: Cannot read property 'params' of null

@giltho
Copy link
Contributor

giltho commented Nov 20, 2017

Hum, something is unclear with what you are doing
Celebrate is a middleware that should be used to validate inputs such as query/body/headers.
I don't see why you need to use Celebrate here, isn't Joi enough ?

celebrate(...)doesn't create a validator, it creates a middleware (a function that takes req, res and next)

Also, i don't know what tries to read the params property of your object but it might not be celebrate, I think the error comes from your call of helpers.mergeObjectWithValidPayload
(Although it does not change your question since it would have failed anyway because of your usage of celebrate

I realize this is not very clear, but you might want to try something more like :

const Validator = Joi.object.keys( {
  params : Joi.object().keys( {
    eventKey : Joi.string().required(),
  } ).unknown( false ),
} );

And then use Joi.validate as you do

@juliancoleman
Copy link
Author

juliancoleman commented Nov 20, 2017

I have no excuse for not figuring that out sooner. I apologize for the miscommunication. I thought Celebrate was a wrapper around Joi. Now I know! Thanks a bunch for another quick response. I've gotten my test passing now. I can continue with my work.

And then when I want to use the Celebrate middleware, will it just be...

router.delete('/events/:eventKey', Celebrate(Validator), (req, res) => {
  // ...
});

@giltho
Copy link
Contributor

giltho commented Nov 20, 2017

It sould be :)
Although depending on your version it might be celebrate(Validator) instead of Celebrate(Validator)
(I think there's a mistake in the readme on that point)

@giltho
Copy link
Contributor

giltho commented Nov 20, 2017

Wait that is not true, if you actually want to use Celebrate, the actual code would be :

const Validator =  {
  params : Joi.object().keys( {
    eventKey : Joi.string().required(),
  } ).unknown( false ),
} ;

router.delete('/events/:eventKey', celebrate(validator), (req, res) => {
   // ...
});

celebrate takes an object with properties params, headers etc. (at least one of them), and each of these property should be a Joi schema.

@juliancoleman
Copy link
Author

That is correct, yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants