Markus Török
Markus Török

Reputation: 1056

Hapi/Joi alternatives when is - testing for regex

I'm having the following joi schema:

const schema = Joi.object({
    name: Joi.string().required(),
    resource: Joi.object({
        uri: Joi.string(),
    }),
    fov: Joi.alternatives().when('resource.uri', {
        is: Joi.string().regex(/\.jpg$/),
        then: Joi.any().forbidden(),
        otherwise: Joi.number().required()
    })
});

I was expecting that when I would send the following request body

{
    name: 'name', 
    resource: {
         uri: 'file.jpg'
    }, 
    fov: 10
}

I would get an error, because the regex of the when.is condition will match 'file.jpg' and therefore fov will be validated as Joi.any().forbidden(). But the validation seems to be ignored. Do you have any ideas what I'm doing wrong?

Thanks for your help!

Upvotes: 2

Views: 3198

Answers (2)

Markus Török
Markus Török

Reputation: 1056

By posting the question I foung the answer:

My initial validation object looked like this:

resource: Joi.object({
    uri: Joi.alternatives().try(
        Joi.string(),
        Joi.array().max(config.objectTargets.maxImages).items(Joi.string())
    ),
    fov: Joi.alternatives().when('resource.uri', {
        is: Joi.string().regex(/\.wto$/),
        then: Joi.any().forbidden(),
        otherwise: Joi.number().required()
    }),
})

So it was looking for resource.uri inside the resource property. The solution is to have the when condition to be a reference to just uri, like here:

resource: Joi.object({
    uri: Joi.alternatives().try(
        Joi.string(),
        Joi.array().max(config.objectTargets.maxImages).items(Joi.string())
    ),
    fov: Joi.alternatives().when('uri', {
        is: Joi.string().regex(/\.wto$/),
        then: Joi.any().forbidden(),
        otherwise: Joi.number().required()
    }),
})

Sorry for not being more attentive before

Upvotes: 3

boehm_s
boehm_s

Reputation: 5544

Well, it seems that it is perfectly working, but the error is not thrown, it is included in the return value :

const Joi = require('joi');

const schema = Joi.object({
    name: Joi.string().required(),
    resource: Joi.object({
        uri: Joi.string(),
    }),
    fov: Joi.alternatives().when('resource.uri', {
        is: Joi.string().regex(/\.jpg$/),
        then: Joi.any().forbidden(),
        otherwise: Joi.number().required()
    })
});

const testVal = format => ({
    name: 'name',
    resource: {
         uri: format
    },
    fov: 10
});

const png = 'file.png';
const jpg = 'file.jpg';

const testPng = testVal(png);
const testJpg = testVal(jpg);

console.log(Joi.validate(testJpg, schema));
console.log("------------------------------");
console.log(Joi.validate(testPng, schema));

Gives this result :

{ error: 
   { ValidationError: child "fov" fails because ["fov" is not allowed]
    at Object.exports.process (/home/boehm-s/tmp/node_modules/joi/lib/errors.js:196:19)
    at internals.Object._validateWithOptions (/home/boehm-s/tmp/node_modules/joi/lib/types/any/index.js:675:31)
    at module.exports.internals.Any.root.validate (/home/boehm-s/tmp/node_modules/joi/lib/index.js:138:23)
    at Object.<anonymous> (/home/boehm-s/tmp/plop.js:29:17)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Function.Module.runMain (module.js:684:10)
     isJoi: true,
     name: 'ValidationError',
     details: [ [Object] ],
     _object: { name: 'name', resource: [Object], fov: 10 },
     annotate: [Function] },
  value: { name: 'name', resource: { uri: 'file.jpg' }, fov: 10 },
  then: [Function: then],
  catch: [Function: catch] }
------------------------------
{ error: null,
  value: { name: 'name', resource: { uri: 'file.png' }, fov: 10 },
  then: [Function: then],
  catch: [Function: catch] }

fov is not allowed because ressource.uri matches the regex that you provided.

Upvotes: 0

Related Questions