def test_decode_with_schema_raises_error(self): """ when using a supplied schema test that a validation error is raised for invalid json. """ from jsonweb.schema import ObjectSchema, ValidationError from jsonweb.schema.validators import String from jsonweb.decode import from_object, object_hook class PersonSchema(ObjectSchema): first_name = String() last_name = String() @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name json_str = '{"__type__": "Person", "first_name": 123, "last_name": "adams"}' with self.assertRaises(ValidationError) as context: person = json.loads(json_str, object_hook=object_hook()) exc = context.exception self.assertEqual(exc.errors["first_name"].message, "Expected str got int instead.")
def test_configured_object_hook_closure(self): """ Test that we can configure a "custom" object_hook callable. """ class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name did_run = [] def person_decoder(cls, obj): did_run.append(True) return cls(obj["first_name"], obj["last_name"]) custom_object_hook = object_hook( handlers={"Person": {"handler": person_decoder, "cls": Person}}, as_type="Person" ) json_str = '{"first_name": "shawn", "last_name": "adams"}' person = json.loads(json_str, object_hook=custom_object_hook) self.assertTrue(isinstance(person, Person)) self.assertEqual(did_run, [True]) json.loads(json_str, object_hook=custom_object_hook) self.assertEqual(did_run, [True, True])
def test_mixed_type_schema(self): """ Test ObjectSchema validates a mix of regular dicts and object hook classes. """ from jsonweb.schema import ObjectSchema from jsonweb.schema.validators import String, List, EnsureType from jsonweb.decode import from_object, object_hook class TestRequestSchema(ObjectSchema): request_guid = String() players = List(EnsureType("Person")) class PersonSchema(ObjectSchema): first_name = String() last_name = String() @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name obj = { "request_guid": "abcd", "persons": [{"__type__": "Person", "first_name": "shawn", "last_name": "adams"}]*2 } request_obj = json.loads(json.dumps(obj), object_hook=object_hook()) self.assertEqual(len(request_obj["persons"]), 2) self.assertTrue(isinstance(request_obj["persons"][0], Person))
def test_configured_object_hook_closure(self): """ Test that we can configure a "custom" object_hook callable. """ class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name did_run = [] def person_decoder(cls, obj): did_run.append(True) return cls(obj["first_name"], obj["last_name"]) custom_object_hook = object_hook( handlers={"Person": { "handler": person_decoder, "cls": Person }}, as_type="Person") json_str = '{"first_name": "shawn", "last_name": "adams"}' person = json.loads(json_str, object_hook=custom_object_hook) self.assertTrue(isinstance(person, Person)) self.assertEqual(did_run, [True]) json.loads(json_str, object_hook=custom_object_hook) self.assertEqual(did_run, [True, True])
def test_mixed_type_schema(self): """ Test ObjectSchema validates a mix of regular dicts and object hook classes. """ class TestRequestSchema(ObjectSchema): request_guid = String() players = List(EnsureType("Person")) class PersonSchema(ObjectSchema): first_name = String() last_name = String() @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name obj = { "request_guid": "abcd", "persons": [{"__type__": "Person", "first_name": "shawn", "last_name": "adams"}]*2 } request_obj = json.loads(json.dumps(obj), object_hook=object_hook()) self.assertEqual(len(request_obj["persons"]), 2) self.assertTrue(isinstance(request_obj["persons"][0], Person))
def test_class_name_as_string_to_ensuretype(self): """ Test that we can pass a string for a class name to EnsureType. The class must of course be defined later and decorated with @from_object """ from jsonweb.schema import ObjectSchema, ValidationError from jsonweb.schema.validators import String, Integer, EnsureType from jsonweb.decode import from_object, object_hook class JobSchema(ObjectSchema): id = Integer() title = String() class PersonSchema(ObjectSchema): first_name = String() last_name = String() job = EnsureType("Job") @from_object(schema=JobSchema) class Job(object): def __init__(self, id, title): self.id = id self.title = title @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name, job): self.first_name = first_name self.last_name = last_name self.job = job obj = { "__type__": "Person", "first_name": "Shawn", "last_name": "Adams", "id": 1, "test": 12.0, "job": { "__type__": "Job", "title": "zoo keeper", "id": 1 }} person = json.loads(json.dumps(obj), object_hook=object_hook()) self.assertTrue(isinstance(person, Person)) self.assertTrue(isinstance(person.job, Job))
def test_decode_with_schema(self): class PersonSchema(ObjectSchema): first_name = String() last_name = String() @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name json_str = '{"__type__": "Person", "first_name": "shawn", ' \ '"last_name": "adams"}' person = json.loads(json_str, object_hook=object_hook()) self.assertTrue(isinstance(person, Person))
def test_class_name_as_string_to_ensuretype_no_such_class(self): """ Test that an error is raised if you pass a string name of a non existent class to EnsureType. Meaning it either was not defined or was not decorated with @from_object """ from jsonweb.schema import ObjectSchema from jsonweb.schema.validators import String, Integer, EnsureType from jsonweb.decode import from_object, object_hook from jsonweb.exceptions import JsonWebError class JobSchema(ObjectSchema): id = Integer() title = String() class PersonSchema(ObjectSchema): first_name = String() last_name = String() job = EnsureType("Job")#No such class Job @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name, job): self.first_name = first_name self.last_name = last_name self.job = job obj = { "__type__": "Person", "first_name": "Shawn", "last_name": "Adams", "id": 1, "test": 12.0, "job": { "title": "zoo keeper", "id": 1 }} with self.assertRaises(JsonWebError) as context: person = json.loads(json.dumps(obj), object_hook=object_hook()) exc = context.exception self.assertEqual(str(exc), "Cannot find class Job.")
def test_class_name_as_string_to_ensuretype(self): """ Test that we can pass a string for a class name to EnsureType. The class must of course be defined later and decorated with @from_object """ class JobSchema(ObjectSchema): id = Integer() title = String() class PersonSchema(ObjectSchema): first_name = String() last_name = String() job = EnsureType("Job") @from_object(schema=JobSchema) class Job(object): def __init__(self, id, title): self.id = id self.title = title @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name, job): self.first_name = first_name self.last_name = last_name self.job = job obj = { "__type__": "Person", "first_name": "Shawn", "last_name": "Adams", "id": 1, "test": 12.0, "job": { "__type__": "Job", "title": "zoo keeper", "id": 1 }} person = json.loads(json.dumps(obj), object_hook=object_hook()) self.assertTrue(isinstance(person, Person)) self.assertTrue(isinstance(person.job, Job))
def test_decode_with_schema_raises_error(self): """ when using a supplied schema test that a validation error is raised for invalid json. """ class PersonSchema(ObjectSchema): first_name = String() last_name = String() @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name json_str = '{"__type__": "Person", "first_name": 123, "last_name": "adams"}' with self.assertRaises(ValidationError) as context: json.loads(json_str, object_hook=object_hook()) exc = context.exception self.assertEqual(str(exc.errors["first_name"]), "Expected str got int instead.")
def test_class_name_as_string_to_ensuretype_no_such_class(self): """ Test that an error is raised if you pass a string name of a non existent class to EnsureType. Meaning it either was not defined or was not decorated with @from_object """ class JobSchema(ObjectSchema): id = Integer() title = String() class PersonSchema(ObjectSchema): first_name = String() last_name = String() job = EnsureType("Job") # No such class Job @from_object(schema=PersonSchema) class Person(object): def __init__(self, first_name, last_name, job): self.first_name = first_name self.last_name = last_name self.job = job obj = { "__type__": "Person", "first_name": "Shawn", "last_name": "Adams", "id": 1, "test": 12.0, "job": { "title": "zoo keeper", "id": 1 }} with self.assertRaises(JsonWebError) as context: json.loads(json.dumps(obj), object_hook=object_hook()) exc = context.exception self.assertEqual(str(exc), "Cannot find class Job.")