Ticket #13173 (closed Bug: fixed)

Opened 19 months ago

Last modified 14 months ago

ContentViewsViewlets relies on ACTUAL_URL to be present

Reported by: miohtama Owned by:
Priority: minor Milestone: 4.x
Component: Templates/CSS Version: 4.1
Keywords: Cc:

Description

In plone.app.layout.viewlets Content View viewlet relies that HTTPRequest object has ACTUAL_URL set. However, there are test code paths where a Plone page gets rendered even if there is no a real HTTP request available. One being RegistrationTool registeredNotify() mail_password_response() which tries to send mail out.

If you trigger registration in unit tests the tests fail because of the page gets rendered (the root cause, not sure if this is what should happen?) and the unit tests fails.

I am not sure what's viewlet policy how they should behave and is it RegistrationTool which needs some fixes?

Full traceback:

    Error in test test_logout_smartcard (xxxtesting.ui.test_smartcard.TestSmartcard)
    Traceback (most recent call last):
      File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 318, in run
        self.setUp()
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/ui/test_smartcard.py", line 193, in setUp
        self.xxx_helper.create_all()
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/xxxhelper.py", line 594, in create_all
        self.create_xxx_manager("xxx_manager")
      File "/Users/mikko/code/xxx-dev/src/xxx-packages/xxxtesting/xxxtesting/xxxhelper.py", line 412, in create_xxx_manager
        mem.update(**data)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/content/member.py", line 653, in update
        triggerAutomaticTransitions(self)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/Extensions/workflow.py", line 34, in triggerAutomaticTransitions
        wf_tool.doActionFor(ob, 'trigger')
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/WorkflowTool.py", line 241, in doActionFor
        wfs, ob, action, wf.doActionFor, (ob, action) + args, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/WorkflowTool.py", line 552, in _invokeWithNotification
        res = func(*args, **kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 282, in doActionFor
        self._changeStateOf(ob, tdef, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 421, in _changeStateOf
        sdef = self._executeTransition(ob, tdef, kwargs)
      File "/Users/mikko/code/buildout-cache/eggs/Products.DCWorkflow-2.2.4-py2.7.egg/Products/DCWorkflow/DCWorkflow.py", line 474, in _executeTransition
        script(sci)  # May throw an exception.
      File "/Users/mikko/code/buildout-cache/eggs/Products.ExternalMethod-2.13.0-py2.7.egg/Products/ExternalMethod/ExternalMethod.py", line 241, in __call__
        return f(self.aq_parent.this(), *args, **kw)
       - __traceback_info__: ((<Products.DCWorkflow.Expression.StateChangeInfo instance at 0x107492e18>,), {}, None)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/Extensions/workflow.py", line 64, in register
        return obj.register()
      File "/Users/mikko/code/xxx-dev/src/xxx-eggs/Products.xxxHospital/Products/xxxHospital/content/xxxUser.py", line 194, in register
        BaseMember.register(self)
      File "/Users/mikko/code/buildout-cache/eggs/Products.remember-1.9.1-py2.7.egg/Products/remember/content/member.py", line 718, in register
        rtool.registeredNotify(self.getId())
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFPlone-4.1.6-py2.7.egg/Products/CMFPlone/RegistrationTool.py", line 345, in registeredNotify
        return self.mail_password_response(self, self.REQUEST)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 322, in __call__
        return self._bindAndExec(args, kw, None)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Shared/DC/Scripts/Bindings.py", line 359, in _bindAndExec
        return self._exec(bound_data, args, kw)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/FSPageTemplate.py", line 237, in _exec
        result = self.pt_render(extra_context=bound_names)
      File "/Users/mikko/code/buildout-cache/eggs/Products.CMFCore-2.2.6-py2.7.egg/Products/CMFCore/FSPageTemplate.py", line 177, in pt_render
        self, source, extra_context
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/PageTemplate.py", line 79, in pt_render
        showtal=showtal)
      File "/Users/mikko/code/buildout-cache/eggs/zope.pagetemplate-3.5.2-py2.7.egg/zope/pagetemplate/pagetemplate.py", line 113, in pt_render
        strictinsert=0, sourceAnnotations=sourceAnnotations)()
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 271, in __call__
        self.interpret(self.program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 888, in do_useMacro
        self.interpret(macro)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
        self.do_optTag(stuff)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 518, in do_optTag
        return self.no_tag(start, program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 954, in do_defineSlot
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 533, in do_optTag_tal
        self.do_optTag(stuff)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 518, in do_optTag
        return self.no_tag(start, program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 858, in do_defineMacro
        self.interpret(macro)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 852, in do_condition
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 742, in do_insertStructure_tal
        structure = self.engine.evaluateStructure(expr)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 218, in evaluateStructure
        text = super(ZopeContext, self).evaluateStructure(expr)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/tales.py", line 696, in evaluate
        return expression(self)
       - file:/Users/mikko/code/xxx-dev/src/xxx-packages/plonetheme.xxxexternal/plonetheme/xxxexternal/skins/plonetheme_xxxexternal_custom_templates/main_template.pt
       - Line 83, Column 20
       - Expression: <StringExpr u'plone.contentviews'>
       - Names:
          {'container': <PloneSite at /plone>,
           'context': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'default': <object object at 0x10204e970>,
           'here': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'loop': {},
           'nothing': None,
           'options': {'args': (<RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
                                <HTTPRequest, URL=http://localhost:55001>)},
           'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x107704c00>,
           'request': <HTTPRequest, URL=http://localhost:55001>,
           'root': <Application at >,
           'template': <FSPageTemplate at /plone/mail_password_response used for /plone/portal_registration>,
           'traverse_subpath': [],
           'user': <PloneUser 'admin'>}
      File "/Users/mikko/code/buildout-cache/eggs/zope.contentprovider-3.7.2-py2.7.egg/zope/contentprovider/tales.py", line 80, in __call__
        return provider.render()
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.viewletmanager-2.0.2-py2.7.egg/plone/app/viewletmanager/manager.py", line 154, in render
        return BaseOrderedViewletManager.render(self)
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.viewletmanager-2.0.2-py2.7.egg/plone/app/viewletmanager/manager.py", line 85, in render
        return u'\n'.join([viewlet.render() for viewlet in self.viewlets])
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/common.py", line 48, in render
        return self.index()
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/Five/browser/pagetemplatefile.py", line 125, in __call__
        return self.im_func(im_self, *args, **kw)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/Five/browser/pagetemplatefile.py", line 59, in __call__
        sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0),
      File "/Users/mikko/code/buildout-cache/eggs/zope.pagetemplate-3.5.2-py2.7.egg/zope/pagetemplate/pagetemplate.py", line 113, in pt_render
        strictinsert=0, sourceAnnotations=sourceAnnotations)()
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 271, in __call__
        self.interpret(self.program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 852, in do_condition
        self.interpret(block)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 531, in do_optTag_tal
        self.no_tag(stuff[-2], stuff[-1])
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 513, in no_tag
        self.interpret(program)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 343, in interpret
        handlers[opcode](self, args)
      File "/Users/mikko/code/buildout-cache/eggs/zope.tal-3.5.2-py2.7.egg/zope/tal/talinterpreter.py", line 583, in do_setLocal_tal
        self.engine.setLocal(name, self.engine.evaluateValue(expr))
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/tales.py", line 696, in evaluate
        return expression(self)
       - /Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/contentviews.pt
       - Line 6, Column 4
       - Expression: <PathExpr standard:u'view/prepareObjectTabs'>
       - Names:
          {'args': (),
           'container': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'context': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'default': <object object at 0x10204e970>,
           'here': <RegistrationTool at /plone/portal_registration used for /plone/portal_memberdata/xxx_manager>,
           'loop': {},
           'nothing': None,
           'options': {},
           'repeat': <Products.PageTemplates.Expressions.SafeMapping object at 0x107afe050>,
           'request': <HTTPRequest, URL=http://localhost:55001>,
           'root': <Application at >,
           'template': <Products.Five.browser.pagetemplatefile.ViewPageTemplateFile object at 0x105dfb810>,
           'traverse_subpath': [],
           'user': <PloneUser 'admin'>,
           'view': <Products.Five.viewlet.metaconfigure.ContentViewsViewlet object at 0x10868c050>,
           'views': <Products.Five.browser.pagetemplatefile.ViewMapper object at 0x107ff1f90>}
      File "/Users/mikko/code/buildout-cache/eggs/zope.tales-3.5.2-py2.7.egg/zope/tales/expressions.py", line 217, in __call__
        return self._eval(econtext)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 155, in _eval
        return render(ob, econtext.vars)
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/Products/PageTemplates/Expressions.py", line 117, in render
        ob = ob()
      File "/Users/mikko/code/buildout-cache/eggs/plone.memoize-1.1.1-py2.7.egg/plone/memoize/view.py", line 47, in memogetter
        value = cache[key] = func(*args, **kwargs)
      File "/Users/mikko/code/buildout-cache/eggs/plone.app.layout-2.1.13-py2.7.egg/plone/app/layout/viewlets/common.py", line 258, in prepareObjectTabs
        request_url = self.request['ACTUAL_URL']
      File "/Users/mikko/code/buildout-cache/eggs/Zope2-2.13.15-py2.7.egg/ZPublisher/HTTPRequest.py", line 1372, in __getitem__
        raise KeyError, key
    KeyError: 'ACTUAL_URL'


Change History

comment:1 Changed 19 months ago by miohtama

Yes in fact it is the registration tool which renders mail_password_response.pt through acquisition even though UI code path has not been taken: there is no way to tell that the request is not a real, or there is no request present to RegistrationTool.

This seems to be regression of some sort. I am pretty sure this did not happen in the past.

comment:2 Changed 19 months ago by kleist

  • Status changed from new to confirmed

comment:3 Changed 14 months ago by vangheem

  • Summary changed from ContentViewViewlets relies on ACTUAL_URL to be represent to ContentViewsViewlets relies on ACTUAL_URL to be represent

comment:4 Changed 14 months ago by kleist

  • Summary changed from ContentViewsViewlets relies on ACTUAL_URL to be represent to ContentViewsViewlets relies on ACTUAL_URL to be present

comment:5 Changed 14 months ago by vangheem

  • Status changed from confirmed to closed
  • Resolution set to fixed
Note: See TracTickets for help on using tickets.