Skip to content

Commit

Permalink
Introduce feature for being able to disable transforms adapters, add …
Browse files Browse the repository at this point in the history
…disable_transform_resolveuid and disable_transform_html to opt-out these transformers

Introduce feature for being able to disable transforms adapters, add disable_transform_resolveuid and disable_transform_html to opt-out these transformers
  • Loading branch information
sneridagh committed Oct 23, 2020
1 parent d3d0198 commit 3b2e04d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 9 deletions.
16 changes: 9 additions & 7 deletions src/plone/restapi/deserializer/blocks.py
Expand Up @@ -15,6 +15,8 @@
from zope.interface import implementer
from zope.publisher.interfaces.browser import IBrowserRequest

import os


def path2uid(context, link):
# unrestrictedTraverse requires a string on py3. see:
Expand Down Expand Up @@ -66,8 +68,10 @@ def __call__(self, value):
):
if h.block_type == block_type or h.block_type is None:
handlers.append(h)

for handler in sorted(handlers, key=lambda h: h.order):
block_value = handler(block_value)
if not getattr(handler, "disabled", False):
block_value = handler(block_value)

value[id] = block_value

Expand All @@ -85,6 +89,7 @@ class ResolveUIDDeserializer(object):

order = 1
block_type = None
disabled = os.environ.get("disable_transform_resolveuid", False)

def __init__(self, context, request):
self.context = context
Expand All @@ -104,6 +109,7 @@ def __call__(self, block):
class TextBlockDeserializer(object):
order = 100
block_type = "text"
disabled = os.environ.get("disable_transform_resolveuid", False)

def __init__(self, context, request):
self.context = context
Expand All @@ -119,11 +125,6 @@ def __call__(self, block):
if entity.get("type") == "LINK":
href = entity.get("data", {}).get("url", "")
entity["data"]["url"] = path2uid(context=self.context, link=href)
print( # noqa
"DESERIALIZE TEXT BLOCK: {} -> {}".format(
href, entity["data"]["url"]
)
)
return block


Expand All @@ -132,6 +133,7 @@ def __call__(self, block):
class HTMLBlockDeserializer(object):
order = 100
block_type = "html"
disabled = os.environ.get("disable_transform_html", False)

def __init__(self, context, request):
self.context = context
Expand All @@ -155,6 +157,7 @@ def __call__(self, block):
class ImageBlockDeserializer(object):
order = 100
block_type = "image"
disabled = os.environ.get("disable_transform_resolveuid", False)

def __init__(self, context, request):
self.context = context
Expand All @@ -163,5 +166,4 @@ def __init__(self, context, request):
def __call__(self, block):
url = block.get("url", "")
block["url"] = path2uid(context=self.context, link=url)
print("DESERIALIZE IMAGE: {} -> {}".format(url, block["url"])) # noqa
return block
2 changes: 2 additions & 0 deletions src/plone/restapi/interfaces.py
Expand Up @@ -94,6 +94,7 @@ class IBlockFieldDeserializationTransformer(Interface):
order = Attribute(
"A number used in sorting value transformers. " "Smaller is executed first"
)
disabled = Attribute("Boolean that disables the transformer if required")

def __init__(field, context, request):
"""Adapts context and the request."""
Expand All @@ -112,6 +113,7 @@ class IBlockFieldSerializationTransformer(Interface):
"A number used in sorting value transformers for the "
"same block. Smaller is executed first"
)
disabled = Attribute("Boolean that disables the transformer if required")

def __init__(field, context, request):
"""Adapts context and the request."""
Expand Down
7 changes: 5 additions & 2 deletions src/plone/restapi/serializer/blocks.py
Expand Up @@ -17,7 +17,7 @@

import copy
import re

import os

RESOLVEUID_RE = re.compile("^[./]*resolve[Uu]id/([^/]*)/?(.*)$")

Expand Down Expand Up @@ -63,7 +63,8 @@ def __call__(self):
handlers.append(h)

for handler in sorted(handlers, key=lambda h: h.order):
block_value = handler(block_value)
if not getattr(handler, "disabled", False):
block_value = handler(block_value)

value[id] = block_value

Expand All @@ -75,6 +76,7 @@ def __call__(self):
class ResolveUIDSerializer(object):
order = 1
block_type = None
disabled = os.environ.get("disable_transform_resolveuid", False)

def __init__(self, context, request):
self.context = context
Expand All @@ -92,6 +94,7 @@ def __call__(self, value):
class TextBlockSerializer(object):
order = 100
block_type = "text"
disabled = os.environ.get("disable_transform_resolveuid", False)

def __init__(self, context, request):
self.context = context
Expand Down
29 changes: 29 additions & 0 deletions src/plone/restapi/tests/test_blocks_deserializer.py
Expand Up @@ -76,6 +76,35 @@ def __call__(self, value):
assert self.portal.doc1._handler_called is True
assert self.portal.doc1.blocks["123"]["value"] == u"changed: text"

def test_disabled_deserializer(self):
@implementer(IBlockFieldDeserializationTransformer)
@adapter(IBlocks, IBrowserRequest)
class TestAdapter(object):
order = 10
block_type = "test"
disabled = True

def __init__(self, context, request):
self.context = context
self.request = request

def __call__(self, value):
self.context._handler_called = True

value["value"] = u"changed: {}".format(value["value"])

return value

provideSubscriptionAdapter(
TestAdapter,
(IDexterityItem, IBrowserRequest),
)

self.deserialize(blocks={"123": {"@type": "test", "value": u"text"}})

assert not getattr(self.portal.doc1, "_handler_called", False)
assert self.portal.doc1.blocks["123"]["value"] == u"text"

def test_register_multiple_transform(self):
@implementer(IBlockFieldDeserializationTransformer)
@adapter(IBlocks, IBrowserRequest)
Expand Down
31 changes: 31 additions & 0 deletions src/plone/restapi/tests/test_blocks_serializer.py
Expand Up @@ -90,3 +90,34 @@ def __call__(self, value):
blocks={"123": {"@type": "test_multi", "value": u"a"}},
)
self.assertEqual(value["123"]["value"], u"c")

def test_disabled_serializer(self):
@implementer(IBlockFieldSerializationTransformer)
@adapter(IBlocks, IBrowserRequest)
class TestAdapter(object):
order = 10
block_type = "test"
disabled = True

def __init__(self, context, request):
self.context = context
self.request = request

def __call__(self, value):
self.context._handler_called = True

value["value"] = u"changed: {}".format(value["value"])

return value

provideSubscriptionAdapter(
TestAdapter,
(IDexterityItem, IBrowserRequest),
)
value = self.serialize(
context=self.portal.doc1,
blocks={"123": {"@type": "test", "value": u"text"}},
)

assert not getattr(self.portal.doc1, "_handler_called", False)
self.assertEqual(value["123"]["value"], u"text")

0 comments on commit 3b2e04d

Please sign in to comment.