opis / json-schema

JSON Schema validator for PHP
https://opis.io/json-schema
Apache License 2.0
566 stars 57 forks source link

[Question] If-then-else and oneOf unexpected behaviour #101

Open Pipeze opened 2 years ago

Pipeze commented 2 years ago

Hi,

I'm having some trouble validating my schema with Opis 1.x. I guess I'm missing something from the way Opis works and I'm hopping you could maybe bring some light on my problem.

Consider the following object:

{
  "a": "one",
  "b": "a string"
}

Which I try to validate using the following schema:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "a": {
      "enum": [
        "one",
        "two"
      ],
      "type": "string"
    },
    "b": {
      "type": "string"
    }
  },
  "if": {
    "properties": {
      "a": {
        "const": "one"
      }
    },
    "required": [
      "a"
    ]
  },
  "then": {
    "required": [
      "b"
    ]
  },
  "else": {
    "not": {
      "required": [
        "b"
      ]
    }
  },
  "additionalProperties": false
}

Expected behaviour

If a is "one", then b is required, else b is forbidden, and additionnal properties are forbidden. I managed to validate the behaviour on this tool: https://www.jsonschemavalidator.net/ which I'm not sure if it respects the way Opis works.

Current behaviour

Opis does not throw any error on validation of the following:

{
  "a": "two",
  "b": "a string"
}

b should be forbidden.

Alternate schema tried

I also tried using "oneOf" this way:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "a": {
      "enum": [
        "one",
        "two"
      ],
      "type": "string"
    },
    "b": {
      "type": "string"
    }
  },
  "oneOf": [
    {
      "properties": {
        "a": {
          "const": "one"
        }
      },
      "required": [
        "a",
        "b"
      ]
    },
    {
      "properties": {
        "a": {
          "not": {
            "const": "one"
          }
        }
      },
      "required": [
        "a"
      ],
      "not": {
        "required": [
          "b"
        ]
      }
    }
  ],
  "additionalProperties": false
}

Which leads to the same result: works in the online validator but Opis would not throw any error.

I saw that: https://opis.io/json-schema/1.x/object.html#dependencies may not allow the expected behaviour because it would check "a" presence but not value. I couldn't find any example in the documentation that seems to allow the coverage of the expected behaviour.

Anyone would have any insight on this problem ?

Good day, P