Skip to content

Commit

Permalink
Merge 59a89c7 into 73fb775
Browse files Browse the repository at this point in the history
  • Loading branch information
hvelarde committed Aug 4, 2017
2 parents 73fb775 + 59a89c7 commit 65bd9b4
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGES.rst
Expand Up @@ -6,6 +6,9 @@ There's a frood who really knows where his towel is.
1.0a4 (unreleased)
------------------

- Implement validation using Cloudflare's AMP linter API endpoint.
[hvelarde]

- Add support for the ``<amp-pixel>`` tag;
see package documentation for more information on this new feature.
[hvelarde]
Expand Down
3 changes: 3 additions & 0 deletions setup.py
Expand Up @@ -55,6 +55,7 @@
'Products.CMFCore',
'Products.CMFPlone >=4.3',
'Products.GenericSetup',
'requests',
'setuptools',
'zope.i18nmessageid',
'zope.interface',
Expand All @@ -69,6 +70,8 @@
'plone.browserlayer',
'plone.registry',
'plone.testing',
'Products.statusmessages',
'requests-mock',
'robotsuite',
'z3c.relationfield',
'zope.component',
Expand Down
6 changes: 6 additions & 0 deletions src/collective/behavior/amp/configure.zcml
Expand Up @@ -19,4 +19,10 @@
<include file="behaviors.zcml" />
<include file="profiles.zcml" />

<subscriber
for="collective.behavior.amp.behaviors.IAMP
Products.DCWorkflow.interfaces.IAfterTransitionEvent"
handler=".subscribers.validate_amp"
/>

</configure>
32 changes: 32 additions & 0 deletions src/collective/behavior/amp/subscribers.py
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
"""Event subscribers."""
from collective.behavior.amp.logger import logger
from plone import api
from urlparse import urlparse

import requests


def validate_amp(obj, event):
"""Validate @@amp view using Cloudflare's AMP linter API endpoint."""
request = obj.REQUEST

if event.status['review_state'] not in ('published', ):
return

# remove the scheme from the URL
url = ''.join(urlparse(obj.absolute_url())[1:])

r = requests.get('https://amp.cloudflare.com/q/' + url + '/@@amp')
validation = r.json()

if validation['valid']:
msg = u'Valid AMP page'
logger.info(msg)
api.portal.show_message(message=msg, request=request, type='info')
else:
msg = u'Not a valid AMP page'
logger.warn(msg)
api.portal.show_message(message=msg, request=request, type='warn')

# TODO: include information about the errors
2 changes: 1 addition & 1 deletion src/collective/behavior/amp/testing.py
Expand Up @@ -37,7 +37,7 @@ def setUpPloneSite(self, portal):

self.applyProfile(portal, 'collective.behavior.amp:default')
enable_amp_behavior('News Item')
portal.portal_workflow.setDefaultChain('one_state_workflow')
portal.portal_workflow.setDefaultChain('simple_publication_workflow')


FIXTURE = Fixture()
Expand Down
55 changes: 55 additions & 0 deletions src/collective/behavior/amp/tests/test_subscribers.py
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
from collective.behavior.amp.testing import INTEGRATION_TESTING
from plone import api
from Products.statusmessages.interfaces import IStatusMessage

import requests_mock
import unittest


class AMPValidationTestCase(unittest.TestCase):

layer = INTEGRATION_TESTING

def setUp(self):
self.portal = self.layer['portal']
self.request = self.layer['request']

with api.env.adopt_roles(['Manager']):
self.obj = api.content.create(self.portal, 'News Item', 'foo')

@requests_mock.mock()
def test_validate_amp_valid(self, m):
RESPONSE_VALID = """{"source":"http://nohost/plone/foo/@@amp","valid":true}"""
m.get('https://amp.cloudflare.com/q/nohost/plone/foo/@@amp', text=RESPONSE_VALID)

with api.env.adopt_roles(['Manager']):
api.content.transition(self.obj, 'publish')

messages = IStatusMessage(self.request).show()
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0].message, u'Valid AMP page')
self.assertEqual(messages[0].type, u'info')

@requests_mock.mock()
def test_validate_amp_invalid(self, m):
RESPONSE_INVALID = """{"source":"http://nohost/plone/foo/@@amp","valid":false,"errors":[{"line":169,"col":0,"code":"GENERAL_DISALLOWED_TAG","error":"The tag 'script' is disallowed except in specific forms."}]}"""
m.get('https://amp.cloudflare.com/q/nohost/plone/foo/@@amp', text=RESPONSE_INVALID)

with api.env.adopt_roles(['Manager']):
api.content.transition(self.obj, 'publish')

messages = IStatusMessage(self.request).show()
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0].message, u'Not a valid AMP page')
self.assertEqual(messages[0].type, u'warn')

@unittest.expectedFailure # FIXME
def test_validate_amp_with_package_uninstalled(self):
from collective.behavior.amp.config import PROJECTNAME
qi = self.portal['portal_quickinstaller']
qi.uninstallProducts(products=[PROJECTNAME])

# don't fail if package uninstalled
with api.env.adopt_roles(['Manager']):
api.content.transition(self.obj, 'publish')

0 comments on commit 65bd9b4

Please sign in to comment.