worldturner / medeia-validator

Medeia JSON-Schema Validator
Other
56 stars 11 forks source link

OneOf validation always succeeds #23

Open jwilmoth-nc opened 3 years ago

jwilmoth-nc commented 3 years ago

The use of oneOf in a schema results in schema validation never failing despite json docs not matching schema. Here's a simplified example:

Schema

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "OneOf Example",
  "type": "object",
  "properties": {
    "address": {
      "type": "string",
      "oneOf": [
        { "format": "email" },
        { "format": "hostname" }
      ]
    }
  },
  "additionalProperties": false
}

Junit 5 Test

The shouldDetectValidJsonWithOneOfEmail and shouldDetectValidJsonWithOneOfHost test pass, but the shouldDetectInvalidJson test doesn't fail.

class OneOfSchemaValidationTest {

  ObjectMapper objectMapper = new ObjectMapper();
  MedeiaJacksonApi api = new MedeiaJacksonApi();

  SchemaValidator SCHEMA_VALIDATOR = loadSchema();

  @Test
  void shouldDetectValidJsonWithOneOfEmail() throws IOException {
    String resource = "{ \"address\": \"test@test.com\" }";
    JsonParser unvalidatedParser = objectMapper.getFactory().createParser(resource);
    JsonParser validatedParser = api.decorateJsonParser(SCHEMA_VALIDATOR, unvalidatedParser);
    OneOfExample oneOfExample = objectMapper.readValue(validatedParser, OneOfExample.class);
    assertEquals("test@test.com", oneOfExample.getAddress());
  }

  @Test
  void shouldDetectValidJsonWithOneOfHost() throws IOException {
    String resource = "{ \"address\": \"127.0.0.1\" }";
    JsonParser unvalidatedParser = objectMapper.getFactory().createParser(resource);
    JsonParser validatedParser = api.decorateJsonParser(SCHEMA_VALIDATOR, unvalidatedParser);
    OneOfExample oneOfExample = objectMapper.readValue(validatedParser, OneOfExample.class);
    assertEquals("127.0.0.1", oneOfExample.getAddress());
  }

  @Test
  void shouldDetectInvalidJson() throws IOException {
    String resource = "{ \"address\": \"*******\" }";
    JsonParser unvalidatedParser = objectMapper.getFactory().createParser(resource);
    JsonParser validatedParser = api.decorateJsonParser(SCHEMA_VALIDATOR, unvalidatedParser);
    assertThrows(ValidationFailedException.class,
                 () -> objectMapper.readValue(validatedParser, OneOfExample.class));
  }

  private SchemaValidator loadSchema() {
    SchemaSource source = new UrlSchemaSource(
        getClass().getResource("/patient/SimpleOneOfExample.schema.json"));
    return api.loadSchema(source);
  }

}