def test_polymorph_field_not_required(self, api): parent = api.model('Person', { 'name': fields.String, }) child1 = api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = api.inherit('Child2', parent, { 'extra2': fields.String, }) class Child1(object): name = 'child1' extra1 = 'extra1' class Child2(object): name = 'child2' extra2 = 'extra2' mapping = {Child1: child1, Child2: child2} thing = api.model('Thing', { 'owner': fields.Polymorph(mapping), }) data = api.marshal({}, thing) assert data == {'owner': None}
def test_polymorph_field_unknown_class(self, api): parent = api.model('Person', { 'name': fields.String, }) child1 = api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = api.inherit('Child2', parent, { 'extra2': fields.String, }) class Child1(object): name = 'child1' extra1 = 'extra1' class Child2(object): name = 'child2' extra2 = 'extra2' mapping = {Child1: child1, Child2: child2} thing = api.model('Thing', { 'owner': fields.Polymorph(mapping), }) with pytest.raises(ValueError): api.marshal({'owner': object()}, thing)
def test_polymorph_field_ambiguous_mapping(self, api): parent = api.model('Parent', { 'name': fields.String, }) child = api.inherit('Child', parent, { 'extra': fields.String, }) class Parent(object): name = 'parent' class Child(Parent): extra = 'extra' mapping = { Parent: parent, Child: child } thing = api.model('Thing', { 'owner': fields.Polymorph(mapping), }) with pytest.raises(ValueError): api.marshal({'owner': Child()}, thing)
def test_marshal_with_handle_polymorph(self, app, client): api = Api(app) parent = api.model('Person', { 'name': fields.String, }) child1 = api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = api.inherit('Child2', parent, { 'extra2': fields.String, }) class Child1(object): name = 'child1' extra1 = 'extra1' class Child2(object): name = 'child2' extra2 = 'extra2' mapping = {Child1: child1, Child2: child2} thing = api.model('Thing', { 'owner': fields.Polymorph(mapping), }) @api.route('/thing-1/') class Thing1Resource(Resource): @api.marshal_with(thing) async def get(self, request): return {'owner': Child1()} @api.route('/thing-2/') class Thing2Resource(Resource): @api.marshal_with(thing) async def get(self, request): return {'owner': Child2()} data = client.get_json('/thing-1/', headers={'X-Fields': 'owner{name}'}) assert data == {'owner': {'name': 'child1'}} data = client.get_json('/thing-1/', headers={'X-Fields': 'owner{extra1}'}) assert data == {'owner': {'extra1': 'extra1'}} data = client.get_json('/thing-2/', headers={'X-Fields': 'owner{name}'}) assert data == {'owner': {'name': 'child2'}}
def test_polymorph_with_discriminator(self, api): parent = api.model('Person', { 'name': fields.String, 'model': fields.String(discriminator=True), }) child1 = api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = api.inherit('Child2', parent, { 'extra2': fields.String, }) class Child1(object): name = 'child1' extra1 = 'extra1' class Child2(object): name = 'child2' extra2 = 'extra2' mapping = {Child1: child1, Child2: child2} thing = api.model('Thing', { 'owner': fields.Polymorph(mapping), }) def data(cls): return api.marshal({'owner': cls()}, thing) assert data(Child1) == { 'owner': { 'name': 'child1', 'model': 'Child1', 'extra1': 'extra1' } } assert data(Child2) == { 'owner': { 'name': 'child2', 'model': 'Child2', 'extra2': 'extra2' } }
def test_polymorph_field_no_common_ancestor(self, api): child1 = api.model('Child1', { 'extra1': fields.String, }) child2 = api.model('Child2', { 'extra2': fields.String, }) class Child1(object): pass class Child2(object): pass mapping = {Child1: child1, Child2: child2} with pytest.raises(ValueError): fields.Polymorph(mapping)
def test_polymorph_inherit_common_ancestor(self): class Child1: pass class Child2: pass parent = Model('Person', { 'name': fields.String, 'age': fields.Integer, }) child1 = parent.inherit('Child1', { 'extra1': fields.String, }) child2 = parent.inherit('Child2', { 'extra2': fields.String, }) mapping = { Child1: child1, Child2: child2, } output = Model('Output', {'child': fields.Polymorph(mapping)}) # Should use the common ancestor assert output.__schema__ == { 'properties': { 'child': { '$ref': '#/definitions/Person' }, }, 'type': 'object' }