Improve Collection rendering

Collection with only one type of objects are rendered as X-OCCI-Location,
as when returned when performing a GET to a resource location.
For collections with more than one type, render each of the individual
objects.

Change-Id: I4978e5f8eacbb3db0e6f0bc2ddf02ac3c6d9ac54
This commit is contained in:
Enol Fernandez 2016-06-23 12:29:17 +02:00 committed by Enol Fernández
parent 3ee034c683
commit 43995a96dc
6 changed files with 68 additions and 9 deletions

View File

@ -20,11 +20,20 @@ class Collection(object):
be one output or another. This class should do the magic and render the
proper information, taking into account what is in the collection.
"""
def __init__(self, kinds=[], mixins=[], actions=[],
resources=[], links=[]):
def __init__(self, kinds=None, mixins=None, actions=None,
resources=None, links=None):
if kinds is None:
kinds = []
self.kinds = kinds
if mixins is None:
mixins = []
self.mixins = mixins
if actions is None:
actions = []
self.actions = actions
if resources is None:
resources = []
self.resources = resources
if links is None:
links = []
self.links = links

View File

@ -108,13 +108,22 @@ class MixinRenderer(CategoryRenderer):
class CollectionRenderer(HeaderRenderer):
def render(self, env={}):
app_url = env.get("application_url", "")
ret = []
for what in [self.obj.kinds, self.obj.mixins, self.obj.actions,
self.obj.resources, self.obj.links]:
for el in what:
url = utils.join_url(app_url, el.location)
ret.append(('X-OCCI-Location', '%s' % url))
contents = (self.obj.kinds, self.obj.mixins, self.obj.actions,
self.obj.resources, self.obj.links)
# Render individual objects if there are more that one type of objects
# otherwise render as X-OCCI-Location headers
if len([x for x in contents if x]) > 1:
for what in contents:
for el in what:
renderer = get_renderer(el)
ret.extend(renderer.render(env=env))
else:
app_url = env.get("application_url", "")
for what in contents:
for el in what:
url = utils.join_url(app_url, el.location)
ret.append(('X-OCCI-Location', '%s' % url))
return ret

View File

@ -57,6 +57,14 @@ class BaseRendererTest(ooi.tests.base.TestCase):
c = collection.Collection(resources=[r1, r2])
self.get_render_and_assert(c)
def test_mixed_collection(self):
res = resource.Resource("foo", [], uuid.uuid4().hex)
knd = kind.Kind("scheme", "term", "title")
c = collection.Collection(kinds=[knd], resources=[res])
r = self.renderer.get_renderer(c)
observed = r.render()
self.assertMixedCollection(knd, res, observed)
def test_exception(self):
exc = webob.exc.HTTPBadRequest()
self.get_render_and_assert(exc)

View File

@ -75,6 +75,18 @@ class TestOCCIHeaderRendering(base.BaseRendererTest):
for attr in attrs:
self.assertIn(("X-OCCI-Attribute", attr), observed)
def assertMixedCollection(self, kind, resource, observed):
expected = self.get_category("kind", kind, kind.location)
expected.extend(self.get_category("kind", resource.kind,
resource.kind.location))
for a in resource.attributes:
# assume string attributes, remove null ones
if resource.attributes[a].value:
attr = ('X-OCCI-Attribute',
'%s="%s"' % (a, resource.attributes[a].value))
expected.append(attr)
self.assertItemsEqual(expected, observed)
def assertMixin(self, obj, observed):
expected = self.get_category("mixin", obj)
self.assertEqual(expected, observed)

View File

@ -14,6 +14,8 @@
import json
import mock
from ooi.occi.core import attribute
from ooi.occi.rendering import occi_json
from ooi.tests.unit.occi.renderings import base
@ -89,6 +91,15 @@ class TestOCCIJsonRendering(base.BaseRendererTest):
}
self.assertEqual(link, json.loads(observed))
def assertMixedCollection(self, kind, resource, observed):
c = mock.MagicMock()
c.kinds = [kind]
c.resources = [resource]
c.mixins = ()
c.actions = ()
c.links = ()
self.assertCollection(c, observed)
def assertMixin(self, obj, observed):
expected = {
"term": obj.term,

View File

@ -46,6 +46,16 @@ class TestOCCITextRendering(test_header.TestOCCIHeaderRendering):
for attr in attrs:
self.assertIn("X-OCCI-Attribute: %s" % attr, observed_lines)
def assertMixedCollection(self, kind, resource, observed):
expected = [self.get_category("kind", kind, kind.location)]
expected.append(self.get_category("kind", resource.kind,
resource.kind.location))
for a in resource.attributes:
if resource.attributes[a].value:
expected.append('X-OCCI-Attribute: '
'%s="%s"' % (a, resource.attributes[a].value))
self.assertEqual("\n".join(expected).strip(), observed.strip())
def assertCollection(self, obj, observed):
expected = []
for what in [obj.kinds, obj.mixins, obj.actions, obj.resources,