Commit bcd82831 authored by Romain Courteaud's avatar Romain Courteaud

erp5_hal_json_style/erp5_web: fix http cache condition

The main query to the hateoas web section must be cache by the browser,
to reduce the number of queries by 2.

Caching policy manager conditions are checked before calculating the query result,
and so, it is not possible anymore to wait for the script to explicitely
ask for the result to be cached.
parent dac1a00c
Pipeline #36810 failed with stage
in 0 seconds
......@@ -1615,7 +1615,6 @@ def calculateHateoas(is_portal=None, is_site_root=None, traversed_document=None,
if is_site_root:
result_dict['default_view'] = 'view'
REQUEST.set("X-HATEOAS-CACHE", 1)
# Global action users for the jIO plugin
# XXX Would be better to not hardcode them but put them as portal type
......
......@@ -15,6 +15,7 @@ import DateTime
import StringIO
import json
import re
import io
from six.moves.urllib.parse import quote, quote_plus
import mock
......@@ -3265,3 +3266,113 @@ class TestERP5ODS(ERP5HALJSONStyleSkinsMixin):
self.assertTrue('Read-Only Quantity' in result, result)
# Ensure it is not the list mode rendering
self.assertTrue(len(result.split('\n')) > 50, result)
class TestERP5Document_getHateoas_cache(ERP5HALJSONStyleSkinsMixin):
def testCache_root_authenticated(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'application/hal+json')
self.assertEqual(ret.getHeader('cache-control'), 'max-age=1800, private')
def testCache_root_authenticatedWrongPath(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath(),
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'application/hal+json')
self.assertEqual(ret.getHeader('cache-control'), 'max-age=1800, private')
def testCache_root_authenticatedAndMethodCall(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/getId',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'text/plain; charset=utf-8')
self.assertEqual(ret.getHeader('cache-control'), 'private')
def testCache_root_authenticatedWrongQueryString(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/?foo=bar',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'application/hal+json')
self.assertEqual(ret.getHeader('cache-control'), 'max-age=0, no-cache, private')
def testCache_root_authenticatedWrongMethod(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/',
user='ERP5TypeTestCase',
request_method='POST'
)
self.assertEqual(ret.getStatus(), 405)
self.assertEqual(ret.getHeader('content-type'), None)
self.assertEqual(ret.getHeader('cache-control'), 'max-age=0, no-cache, private')
def testCache_root_anonymous(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/',
)
self.assertEqual(ret.getStatus(), 401)
self.assertEqual(ret.getHeader('content-type'), None)
self.assertEqual(ret.getHeader('cache-control'), 'max-age=0, no-cache, private')
def testCache_traverse_authenticatedAndWrongTraverse(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/ERP5Document_getHateoas?mode=traverse&relative_url=unexisting_module&view=view',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 404)
self.assertEqual(ret.getHeader('content-type'), None)
self.assertEqual(ret.getHeader('cache-control'), 'private')
def testCache_traverse_authenticatedAndTraverse(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/ERP5Document_getHateoas?mode=traverse&relative_url=foo_module&view=view',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'application/hal+json')
self.assertEqual(ret.getHeader('cache-control'), 'private')
def testCache_traverse_authenticatedAndTraverseWrongView(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/ERP5Document_getHateoas?mode=traverse&relative_url=foo_module&view=foobarview',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 404)
self.assertEqual(ret.getHeader('content-type'), None)
self.assertEqual(ret.getHeader('cache-control'), 'private')
def testCache_traverse_authenticatedAndSearch(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/ERP5Document_getHateoas?mode=search',
user='ERP5TypeTestCase'
)
self.assertEqual(ret.getStatus(), 200)
self.assertEqual(ret.getHeader('content-type'), 'application/hal+json')
self.assertEqual(ret.getHeader('cache-control'), 'private')
def testCache_traverse_authenticatedAndDoAction(self):
ret = self.publish(
self.portal.web_site_module.hateoas.getPath() + '/foo_module/Base_callDialogMethod',
user='ERP5TypeTestCase',
request_method='POST',
stdin=io.BytesIO(
'field_your_select_action=add Foo&' +
'form_id=FooModule_viewFooList&' +
'dialog_id=Base_viewNewContentDialog&' +
'dialog_method=Base_doAction'
),
env={'CONTENT_TYPE': 'application/x-www-form-urlencoded'}
)
self.assertEqual(ret.getStatus(), 201)
self.assertEqual(ret.getHeader('content-type'), 'application/json; charset=utf-8')
self.assertEqual(ret.getHeader('cache-control'), 'private')
......@@ -1506,7 +1506,7 @@
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: member is not None and (lambda x: x is not None and x.getCachingPolicy() =="hateoas")(object.getWebSectionValue()) and request.get("X-HATEOAS-CACHE")</string> </value>
<value> <string>python: (member is not None) and (request.other[\'method\'] == "GET") and (request.environ[\'QUERY_STRING\'] == "") and (lambda x: (x is not None) and (request.other[\'PUBLISHED\'] == x) and (x.getCachingPolicy() == "hateoas"))(object.getWebSectionValue())</string> </value>
  • @romain This change caused some test failures like

    ======================================================================
    ERROR: test_CreateImage (erp5.component.test.erp5_version.testERP5Base.TestImage)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "/(SR)/parts/erp5/bt5/erp5_core_test/TestTemplateItem/portal_components/test.erp5.testERP5Base.py", line 2091, in test_CreateImage
        image.view() # viewing the image does not cause error
      File "/(SR)/parts/erp5/product/ERP5Type/Base.py", line 2562, in view
        _setCacheHeaders(view, {})
      File "/(SR)/eggs/Products.CMFCore-2.7.0+slapospatched003-py2.7.egg/Products/CMFCore/utils.py", line 501, in _setCacheHeaders
        content, view_name, extra_context)
      File "/(SR)/eggs/Products.CMFCore-2.7.0+slapospatched003-py2.7.egg/Products/CMFCore/CachingPolicyManager.py", line 808, in getHTTPCachingHeaders
        headers = policy.getHeaders(context)
      File "/(SR)/parts/erp5/product/ERP5Type/patches/CachingPolicyManager.py", line 105, in getHeaders
        if self.testPredicate( expr_context ):
      File "/(SR)/eggs/Products.CMFCore-2.7.0+slapospatched003-py2.7.egg/Products/CMFCore/CachingPolicyManager.py", line 374, in testPredicate
        return self._predicate(expr_context)
      File "/(SR)/eggs/Products.CMFCore-2.7.0+slapospatched003-py2.7.egg/Products/CMFCore/Expression.py", line 53, in __call__
        res = compiled(econtext)
      File "/(SR)/eggs/Zope-4.8.11+slapospatched002-py2.7.egg/Products/PageTemplates/ZRPythonExpr.py", line 49, in __call__
        return eval(self._code, vars, {})
      File "PythonExpr", line 1, in <module>
      File "/(SR)/eggs/AccessControl-4.4-py2.7-linux-x86_64.egg/AccessControl/ZopeGuards.py", line 110, in guarded_getitem
        v = object[index]
    KeyError: 'QUERY_STRING'
    
Please register or sign in to reply
</item>
</dictionary>
</pickle>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment