def test_nested_multilevel(self): schema = { "subscription": { 'type': 'dict', 'schema': { 'type': { 'type': 'string' }, 'when': { 'type': 'dict', 'schema': { 'timestamp': { 'type': 'int', 'default': 0 }, 'repr': { 'type': 'string', 'default': '0' } } } } } } res = build_defaults(schema) self.assertEqual( {'subscription': { 'when': { 'timestamp': 0, 'repr': '0' } }}, res)
def test_simple(self): schema = { "name": {'type': 'string'}, "email": {'type': 'string', 'default': "*****@*****.**"} } res = build_defaults(schema) self.assertEqual({'email': '*****@*****.**'}, res)
def _set_resource_projection(self, ds, schema, settings): """ Set datasource projection for a resource .. versionchanged:: 0.6.3 Fix: If datasource source is specified no fields are included by default. Closes #842. .. versionadded:: 0.6.2 """ projection = ds.get('projection', {}) # check if any exclusion projection is defined exclusion = any(((k, v) for k, v in projection.items() if v == 0)) \ if projection else None # If no exclusion projection is defined, enhance the projection # with automatic fields. Using both inclusion and exclusion will # be rejected by Mongo if not exclusion and len(schema) and \ settings['allow_unknown'] is False: if not projection: projection.update(dict((field, 1) for (field) in schema)) # enable retrieval of actual schema fields only. Eventual db # fields not included in the schema won't be returned. # despite projection, automatic fields are always included. projection[settings['id_field']] = 1 projection[self.config['LAST_UPDATED']] = 1 projection[self.config['DATE_CREATED']] = 1 projection[self.config['ETAG']] = 1 if settings['versioning'] is True: projection[self.config['VERSION']] = 1 projection[settings['id_field'] + self.config['VERSION_ID_SUFFIX']] = 1 else: # all fields are returned. projection = None ds.setdefault('projection', projection) if settings['soft_delete'] is True and not exclusion and \ ds['projection'] is not None: ds['projection'][self.config['DELETED']] = 1 # 'defaults' helper set contains the names of fields with default # values in their schema definition. # TODO support default values for embedded documents. settings['defaults'] = build_defaults(schema) # list of all media fields for the resource settings['_media'] = [ field for field, definition in schema.items() if definition.get('type') == 'media' ] if settings['_media'] and not self.media: raise ConfigException('A media storage class of type ' ' eve.io.media.MediaStorage but be defined ' 'for "media" fields to be properly stored.')
def test_schemaless_dict(self): schema = { "address": { 'type': 'dict' } } self.assertEqual({}, build_defaults(schema))
def test_default_in_list_schema(self): schema = { "one": { 'type': 'list', 'schema': { 'type': 'dict', 'schema': { 'title': { 'type': 'string', 'default': 'M.' } } } }, "two": { 'type': 'list', 'schema': { 'type': 'dict', 'schema': { 'name': {'type': 'string'} } } } } res = build_defaults(schema) self.assertEqual({"one": [{'title': 'M.'}]}, res)
def test_default_in_list_schema(self): schema = { "one": { 'type': 'list', 'schema': { 'type': 'dict', 'schema': { 'title': { 'type': 'string', 'default': 'M.' } } } }, "two": { 'type': 'list', 'schema': { 'type': 'dict', 'schema': { 'name': { 'type': 'string' } } } } } res = build_defaults(schema) self.assertEqual({"one": [{'title': 'M.'}]}, res)
def _set_resource_projection(self, ds, schema, settings): """ Set datasource projection for a resource .. versionchanged:: 0.6.3 Fix: If datasource source is specified no fields are included by default. Closes #842. .. versionadded:: 0.6.2 """ projection = ds.get('projection', {}) # check if any exclusion projection is defined exclusion = any(((k, v) for k, v in projection.items() if v == 0)) \ if projection else None # If no exclusion projection is defined, enhance the projection # with automatic fields. Using both inclusion and exclusion will # be rejected by Mongo if not exclusion and len(schema) and \ settings['allow_unknown'] is False: if not projection: projection.update(dict((field, 1) for (field) in schema)) # enable retrieval of actual schema fields only. Eventual db # fields not included in the schema won't be returned. # despite projection, automatic fields are always included. projection[settings['id_field']] = 1 projection[self.config['LAST_UPDATED']] = 1 projection[self.config['DATE_CREATED']] = 1 projection[self.config['ETAG']] = 1 if settings['versioning'] is True: projection[self.config['VERSION']] = 1 projection[ settings['id_field'] + self.config['VERSION_ID_SUFFIX']] = 1 else: # all fields are returned. projection = None ds.setdefault('projection', projection) if settings['soft_delete'] is True and not exclusion and \ ds['projection'] is not None: ds['projection'][self.config['DELETED']] = 1 # 'defaults' helper set contains the names of fields with default # values in their schema definition. # TODO support default values for embedded documents. settings['defaults'] = build_defaults(schema) # list of all media fields for the resource settings['_media'] = [field for field, definition in schema.items() if definition.get('type') == 'media'] if settings['_media'] and not self.media: raise ConfigException('A media storage class of type ' ' eve.io.media.MediaStorage but be defined ' 'for "media" fields to be properly stored.')
def test_default_in_list_without_schema(self): schema = { "one": { 'type': 'list', 'schema': { 'type': 'string', 'default': 'item' } } } res = build_defaults(schema) self.assertEqual({"one": ['item']}, res)
def test_simple(self): schema = { "name": { 'type': 'string' }, "email": { 'type': 'string', 'default': "*****@*****.**" } } res = build_defaults(schema) self.assertEqual({'email': '*****@*****.**'}, res)
def test_nested_one_level(self): schema = { "address": { 'type': 'dict', 'schema': { 'street': {'type': 'string'}, 'country': {'type': 'string', 'default': 'wonderland'} } } } res = build_defaults(schema) self.assertEqual({'address': {'country': 'wonderland'}}, res)
def test_lists_of_lists_with_default(self): schema = { 'twisting': { 'type': 'list', # list of groups 'required': True, 'schema': { 'type': 'list', # list of signals (in one group) 'schema': { 'type': 'string', 'default': 'listoflist', } } } } res = build_defaults(schema) self.assertEqual({'twisting': [['listoflist']]}, res)
def test_lists_of_lists_without_default(self): schema = { 'twisting': { 'type': 'list', # list of groups 'required': True, 'schema': { 'type': 'list', # list of signals (in one group) 'schema': { 'type': 'ObjectId', 'required': True } } } } res = build_defaults(schema) self.assertEqual({}, res)
def test_nested_one_level(self): schema = { "address": { 'type': 'dict', 'schema': { 'street': { 'type': 'string' }, 'country': { 'type': 'string', 'default': 'wonderland' } } } } res = build_defaults(schema) self.assertEqual({'address': {'country': 'wonderland'}}, res)
def test_empty_defaults_multiple_level(self): schema = { 'subscription': { 'type': 'dict', 'schema': { 'type': {'type': 'string'}, 'when': { 'type': 'dict', 'schema': { 'timestamp': {'type': 'int'}, 'repr': {'type': 'string'} } } } } } res = build_defaults(schema) self.assertEqual({}, res)
def test_nested_multilevel(self): schema = { "subscription": { 'type': 'dict', 'schema': { 'type': {'type': 'string'}, 'when': { 'type': 'dict', 'schema': { 'timestamp': {'type': 'int', 'default': 0}, 'repr': {'type': 'string', 'default': '0'} } } } } } res = build_defaults(schema) self.assertEqual( {'subscription': {'when': {'timestamp': 0, 'repr': '0'}}}, res)
def test_empty_defaults_multiple_level(self): schema = { 'subscription': { 'type': 'dict', 'schema': { 'type': { 'type': 'string' }, 'when': { 'type': 'dict', 'schema': { 'timestamp': { 'type': 'int' }, 'repr': { 'type': 'string' } } } } } } res = build_defaults(schema) self.assertEqual({}, res)
def _set_resource_defaults(self, resource, settings): """ Low-level method which sets default values for one resource. .. versionchanged:: 0.5 Don't set default projection if 'allow_unknown' is active (#497). 'internal_resource' .. versionchanged:: 0.3 Set projection to None when schema is not provided for the resource. Support for '_media' helper. .. versionchanged:: 0.2 'resource_title', 'default_sort', 'embedded_fields'. Support for endpoint-level authenticatoin classes. """ settings.setdefault('url', resource) settings.setdefault('resource_methods', self.config['RESOURCE_METHODS']) settings.setdefault('public_methods', self.config['PUBLIC_METHODS']) settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES']) settings.setdefault('allowed_read_roles', self.config['ALLOWED_READ_ROLES']) settings.setdefault('allowed_write_roles', self.config['ALLOWED_WRITE_ROLES']) settings.setdefault('cache_control', self.config['CACHE_CONTROL']) settings.setdefault('cache_expires', self.config['CACHE_EXPIRES']) settings.setdefault('item_lookup_field', self.config['ITEM_LOOKUP_FIELD']) settings.setdefault('item_url', self.config['ITEM_URL']) settings.setdefault('resource_title', settings['url']) settings.setdefault('item_title', resource.rstrip('s').capitalize()) settings.setdefault('item_lookup', self.config['ITEM_LOOKUP']) settings.setdefault('public_item_methods', self.config['PUBLIC_ITEM_METHODS']) settings.setdefault('allowed_item_roles', self.config['ALLOWED_ITEM_ROLES']) settings.setdefault('allowed_item_read_roles', self.config['ALLOWED_ITEM_READ_ROLES']) settings.setdefault('allowed_item_write_roles', self.config['ALLOWED_ITEM_WRITE_ROLES']) settings.setdefault('allowed_filters', self.config['ALLOWED_FILTERS']) settings.setdefault('sorting', self.config['SORTING']) settings.setdefault('embedding', self.config['EMBEDDING']) settings.setdefault('embedded_fields', []) settings.setdefault('pagination', self.config['PAGINATION']) settings.setdefault('projection', self.config['PROJECTION']) settings.setdefault('versioning', self.config['VERSIONING']) settings.setdefault('internal_resource', self.config['INTERNAL_RESOURCE']) # TODO make sure that this we really need the test below if settings['item_lookup']: item_methods = self.config['ITEM_METHODS'] else: item_methods = eve.ITEM_METHODS settings.setdefault('item_methods', item_methods) settings.setdefault('auth_field', self.config['AUTH_FIELD']) settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN']) settings.setdefault('extra_response_fields', self.config['EXTRA_RESPONSE_FIELDS']) settings.setdefault('mongo_write_concern', self.config['MONGO_WRITE_CONCERN']) settings.setdefault('hateoas', self.config['HATEOAS']) settings.setdefault('authentication', self.auth if self.auth else None) # empty schemas are allowed for read-only access to resources schema = settings.setdefault('schema', {}) self.set_schema_defaults(schema) datasource = {} settings.setdefault('datasource', datasource) settings['datasource'].setdefault('source', resource) settings['datasource'].setdefault('filter', None) settings['datasource'].setdefault('default_sort', None) if len(schema) and settings['allow_unknown'] is False: # enable retrieval of actual schema fields only. Eventual db # fields not included in the schema won't be returned. projection = {} # despite projection, automatic fields are always included. projection[self.config['ID_FIELD']] = 1 projection[self.config['LAST_UPDATED']] = 1 projection[self.config['DATE_CREATED']] = 1 projection[self.config['ETAG']] = 1 if settings['versioning'] is True: projection[self.config['VERSION']] = 1 projection[ self.config['ID_FIELD'] + self.config['VERSION_ID_SUFFIX']] = 1 projection.update(dict((field, 1) for (field) in schema)) else: # all fields are returned. projection = None settings['datasource'].setdefault('projection', projection) # 'defaults' helper set contains the names of fields with default # values in their schema definition. # TODO support default values for embedded documents. settings['defaults'] = build_defaults(schema) # list of all media fields for the resource settings['_media'] = [field for field, definition in schema.items() if definition.get('type') == 'media'] if settings['_media'] and not self.media: raise ConfigException('A media storage class of type ' ' eve.io.media.MediaStorage but be defined ' 'for "media" fields to be properly stored.')
def _set_resource_defaults(self, resource, settings): """ Low-level method which sets default values for one resource. .. versionchanged:: 0.6.2 Fix: startup crash when both SOFT_DELETE and ALLOW_UNKNOWN are True. (#722). .. versionchanged:: 0.6.1 Fix: inclusive projection defined for a datasource is ignored (#722). .. versionchanged:: 0.6 Support for 'mongo_indexes'. .. versionchanged:: 0.5 Don't set default projection if 'allow_unknown' is active (#497). 'internal_resource' .. versionchanged:: 0.3 Set projection to None when schema is not provided for the resource. Support for '_media' helper. .. versionchanged:: 0.2 'resource_title', 'default_sort', 'embedded_fields'. Support for endpoint-level authenticatoin classes. """ settings.setdefault('url', resource) settings.setdefault('resource_methods', self.config['RESOURCE_METHODS']) settings.setdefault('public_methods', self.config['PUBLIC_METHODS']) settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES']) settings.setdefault('allowed_read_roles', self.config['ALLOWED_READ_ROLES']) settings.setdefault('allowed_write_roles', self.config['ALLOWED_WRITE_ROLES']) settings.setdefault('cache_control', self.config['CACHE_CONTROL']) settings.setdefault('cache_expires', self.config['CACHE_EXPIRES']) settings.setdefault('id_field', self.config['ID_FIELD']) settings.setdefault('item_lookup_field', self.config['ITEM_LOOKUP_FIELD']) settings.setdefault('item_url', self.config['ITEM_URL']) settings.setdefault('resource_title', settings['url']) settings.setdefault('item_title', resource.rstrip('s').capitalize()) settings.setdefault('item_lookup', self.config['ITEM_LOOKUP']) settings.setdefault('public_item_methods', self.config['PUBLIC_ITEM_METHODS']) settings.setdefault('allowed_item_roles', self.config['ALLOWED_ITEM_ROLES']) settings.setdefault('allowed_item_read_roles', self.config['ALLOWED_ITEM_READ_ROLES']) settings.setdefault('allowed_item_write_roles', self.config['ALLOWED_ITEM_WRITE_ROLES']) settings.setdefault('allowed_filters', self.config['ALLOWED_FILTERS']) settings.setdefault('sorting', self.config['SORTING']) settings.setdefault('embedding', self.config['EMBEDDING']) settings.setdefault('embedded_fields', []) settings.setdefault('pagination', self.config['PAGINATION']) settings.setdefault('projection', self.config['PROJECTION']) settings.setdefault('versioning', self.config['VERSIONING']) settings.setdefault('soft_delete', self.config['SOFT_DELETE']) settings.setdefault('bulk_enabled', self.config['BULK_ENABLED']) settings.setdefault('internal_resource', self.config['INTERNAL_RESOURCE']) settings.setdefault('etag_ignore_fields', None) # TODO make sure that this we really need the test below if settings['item_lookup']: item_methods = self.config['ITEM_METHODS'] else: item_methods = eve.ITEM_METHODS settings.setdefault('item_methods', item_methods) settings.setdefault('auth_field', self.config['AUTH_FIELD']) settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN']) settings.setdefault('transparent_schema_rules', self.config['TRANSPARENT_SCHEMA_RULES']) settings.setdefault('extra_response_fields', self.config['EXTRA_RESPONSE_FIELDS']) settings.setdefault('mongo_write_concern', self.config['MONGO_WRITE_CONCERN']) settings.setdefault('mongo_indexes', {}) settings.setdefault('hateoas', self.config['HATEOAS']) settings.setdefault('authentication', self.auth if self.auth else None) # empty schemas are allowed for read-only access to resources schema = settings.setdefault('schema', {}) self.set_schema_defaults(schema, settings['id_field']) # 'defaults' helper set contains the names of fields with default # values in their schema definition. # TODO support default values for embedded documents. settings['defaults'] = build_defaults(schema) # list of all media fields for the resource settings['_media'] = [field for field, definition in schema.items() if definition.get('type') == 'media'] if settings['_media'] and not self.media: raise ConfigException('A media storage class of type ' ' eve.io.media.MediaStorage but be defined ' 'for "media" fields to be properly stored.') self._set_resource_datasource(resource, schema, settings)
def test_schemaless_dict(self): schema = {"address": {'type': 'dict'}} self.assertEqual({}, build_defaults(schema))
def _set_resource_defaults(self, resource, settings): """ Low-level method which sets default values for one resource. .. versionchanged:: 0.6.2 Fix: startup crash when both SOFT_DELETE and ALLOW_UNKNOWN are True. (#722). .. versionchanged:: 0.6.1 Fix: inclusive projection defined for a datasource is ignored (#722). .. versionchanged:: 0.6 Support for 'mongo_indexes'. .. versionchanged:: 0.5 Don't set default projection if 'allow_unknown' is active (#497). 'internal_resource' .. versionchanged:: 0.3 Set projection to None when schema is not provided for the resource. Support for '_media' helper. .. versionchanged:: 0.2 'resource_title', 'default_sort', 'embedded_fields'. Support for endpoint-level authenticatoin classes. """ settings.setdefault('url', resource) settings.setdefault('resource_methods', self.config['RESOURCE_METHODS']) settings.setdefault('public_methods', self.config['PUBLIC_METHODS']) settings.setdefault('allowed_roles', self.config['ALLOWED_ROLES']) settings.setdefault('allowed_read_roles', self.config['ALLOWED_READ_ROLES']) settings.setdefault('allowed_write_roles', self.config['ALLOWED_WRITE_ROLES']) settings.setdefault('cache_control', self.config['CACHE_CONTROL']) settings.setdefault('cache_expires', self.config['CACHE_EXPIRES']) settings.setdefault('id_field', self.config['ID_FIELD']) settings.setdefault('item_lookup_field', self.config['ITEM_LOOKUP_FIELD']) settings.setdefault('item_url', self.config['ITEM_URL']) settings.setdefault('resource_title', settings['url']) settings.setdefault('item_title', resource.rstrip('s').capitalize()) settings.setdefault('item_lookup', self.config['ITEM_LOOKUP']) settings.setdefault('public_item_methods', self.config['PUBLIC_ITEM_METHODS']) settings.setdefault('allowed_item_roles', self.config['ALLOWED_ITEM_ROLES']) settings.setdefault('allowed_item_read_roles', self.config['ALLOWED_ITEM_READ_ROLES']) settings.setdefault('allowed_item_write_roles', self.config['ALLOWED_ITEM_WRITE_ROLES']) settings.setdefault('allowed_filters', self.config['ALLOWED_FILTERS']) settings.setdefault('sorting', self.config['SORTING']) settings.setdefault('embedding', self.config['EMBEDDING']) settings.setdefault('embedded_fields', []) settings.setdefault('pagination', self.config['PAGINATION']) settings.setdefault('projection', self.config['PROJECTION']) settings.setdefault('versioning', self.config['VERSIONING']) settings.setdefault('soft_delete', self.config['SOFT_DELETE']) settings.setdefault('bulk_enabled', self.config['BULK_ENABLED']) settings.setdefault('internal_resource', self.config['INTERNAL_RESOURCE']) settings.setdefault('etag_ignore_fields', None) # TODO make sure that this we really need the test below if settings['item_lookup']: item_methods = self.config['ITEM_METHODS'] else: item_methods = eve.ITEM_METHODS settings.setdefault('item_methods', item_methods) settings.setdefault('auth_field', self.config['AUTH_FIELD']) settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN']) settings.setdefault('transparent_schema_rules', self.config['TRANSPARENT_SCHEMA_RULES']) settings.setdefault('extra_response_fields', self.config['EXTRA_RESPONSE_FIELDS']) settings.setdefault('mongo_write_concern', self.config['MONGO_WRITE_CONCERN']) settings.setdefault('mongo_indexes', {}) settings.setdefault('hateoas', self.config['HATEOAS']) settings.setdefault('authentication', self.auth if self.auth else None) # empty schemas are allowed for read-only access to resources schema = settings.setdefault('schema', {}) self.set_schema_defaults(schema, settings['id_field']) datasource = {} settings.setdefault('datasource', datasource) ds = settings['datasource'] ds.setdefault('source', resource) ds.setdefault('filter', None) ds.setdefault('default_sort', None) projection = ds.get('projection', {}) # check if any exclusion projection is defined exclusion = any(((k, v) for k, v in projection.items() if v == 0)) # If no exclusion projection is defined, enhance the projection # with automatic fields. Using both inclusion and exclusion will # be rejected by Mongo if not exclusion and len(schema) and \ settings['allow_unknown'] is False: if not projection: projection.update(dict((field, 1) for (field) in schema)) # enable retrieval of actual schema fields only. Eventual db # fields not included in the schema won't be returned. # despite projection, automatic fields are always included. projection[settings['id_field']] = 1 projection[self.config['LAST_UPDATED']] = 1 projection[self.config['DATE_CREATED']] = 1 projection[self.config['ETAG']] = 1 if settings['versioning'] is True: projection[self.config['VERSION']] = 1 projection[ settings['id_field'] + self.config['VERSION_ID_SUFFIX']] = 1 else: # all fields are returned. projection = None ds.setdefault('projection', projection) if settings['soft_delete'] is True and not exclusion and \ ds['projection'] is not None: ds['projection'][self.config['DELETED']] = 1 # 'defaults' helper set contains the names of fields with default # values in their schema definition. # TODO support default values for embedded documents. settings['defaults'] = build_defaults(schema) # list of all media fields for the resource settings['_media'] = [field for field, definition in schema.items() if definition.get('type') == 'media'] if settings['_media'] and not self.media: raise ConfigException('A media storage class of type ' ' eve.io.media.MediaStorage but be defined ' 'for "media" fields to be properly stored.')