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:
parent
3ee034c683
commit
43995a96dc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue