Merge lp:~sinzui/charmworld/charm-object-damn-it-2 into lp:~juju-jitsu/charmworld/trunk

Proposed by Curtis Hovey
Status: Merged
Approved by: Aaron Bentley
Approved revision: 298
Merged at revision: 295
Proposed branch: lp:~sinzui/charmworld/charm-object-damn-it-2
Merge into: lp:~juju-jitsu/charmworld/trunk
Diff against target: 273 lines (+71/-47)
3 files modified
charmworld/templates/charm-collection.pt (+3/-3)
charmworld/views/charms.py (+31/-29)
charmworld/views/tests/test_charms.py (+37/-15)
To merge this branch: bzr merge lp:~sinzui/charmworld/charm-object-damn-it-2
Reviewer Review Type Date Requested Status
Aaron Bentley (community) Approve
Review via email: mp+172898@code.launchpad.net

Commit message

Always pass charm objects to the charm-collection template.

Description of the change

Always pass charm objects to the charm-collection template.

RULES

    This branch, pre-implementation: abentley
    * Update all the charm-collection.py views to use a charm object.
    * Extract the common query and format logic in the views to a
      helper function

    Next Branches
    * The hooks template still uses a charm dict.

QA

    Verify these pages load. Each has the problem bonnie charm.
    * Visit http://staging.jujucharms.com/charms
    * Visit http://staging.jujucharms.com/charms/precise
    * Visit http://staging.jujucharms.com/~charmers
    * Visit http://staging.jujucharms.com/~charmers/precise

To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmworld/templates/charm-collection.pt'
2--- charmworld/templates/charm-collection.pt 2013-07-03 15:29:09 +0000
3+++ charmworld/templates/charm-collection.pt 2013-07-03 20:14:25 +0000
4@@ -33,9 +33,9 @@
5 </tr>
6 </thead>
7 <tr tal:repeat="charm charms">
8- <td><a href="/charms/${charm['series']}/${charm['name']}">${charm["name"]}</a></td>
9- <td tal:content="charm['summary'] | nothing"></td>
10- <td tal:content="charm['series']"></td>
11+ <td><a href="/charms/${charm.series}/${charm.name}">${charm.name}</a></td>
12+ <td tal:content="charm.summary"></td>
13+ <td tal:content="charm.series"></td>
14 </tr>
15 </table>
16 </div>
17
18=== modified file 'charmworld/views/charms.py'
19--- charmworld/views/charms.py 2013-06-25 08:59:50 +0000
20+++ charmworld/views/charms.py 2013-07-03 20:14:25 +0000
21@@ -178,16 +178,38 @@
22 content_type=u"application/json")
23
24
25+def found_charm_collection(db, query, sub_only, only_promulgated=False):
26+ """Return a dict of found charms with subordinates flag.
27+
28+ Build a list of Charm objects for the found charm data. The list is
29+ added to a dict (as charms) with a sub_only key to indicate if the
30+ query is for subordinates only. The dict is compatible with the
31+ charm-collection.pt template.
32+
33+ :param db: The database to query.
34+ :param query: The query to match charms.
35+ :param sub_only: Is the query restricted to subordinates?
36+ :param only_promulgated: restrict the query to promulgated charms.
37+ Default False.
38+ :return: A dict {charms: [<Charm>], sub_only: sub_only}.
39+ """
40+ collection_project = {
41+ "name": 1, "owner": 1, "series": 1, "summary": 1, "short_url": 1}
42+ collection_sort = [("name", pymongo.ASCENDING)]
43+ results = found(find_charms(
44+ db, query, collection_project,
45+ sort=collection_sort, only_promulgated=only_promulgated))
46+ charms = [Charm(charm_data) for charm_data in results]
47+ return {"charms": charms, 'sub_only': sub_only}
48+
49+
50 @cached_view_config(
51 route_name="charm-collection",
52 renderer="charmworld:templates/charm-collection.pt")
53 def charm_collection(request):
54 query, sub_only = sub_filter({}, request)
55- charms = found(find_charms(
56- request.db, query,
57- {"name": 1, "owner": 1, "series": 1, "summary": 1, "short_url": 1},
58- sort=[("name", pymongo.ASCENDING)], only_promulgated=True))
59- return {"charms": list(charms), 'sub_only': sub_only}
60+ return found_charm_collection(
61+ request.db, query, sub_only, only_promulgated=True)
62
63
64 @cached_view_config(
65@@ -197,11 +219,7 @@
66 query, sub_only = sub_filter({
67 "owner": request.matchdict["owner"]
68 }, request)
69- charms = found(find_charms(
70- request.db, query,
71- {"name": 1, "owner": 1, "series": 1, "summary": 1, "short_url": 1},
72- sort=[("name", pymongo.ASCENDING)]))
73- return {"charms": list(charms), "sub_only": sub_only}
74+ return found_charm_collection(request.db, query, sub_only)
75
76
77 @cached_view_config(
78@@ -210,19 +228,8 @@
79 def series_collection(request):
80 query, sub_only = sub_filter(
81 {"series": request.matchdict["series"]}, request)
82- charms = found(find_charms(
83- request.db, query,
84- {
85- "name": 1,
86- "owner": 1,
87- "series": 1,
88- "summary": 1,
89- "short_url": 1,
90- 'store_url': True,
91- },
92- sort=[("name", pymongo.ASCENDING)],
93- only_promulgated=True))
94- return {"charms": list(charms), 'sub_only': sub_only}
95+ return found_charm_collection(
96+ request.db, query, sub_only, only_promulgated=True)
97
98
99 @cached_view_config(
100@@ -235,12 +242,7 @@
101 "series": request.matchdict["series"]
102 },
103 request)
104-
105- charms = found(find_charms(
106- request.db, query,
107- {"name": 1, "owner": 1, "series": 1, "summary": 1, "short_url": 1},
108- sort=[("name", pymongo.ASCENDING)]))
109- return {"charms": list(charms), 'sub_only': sub_only}
110+ return found_charm_collection(request.db, query, sub_only)
111
112
113 def find_charm(request, promulgated=False):
114
115=== modified file 'charmworld/views/tests/test_charms.py'
116--- charmworld/views/tests/test_charms.py 2013-07-03 15:29:09 +0000
117+++ charmworld/views/tests/test_charms.py 2013-07-03 20:14:25 +0000
118@@ -24,6 +24,7 @@
119 config,
120 distro_charm,
121 distro_charm_json,
122+ found_charm_collection,
123 hook,
124 interface,
125 featured_edit,
126@@ -39,6 +40,27 @@
127
128 class TestCharms(ViewTestBase):
129
130+ def test_found_charm_collection(self):
131+ """found_charm_collection() returns a dict of charm objects."""
132+ _id, one = factory.makeCharm(self.db, name='bee', promulgated=True)
133+ _id, two = factory.makeCharm(self.db, name='awk', promulgated=True)
134+ _id, three = factory.makeCharm(self.db, name='cat', promulgated=False)
135+ query = {"series": 'precise'}
136+ sub_only = False
137+ # The only_promulgated kwarg limits the sorted charms.
138+ collection = found_charm_collection(
139+ self.db, dict(query), sub_only, only_promulgated=True)
140+ promulgated_names = [charm.name for charm in collection['charms']]
141+ expected = [two['name'], one['name']]
142+ self.assertEqual(expected, promulgated_names)
143+ self.assertIs(False, collection['sub_only'])
144+ # The only_promulgated kwarg defaults to False, getting all sorted
145+ # charms.
146+ collection = found_charm_collection(self.db, dict(query), sub_only)
147+ all_names = [charm.name for charm in collection['charms']]
148+ expected = [two['name'], one['name'], three['name']]
149+ self.assertEqual(expected, all_names)
150+
151 def test_charm_collection_basic(self):
152 """Simple sanity check."""
153 one_id, one = factory.makeCharm(self.db, promulgated=True)
154@@ -46,7 +68,7 @@
155 three_id, three = factory.makeCharm(self.db, promulgated=False)
156
157 response = charm_collection(self.getRequest())
158- charm_names = set(charm['name'] for charm in response['charms'])
159+ charm_names = set(charm.name for charm in response['charms'])
160 expected = set((one['name'], two['name']))
161 self.assertEqual(expected, charm_names)
162
163@@ -61,7 +83,7 @@
164 response = charm_collection(request)
165 charms = response['charms']
166 self.assertEqual(1, len(charms))
167- self.assertEqual(one['name'], charms[0]['name'])
168+ self.assertEqual(one['name'], charms[0].name)
169
170 def test_charm_collection_charms_with_errors(self):
171 """Charms with errors are not returned by charm_collection()."""
172@@ -71,7 +93,7 @@
173 response = charm_collection(self.getRequest())
174 charms = response['charms']
175 self.assertEqual(1, len(charms))
176- self.assertEqual(one['name'], charms[0]['name'])
177+ self.assertEqual(one['name'], charms[0].name)
178
179 def test_personal_collection(self):
180 # personal_collection() returns only charms owned by the given
181@@ -83,7 +105,7 @@
182 response = personal_collection(request)
183 charms = response['charms']
184 self.assertEqual(1, len(charms))
185- self.assertEqual('foo', charms[0]['owner'])
186+ self.assertEqual('foo', charms[0].owner)
187
188 def test_personal_collection_sub_filter(self):
189 # If the request parameter 'sub' is set, only subordinate charms
190@@ -98,15 +120,15 @@
191 response = personal_collection(request)
192 charms = response['charms']
193 self.assertEqual(1, len(charms))
194- self.assertEqual(three['name'], charms[0]['name'])
195+ self.assertEqual(three['name'], charms[0].name)
196 # If the filter is no given in the request, all charms are returned.
197 request = self.getRequest()
198 request.matchdict = {'owner': 'foo'}
199 response = personal_collection(request)
200 charms = response['charms']
201 self.assertEqual(2, len(charms))
202- self.assertEqual('foo', charms[0]['owner'])
203- self.assertEqual('foo', charms[1]['owner'])
204+ self.assertEqual('foo', charms[0].owner)
205+ self.assertEqual('foo', charms[1].owner)
206
207 def test_personal_collection_charms_with_errors(self):
208 # Charms with errors are not returned by personal_collection().
209@@ -119,7 +141,7 @@
210 response = personal_collection(request)
211 charms = response['charms']
212 self.assertEqual(1, len(charms))
213- self.assertEqual(one['name'], charms[0]['name'])
214+ self.assertEqual(one['name'], charms[0].name)
215
216 def test_series_collection(self):
217 # series_collection() returns only promulgated charms for a
218@@ -138,8 +160,8 @@
219 response = series_collection(request)
220 charms = response['charms']
221 self.assertEqual(
222- ['charm-a', 'charm-b'], [charm['name'] for charm in charms])
223- self.assertEqual('one', charms[0]['series'])
224+ ['charm-a', 'charm-b'], [charm.name for charm in charms])
225+ self.assertEqual('one', charms[0].series)
226
227 def test_series_collection_sub_filter(self):
228 # If the request parameter 'sub' is set, only subordinate charms
229@@ -156,7 +178,7 @@
230 response = series_collection(request)
231 charms = response['charms']
232 self.assertEqual(1, len(charms))
233- self.assertEqual(three['name'], charms[0]['name'])
234+ self.assertEqual(three['name'], charms[0].name)
235
236 def test_series_collection_charms_with_errors(self):
237 # Charms with errors are not returned by series_collection().
238@@ -171,7 +193,7 @@
239 response = series_collection(request)
240 charms = response['charms']
241 self.assertEqual(1, len(charms))
242- self.assertEqual(one['name'], charms[0]['name'])
243+ self.assertEqual(one['name'], charms[0].name)
244
245 def test_personal_series_collection(self):
246 # personal_series_collection() returns only charms for a given
247@@ -187,7 +209,7 @@
248 response = personal_series_collection(request)
249 charms = response['charms']
250 self.assertEqual(1, len(charms))
251- self.assertEqual(one['name'], charms[0]['name'])
252+ self.assertEqual(one['name'], charms[0].name)
253
254 def test_personal_series_collection_sub_filter(self):
255 # If the parameter 'sub' is set, personal_series_collection()
256@@ -206,7 +228,7 @@
257 response = personal_series_collection(request)
258 charms = response['charms']
259 self.assertEqual(1, len(charms))
260- self.assertEqual(four['name'], charms[0]['name'])
261+ self.assertEqual(four['name'], charms[0].name)
262
263 def test_personal_series_collection_charms_with_errors(self):
264 # Charms with errors are not returned by series_collection().
265@@ -223,7 +245,7 @@
266 response = personal_series_collection(request)
267 charms = response['charms']
268 self.assertEqual(1, len(charms))
269- self.assertEqual(one['name'], charms[0]['name'])
270+ self.assertEqual(one['name'], charms[0].name)
271
272 def test_interface(self):
273 # interface() returns all charms reqiring or providing a given

Subscribers

People subscribed via source and target branches