Commit 77121516 authored by Denis Laxalde's avatar Denis Laxalde
Browse files

Add a CollectionMapper for unspecified entity types

This is useful for representing collection of heterogeneous entities.

This mapper would be selected by its regid only, with no extra argument
in contrast with other 'jsonschema.collection' mappers that either
accepts an "etype" parameter or a relation context. This mapper does not
handle submission (i.e. entity creation) since the target entity type is
unspecified; so we return a "false" JSON Schema for "creation" role.

In tests, we rename prior test case CollectionMapperTC as
EntityCollectionMapperTC and add back a CollectionMapperTC explicitly
testing the new mapper class.
parent 94157194f0e0
......@@ -48,6 +48,7 @@ from . import _utils
__all__ = [
'CollectionMapper',
'EntityCollectionMapper',
'RelatedCollectionMapper',
'CollectionItemMapper',
......@@ -55,24 +56,13 @@ __all__ = [
]
@JSONSchemaDeserializer.register
@JSONSchemaSerializer.register
class EntityCollectionMapper(JSONSchemaMapper):
class CollectionMapper(JSONSchemaMapper):
"""Mapper for a collection of entities."""
__regid__ = 'jsonschema.collection'
__select__ = match_kwargs('etype')
def __repr__(self):
return '<{0.__class__.__name__} etype={0.etype}>'.format(self)
@property
def etype(self):
return self.cw_extra_kwargs['etype']
@property
def title(self):
"""Title of the collection, plural form of entity type."""
return self._cw._('{}_plural').format(self.etype)
return '<{0.__class__.__name__}>'.format(self)
@add_links
def schema_and_definitions(self, schema_role=None):
......@@ -81,12 +71,9 @@ class EntityCollectionMapper(JSONSchemaMapper):
return self._array_schema(schema_role=schema_role)
def _submission_schema_and_definitions(self):
"""Delegate generation of schema and definitions to the "entity"
mapper corresponding to the entity type in this collection.
"""
mapper = self.select_mapper(
'jsonschema.entity', **self.cw_extra_kwargs)
return mapper.schema_and_definitions(schema_role=CREATION_ROLE)
# Disallow submission as we have no knowledge of target entity type in
# this mapper.
return False, {}
def _array_schema(self, schema_role=None):
item_mapper = self.select_mapper(
......@@ -105,10 +92,49 @@ class EntityCollectionMapper(JSONSchemaMapper):
"""
if schema_role is not None:
return
for link in super(EntityCollectionMapper, self).links(
for link in super(CollectionMapper, self).links(
schema_role=schema_role):
yield link
def serialize(self, entities):
"""Return a list of collection item representing each entity in
`entities`.
"""
def mapper(entity):
"""Select jsonschema.item mapper using entity's type."""
return self.select_mapper(
'jsonschema.item',
etype=entity.cw_etype, **self.cw_extra_kwargs)
return [mapper(entity).serialize(entity) for entity in entities]
@JSONSchemaDeserializer.register
class EntityCollectionMapper(CollectionMapper):
"""Mapper for a collection of entities of a given type."""
__regid__ = 'jsonschema.collection'
__select__ = CollectionMapper.__select__ & match_kwargs('etype')
def __repr__(self):
return '<{0.__class__.__name__} etype={0.etype}>'.format(self)
@property
def etype(self):
return self.cw_extra_kwargs['etype']
@property
def title(self):
"""Title of the collection, plural form of entity type."""
return self._cw._('{}_plural').format(self.etype)
def _submission_schema_and_definitions(self):
"""Delegate generation of schema and definitions to the "entity"
mapper corresponding to the entity type in this collection.
"""
mapper = self.select_mapper(
'jsonschema.entity', **self.cw_extra_kwargs)
return mapper.schema_and_definitions(schema_role=CREATION_ROLE)
def values(self, instance):
mapper = self.select_mapper(
'jsonschema.entity', **self.cw_extra_kwargs)
......
......@@ -167,6 +167,53 @@ class JSONSchemaMapperTC(CubicWebTC):
class CollectionMapperTC(CubicWebTC):
def test_schema_view(self):
with self.admin_access.cnx() as cnx:
mapper = cnx.vreg['mappers'].select(
'jsonschema.collection', cnx)
j_schema = mapper.json_schema(VIEW_ROLE)
expected = {
'type': 'array',
'items': {
'properties': {
'type': {'type': 'string'},
'id': {'type': 'string'},
'title': {'type': 'string'},
},
'type': 'object',
},
}
self.assertEqual(j_schema, expected)
def test_schema_creation(self):
with self.admin_access.cnx() as cnx:
mapper = cnx.vreg['mappers'].select(
'jsonschema.collection', cnx)
schema = mapper.json_schema(CREATION_ROLE)
self.assertEqual(schema, False)
def test_serialize(self):
with self.admin_access.cnx() as cnx:
author = cnx.create_entity('Author', name=u'bob')
book = cnx.create_entity('Book', title=u'b',
author=author)
mapper = cnx.vreg['mappers'].select(
'jsonschema.collection', cnx)
data = mapper.serialize([author, book])
expected = [{
'id': str(author.eid),
'title': 'bob',
'type': 'author',
}, {
'id': str(book.eid),
'title': 'b',
'type': 'book',
}]
self.assertEqual(data, expected)
class EntityCollectionMapperTC(CubicWebTC):
def test_schema_view(self):
with self.admin_access.cnx() as cnx:
mapper = cnx.vreg['mappers'].select(
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment