Skip to content

Commit

Permalink
Be able to not automatically serialize behaviors
Browse files Browse the repository at this point in the history
  • Loading branch information
vangheem committed Mar 19, 2018
1 parent c94d571 commit 7e9c469
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 3 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.rst
@@ -1,7 +1,8 @@
2.5.1 (unreleased)
------------------

- Nothing changed yet.
- Be able to not automatically serialize behaviors
[vangheem]


2.5.0 (2018-03-19)
Expand Down
1 change: 1 addition & 0 deletions guillotina/behaviors/dublincore.py
Expand Up @@ -77,6 +77,7 @@ class IDublinCore(Interface):
marker=IMarkerDublinCore,
for_="guillotina.interfaces.IResource")
class DublinCore(AnnotationBehavior):
auto_serialize = True

title = ContextProperty('title', None)
creators = ContextProperty('creators', ())
Expand Down
7 changes: 5 additions & 2 deletions guillotina/behaviors/instance.py
Expand Up @@ -11,9 +11,11 @@


@implementer(IAsyncBehavior)
class AnnotationBehavior(object):
class AnnotationBehavior:
"""A factory that knows how to store data in a separate object."""

auto_serialize = True

__local__properties__ = []

# each annotation is stored
Expand Down Expand Up @@ -82,8 +84,9 @@ def _p_register(self):


@implementer(IContentBehavior)
class ContextBehavior(object):
class ContextBehavior:
"""A factory that knows how to store data in a dict in the context."""
auto_serialize = True

def __init__(self, context):
self.__dict__['schema'] = [x for x in self.__implemented__][0]
Expand Down
2 changes: 2 additions & 0 deletions guillotina/interfaces/behaviors.py
@@ -1,4 +1,5 @@
from guillotina import schema
from zope.interface import Attribute
from zope.interface import Interface
from zope.interface.interfaces import IInterface

Expand Down Expand Up @@ -85,6 +86,7 @@ def __call__(context): # noqa: N805
class IContentBehavior(Interface):
'''
'''
auto_serialize = Attribute('Automatically serialize behavior')


class IAsyncBehavior(IContentBehavior):
Expand Down
3 changes: 3 additions & 0 deletions guillotina/json/serialize_content.py
Expand Up @@ -83,6 +83,9 @@ async def __call__(self, include=[], omit=[]):
(len(included_ifaces) > 0 and dotted_name not in included_ifaces)):
# make sure the schema isn't filtered
continue
if (not getattr(behavior, 'auto_serialize', True) and
dotted_name not in included_ifaces):
continue
if IAsyncBehavior.implementedBy(behavior.__class__):
# providedBy not working here?
await behavior.load(create=False)
Expand Down
12 changes: 12 additions & 0 deletions guillotina/test_package.py
Expand Up @@ -90,6 +90,18 @@ class GContextTestBehavior(ContextBehavior):
pass


class ITestNoSerializeBehavior(Interface):
foobar = schema.TextLine()


@configure.behavior(
title="",
provides=ITestNoSerializeBehavior,
for_="guillotina.interfaces.IResource")
class GTestNoSerializeBehavior(ContextBehavior):
auto_serialize = False


class IFileContent(IItem):
file = CloudFileField(required=False)

Expand Down
49 changes: 49 additions & 0 deletions guillotina/tests/test_dynamic_schema.py
Expand Up @@ -115,6 +115,55 @@ async def test_set_dynamic_context_behavior(custom_type_container_requester):
assert response['guillotina.test_package.ITestContextBehavior']['foobar'] == 'foobar'


async def test_auto_serialize_behavior(custom_type_container_requester):
async with custom_type_container_requester as requester:
response, status = await requester(
'POST',
'/db/guillotina/',
data=json.dumps({
"@type": "Foobar",
"title": "Item1",
"id": "item1"
})
)
assert status == 201

dotted_name = 'guillotina.test_package.ITestNoSerializeBehavior'
# We create the behavior
response, status = await requester(
'PATCH',
'/db/guillotina/item1/@behaviors',
data=json.dumps({
'behavior': dotted_name
})
)
assert status == 200

# We check that the behavior is not serialized
response, status = await requester('GET', '/db/guillotina/item1')
assert dotted_name not in response

# now is should be...
response, status = await requester(
'GET', f'/db/guillotina/item1?include={dotted_name}')
assert dotted_name in response

# set values on behavior
response, status = await requester(
'PATCH',
'/db/guillotina/item1',
data=json.dumps({
dotted_name: {
'foobar': 'foobar'
}
})
)
response, status = await requester(
'GET', f'/db/guillotina/item1?include={dotted_name}')
assert dotted_name in response
assert response[dotted_name]['foobar'] == 'foobar'


async def test_create_delete_dynamic_behavior(custom_type_container_requester):
async with custom_type_container_requester as requester:
response, status = await requester(
Expand Down

0 comments on commit 7e9c469

Please sign in to comment.