Commit 9651e553 authored by Jérome Perrin's avatar Jérome Perrin

CMFActivity: Always set zope.globalrequest

ERP5 uses a mix of context.REQUEST and Products.ERP5Type.Global.get_request(),
which now uses zope.globalrequest.getRequest().
CMFActivity reconstruct the original request before executing activity, so that
the activity is executed with a request equivalent to the request at the time
where the method was activated. For this, context.REQUEST was properly restored,
but get_request()/globalrequest was only restored when the REQUEST had some
Accept-Language header, so that it replays the language negociation for
Localizer.

With browser requests, I guess every browser pass an Accept-Language header (
according to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language
all major browser support it), but within unit tests such header is not present.
So this lead to activities with unit test requests being slightly different,
because as they don't have Accept-Language, context.REQUEST was set, but the
global request was not set, so they were running with two different requests
in context.REQUEST and global request, leading to some problems for example
with formulator fields.
parent 9e6db4ee
Pipeline #14476 failed with stage
in 0 seconds
...@@ -1497,7 +1497,6 @@ class ActivityTool (BaseTool): ...@@ -1497,7 +1497,6 @@ class ActivityTool (BaseTool):
def invoke(self, message): def invoke(self, message):
if self.activity_tracking: if self.activity_tracking:
activity_tracking_logger.info('invoking message: object_path=%s, method_id=%s, args=%r, kw=%r, activity_kw=%r, user_name=%s' % ('/'.join(message.object_path), message.method_id, message.args, message.kw, message.activity_kw, message.user_name)) activity_tracking_logger.info('invoking message: object_path=%s, method_id=%s, args=%r, kw=%r, activity_kw=%r, user_name=%s' % ('/'.join(message.object_path), message.method_id, message.args, message.kw, message.activity_kw, message.user_name))
restore_request = False
if getattr(self, 'aq_chain', None) is not None: if getattr(self, 'aq_chain', None) is not None:
# Grab existing acquisition chain and extrach base objects. # Grab existing acquisition chain and extrach base objects.
base_chain = [aq_base(x) for x in self.aq_chain] base_chain = [aq_base(x) for x in self.aq_chain]
...@@ -1521,7 +1520,9 @@ class ActivityTool (BaseTool): ...@@ -1521,7 +1520,9 @@ class ActivityTool (BaseTool):
request.environ['PATH_INFO'] = '/Control_Panel/timer_service/process_timer' request.environ['PATH_INFO'] = '/Control_Panel/timer_service/process_timer'
# restore request information # restore request information
old_request = getRequest()
new_request = request.clone() new_request = request.clone()
setRequest(new_request)
request_info = message.request_info request_info = message.request_info
# PARENTS is truncated by clone # PARENTS is truncated by clone
new_request.other['PARENTS'] = parents new_request.other['PARENTS'] = parents
...@@ -1533,9 +1534,6 @@ class ActivityTool (BaseTool): ...@@ -1533,9 +1534,6 @@ class ActivityTool (BaseTool):
new_request.other['VirtualRootPhysicalPath'] = request_info['VirtualRootPhysicalPath'] new_request.other['VirtualRootPhysicalPath'] = request_info['VirtualRootPhysicalPath']
if 'HTTP_ACCEPT_LANGUAGE' in request_info: if 'HTTP_ACCEPT_LANGUAGE' in request_info:
new_request.environ['HTTP_ACCEPT_LANGUAGE'] = request_info['HTTP_ACCEPT_LANGUAGE'] new_request.environ['HTTP_ACCEPT_LANGUAGE'] = request_info['HTTP_ACCEPT_LANGUAGE']
old_request = getRequest()
restore_request = True
setRequest(new_request)
new_request.processInputs() new_request.processInputs()
new_request_container = request_container.__class__(REQUEST=new_request) new_request_container = request_container.__class__(REQUEST=new_request)
...@@ -1554,8 +1552,7 @@ class ActivityTool (BaseTool): ...@@ -1554,8 +1552,7 @@ class ActivityTool (BaseTool):
# Restore default skin selection # Restore default skin selection
skinnable = self.getPortalObject() skinnable = self.getPortalObject()
skinnable.changeSkin(skinnable.getSkinNameFromRequest(request)) skinnable.changeSkin(skinnable.getSkinNameFromRequest(request))
if restore_request: setRequest(old_request)
setRequest(old_request)
if self.activity_tracking: if self.activity_tracking:
activity_tracking_logger.info('invoked message') activity_tracking_logger.info('invoked message')
if my_self is not self: # We rewrapped self if my_self is not self: # We rewrapped self
......
...@@ -1089,6 +1089,25 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor): ...@@ -1089,6 +1089,25 @@ class TestCMFActivity(ERP5TypeTestCase, LogInterceptor):
del Organisation.putMarkerValue del Organisation.putMarkerValue
del Organisation.checkMarkerValue del Organisation.checkMarkerValue
def test_globalrequest(self):
"""zope.globalrequest.getRequest (also known as Products.Global.get_request)
should be same as app.REQUEST, also when executing activities.
"""
from zope.globalrequest import getRequest
get_request_before = getRequest()
def checkRequest(active_self):
self.assertIs(getRequest(), active_self.REQUEST)
obj = self.portal.organisation_module.newContent(portal_type='Organisation')
Organisation.checkRequest = checkRequest
try:
obj.activate(activity='SQLQueue').checkRequest()
obj.activate(activity='SQLDict').checkRequest()
self.tic()
finally:
del Organisation.checkRequest
self.assertIs(getRequest(), get_request_before)
@for_each_activity @for_each_activity
def testTryUserNotificationOnActivityFailure(self, activity): def testTryUserNotificationOnActivityFailure(self, activity):
message_list = self.portal.MailHost._message_list message_list = self.portal.MailHost._message_list
......
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