diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 84ba660c9..5d67df530 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -6,8 +6,9 @@ from jsonschema.tests.compat import mock, unittest from jsonschema.validators import ( RefResolutionError, UnknownType, Draft3Validator, - Draft4Validator, RefResolver, create, extend, validator_for, validate, + Draft4Validator, RefResolver, create, extend, validator_for, validate ) +from jsonschema.compat import unquote class TestCreateAndExtend(unittest.TestCase): @@ -771,6 +772,20 @@ class TestRefResolver(unittest.TestCase): stored_uri = "foo://stored" stored_schema = {"stored" : "schema"} + def prev_resolve_fragment(self, document, fragment): + fragment = fragment.lstrip(u"/") + parts = unquote(fragment).split(u"/") if fragment else [] + + for part in parts: + try: + document = document[part] + except (TypeError, LookupError): + raise RefResolutionError( + "Unresolvable JSON pointer: %r" % fragment + ) + + return document + def setUp(self): self.referrer = {} self.store = {self.stored_uri : self.stored_schema} @@ -898,6 +913,63 @@ def test_helpful_error_message_on_failed_pop_scope(self): resolver.pop_scope() self.assertIn("Failed to pop the scope", str(exc.exception)) + def test_prev_resolve_fragment_raises_exception(self): + schema = { + "definitions": { + "Pet": { + "properties": { + "category": { + "type": "array", + "items": { + "$ref": "#/definitions/Category" + } + } + } + }, + "Category": { + "properties": { + "name": { + "type": "string" + }, + } + } + } + } + resolver = RefResolver.from_schema(schema) + resolver.resolve_fragment = mock.MagicMock( + side_effect=self.prev_resolve_fragment) + self.assertRaises(RefResolutionError, + resolver.resolve_fragment, + schema, + "#/definitions/Category") + + def test_resolve_fragment(self): + schema = { + "definitions": { + "Pet": { + "properties": { + "category": { + "type": "array", + "items": { + "$ref": "#/definitions/Category" + } + } + } + }, + "Category": { + "properties": { + "name": { + "type": "string" + }, + } + } + } + } + resolver = RefResolver.from_schema(schema) + self.assertEqual(resolver.resolve_fragment + (schema, "#/definitions/Category"), + schema['definitions']['Category']) + class UniqueTupleItemsMixin(object): """ diff --git a/jsonschema/validators.py b/jsonschema/validators.py index 0945949c9..b8f22ec88 100644 --- a/jsonschema/validators.py +++ b/jsonschema/validators.py @@ -14,9 +14,8 @@ Sequence, urljoin, urlsplit, urldefrag, unquote, urlopen, str_types, int_types, iteritems, lru_cache, ) -from jsonschema.exceptions import ErrorTree # Backwards compatibility # noqa from jsonschema.exceptions import RefResolutionError, SchemaError, UnknownType - +from jsonschema.exceptions import ErrorTree # Backwards compatibility # noqa _unset = _utils.Unset() @@ -356,7 +355,7 @@ def resolve_fragment(self, document, fragment): """ - fragment = fragment.lstrip(u"/") + fragment = fragment.lstrip(u"#").lstrip(u"/") parts = unquote(fragment).split(u"/") if fragment else [] for part in parts: