Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix a serialization bug that randomly skips fields if "x_of" is encountered #1042

Merged
merged 1 commit into from Aug 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -125,6 +125,7 @@ Patches and Contributions
- Petr Jašek
- Prayag Verma
- Ralph Smith
- Raychee
- Robert Wlodarczyk
- Roberto 'Kalamun' Pasini
- Rodrigo Rodriguez
Expand Down
33 changes: 16 additions & 17 deletions eve/methods/common.py
Expand Up @@ -387,15 +387,16 @@ def serialize(document, resource=None, schema=None, fields=None):
if field in schema:
field_schema = schema[field]
field_type = field_schema.get('type')
if field_type is None:
for x_of in ['allof', 'anyof', 'oneof', 'noneof']:
for optschema in field_schema.get(x_of, []):
schema = {field: optschema}
serialize(document, schema=schema)
x_of_type = '{0}_type'.format(x_of)
for opttype in field_schema.get(x_of_type, []):
schema = {field: {'type': opttype}}
serialize(document, schema=schema)
for x_of in ['allof', 'anyof', 'oneof', 'noneof']:
for optschema in field_schema.get(x_of, []):
optschema = dict(field_schema, **optschema)
optschema.pop(x_of, None)
serialize(document, schema={field: optschema})
x_of_type = '{0}_type'.format(x_of)
for opttype in field_schema.get(x_of_type, []):
optschema = dict(field_schema, type=opttype)
optschema.pop(x_of_type, None)
serialize(document, schema={field: optschema})
if config.AUTO_CREATE_LISTS and field_type == 'list':
# Convert single values to lists
if not isinstance(document[field], list):
Expand Down Expand Up @@ -432,16 +433,14 @@ def serialize(document, resource=None, schema=None, fields=None):
# a list of items determined by *of rules
for x_of in ['allof', 'anyof', 'oneof', 'noneof']:
for optschema in field_schema.get(x_of, []):
schema = {field: {
'type': field_type,
'schema': optschema}}
serialize(document, schema=schema)
serialize(document,
schema={field: {'type': field_type,
'schema': optschema}})
x_of_type = '{0}_type'.format(x_of)
for opttype in field_schema.get(x_of_type, []):
schema = {field: {
'type': field_type,
'schema': {'type': opttype}}}
serialize(document, schema=schema)
serialize(document,
schema={field: {'type': field_type,
'schema': {'type': opttype}}})
else:
# a list of one type, arbitrary length
field_type = field_schema.get('type')
Expand Down
39 changes: 39 additions & 0 deletions eve/tests/methods/common.py
Expand Up @@ -11,6 +11,12 @@
from eve.tests.test_settings import MONGO_DBNAME
from eve.utils import config

try:
from collections import OrderedDict # noqa
except ImportError:
# Python 2.6 needs this back-port
from ordereddict import OrderedDict


class TestSerializer(TestBase):
def test_serialize_subdocument(self):
Expand Down Expand Up @@ -329,6 +335,39 @@ def test_serialize_inside_x_of_rules(self):
serialized = serialize(doc, schema=schema)
self.assertTrue(isinstance(serialized['x_of-field'], ObjectId))

def test_serialize_alongside_x_of_rules(self):
for x_of in ['allof', 'anyof', 'oneof', 'noneof']:
schema = OrderedDict([
('x_of-field', {
x_of: [
{'type': 'objectid'},
{'required': True}
]
}),
('oid-field', {'type': 'objectid'})
])
doc = OrderedDict([('x_of-field', '50656e4538345b39dd0414f0'), ('oid-field', '50656e4538345b39dd0414f0')])
with self.app.app_context():
serialized = serialize(doc, schema=schema)
self.assertTrue(isinstance(serialized['x_of-field'], ObjectId))
self.assertTrue(isinstance(serialized['oid-field'], ObjectId))

def test_serialize_list_alongside_x_of_rules(self):
for x_of in ['allof', 'anyof', 'oneof', 'noneof']:
schema = {
'x_of-field': {
"type": "list",
x_of: [
{"schema": {'type': 'objectid'}},
{"schema": {'type': 'datetime'}}
]
}
}
doc = {'x_of-field': ['50656e4538345b39dd0414f0']}
with self.app.app_context():
serialized = serialize(doc, schema=schema)
self.assertTrue(isinstance(serialized['x_of-field'][0], ObjectId))

def test_serialize_inside_nested_x_of_rules(self):
schema = {
'nested-x_of-field': {
Expand Down