Merge lp:~sinzui/launchpad/redirect-201 into lp:launchpad

Proposed by Curtis Hovey on 2012-11-26
Status: Merged
Approved by: Curtis Hovey on 2012-11-26
Approved revision: no longer in the source branch.
Merged at revision: 16311
Proposed branch: lp:~sinzui/launchpad/redirect-201
Merge into: lp:launchpad
Diff against target: 83 lines (+24/-20)
3 files modified
lib/lp/app/doc/launchpadview.txt (+0/-19)
lib/lp/services/webapp/publisher.py (+3/-1)
lib/lp/services/webapp/tests/test_publisher.py (+21/-0)
To merge this branch: bzr merge lp:~sinzui/launchpad/redirect-201
Reviewer Review Type Date Requested Status
Benji York (community) code 2012-11-26 Approve on 2012-11-26
Review via email: mp+136198@code.launchpad.net

Commit Message

Do not render html when status is 201.

Description of the Change

I'm getting oopses while trying to submit a merge proposal where the
description has a non-ASCII character in it. The character in question
was a Unicode emdash.

The traceback shows that the MP was was created, the error happened when
that page is rendeder. While the unicode error is odd, it is equally
odd that the view is rendering HTML for an ajax view with a status
of 201. The work is wasteful.

--------------------------------------------------------------------

RULES

    Pre-implementation: no one
    * The action is setting 201 and the location so that the ajax method
      will issue its own redirect.
      * When the HTML for is used, the action sets next_url which sets up
        a redirection view and does not render the template.
    * Add 201 to the list of statuses that the LaunchpadView does not
      render a content.

QA

    * Visit https://code.qastaging.launchpad.net/~sinzui/launchpad/mailman-archive-0/+register-merge
    * Enter "This has a mdash — that I can see" in the comment field.
    * Submit the MP.
    * Verify your browser loads the MP.

LINT

    lib/lp/app/doc/launchpadview.txt
    lib/lp/services/webapp/publisher.py
    lib/lp/services/webapp/tests/test_publisher.py

LoC

    I have a 16,000 credit this week

TEST

    ./bin/test -vvc -t LaunchpadView lp.services.webapp.tests.test_publisher
    ./bin/test -vvc -t launchpadview.txt lp.app.tests.test_doc

IMPLEMENTATION

I added unittests for _isRedirected() and how __call__() uses it. Added
201 to the list of statuses that do not render page content. I removed
a doctest that was replaced by a unittest.
    lib/lp/app/doc/launchpadview.txt
    lib/lp/services/webapp/publisher.py
    lib/lp/services/webapp/tests/test_publisher.py

Do not render html when status is 201.

To post a comment you must log in.
Benji York (benji) wrote :

The branch looks good.

Trivial thought: it might be nice if the list of status codes that do not trigger a page render were stored in a variable so the tests could iterate over them instead of having to keep the tests in sync with the implementation.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/app/doc/launchpadview.txt'
2--- lib/lp/app/doc/launchpadview.txt 2011-12-24 17:49:30 +0000
3+++ lib/lp/app/doc/launchpadview.txt 2012-11-26 18:46:23 +0000
4@@ -51,25 +51,6 @@
5 >>> print view.user.name
6 name16
7
8-When the initialize method does a redirection, the render method should
9-not be called.
10-
11- >>> class MyRedirectView(LaunchpadView):
12- ...
13- ... def initialize(self):
14- ... print "Redirecting..."
15- ... self.request.response.redirect('http://localhost/')
16- ...
17- ... def render(self):
18- ... return "Should not be called."
19- ...
20- >>> request = LaunchpadTestRequest()
21- >>> view = MyRedirectView(context, request)
22- >>> result = view()
23- Redirecting...
24- >>> result
25- u''
26-
27 A view can have `error_message` or `info_message` set for display in
28 the template (each template is responsible for including the messages,
29 using a `structure` directive). The supplied value must be None or
30
31=== modified file 'lib/lp/services/webapp/publisher.py'
32--- lib/lp/services/webapp/publisher.py 2012-10-04 20:38:22 +0000
33+++ lib/lp/services/webapp/publisher.py 2012-11-26 18:46:23 +0000
34@@ -293,6 +293,8 @@
35 (i.e. context doesn't properly indicate privacy).
36 """
37
38+ REDIRECTED_STATUSES = [201, 301, 302, 303, 307]
39+
40 @property
41 def private(self):
42 """A view is private if its context is."""
43@@ -431,7 +433,7 @@
44
45 Check if the response status is one of 301, 302, 303 or 307.
46 """
47- return self.request.response.getStatus() in [301, 302, 303, 307]
48+ return self.request.response.getStatus() in self.REDIRECTED_STATUSES
49
50 def __call__(self):
51 self.initialize()
52
53=== modified file 'lib/lp/services/webapp/tests/test_publisher.py'
54--- lib/lp/services/webapp/tests/test_publisher.py 2012-09-11 02:01:52 +0000
55+++ lib/lp/services/webapp/tests/test_publisher.py 2012-11-26 18:46:23 +0000
56@@ -140,6 +140,27 @@
57 self.assertIsCanada(json_dict['context'])
58 self.assertIn('my_bool', json_dict)
59
60+ def test_isRedirected_status_codes(self):
61+ request = LaunchpadTestRequest()
62+ view = LaunchpadView(object(), request)
63+ for code in view.REDIRECTED_STATUSES:
64+ request.response.setStatus(code)
65+ self.assertTrue(view._isRedirected())
66+ for code in [100, 200, 403, 404, 500]:
67+ request.response.setStatus(code)
68+ self.assertFalse(view._isRedirected())
69+
70+ def test_call_render_with_isRedirected(self):
71+ class TestView(LaunchpadView):
72+ def render(self):
73+ return u'rendered'
74+ request = LaunchpadTestRequest()
75+ view = TestView(object(), request)
76+ request.response.setStatus(200)
77+ self.assertEqual(u'rendered', view())
78+ request.response.setStatus(301)
79+ self.assertEqual(u'', view())
80+
81 def test_related_feature_info__default(self):
82 # By default, LaunchpadView.related_feature_info is empty.
83 request = LaunchpadTestRequest()