| // 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) |
| } |
| } |
| } |