Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The schema location is not always computed correctly for ReferenceSchema #233

Closed
octavianN opened this issue Oct 24, 2018 · 2 comments
Closed

Comments

@octavianN
Copy link

Hello,

  1. I made a simple test that assets the schema location for a JSON Schema that has a reference to an external "definitions.json" schema.
    Please note that the schema location for the "city" schema is "#/properties/billing_address/properties/city". But this location does not exists.
    Maybe the location should be something like this: "#definitions.json/definitions/address/properties/city".
@Test
    public void testGetSchemaLocation() throws Exception {
      String definitions = "{\n" + 
          "  \"definitions\": {\n" + 
          "    \"address\": {\n" + 
          "      \"type\": \"object\",\n" + 
          "      \"properties\": {\n" + 
          "        \"city\":           { \"type\": \"string\" },\n" + 
          "        \"state\":          { \"type\": \"string\" }\n" + 
          "      }\n" +
          "    }\n" + 
          "  }\n" + 
          "}";
      
      Reader schema = new StringReader("{\n" + 
          "  \"properties\": {\n" + 
          "    \"billing_address\": { \"$ref\": \"definitions.json#/definitions/address\" }\n" + 
          "  }\n" + 
          "}");
      JSONObject schemaJson = new JSONObject(new JSONTokener(schema));
      
      SchemaClient httpClient = new SchemaClient() {
        @Override
        public InputStream get(String url) {
          if ("definitions.json".equals(url)) {
            return new ByteArrayInputStream(definitions.getBytes());
          }
          return null;
        }
      };
      ObjectSchema compiledSchema = (ObjectSchema) SchemaLoader.load(schemaJson, httpClient);
      
      assertEquals("#", compiledSchema.getSchemaLocation());
      
      ReferenceSchema billing_addresSchema = (ReferenceSchema) compiledSchema.getPropertySchemas().get("billing_address");
      assertEquals(null, billing_addresSchema.getSchemaLocation());
      ObjectSchema referredSchema = (ObjectSchema) billing_addresSchema.getReferredSchema();
      assertEquals("#/properties/billing_address", referredSchema.getSchemaLocation());
      
      Schema citySchema = referredSchema.getPropertySchemas().get("city");
      assertEquals("#/properties/billing_address/properties/city", citySchema.getSchemaLocation());
    }
@octavianN
Copy link
Author

Another problem is that if the referred definition is in the same file, the reference schema has the location null, and the referred schema has the location of the referred definition. See the test case below.
Maybe the reference schema should have the location "#/properties/billing_address".

@Test
   public void testGetSchemaLocation2() throws Exception {
     Reader schema = new StringReader("{\n" + 
         "    \"properties\": {\n" + 
         "        \"billing_address\": {\"$ref\": \"#/definitions/address\"}\n" + 
         "    },\n" + 
         "    \"definitions\": {\n" + 
         "        \"address\": {\n" + 
         "            \"type\": \"object\",\n" + 
         "            \"properties\": {\n" + 
         "                \"city\": {\"type\": \"string\"},\n" + 
         "                \"state\": {\"type\": \"string\"}\n" + 
         "            }\n" + 
         "        }\n" + 
         "    }\n" + 
         "}");
     JSONObject schemaJson = new JSONObject(new JSONTokener(schema));
     ObjectSchema compiledSchema = (ObjectSchema) SchemaLoader.load(schemaJson);
     
     assertEquals("#", compiledSchema.getSchemaLocation());
     
     ReferenceSchema billing_addresSchema = (ReferenceSchema) compiledSchema.getPropertySchemas().get("billing_address");
     assertEquals(null, billing_addresSchema.getSchemaLocation());
     ObjectSchema referredSchema = (ObjectSchema) billing_addresSchema.getReferredSchema();
     assertEquals("#/definitions/address", referredSchema.getSchemaLocation());
   }

@erosb erosb closed this as completed in afc26d5 Dec 27, 2018
erosb added a commit that referenced this issue Dec 27, 2018
erosb added a commit that referenced this issue Dec 27, 2018
 * wiring SchemaLocation into SchemaBuilder
 * adding `JSONPointer#getRefTokens()`
 * tracking the location in both `Schema#location` and `Schema#schemaLocation` (unfortunately the latter is protected so needs to be maintained)
 * adding `SchemaLocation#parseURI()` and using it in `ReferenceLookup`
@erosb
Copy link
Contributor

erosb commented Dec 27, 2018

Hello @octavianN , thank you for reporting it. It is now fixed on current master, and will be included in the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants