// Copyright 2018 johandorland ( https://github.com/johandorland ) // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package gojsonschema import ( "testing" "github.com/stretchr/testify/assert" ) func TestSchemaLoaderWithReferenceToAddedSchema(t *testing.T) { sl := NewSchemaLoader() err := sl.AddSchemas(NewStringLoader(`{ "$id" : "http://localhost:1234/test1.json", "type" : "integer" }`)) assert.Nil(t, err) schema, err := sl.Compile(NewReferenceLoader("http://localhost:1234/test1.json")) assert.Nil(t, err) result, err := schema.Validate(NewStringLoader(`"hello"`)) assert.Nil(t, err) if len(result.Errors()) != 1 || result.Errors()[0].Type() != "invalid_type" { t.Errorf("Expected invalid type erorr, instead got %v", result.Errors()) } } func TestCrossReference(t *testing.T) { schema1 := NewStringLoader(`{ "$ref" : "http://localhost:1234/test3.json", "definitions" : { "foo" : { "type" : "integer" } } }`) schema2 := NewStringLoader(`{ "$ref" : "http://localhost:1234/test2.json#/definitions/foo" }`) sl := NewSchemaLoader() err := sl.AddSchema("http://localhost:1234/test2.json", schema1) assert.Nil(t, err) err = sl.AddSchema("http://localhost:1234/test3.json", schema2) assert.Nil(t, err) schema, err := sl.Compile(NewStringLoader(`{"$ref" : "http://localhost:1234/test2.json"}`)) assert.Nil(t, err) result, err := schema.Validate(NewStringLoader(`"hello"`)) assert.Nil(t, err) if len(result.Errors()) != 1 || result.Errors()[0].Type() != "invalid_type" { t.Errorf("Expected invalid type erorr, instead got %v", result.Errors()) } } // Multiple schemas identifying under the same $id should throw an error func TestDoubleIDReference(t *testing.T) { sl := NewSchemaLoader() err := sl.AddSchema("http://localhost:1234/test4.json", NewStringLoader("{}")) assert.Nil(t, err) err = sl.AddSchemas(NewStringLoader(`{ "$id" : "http://localhost:1234/test4.json"}`)) assert.NotNil(t, err) } func TestCustomMetaSchema(t *testing.T) { loader := NewStringLoader(`{ "$id" : "http://localhost:1234/test5.json", "properties" : { "multipleOf" : false } }`) // Test a custom metaschema in which we disallow the use of the keyword "multipleOf" sl := NewSchemaLoader() sl.Validate = true err := sl.AddSchemas(loader) assert.Nil(t, err) _, err = sl.Compile(NewStringLoader(`{ "$id" : "http://localhost:1234/test6.json", "$schema" : "http://localhost:1234/test5.json", "type" : "string" }`)) assert.Nil(t, err) sl = NewSchemaLoader() sl.Validate = true err = sl.AddSchemas(loader) _, err = sl.Compile(NewStringLoader(`{ "$id" : "http://localhost:1234/test7.json", "$schema" : "http://localhost:1234/test5.json", "multipleOf" : 5 }`)) assert.NotNil(t, err) } func TestSchemaDetection(t *testing.T) { loader := NewStringLoader(`{ "$schema" : "http://json-schema.org/draft-04/schema#", "exclusiveMinimum" : 5 }`) // The schema should produce an error in draft-04 mode _, err := NewSchema(loader) assert.NotNil(t, err) // With schema detection disabled the schema should not produce an error in hybrid mode sl := NewSchemaLoader() sl.AutoDetect = false _, err = sl.Compile(loader) assert.Nil(t, err) } func TestDraftCrossReferencing(t *testing.T) { // Tests the following cross referencing with any combination // of autodetection and preset draft version. loader1 := NewStringLoader(`{ "$schema" : "http://json-schema.org/draft-04/schema#", "id" : "http://localhost:1234/file.json", "$id" : "http://localhost:1234/file.json", "exclusiveMinimum" : 5 }`) loader2 := NewStringLoader(`{ "$schema" : "http://json-schema.org/draft-07/schema#", "id" : "http://localhost:1234/main.json", "$id" : "http://localhost:1234/main.json", "$ref" : "file.json" }`) for _, b := range []bool{true, false} { for _, draft := range []Draft{Draft4, Draft6, Draft7} { sl := NewSchemaLoader() sl.Draft = draft sl.AutoDetect = b err := sl.AddSchemas(loader1) assert.Nil(t, err) _, err = sl.Compile(loader2) // It will always fail with autodetection on as "exclusiveMinimum" : 5 // is only valid since draft-06. With autodetection off it will pass if // draft-06 or newer is used assert.Equal(t, err == nil, !b && draft >= Draft6) } } }