tdegrunt / jsonschema

JSON Schema validation
Other
1.83k stars 263 forks source link

false positive on enum validation #327

Closed ahtokca closed 4 years ago

ahtokca commented 4 years ago

First of all thanks for very convenient module to validate the schema.

I found a false positive when validating enums. I made a jest test for you.

test('test_enum', async () => {
  const schema = {
    type: 'object',
    properties: {
      payload: {
        type: 'object',
        properties: {
          claim: {
            status: {
              type: 'string',
              enum: ['accepted', 'declined'],
            },
            required: ['status'],
          },
        },
        required: ['claim'],
      },
    },
    required: ['payload'],
  };

  const transaction = {
    payload: {
      claim: {
        status: 'break',
      },
    },
  };
  await expect(validate(transaction, schema).errors)
    .toMatchObject([{ message: 'is not one of enum values: accepted,declined' }]);
});

I use node 14.0.0. and 1.4.0 of jsonschema and I expect the test to pass by having validate to produce an error

ahtokca commented 4 years ago

another case of false positive I found is 'string vs object'

test('string vs object', async () => {
  const schema = {
    type: 'object',
    properties: {
      payload: {
        type: 'object',
        properties: {
          claim: {
            status: {
              type: 'string',
            },
            required: ['status'],
          },
        },
        required: ['claim'],
      },
    },
    required: ['payload'],
  };
  const transaction = {
    payload: {
      claim: {
        status: {},
      },
    },
  };
  await expect(validate(transaction, schema).errors)
    .toMatchObject([{ message: 'is not of a type(s) string' }]);
});
awwright commented 4 years ago

Hi @ahtokca, thanks for providing a code sample.

Try this first: https://github.com/tdegrunt/jsonschema#fail-on-unknown-keywords

Take a closer look at this part of the code:

        properties: {
          claim: {
            status: {
              type: 'string',
            },
            required: ['status'],
          },
        },

The "properties" keyword expects an object of schemas. You are defining a "claim" property, but the schema it defines uses an unknown keyword, "status". This unknown keyword is ignored. You probably want to use a "properties" keyword here, with "status" as a property within it.

ahtokca commented 4 years ago

Thanks for quick reply. BTW I figured out. My schema is invalid. it should be

const schemaEnum = {
  type: 'object',
  properties: {
    payload: {
      type: 'object',
      properties: {
        claim: {
          type: 'object',
          properties: {
            status: {
              type: 'string',
              enum: ['accepted', 'declined'],
            },
            required: ['status'],
          },
        },
      },
      required: ['claim'],
    },
  },
  required: ['payload'],
};

issue can be closed