Skip to content

Commit

Permalink
Merge pull request #309 from tisdall/fix_schema_typing
Browse files Browse the repository at this point in the history
Fix schema typing
  • Loading branch information
almet committed Jul 8, 2015
2 parents 6647ac4 + 1a95e87 commit d3606b9
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 8 deletions.
15 changes: 9 additions & 6 deletions cornice/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,17 @@ def from_colander(klass, colander_schema, **kwargs):

def validate_colander_schema(schema, request):
"""Validates that the request is conform to the given schema"""
from colander import Invalid, Sequence, drop, null, MappingSchema
from colander import Invalid, Sequence, drop, null, Mapping

schema_type = schema.colander_schema.schema_type()
# CorniceSchema.colander_schema guarantees that we have a colander
# instance and not a class so we should use `typ` and not
# `schema_type()` to determine the type.
schema_type = schema.colander_schema.typ
unknown = getattr(schema_type, 'unknown', None)

if not isinstance(schema.colander_schema, MappingSchema):
raise SchemaError('schema is not a MappingSchema: %s' %
type(schema.colander_schema))
if not isinstance(schema_type, Mapping):
raise SchemaError('colander schema type is not a Mapping: %s' %
type(schema_type))

def _validate_fields(location, data):
if location == 'body':
Expand Down Expand Up @@ -167,7 +170,7 @@ def _validate_fields(location, data):
_validate_fields('querystring', qs)

# validate unknown
if schema.colander_schema.typ.unknown == 'raise':
if unknown == 'raise':
attrs = schema.get_attributes(location=('body', 'querystring'),
request=request)
params = list(qs.keys()) + list(body.keys())
Expand Down
22 changes: 20 additions & 2 deletions cornice/tests/test_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
deferred,
Mapping,
MappingSchema,
Sequence,
SequenceSchema,
SchemaNode,
String,
Expand Down Expand Up @@ -66,7 +67,7 @@ class DropSchema(MappingSchema):
class StrictMappingSchema(MappingSchema):
@staticmethod
def schema_type():
return MappingSchema.schema_type(unknown='raise')
return Mapping(unknown='raise')

class StrictSchema(StrictMappingSchema):
foo = SchemaNode(String(), type='str', location="body", missing=drop)
Expand Down Expand Up @@ -110,7 +111,8 @@ class TestingSchemaWithHeader(MappingSchema):
class PreserveUnkownSchema(MappingSchema):
bar = SchemaNode(String(), type='str')

def schema_type(self, **kw):
@staticmethod
def schema_type():
return Mapping(unknown='preserve')

def get_mock_request(body, get=None):
Expand Down Expand Up @@ -228,6 +230,9 @@ def test_imperative_colander_schema(self):
self.assertEqual(len(body_fields), 2)
self.assertEqual(len(qs_fields), 1)

dummy_request = get_mock_request('{"bar": "some data"}')
validate_colander_schema(schema, dummy_request)

def test_colander_schema_using_drop(self):
"""
remove fields from validated data if they deserialize to colander's
Expand Down Expand Up @@ -345,6 +350,19 @@ def test_only_mapping_is_accepted(self):
self.assertRaises(SchemaError,
validate_colander_schema, schema, dummy_request)

# We shouldn't accept a MappingSchema if the `typ` has
# been set to something else:
schema = CorniceSchema.from_colander(
MappingSchema(
Sequence,
SchemaNode(String(), name='foo'),
SchemaNode(String(), name='bar'),
SchemaNode(String(), name='baz')
)
)
self.assertRaises(SchemaError,
validate_colander_schema, schema, dummy_request)

def test_extra_params_qs(self):
schema = CorniceSchema.from_colander(QsSchema)
dummy_request = get_mock_request('', {'foo': 'test',
Expand Down

0 comments on commit d3606b9

Please sign in to comment.