launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #11769
[Merge] lp:~wallyworld/launchpad/bug-page-oops-1027797 into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/bug-page-oops-1027797 into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #1027797 in Launchpad itself: "OOPS rendering ++model++ page in a context less bug page "
https://bugs.launchpad.net/launchpad/+bug/1027797
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/bug-page-oops-1027797/+merge/123673
== Implementation ==
A url like https://bugs.launchpad.net/bugs/5/++model++ oopes because normally such a url without the ++model++ bit loads a RedirectionView which redirects to the bugtask url. This view has none of the methods called by JsonModelNamespaceView to fetch the model, hence the oops.
I at first extended RedirectionView just to provide empty stubs for the required methods. But, with a little extra work, it was possible to refactor things so that the RedirectionView held on to enough state so that it could, if asked, provide the correct ++model++ data for the redirected view. This requires that RedirectionView subclasses be modified to support this; the default is just to return an empty model. I've fixed the 2 bug view subclasses. Others can be done as and when required.
There's also a bit of lint fixed.
== Tests ==
Provide tests for the RedirectionView ++model++ with and without a cache_view instance.
== Lint ==
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/bugs/browser/bug.py
lib/lp/services/webapp/publisher.py
lib/lp/services/webapp/tests/test_publisher.py
--
https://code.launchpad.net/~wallyworld/launchpad/bug-page-oops-1027797/+merge/123673
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/bug-page-oops-1027797 into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bug.py'
--- lib/lp/bugs/browser/bug.py 2012-09-10 06:45:22 +0000
+++ lib/lp/bugs/browser/bug.py 2012-09-11 02:20:24 +0000
@@ -2,6 +2,7 @@
# GNU Affero General Public License version 3 (see the file LICENSE).
"""IBug related view classes."""
+from zope.publisher.defaultview import getDefaultViewName
__metaclass__ = type
@@ -705,8 +706,12 @@
"""
def __init__(self, context, request):
+ redirected_context = context.default_bugtask
+ viewname = getDefaultViewName(redirected_context, request)
+ cache_view = getMultiAdapter(
+ (redirected_context, request), name=viewname)
super(BugWithoutContextView, self).__init__(
- canonical_url(context.default_bugtask), request)
+ canonical_url(redirected_context), request, cache_view=cache_view)
class BugEditViewBase(LaunchpadEditFormView):
@@ -980,15 +985,15 @@
"""
def __init__(self, context, request):
- self.context = context
- self.request = request
+ redirected_context = getUtility(ILaunchBag).user
+ viewname = '+assignedbugs'
+ cache_view = getMultiAdapter(
+ (redirected_context, request), name=viewname)
+ target = canonical_url(redirected_context, view_name='+assignedbugs')
+ super(DeprecatedAssignedBugsView, self).__init__(
+ target, request, cache_view=cache_view)
self.status = 303
- def __call__(self):
- self.target = canonical_url(
- getUtility(ILaunchBag).user, view_name='+assignedbugs')
- super(DeprecatedAssignedBugsView, self).__call__()
-
normalize_mime_type = re.compile(r'\s+')
=== modified file 'lib/lp/services/webapp/publisher.py'
--- lib/lp/services/webapp/publisher.py 2012-06-29 08:40:05 +0000
+++ lib/lp/services/webapp/publisher.py 2012-09-11 02:20:24 +0000
@@ -982,7 +982,7 @@
text=stepthrough_text)
self.request.traversed_objects.append(
stepthrough_breadcrumb)
-
+
return self._handle_next_object(nextobj, request,
nextstep)
@@ -1018,10 +1018,21 @@
class RedirectionView:
implements(IBrowserPublisher)
- def __init__(self, target, request, status=None):
+ def __init__(self, target, request, status=None, cache_view=None):
self.target = target
self.request = request
self.status = status
+ self.cache_view = cache_view
+
+ def initialize(self):
+ if self.cache_view:
+ self.cache_view.initialize()
+
+ def getCacheJSON(self):
+ if self.cache_view:
+ return self.cache_view.getCacheJSON()
+ else:
+ return simplejson.dumps({})
def __call__(self):
self.request.response.redirect(self.target, status=self.status)
=== modified file 'lib/lp/services/webapp/tests/test_publisher.py'
--- lib/lp/services/webapp/tests/test_publisher.py 2012-05-22 17:00:08 +0000
+++ lib/lp/services/webapp/tests/test_publisher.py 2012-09-11 02:20:24 +0000
@@ -22,6 +22,7 @@
from lp.services.webapp.publisher import (
FakeRequest,
LaunchpadView,
+ RedirectionView,
)
from lp.services.webapp.servers import LaunchpadTestRequest
from lp.services.worlddata.interfaces.country import ICountrySet
@@ -117,6 +118,28 @@
self.assertIs(None, view.user)
self.assertNotIn('user@domain', view.getCacheJSON())
+ def test_getCache_redirected_view_default(self):
+ # A redirection view by default provides no json cache data.
+ request = LaunchpadTestRequest()
+ view = RedirectionView(None, request)
+ json_dict = simplejson.loads(view.getCacheJSON())
+ self.assertEqual({}, json_dict)
+
+ def test_getCache_redirected_view(self):
+ # A redirection view may be provided with a target view instance from
+ # which json cache data is obtained.
+
+ class TestView(LaunchpadView):
+ pass
+
+ request = LaunchpadTestRequest()
+ test_view = TestView(self.getCanada(), request)
+ view = RedirectionView(None, request, cache_view=test_view)
+ IJSONRequestCache(request).objects['my_bool'] = True
+ json_dict = simplejson.loads(view.getCacheJSON())
+ self.assertIsCanada(json_dict['context'])
+ self.assertIn('my_bool', json_dict)
+
def test_related_feature_info__default(self):
# By default, LaunchpadView.related_feature_info is empty.
request = LaunchpadTestRequest()
@@ -310,7 +333,7 @@
view = LaunchpadView(PrivateObject(False), FakeRequest())
self.assertFalse(view.private)
-
+
def test_view_beta_features_simple(self):
class TestView(LaunchpadView):
related_features = ['test_feature']
@@ -322,7 +345,7 @@
view = TestView(object(), request)
expected_beta_features = [{
'url': 'http://wiki.lp.dev/LEP/sample', 'is_beta': True,
- 'value': u'on', 'title': 'title'}]
+ 'value': u'on', 'title': 'title'}]
self.assertEqual(expected_beta_features, view.beta_features)
def test_view_beta_features_mixed(self):
@@ -342,9 +365,10 @@
view = TestView(object(), request)
expected_beta_features = [{
'url': 'http://wiki.lp.dev/LEP/sample', 'is_beta': True,
- 'value': u'on', 'title': 'title'}]
+ 'value': u'on', 'title': 'title'}]
self.assertEqual(expected_beta_features, view.beta_features)
+
def test_suite():
suite = TestSuite()
suite.addTest(DocTestSuite(publisher, optionflags=ELLIPSIS))
Follow ups