Merge lp:~fabricematrat/charmworld/redirect-interfaces into lp:charmworld

Proposed by Fabrice Matrat
Status: Merged
Approved by: Fabrice Matrat
Approved revision: 521
Merged at revision: 522
Proposed branch: lp:~fabricematrat/charmworld/redirect-interfaces
Merge into: lp:charmworld
Diff against target: 317 lines (+62/-104)
2 files modified
charmworld/views/charms.py (+45/-21)
charmworld/views/tests/test_charms.py (+17/-83)
To merge this branch: bzr merge lp:~fabricematrat/charmworld/redirect-interfaces
Reviewer Review Type Date Requested Status
Juju Gui Bot continuous-integration Approve
Francesco Banconi Approve
Brad Crittenden (community) code + qa Approve
Review via email: mp+249681@code.launchpad.net

Commit message

Added redirection for interface, config, hook
R=bac, frankban

Description of the change

Added redirection for interface, config, hook

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :

Code looks good.
QA OK

review: Approve (code + qa)
Revision history for this message
Francesco Banconi (frankban) wrote :

Looks good.

review: Approve
Revision history for this message
Juju Gui Bot (juju-gui-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmworld/views/charms.py'
2--- charmworld/views/charms.py 2015-02-09 18:46:13 +0000
3+++ charmworld/views/charms.py 2015-02-13 16:29:40 +0000
4@@ -35,7 +35,6 @@
5 format_change,
6 format_proof,
7 found,
8- interfaces,
9 name_filter,
10 )
11
12@@ -356,30 +355,62 @@
13 route_name="hook",
14 renderer="charmworld:templates/hook.pt")
15 def hook(request):
16- charm = Charm(find_charm(request, promulgated=True))
17- return _hook_view(request, charm, request.matchdict["hook"])
18+ _reconcile_revision(request)
19+ redirect_url = request.registry.settings.get('redirect_jujucharms')
20+ match = request.matchdict
21+ location = '{url}/{charm}/{series}'.format(
22+ url=redirect_url,
23+ charm=match['charm'],
24+ series=match['series']
25+ )
26+ raise HTTPMovedPermanently(location=location)
27
28
29 @cached_view_config(
30 route_name="personal-hook",
31 renderer="charmworld:templates/hook.pt")
32 def personal_hook(request):
33- charm = Charm(find_charm(request))
34- return _hook_view(request, charm, request.matchdict["hook"])
35+ _reconcile_revision(request)
36+ redirect_url = request.registry.settings.get('redirect_jujucharms')
37+ match = request.matchdict
38+ location = '{url}/u/{owner}/{charm}/{series}'.format(
39+ url=redirect_url,
40+ owner=match['owner'],
41+ charm=match['charm'],
42+ series=match['series']
43+ )
44+ raise HTTPMovedPermanently(location=location)
45
46
47 @cached_view_config(
48 route_name="config",
49 renderer="charmworld:templates/config.pt")
50 def config(request):
51- return _config_view(find_charm(request, promulgated=True))
52+ _reconcile_revision(request)
53+ redirect_url = request.registry.settings.get('redirect_jujucharms')
54+ match = request.matchdict
55+ location = '{url}/{charm}/{series}#configuration'.format(
56+ url=redirect_url,
57+ charm=match['charm'],
58+ series=match['series']
59+ )
60+ raise HTTPMovedPermanently(location=location)
61
62
63 @cached_view_config(
64 route_name="personal-config",
65 renderer="charmworld:templates/config.pt")
66 def personal_config(request):
67- return _config_view(find_charm(request))
68+ _reconcile_revision(request)
69+ redirect_url = request.registry.settings.get('redirect_jujucharms')
70+ match = request.matchdict
71+ location = '{url}/u/{owner}/{charm}/{series}#configuration'.format(
72+ url=redirect_url,
73+ owner=match['owner'],
74+ charm=match['charm'],
75+ series=match['series']
76+ )
77+ raise HTTPMovedPermanently(location=location)
78
79
80 @cached_view_config(
81@@ -389,10 +420,8 @@
82 route_name="interface-collection",
83 renderer="charmworld:templates/interface-collection-redux.pt")
84 def interface_collection(request):
85- return {
86- "interfaces": interfaces(request.db),
87- "project": request.registry.settings.get('project_name', 'Not Set.'),
88- }
89+ redirect_url = request.registry.settings.get('redirect_jujucharms')
90+ raise HTTPMovedPermanently(location='{}/solutions'.format(redirect_url))
91
92
93 @cached_view_config(
94@@ -400,16 +429,11 @@
95 renderer="charmworld:templates/interface.pt")
96 def interface(request):
97 iface = request.matchdict["interface"]
98- return {
99- "interface": iface,
100- "providers": [
101- Charm(charm)
102- for charm in find_charms(request.db, {"i_provides": iface},
103- sort=[("name", pymongo.ASCENDING)])],
104- "requirers": [
105- Charm(charm)
106- for charm in find_charms(request.db, {"i_requires": iface},
107- sort=[("name", pymongo.ASCENDING)])]}
108+ redirect_url = request.registry.settings.get('redirect_jujucharms')
109+ raise HTTPMovedPermanently(
110+ location='{url}/q/{interface}'.format(url=redirect_url,
111+ interface=iface)
112+ )
113
114
115 @view_config(
116
117=== modified file 'charmworld/views/tests/test_charms.py'
118--- charmworld/views/tests/test_charms.py 2015-02-09 14:16:33 +0000
119+++ charmworld/views/tests/test_charms.py 2015-02-13 16:29:40 +0000
120@@ -159,64 +159,29 @@
121 self.assertIn('/q/me/one', e.exception.location)
122
123 def test_interface(self):
124- # interface() returns all charms requiring or providing a given
125- # interface.
126- providing = Charm(factory.makeCharm(
127- self.db, provides={'foo': {'interface': 'httpX'}})[1])
128- requiring = Charm(factory.makeCharm(
129- self.db, requires={'bar': {'interface': 'httpX'}})[1])
130- ignore, other = factory.makeCharm(self.db)
131- request = self.getRequest()
132- request.matchdict = {'interface': 'httpX'}
133- response = interface(request)
134- self.assertEqual('httpX', response['interface'])
135- found_providing = response['providers']
136- self.assertEqual(1, len(found_providing))
137- self.assertEqual(providing, found_providing[0])
138- found_requiring = response['requirers']
139- self.assertEqual(1, len(found_requiring))
140- self.assertEqual(requiring, found_requiring[0])
141-
142- def test_interface_charm_with_errors(self):
143- # Charms with errors are not returned by interface().
144- providing = Charm(factory.makeCharm(
145- self.db, provides={'foo': {'interface': 'httpX'}})[1])
146- Charm(factory.makeCharm(
147- self.db, requires={'bar': {'interface': 'httpX'}},
148- charm_error=True)[1])
149- request = self.getRequest()
150- request.matchdict = {'interface': 'httpX'}
151- response = interface(request)
152- self.assertEqual('httpX', response['interface'])
153- found_providing = response['providers']
154- self.assertEqual(1, len(found_providing))
155- self.assertEqual(providing, found_providing[0])
156- found_requiring = response['requirers']
157- self.assertEqual(0, len(found_requiring))
158+ request = self.getRequest()
159+ request.matchdict = {'interface': 'httpX'}
160+ with self.assertRaises(HTTPMovedPermanently) as e:
161+ interface(request)
162+ self.assertIn('/q/httpX', e.exception.location)
163
164 def test_config(self):
165- ignore, charm = factory.makeCharm(
166- self.db, name='foo', owner='bar', series='precise',
167- promulgated=True)
168 request = self.getRequest()
169 request.matchdict = {'charm': 'foo', 'series': 'precise'}
170- response = config(request)
171- expected = {"charm": Charm(charm), "onload": "prettyPrint()"}
172- self.assertEqual(expected, response)
173+ with self.assertRaises(HTTPMovedPermanently) as e:
174+ config(request)
175+ self.assertIn('/foo/precise#configuration', e.exception.location)
176
177 def test_personal_config(self):
178- ignore, charm = factory.makeCharm(
179- self.db, name='foo', owner='bar', series='precise',
180- promulgated=False)
181 request = self.getRequest()
182 request.matchdict = {
183 'charm': 'foo',
184 'series': 'precise',
185 'owner': 'bar'
186 }
187- response = personal_config(request)
188- expected = {"charm": Charm(charm), "onload": "prettyPrint()"}
189- self.assertEqual(expected, response)
190+ with self.assertRaises(HTTPMovedPermanently) as e:
191+ personal_config(request)
192+ self.assertIn('/bar/foo/precise#configuration', e.exception.location)
193
194 def make_charm_with_files(self, promulgated):
195 ignore, charm = factory.makeCharm(
196@@ -232,23 +197,17 @@
197 return charm
198
199 def test_hook(self):
200- charm = Charm(self.make_charm_with_files(promulgated=True))
201 request = self.getRequest()
202 request.matchdict = {
203 'charm': 'sample_charm',
204 'series': 'precise',
205 'hook': 'install',
206 }
207- response = hook(request)
208- self.assertEqual('Not Set.', response['project'])
209- self.assertEqual('install', response['hook'])
210- self.assertTrue(response['hook_raw'].startswith(
211- '#!/bin/bash\nset -eux\n\n# This PPA is no longer required.'))
212- self.assertEqual(charm, response['charm'])
213- self.assertEqual('prettyPrint()', response['onload'])
214+ with self.assertRaises(HTTPMovedPermanently) as e:
215+ hook(request)
216+ self.assertIn('/sample_charm/precise', e.exception.location)
217
218 def test_personal_hook(self):
219- charm = Charm(self.make_charm_with_files(promulgated=False))
220 request = self.getRequest()
221 request.matchdict = {
222 'charm': 'sample_charm',
223@@ -256,17 +215,11 @@
224 'hook': 'install',
225 'owner': 'bar',
226 }
227- response = personal_hook(request)
228- self.assertEqual('Not Set.', response['project'])
229- self.assertEqual('install', response['hook'])
230- self.assertTrue(response['hook_raw'].startswith(
231- '#!/bin/bash\nset -eux\n\n# This PPA is no longer required.'))
232- self.assertEqual(charm, response['charm'])
233- self.assertEqual('prettyPrint()', response['onload'])
234+ with self.assertRaises(HTTPMovedPermanently) as e:
235+ personal_hook(request)
236+ self.assertIn('/bar/sample_charm/precise', e.exception.location)
237
238 def test_distro_charm(self):
239- self.enable_routes()
240- self.make_charm_with_files(promulgated=True)
241 request = self.getRequest()
242 request.matchdict = {
243 'charm': 'sample_charm',
244@@ -377,10 +330,6 @@
245
246 def test_charm_collection_with_missing_data(self):
247 """Charms with missing data are rendered."""
248- one_id, one = factory.makeCharm(self.db, promulgated=True)
249- two_id, two = factory.makeCharm(self.db, promulgated=True)
250- del two['summary']
251- self.db.charms.save(two)
252 response = self.app.get('/charms/precise', status=301)
253 self.assertIn('/q/precise', response.body)
254
255@@ -388,8 +337,6 @@
256 # The route /~owner/series/charm-1 finds charms using owner,
257 # series, charm name, and revision. The deploy instruction
258 # does not include the revision.
259- ignore, charm = factory.makeCharm(
260- self.db, owner='owner', series='series', name='charm', files={})
261 response = self.app.get('/~owner/series/charm-1', status=301)
262 self.assertIn('/u/owner/charm/series/1', response.body)
263
264@@ -397,17 +344,12 @@
265 # /~owner/series/charm-name-1 route find the charm.
266 # This is a corner-case where the revision and charm name are
267 # ambigous because they are munged.
268- ignore, charm = factory.makeCharm(
269- self.db, owner='owner', series='series', name='charm-name',
270- files={})
271 response = self.app.get('/~owner/series/charm-name-1', status=301)
272 self.assertIn('/u/owner/charm-name/series/1', response.body)
273
274 def test_route_personal_charm_with_head_revision(self):
275 # the /~owner/series/charm-name-HEAD route finds the charm.
276 # The juju-gui apache rewrite versionless charm urls to help the GUI.
277- ignore, charm = factory.makeCharm(
278- self.db, owner='owner', series='series', name='charm', files={})
279 response = self.app.get('/~owner/series/charm-HEAD', status=301)
280 self.assertIn('/u/owner/charm/series', response.body)
281 self.assertNotIn('HEAD', response.body)
282@@ -416,8 +358,6 @@
283 # The route /~owner/series/charm route finds the charm using owner
284 # series, and charm name. Revision is ignored. The deploy instruction
285 # matches the route.
286- ignore, charm = factory.makeCharm(
287- self.db, owner='owner', series='series', name='charm', files={})
288 response = self.app.get('/~owner/series/charm', status=301)
289 self.assertIn('/u/owner/charm/series', response.body)
290
291@@ -443,8 +383,6 @@
292 # The route /series/charm-1 route finds promulgated charms using
293 # The series, charm name and version. The deploy instruction does not
294 # include the version.
295- factory.makeCharm(
296- self.db, promulgated=True, series='series', name='charm', files={})
297 response = self.app.get('/series/charm-1', status=301)
298 self.assertIn('/charm/series/1', response.body)
299
300@@ -452,8 +390,6 @@
301 # The route /series/charm-HEAD finds promulgated charms using
302 # series, charm name, and head revision. The revision is not included
303 # in the deploy instruction.
304- ignore, charm = factory.makeCharm(
305- self.db, promulgated=True, series='series', name='charm', files={})
306 response = self.app.get('/series/charm-HEAD', status=301)
307 self.assertNotIn('HEAD', response.body)
308 self.assertIn('/charm/series', response.body)
309@@ -461,8 +397,6 @@
310 def test_route_promulgated_charm_without_revision(self):
311 # The route /series/charm finds the promulgated charms using just
312 # the series and charm name. The deploy instruction matches the route.
313- factory.makeCharm(
314- self.db, promulgated=True, series='series', name='charm', files={})
315 self.app.get('/series/charm', status=301)
316
317 def test_charm_short_url_route(self):

Subscribers

People subscribed via source and target branches

to all changes: