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_does_not_have_ambiguous_mappings(self, api): """ Regression test for https://github.com/noirbizarre/flask-restplus/pull/691 """ 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), }) api.marshal({'owner': Child()}, 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_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 self.assertEqual(output.__schema__, { 'properties': { 'child': {'$ref': '#/definitions/Person'}, } })
def test_polymorph_field_required_default(self): parent = self.api.model('Person', { 'name': fields.String, }) child1 = self.api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = self.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 = self.api.model( 'Thing', { 'owner': fields.Polymorph( mapping, required=True, default={'name': 'default'}), }) data = self.api.marshal({}, thing) assert_equal(data, {'owner': {'name': 'default'}})
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) def get(self): return {'owner': Child1()} @api.route('/thing-2/') class Thing2Resource(Resource): @api.marshal_with(thing) def get(self): 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_field(self): parent = self.api.model('Person', { 'name': fields.String, }) child1 = self.api.inherit('Child1', parent, { 'extra1': fields.String, }) child2 = self.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 = self.api.model('Thing', { 'owner': fields.Polymorph(mapping), }) def data(cls): return self.api.marshal({'owner': cls()}, thing) assert_equal(data(Child1), {'owner': { 'name': 'child1', 'extra1': 'extra1' }}) assert_equal(data(Child2), {'owner': { 'name': 'child2', 'extra2': 'extra2' }})
'status': fields.String(description='Element\'s status', attribute='status.value', enum=[status.name for status in LabelElementStatus]), }) out__rectangular_label_element = api.inherit('Rectangular Label Element model', out__common_label_element, { 'x': fields.Float(description='Element\'s X position', min=0.0, max=1.0), 'y': fields.Float(description='Element\'s Y position', min=0.0, max=1.0), 'width': fields.Float(description='Element\'s width', min=0.0, max=1.0), 'height': fields.Float(description='Element\'s height', min=0.0, max=1.0), }) out__brush_label_element = api.inherit('Brush Label Element model', out__common_label_element, { 'width': fields.Integer(description='Image\'s width', min=0), 'height': fields.Integer(description='Image\'s height', min=0), }) out__label_status = api.model('Label status and ID', { 'label_id': fields.String(description='Label\'s ID', attribute='id'), 'status': fields.String(description='Status of the label', attribute='status.name'), }) out__label = api.inherit('Label model', out__label_status, { 'scan_id': fields.String(description='Scan\'s ID'), 'elements': fields.List(fields.Polymorph({ RectangularLabelElement: out__rectangular_label_element, BrushLabelElement: out__brush_label_element, })), 'labeling_time': fields.Float(description='Time in seconds that user spent on labeling'), 'status': fields.String(description='Label\'s status', enum=[status.name for status in LabelVerificationStatus]), })
'points': fields.List(fields.Nested({ 'x': fields.Float(description='X position', min=0.0, max=1.0), 'y': fields.Float(description='Y position', min=0.0, max=1.0), }), description='Points of chain'), }) out__label_status = api.model('Label status and ID', { 'label_id': fields.String(description='Label\'s ID', attribute='id'), 'status': fields.String(description='Status of the label', attribute='status.name'), }) out__label = api.inherit('Label model', out__label_status, { 'scan_id': fields.String(description='Scan\'s ID'), 'elements': fields.List(fields.Polymorph({ RectangularLabelElement: out__rectangular_label_element, BrushLabelElement: out__brush_label_element, PointLabelElement: out__point_label_element, ChainLabelElement: out__chain_label_element, })), 'labeling_time': fields.Float(description='Time in seconds that user spent on labeling'), 'comment': fields.String(description='Comment describing a label'), 'status': fields.String(description='Label\'s status', enum=[status.name for status in LabelVerificationStatus]), }) out__action = api.model('Action model', { 'action_id': fields.Integer(description='Action\'s ID', attribute='id'), 'action_type': fields.String(description='Action\'s Type'), 'details': fields.Raw(attribute=lambda action: action.get_details()), }) out__action_response = api.model('Action Response model', { 'response_id': fields.Integer(description='Action Response\'s ID', attribute='id'),