fluent-json-schema icon indicating copy to clipboard operation
fluent-json-schema copied to clipboard

additionalProperties schemas causing unexpected behavior when passed to oneOf

Open arquadrado opened this issue 3 years ago • 2 comments

Prerequisites

  • [X] I have written a descriptive issue title
  • [X] I have searched existing issues to ensure the bug has not already been reported

Fastify version

3.25.1

Plugin version

3.0.1

Node.js version

16

Operating system

Linux

Operating system version (i.e. 20.04, 11.3, 10)

20.04

Description

I have a patch endpoint which can receive one of two payload types. For each payload I defined a schema. Example:

const first = S.object()
    .prop('name', S.string().
    .prop('email', S.string().required()

const second = S.object()
    .prop('name', S.string().required().
    .prop('title', S.string().required()

For the endpoint validation schema I did:

const schema = { body: S.oneOf([first, second]) }

This was working properly but I noticed that I was receiving additional properties in the payload that were not being filtered out. For example:

{ name: 'John', email: '[email protected]', other: 'stuff i want out'}

So I was checking how I could do this and came across the additionalProperties() function. So I altered my schemas to be:

const first = S.object()
    .additionalProperties(false)
    .prop('name', S.string().
    .prop('email', S.string().required()

const second = S.object()
    .additionalProperties(false)
    .prop('name', S.string().required().
    .prop('title', S.string().required()

Now I have the most unexpected behavior. If I leave it like it was, the first payload gets stripped from everything except the name property. Example:

{ name: 'John', email: '[email protected]', other: 'stuff i want out'} => { name: 'John' }

When it should be

{ name: 'John', email: '[email protected]', other: 'stuff i want out'} => { name: 'John', email: '[email protected]' }

For the second payload I get 400 right away saying:

body should have required property 'email', body should have required property 'title', body should match exactly one schema in oneOf

I don't know what I am missing here but I have spent several hours around this trying to get through but with no success. I hope some here can help me.

Steps to Reproduce

Described above.

Expected Behavior

No response

arquadrado avatar May 19 '22 16:05 arquadrado

I'm not sure I got what you mean, but I feel it's more likely a wrong usage of the concatenation rather than a bug.

Are you sure of the second schema? It could be that rather than your version, you should have:

const second = S.object()
    .additionalProperties(false)
    .prop('name', S.string().required())
    .prop('title', S.string().required())

If you still feel it's an issue of fluent-json-schema try to print the schema and compare it to what it should look like. If the expected schema is different to the target one then it's an actual issue.

aboutlo avatar May 22 '22 21:05 aboutlo

@aboutlo I did that already and the schemas are what they are supposed to be.

arquadrado avatar May 23 '22 08:05 arquadrado

not related to fluent-json-schema

aboutlo avatar Aug 25 '22 13:08 aboutlo