Merge lp:~rharding/launchpad/oops_912178 into lp:launchpad

Proposed by Richard Harding on 2012-01-05
Status: Merged
Approved by: Richard Harding on 2012-01-06
Approved revision: no longer in the source branch.
Merged at revision: 14648
Proposed branch: lp:~rharding/launchpad/oops_912178
Merge into: lp:launchpad
Diff against target: 143 lines (+77/-0)
4 files modified
lib/lp/app/javascript/listing_navigator.js (+26/-0)
lib/lp/app/javascript/tests/test_listing_navigator.js (+24/-0)
lib/lp/bugs/browser/bugtask.py (+3/-0)
lib/lp/bugs/browser/tests/test_bugs.py (+24/-0)
To merge this branch: bzr merge lp:~rharding/launchpad/oops_912178
Reviewer Review Type Date Requested Status
Abel Deuring (community) code 2012-01-05 Approve on 2012-01-06
Review via email: mp+87675@code.launchpad.net

Commit Message

[r=adeuring][bug=912178] Add missing method to BugsBugTaskSearchListingView and support a context less View for the buglisting ajax loading.

Description of the Change

= Summary =
The main bug search page threw an oops due to a missing method the template expected.

== Proposed Fix ==
Add the search_macro_title method to the View object so that it can be provided to the template.

== Implementation Details ==
During fixing this, it was also found that the javascript for the bug columns is built with the knowledge that there is always a content in LP.cache for it. This View does not provide a context. I added a special case in order to provide the bare minimum of a lp.client.Entry object for the rest of the javascript to proceed.

== Tests ==
./bin/test -cvvt "test_bugs\.

== Demo and Q/A ==
Make sure you can load and operate the bug listing at bugs.launchpad.net/bugs/+bugs

== Lint ==

Linting changed files:
  lib/lp/app/javascript/client.js
  lib/lp/app/javascript/listing_navigator.js
  lib/lp/bugs/browser/bugtask.py
  lib/lp/bugs/browser/tests/test_bugs.py

To post a comment you must log in.
Abel Deuring (adeuring) wrote :

looks good.

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/javascript/listing_navigator.js'
2--- lib/lp/app/javascript/listing_navigator.js 2011-12-15 17:09:48 +0000
3+++ lib/lp/app/javascript/listing_navigator.js 2012-01-06 13:27:31 +0000
4@@ -16,6 +16,19 @@
5 return new Y.NodeList([]);
6 }
7
8+/**
9+ * If there is no context (say /bugs/+bugs) we need to generate a weblink for
10+ * the lp.client to use for things. This is a helper to take the current url
11+ * and try to generate a likely web_link value to build a url off of.
12+ */
13+function likely_web_link() {
14+ var url = location.href;
15+ var cut_at = url.indexOf('+');
16+
17+ // make sure we trim the trailing / off the web link we generate
18+ return url.substr(0, cut_at - 1);
19+}
20+
21
22 /**
23 * Constructor.
24@@ -362,6 +375,19 @@
25 if (Y.Lang.isValue(this.get('io_provider'))) {
26 load_model_config.io_provider = this.get('io_provider');
27 }
28+
29+ if (!context) {
30+ // try to see if there is no context we can fake the object in
31+ // order to pass through
32+ context = new Y.lp.client.Entry(
33+ new Y.lp.client.Launchpad({
34+ io_provider: load_model_config.io_provider
35+ }), {
36+ 'web_link': likely_web_link()
37+ }
38+ );
39+ }
40+
41 Y.lp.client.load_model(
42 context, view_name, load_model_config, query);
43 }
44
45=== modified file 'lib/lp/app/javascript/tests/test_listing_navigator.js'
46--- lib/lp/app/javascript/tests/test_listing_navigator.js 2011-12-14 19:23:02 +0000
47+++ lib/lp/app/javascript/tests/test_listing_navigator.js 2012-01-06 13:27:31 +0000
48@@ -623,7 +623,31 @@
49 navigator.prev_batch();
50 Y.Assert.areSame(
51 null, navigator.get('io_provider').last_request);
52+ },
53+
54+ /**
55+ * Verify we get a reasonable default context if there is no context
56+ * available as is the case with the BugsBugTaskSearchListingView.
57+ */
58+ test_default_context: function () {
59+ var navigator = get_navigator('', {target: this.target});
60+ // now remove the context
61+ var batch = navigator.get_current_batch();
62+ delete batch.context;
63+
64+ navigator.get_current_batch().view_name = '+funitems';
65+ navigator.load_model({});
66+
67+ // the start of the url used will be whatever the current
68+ // location.href is for the window object. We can make sure we did get
69+ // a nicely generated url though by checking they end built correctly.
70+ var generated_url = navigator.get('io_provider').last_request.url;
71+
72+ Y.Assert.areSame(
73+ '+funitems/++model++',
74+ generated_url.substr(generated_url.indexOf('+')));
75 }
76+
77 }));
78
79 suite.add(new Y.Test.Case({
80
81=== modified file 'lib/lp/bugs/browser/bugtask.py'
82--- lib/lp/bugs/browser/bugtask.py 2011-12-30 08:03:42 +0000
83+++ lib/lp/bugs/browser/bugtask.py 2012-01-06 13:27:31 +0000
84@@ -4233,6 +4233,9 @@
85 """Return the heading to search all Bugs."""
86 return "Search all bug reports"
87
88+ def search_macro_title(self):
89+ return u'Search all bugs'
90+
91 @property
92 def label(self):
93 return self.getSearchPageHeading()
94
95=== modified file 'lib/lp/bugs/browser/tests/test_bugs.py'
96--- lib/lp/bugs/browser/tests/test_bugs.py 2012-01-01 02:58:52 +0000
97+++ lib/lp/bugs/browser/tests/test_bugs.py 2012-01-06 13:27:31 +0000
98@@ -5,10 +5,15 @@
99
100 __metaclass__ = type
101
102+from contextlib import contextmanager
103 from zope.component import getUtility
104
105 from lp.bugs.interfaces.malone import IMaloneApplication
106 from lp.bugs.publisher import BugsLayer
107+from lp.testing import (
108+ set_feature_flag,
109+ feature_flags,
110+ )
111 from lp.services.webapp.publisher import canonical_url
112 from lp.testing import (
113 celebrity_logged_in,
114@@ -19,6 +24,14 @@
115 from lp.testing.views import create_initialized_view
116
117
118+@contextmanager
119+def dynamic_listings():
120+ """Context manager to enable new bug listings."""
121+ with feature_flags():
122+ set_feature_flag(u'bugs.dynamic_bug_listings.enabled', u'on')
123+ yield
124+
125+
126 class TestMaloneView(TestCaseWithFactory):
127 """Test the MaloneView for the Bugs application."""
128 layer = DatabaseFunctionalLayer
129@@ -90,3 +103,14 @@
130 self.assertIn(picker_vocab, text)
131 focus_script = "setFocusByName('field.searchtext')"
132 self.assertIn(focus_script, text)
133+
134+ def test_search_all_bugs_rendering(self):
135+ with dynamic_listings():
136+ view = create_initialized_view(
137+ self.application,
138+ '+bugs',
139+ rootsite='bugs')
140+ content = view.render()
141+
142+ # we should get some valid content out of this
143+ self.assertIn('Search all bugs', content)