Merge lp:~james-w/lava-dashboard/use-testscenarios into lp:~zyga/lava-dashboard/stable.rpc-client
- use-testscenarios
- Merge into stable.rpc-client
Proposed by
James Westby
Status: | Merged |
---|---|
Merged at revision: | 88 |
Proposed branch: | lp:~james-w/lava-dashboard/use-testscenarios |
Merge into: | lp:~zyga/lava-dashboard/stable.rpc-client |
Diff against target: |
815 lines (+355/-328) 2 files modified
launch_control/dashboard_app/fixtures.py (+2/-30) launch_control/dashboard_app/tests.py (+353/-298) |
To merge this branch: | bzr merge lp:~james-w/lava-dashboard/use-testscenarios |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Zygmunt Krynicki | Approve | ||
Review via email: mp+34919@code.launchpad.net |
Commit message
Description of the change
Hi,
This uses testscenarios rather than the custom decorator, which
means that the tests are cloned and so the different scenarios
should not interfere with one another.
Thanks,
James
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'launch_control/dashboard_app/fixtures.py' |
2 | --- launch_control/dashboard_app/fixtures.py 2010-09-08 16:52:54 +0000 |
3 | +++ launch_control/dashboard_app/fixtures.py 2010-09-08 20:59:40 +0000 |
4 | @@ -39,34 +39,6 @@ |
5 | return self._last |
6 | |
7 | |
8 | -def use_test_scenarios(*scenarios): |
9 | - """ |
10 | - Helper decorator for test cases that use scenarios. |
11 | - Turns wrapped function into a parametrized test case. |
12 | - |
13 | - scenarios is a list of tuples(scenario_name, args) |
14 | - args must be a dictionary, it is passed as keyword |
15 | - arguments to the test case function. |
16 | - |
17 | - Any test failures will be annotated with scenario name. |
18 | - """ |
19 | - def run_with_scenarios(func): |
20 | - def decorator(self): |
21 | - if not scenarios: |
22 | - effective_scenarios = self.scenarios |
23 | - else: |
24 | - effective_scenarios = scenarios |
25 | - with test_loop(effective_scenarios) as loop_items: |
26 | - for scenario_name, values in loop_items: |
27 | - try: |
28 | - func(self, **values) |
29 | - except Exception, ex: |
30 | - self.fail("Unexpectedly failed with scenario {0!r}: {1!r}".format( |
31 | - scenario_name, ex)) |
32 | - return decorator |
33 | - return run_with_scenarios |
34 | - |
35 | - |
36 | @contextmanager |
37 | def created_bundle_streams(spec): |
38 | """ |
39 | @@ -128,7 +100,7 @@ |
40 | bundles = [] |
41 | users = set() |
42 | groups = set() |
43 | - # make all bundle streams required |
44 | + # make all bundle streams required |
45 | for pathname, content_filename, content in spec: |
46 | pathname_parts = pathname.split('/') |
47 | if len(pathname_parts) < 3: |
48 | @@ -183,7 +155,7 @@ |
49 | # Note: We explicitly remove bundles because our @uses_scenarios |
50 | # wrapper does not cope with pristine database configuration Also |
51 | # because of FileField we need to call delete to get rid of test |
52 | - # files in the file system |
53 | + # files in the file system |
54 | for bundle in bundles: |
55 | bundle.delete() |
56 | for bundle_stream in bundle_streams.itervalues(): |
57 | |
58 | === modified file 'launch_control/dashboard_app/tests.py' |
59 | --- launch_control/dashboard_app/tests.py 2010-09-07 14:41:06 +0000 |
60 | +++ launch_control/dashboard_app/tests.py 2010-09-08 20:59:40 +0000 |
61 | @@ -2,12 +2,10 @@ |
62 | Unit tests of the Dashboard application |
63 | """ |
64 | import hashlib |
65 | -import inspect |
66 | import xmlrpclib |
67 | import contextlib |
68 | |
69 | from django.contrib.auth.models import (User, Group) |
70 | -from django.contrib.contenttypes import generic |
71 | from django.core.files.base import ContentFile |
72 | from django.db import IntegrityError |
73 | from django.test import TestCase |
74 | @@ -81,72 +79,83 @@ |
75 | |
76 | class BundleTest(TestCase): |
77 | |
78 | + _NAME = "name" |
79 | + _SLUG = "slug" |
80 | + _GROUPNAME = "group" |
81 | + _USERNAME = "user" |
82 | + |
83 | + scenarios = [ |
84 | + ('anonymous-no-slug', { |
85 | + 'pathname': '/anonymous/', |
86 | + }), |
87 | + ('anonymous-with-slug', { |
88 | + 'name': _NAME, |
89 | + 'slug': _SLUG, |
90 | + 'pathname': '/anonymous/slug/', |
91 | + }), |
92 | + ('personal-no-slug', { |
93 | + 'username': _USERNAME, |
94 | + 'pathname': '/personal/user/', |
95 | + }), |
96 | + ('personal-with-slug', { |
97 | + 'username': _USERNAME, |
98 | + 'name': _NAME, |
99 | + 'slug': _SLUG, |
100 | + 'pathname': '/personal/user/slug/', |
101 | + }), |
102 | + ('team-no-slug', { |
103 | + 'groupname': _GROUPNAME, |
104 | + 'pathname': '/team/group/', |
105 | + }), |
106 | + ('team-with-slug', { |
107 | + 'groupname': _GROUPNAME, |
108 | + 'name': _NAME, |
109 | + 'slug': _SLUG, |
110 | + 'pathname': '/team/group/slug/', |
111 | + }), |
112 | + ] |
113 | + |
114 | + groupname = None |
115 | + username = None |
116 | + group = None |
117 | + user = None |
118 | + name = '' |
119 | + slug = '' |
120 | + |
121 | def setUp(self): |
122 | - self.user = User.objects.create(username='user') |
123 | - self.group = Group.objects.create(name='group') |
124 | - self.name = 'Name' |
125 | - self.slug = 'slug' |
126 | - self.scenarios = ( |
127 | - ('anonymous-no-slug', { |
128 | - 'pathname': '/anonymous/', |
129 | - }), |
130 | - ('anonymous-with-slug', { |
131 | - 'name': self.name, |
132 | - 'slug': self.slug, |
133 | - 'pathname': '/anonymous/slug/', |
134 | - }), |
135 | - ('personal-no-slug', { |
136 | - 'user': self.user, |
137 | - 'pathname': '/personal/user/', |
138 | - }), |
139 | - ('personal-with-slug', { |
140 | - 'user': self.user, |
141 | - 'name': self.name, |
142 | - 'slug': self.slug, |
143 | - 'pathname': '/personal/user/slug/', |
144 | - }), |
145 | - ('team-no-slug', { |
146 | - 'group': self.group, |
147 | - 'pathname': '/team/group/', |
148 | - }), |
149 | - ('team-with-slug', { |
150 | - 'group': self.group, |
151 | - 'name': self.name, |
152 | - 'slug': self.slug, |
153 | - 'pathname': '/team/group/slug/', |
154 | - }), |
155 | - ) |
156 | - |
157 | - @fixtures.use_test_scenarios |
158 | - def test_creation(self, user, group, name='', slug='', **unused): |
159 | - bundle_stream = BundleStream.objects.create(user=user, |
160 | - group=group, name=name, slug=slug) |
161 | - bundle_stream.save() |
162 | - self.assertEqual(bundle_stream.user, user) |
163 | - self.assertEqual(bundle_stream.group, group) |
164 | - self.assertEqual(bundle_stream.name, name) |
165 | - self.assertEqual(bundle_stream.slug, slug) |
166 | - |
167 | - @fixtures.use_test_scenarios |
168 | - def test_team_named_stream(self, user, group, pathname, name='', slug=''): |
169 | - bundle_stream = BundleStream.objects.create(user=user, |
170 | - group=group, name=name, slug=slug) |
171 | - bundle_stream.save() |
172 | - self.assertEqual(bundle_stream.pathname, pathname) |
173 | - |
174 | - @fixtures.use_test_scenarios |
175 | - def test_pathname_uniqueness(self, user, group, pathname, name='', slug=''): |
176 | - bundle_stream = BundleStream.objects.create(user=user, |
177 | - group=group, name=name, slug=slug) |
178 | + super(BundleTest, self).setUp() |
179 | + if self.username is not None: |
180 | + self.user = User.objects.create(username='user') |
181 | + if self.groupname is not None: |
182 | + self.group = Group.objects.create(name='group') |
183 | + |
184 | + def test_creation(self): |
185 | + bundle_stream = BundleStream.objects.create(user=self.user, |
186 | + group=self.group, name=self.name, slug=self.slug) |
187 | + bundle_stream.save() |
188 | + self.assertEqual(bundle_stream.user, self.user) |
189 | + self.assertEqual(bundle_stream.group, self.group) |
190 | + self.assertEqual(bundle_stream.name, self.name) |
191 | + self.assertEqual(bundle_stream.slug, self.slug) |
192 | + |
193 | + def test_team_named_stream(self): |
194 | + bundle_stream = BundleStream.objects.create(user=self.user, |
195 | + group=self.group, name=self.name, slug=self.slug) |
196 | + bundle_stream.save() |
197 | + self.assertEqual(bundle_stream.pathname, self.pathname) |
198 | + |
199 | + def test_pathname_uniqueness(self): |
200 | + bundle_stream = BundleStream.objects.create(user=self.user, |
201 | + group=self.group, name=self.name, slug=self.slug) |
202 | bundle_stream.save() |
203 | self.assertRaises(IntegrityError, |
204 | BundleStream.objects.create, |
205 | - user=user, group=group, slug=slug, name=name) |
206 | + user=self.user, group=self.group, slug=self.slug, |
207 | + name=self.name) |
208 | |
209 | - @fixtures.use_test_scenarios |
210 | - def test_pathname_update(self, user, group, pathname, name='', slug=''): |
211 | - bundle_stream = BundleStream.objects.create(user=user, |
212 | - group=group, name=name, slug=slug) |
213 | + def test_pathname_update(self): |
214 | + bundle_stream = BundleStream.objects.create(user=self.user, |
215 | + group=self.group, name=self.name, slug=self.slug) |
216 | bundle_stream.save() |
217 | old_pathname = bundle_stream.pathname |
218 | bundle_stream.slug += "-changed" |
219 | @@ -269,10 +278,10 @@ |
220 | raise Exception("internal boom") |
221 | |
222 | |
223 | -class DjangoXMLRPCDispatcherTest(TestCase): |
224 | +class DjangoXMLRPCDispatcherTestCase(TestCase): |
225 | |
226 | def setUp(self): |
227 | - super(DjangoXMLRPCDispatcherTest, self).setUp() |
228 | + super(DjangoXMLRPCDispatcherTestCase, self).setUp() |
229 | self.dispatcher = DjangoXMLRPCDispatcher() |
230 | self.dispatcher.register_instance(TestAPI()) |
231 | |
232 | @@ -290,6 +299,9 @@ |
233 | # (which we don't have here as this is a response message). |
234 | return xmlrpclib.loads(response)[0][0] |
235 | |
236 | + |
237 | +class DjangoXMLRPCDispatcherTests(DjangoXMLRPCDispatcherTestCase): |
238 | + |
239 | def test_standard_fault_code_for_missing_method(self): |
240 | try: |
241 | self.xml_rpc_call("method_that_hopefully_does_not_exist") |
242 | @@ -300,24 +312,6 @@ |
243 | else: |
244 | self.fail("Calling missing method did not raise an exception") |
245 | |
246 | - @fixtures.use_test_scenarios( |
247 | - ('method_not_found', { |
248 | - 'method': "method_that_hopefully_does_not_exist", |
249 | - 'faultCode': FaultCodes.ServerError.REQUESTED_METHOD_NOT_FOUND, |
250 | - }), |
251 | - ('internal_error', { |
252 | - 'method': "internal_boom", |
253 | - 'faultCode': FaultCodes.ServerError.INTERNAL_XML_RPC_ERROR, |
254 | - }), |
255 | - ) |
256 | - def test_standard_fault_codes(self, method, faultCode): |
257 | - try: |
258 | - self.xml_rpc_call(method) |
259 | - except xmlrpclib.Fault as ex: |
260 | - self.assertEqual(ex.faultCode, faultCode) |
261 | - else: |
262 | - self.fail("Exception not raised") |
263 | - |
264 | def test_ping(self): |
265 | retval = self.xml_rpc_call("ping") |
266 | self.assertEqual(retval, "pong") |
267 | @@ -332,10 +326,32 @@ |
268 | self.xml_rpc_call, "boom", 1, "str") |
269 | |
270 | |
271 | -class DashboardAPITest(TestCase): |
272 | +class DjangoXMLRPCDispatcherFaultCodeTests(DjangoXMLRPCDispatcherTestCase): |
273 | + |
274 | + scenarios = [ |
275 | + ('method_not_found', { |
276 | + 'method': "method_that_hopefully_does_not_exist", |
277 | + 'faultCode': FaultCodes.ServerError.REQUESTED_METHOD_NOT_FOUND, |
278 | + }), |
279 | + ('internal_error', { |
280 | + 'method': "internal_boom", |
281 | + 'faultCode': FaultCodes.ServerError.INTERNAL_XML_RPC_ERROR, |
282 | + }), |
283 | + ] |
284 | + |
285 | + def test_standard_fault_codes(self): |
286 | + try: |
287 | + self.xml_rpc_call(self.method) |
288 | + except xmlrpclib.Fault as ex: |
289 | + self.assertEqual(ex.faultCode, self.faultCode) |
290 | + else: |
291 | + self.fail("Exception not raised") |
292 | + |
293 | + |
294 | +class DashboardAPITestCase(TestCase): |
295 | |
296 | def setUp(self): |
297 | - super(DashboardAPITest, self).setUp() |
298 | + super(DashboardAPITestCase, self).setUp() |
299 | self.client = Client() |
300 | |
301 | def xml_rpc_call(self, method, *args): |
302 | @@ -345,6 +361,9 @@ |
303 | content_type="text/xml") |
304 | return xmlrpclib.loads(response.content)[0][0] |
305 | |
306 | + |
307 | +class DashboardAPITests(DashboardAPITestCase): |
308 | + |
309 | def test_xml_rpc_help_returns_200(self): |
310 | response = self.client.get("/xml-rpc/") |
311 | self.assertEqual(response.status_code, 200) |
312 | @@ -374,97 +393,105 @@ |
313 | self.assertEqual(self.xml_rpc_call('version'), |
314 | ".".join(map(str, __version__))) |
315 | |
316 | - @fixtures.use_test_scenarios( |
317 | - ('empty', { |
318 | - 'streams': [], |
319 | - 'expected_response': [], |
320 | - }), |
321 | - ('one_public_stream', { |
322 | - 'streams': [ |
323 | - {'slug': '', 'user': None, 'group': None}], |
324 | - 'expected_response': [{ |
325 | - 'bundle_count': 0, |
326 | - 'user': '', |
327 | - 'group': '', |
328 | - 'name': '', |
329 | - 'pathname': '/anonymous/'}], |
330 | - }), |
331 | - ('private_streams_are_not_shown', { |
332 | - 'streams': [ |
333 | - {'slug': '', 'user': 'joe', 'group': None}, |
334 | - {'slug': '', 'user': None, 'group': None}], |
335 | - 'expected_response': [{ |
336 | - 'bundle_count': 0, |
337 | - 'user': '', |
338 | - 'group': '', |
339 | - 'name': '', |
340 | - 'pathname': '/anonymous/'}], |
341 | - }), |
342 | - ('team_streams_are_not_shown', { |
343 | - 'streams': [ |
344 | - {'slug': '', 'user': None, 'group': 'group'}, |
345 | - {'slug': '', 'user': None, 'group': None}], |
346 | - 'expected_response': [{ |
347 | - 'bundle_count': 0, |
348 | - 'user': '', |
349 | - 'group': '', |
350 | - 'name': '', |
351 | - 'pathname': '/anonymous/'}], |
352 | - }), |
353 | - ) |
354 | - def test_streams(self, streams, expected_response): |
355 | - with fixtures.created_bundle_streams(streams): |
356 | + |
357 | +class DashboardAPIStreamsTests(DashboardAPITestCase): |
358 | + |
359 | + scenarios = [ |
360 | + ('empty', { |
361 | + 'streams': [], |
362 | + 'expected_response': [], |
363 | + }), |
364 | + ('one_public_stream', { |
365 | + 'streams': [ |
366 | + {'slug': '', 'user': None, 'group': None}], |
367 | + 'expected_response': [{ |
368 | + 'bundle_count': 0, |
369 | + 'user': '', |
370 | + 'group': '', |
371 | + 'name': '', |
372 | + 'pathname': '/anonymous/'}], |
373 | + }), |
374 | + ('private_streams_are_not_shown', { |
375 | + 'streams': [ |
376 | + {'slug': '', 'user': 'joe', 'group': None}, |
377 | + {'slug': '', 'user': None, 'group': None}], |
378 | + 'expected_response': [{ |
379 | + 'bundle_count': 0, |
380 | + 'user': '', |
381 | + 'group': '', |
382 | + 'name': '', |
383 | + 'pathname': '/anonymous/'}], |
384 | + }), |
385 | + ('team_streams_are_not_shown', { |
386 | + 'streams': [ |
387 | + {'slug': '', 'user': None, 'group': 'group'}, |
388 | + {'slug': '', 'user': None, 'group': None}], |
389 | + 'expected_response': [{ |
390 | + 'bundle_count': 0, |
391 | + 'user': '', |
392 | + 'group': '', |
393 | + 'name': '', |
394 | + 'pathname': '/anonymous/'}], |
395 | + }), |
396 | + ] |
397 | + |
398 | + def test_streams(self): |
399 | + with fixtures.created_bundle_streams(self.streams): |
400 | response = self.xml_rpc_call('streams') |
401 | - self.assertEqual(response, expected_response) |
402 | - |
403 | - @fixtures.use_test_scenarios( |
404 | - ('empty', { |
405 | - 'query': '/anonymous/', |
406 | - 'bundles': [], |
407 | - 'expected_results': [], |
408 | - }), |
409 | - ('several_bundles_we_can_see', { |
410 | - 'query': '/anonymous/', |
411 | - 'bundles': [ |
412 | - ('/anonymous/', 'test1.json', '{"foobar": 5}'), |
413 | - ('/anonymous/', 'test2.json', '{"froz": "bot"}'), |
414 | - ], |
415 | - 'expected_results': [{ |
416 | - 'content_filename': 'test1.json', |
417 | - 'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19', |
418 | - }, { |
419 | - 'content_filename': 'test2.json', |
420 | - 'content_sha1': '67dd49730d4e3b38b840f3d544d45cad74bcfb09', |
421 | - }], |
422 | - }), |
423 | - ('several_bundles_in_other_stream', { |
424 | - 'query': '/anonymous/other/', |
425 | - 'bundles': [ |
426 | - ('/anonymous/', 'test3.json', '{}'), |
427 | - ('/anonymous/other/', 'test4.json', '{"x": true}'), |
428 | - ], |
429 | - 'expected_results': [{ |
430 | - 'content_filename': 'test4.json', |
431 | - 'content_sha1': 'bac148f29c35811441a7b4746a022b04c65bffc0', |
432 | - }], |
433 | - }), |
434 | - ('several_bundles_in_bogus_pathname', { |
435 | - 'query': '/bogus/', |
436 | - 'bundles': [ |
437 | - ('/anonymous/', 'test5.json', '{}'), |
438 | - ], |
439 | - 'expected_results': [], |
440 | - }), |
441 | - ) |
442 | - def test_bundles(self, bundles, query, expected_results): |
443 | + self.assertEqual(response, self.expected_response) |
444 | + |
445 | + |
446 | +class DashboardAPIBundlesTests(DashboardAPITestCase): |
447 | + |
448 | + scenarios = [ |
449 | + ('empty', { |
450 | + 'query': '/anonymous/', |
451 | + 'bundles': [], |
452 | + 'expected_results': [], |
453 | + }), |
454 | + ('several_bundles_we_can_see', { |
455 | + 'query': '/anonymous/', |
456 | + 'bundles': [ |
457 | + ('/anonymous/', 'test1.json', '{"foobar": 5}'), |
458 | + ('/anonymous/', 'test2.json', '{"froz": "bot"}'), |
459 | + ], |
460 | + 'expected_results': [{ |
461 | + 'content_filename': 'test1.json', |
462 | + 'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19', |
463 | + }, { |
464 | + 'content_filename': 'test2.json', |
465 | + 'content_sha1': '67dd49730d4e3b38b840f3d544d45cad74bcfb09', |
466 | + }], |
467 | + }), |
468 | + ('several_bundles_in_other_stream', { |
469 | + 'query': '/anonymous/other/', |
470 | + 'bundles': [ |
471 | + ('/anonymous/', 'test3.json', '{}'), |
472 | + ('/anonymous/other/', 'test4.json', '{"x": true}'), |
473 | + ], |
474 | + 'expected_results': [{ |
475 | + 'content_filename': 'test4.json', |
476 | + 'content_sha1': 'bac148f29c35811441a7b4746a022b04c65bffc0', |
477 | + }], |
478 | + }), |
479 | + ('several_bundles_in_bogus_pathname', { |
480 | + 'query': '/bogus/', |
481 | + 'bundles': [ |
482 | + ('/anonymous/', 'test5.json', '{}'), |
483 | + ], |
484 | + 'expected_results': [], |
485 | + }), |
486 | + ] |
487 | + |
488 | + def test_bundles(self): |
489 | """ |
490 | Make a bunch of bundles (all in a public branch) and check that |
491 | they are returned by the XML-RPC request. |
492 | """ |
493 | - with fixtures.created_bundles(bundles): |
494 | - results = self.xml_rpc_call('bundles', query) |
495 | - self.assertEqual(len(results), len(expected_results)) |
496 | - with fixtures.test_loop(zip(results, expected_results)) as loop_items: |
497 | + with fixtures.created_bundles(self.bundles): |
498 | + results = self.xml_rpc_call('bundles', self.query) |
499 | + self.assertEqual(len(results), len(self.expected_results)) |
500 | + with fixtures.test_loop(zip(results, self.expected_results)) as loop_items: |
501 | for result, expected_result in loop_items: |
502 | self.assertEqual( |
503 | result['content_filename'], |
504 | @@ -473,156 +500,184 @@ |
505 | result['content_sha1'], |
506 | expected_result['content_sha1']) |
507 | |
508 | - @fixtures.use_test_scenarios( |
509 | - ('bundle_we_can_access', { |
510 | - 'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19', |
511 | - 'bundles': [ |
512 | - ('/anonymous/', 'test1.json', '{"foobar": 5}'), |
513 | - ('/anonymous/', 'test2.json', '{"froz": "bot"}'), |
514 | - ], |
515 | - 'expected_result': { |
516 | - 'content_filename': 'test1.json', |
517 | - 'content': '{"foobar": 5}', |
518 | - } |
519 | - }), |
520 | - ) |
521 | - def test_get(self, content_sha1, bundles, expected_result): |
522 | +class DashboardAPIGetTests(DashboardAPITestCase): |
523 | + |
524 | + scenarios = [ |
525 | + ('bundle_we_can_access', { |
526 | + 'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19', |
527 | + 'bundles': [ |
528 | + ('/anonymous/', 'test1.json', '{"foobar": 5}'), |
529 | + ('/anonymous/', 'test2.json', '{"froz": "bot"}'), |
530 | + ], |
531 | + 'expected_result': { |
532 | + 'content_filename': 'test1.json', |
533 | + 'content': '{"foobar": 5}', |
534 | + } |
535 | + }), |
536 | + ] |
537 | + |
538 | + def test_get(self): |
539 | """ |
540 | Make a bunch of bundles (all in a public branch) and check that |
541 | we can get them back by calling get() |
542 | """ |
543 | - with fixtures.created_bundles(bundles): |
544 | - result = self.xml_rpc_call('get', content_sha1) |
545 | + with fixtures.created_bundles(self.bundles): |
546 | + result = self.xml_rpc_call('get', self.content_sha1) |
547 | self.assertTrue(isinstance(result, dict)) |
548 | self.assertEqual( |
549 | result['content_filename'], |
550 | - expected_result['content_filename']) |
551 | + self.expected_result['content_filename']) |
552 | self.assertEqual( |
553 | result['content'], |
554 | - expected_result['content']) |
555 | - |
556 | - @fixtures.use_test_scenarios( |
557 | - ('bad_sha1', { |
558 | - 'content_sha1': '', |
559 | - 'faultCode': errors.NOT_FOUND |
560 | - }), |
561 | - ('no_access_to_personal_bundles', { |
562 | - 'bundles': [ |
563 | - ('/personal/bob/', 'test1.json', '{"foobar": 5}'), |
564 | - ], |
565 | - 'faultCode': errors.FORBIDDEN |
566 | - }), |
567 | - ('no_access_to_named_personal_bundles', { |
568 | - 'bundles': [ |
569 | - ('/personal/bob/some-name/', 'test1.json', '{"foobar": 5}'), |
570 | - ], |
571 | - 'faultCode': errors.FORBIDDEN |
572 | - }), |
573 | - ('no_access_to_team_bundles', { |
574 | - 'bundles': [ |
575 | - ('/team/members/', 'test1.json', '{"foobar": 5}'), |
576 | - ], |
577 | - 'faultCode': errors.FORBIDDEN |
578 | - }), |
579 | - ('no_access_to_named_team_bundles', { |
580 | - 'bundles': [ |
581 | - ('/team/members/some-name/', 'test1.json', '{"foobar": 5}'), |
582 | - ], |
583 | - 'faultCode': errors.FORBIDDEN |
584 | - }), |
585 | - ) |
586 | - def test_get_failure(self, faultCode, |
587 | - content_sha1='72996acd68de60c766b60c2ca6f6169f67cdde19', |
588 | - bundles=[]): |
589 | - with fixtures.created_bundles(bundles): |
590 | + self.expected_result['content']) |
591 | + |
592 | + |
593 | +class DashboardAPIGetFailureTests(DashboardAPITestCase): |
594 | + |
595 | + scenarios = [ |
596 | + ('bad_sha1', { |
597 | + 'content_sha1': '', |
598 | + 'faultCode': errors.NOT_FOUND |
599 | + }), |
600 | + ('no_access_to_personal_bundles', { |
601 | + 'bundles': [ |
602 | + ('/personal/bob/', 'test1.json', '{"foobar": 5}'), |
603 | + ], |
604 | + 'faultCode': errors.FORBIDDEN |
605 | + }), |
606 | + ('no_access_to_named_personal_bundles', { |
607 | + 'bundles': [ |
608 | + ('/personal/bob/some-name/', 'test1.json', '{"foobar": 5}'), |
609 | + ], |
610 | + 'faultCode': errors.FORBIDDEN |
611 | + }), |
612 | + ('no_access_to_team_bundles', { |
613 | + 'bundles': [ |
614 | + ('/team/members/', 'test1.json', '{"foobar": 5}'), |
615 | + ], |
616 | + 'faultCode': errors.FORBIDDEN |
617 | + }), |
618 | + ('no_access_to_named_team_bundles', { |
619 | + 'bundles': [ |
620 | + ('/team/members/some-name/', 'test1.json', '{"foobar": 5}'), |
621 | + ], |
622 | + 'faultCode': errors.FORBIDDEN |
623 | + }), |
624 | + ] |
625 | + |
626 | + bundles = [] |
627 | + content_sha1='72996acd68de60c766b60c2ca6f6169f67cdde19' |
628 | + |
629 | + def test_get_failure(self): |
630 | + with fixtures.created_bundles(self.bundles): |
631 | try: |
632 | - self.xml_rpc_call('get', content_sha1) |
633 | + self.xml_rpc_call('get', self.content_sha1) |
634 | except xmlrpclib.Fault as ex: |
635 | - self.assertEqual(ex.faultCode, faultCode) |
636 | + self.assertEqual(ex.faultCode, self.faultCode) |
637 | else: |
638 | self.fail("Should have raised an exception") |
639 | |
640 | - @fixtures.use_test_scenarios( |
641 | - ('store_to_public_stream', { |
642 | - 'bundle_streams': [{}], |
643 | - 'content': '{"foobar": 5}', |
644 | - 'content_filename': 'test1.json', |
645 | - 'pathname': '/anonymous/', |
646 | - }), |
647 | - ('store_to_public_named_stream', { |
648 | - 'bundle_streams': [{'slug': 'some-name'}], |
649 | - 'content': '{"foobar": 5}', |
650 | - 'content_filename': 'test1.json', |
651 | - 'pathname': '/anonymous/some-name/', |
652 | - }), |
653 | - ) |
654 | - def test_put(self, bundle_streams, content, content_filename, pathname): |
655 | - with fixtures.created_bundle_streams(bundle_streams): |
656 | + |
657 | +class DashboardAPIPutTests(DashboardAPITestCase): |
658 | + |
659 | + scenarios = [ |
660 | + ('store_to_public_stream', { |
661 | + 'bundle_streams': [{}], |
662 | + 'content': '{"foobar": 5}', |
663 | + 'content_filename': 'test1.json', |
664 | + 'pathname': '/anonymous/', |
665 | + }), |
666 | + ('store_to_public_named_stream', { |
667 | + 'bundle_streams': [{'slug': 'some-name'}], |
668 | + 'content': '{"foobar": 5}', |
669 | + 'content_filename': 'test1.json', |
670 | + 'pathname': '/anonymous/some-name/', |
671 | + }), |
672 | + ] |
673 | + |
674 | + def test_put(self): |
675 | + with fixtures.created_bundle_streams(self.bundle_streams): |
676 | content_sha1 = self.xml_rpc_call("put", |
677 | - content, content_filename, pathname) |
678 | + self.content, self.content_filename, self.pathname) |
679 | stored = Bundle.objects.get(content_sha1=content_sha1) |
680 | try: |
681 | self.assertEqual(stored.content_sha1, content_sha1) |
682 | - self.assertEqual(stored.content.read(), content) |
683 | - self.assertEqual(stored.content_filename, content_filename) |
684 | - self.assertEqual(stored.bundle_stream.pathname, pathname) |
685 | + self.assertEqual(stored.content.read(), self.content) |
686 | + self.assertEqual( |
687 | + stored.content_filename, self.content_filename) |
688 | + self.assertEqual(stored.bundle_stream.pathname, self.pathname) |
689 | finally: |
690 | stored.delete() |
691 | |
692 | - @fixtures.use_test_scenarios( |
693 | - ('store_to_personal_stream', { |
694 | - 'bundle_streams': [{'user': 'joe'}], |
695 | - 'content': '{"foobar": 5}', |
696 | - 'content_filename': 'test1.json', |
697 | - 'pathname': '/personal/joe/', |
698 | - 'faultCode': errors.FORBIDDEN, |
699 | - }), |
700 | - ('store_to_named_personal_stream', { |
701 | - 'bundle_streams': [{'user': 'joe', 'slug': 'some-name'}], |
702 | - 'content': '{"foobar": 5}', |
703 | - 'content_filename': 'test1.json', |
704 | - 'pathname': '/personal/joe/some-name/', |
705 | - 'faultCode': errors.FORBIDDEN, |
706 | - }), |
707 | - ('store_to_team_stream', { |
708 | - 'bundle_streams': [{'group': 'members'}], |
709 | - 'content': '{"foobar": 5}', |
710 | - 'content_filename': 'test1.json', |
711 | - 'pathname': '/team/members/', |
712 | - 'faultCode': errors.FORBIDDEN, |
713 | - }), |
714 | - ('store_to_named_team_stream', { |
715 | - 'bundle_streams': [{'group': 'members', 'slug': 'some-name'}], |
716 | - 'content': '{"foobar": 5}', |
717 | - 'content_filename': 'test1.json', |
718 | - 'pathname': '/team/members/some-name/', |
719 | - 'faultCode': errors.FORBIDDEN, |
720 | - }), |
721 | - ('store_to_missing_stream', { |
722 | - 'bundle_streams': [], |
723 | - 'content': '{"foobar": 5}', |
724 | - 'content_filename': 'test1.json', |
725 | - 'pathname': '/anonymous/', |
726 | - 'faultCode': errors.NOT_FOUND, |
727 | - }), |
728 | - ('store_duplicate', { |
729 | - 'bundle_streams': [], |
730 | - 'bundles': [('/anonymous/', 'test1.json', '{"foobar": 5}')], |
731 | - 'content': '{"foobar": 5}', |
732 | - 'content_filename': 'test1.json', |
733 | - 'pathname': '/anonymous/', |
734 | - 'faultCode': errors.CONFLICT, |
735 | - }), |
736 | - ) |
737 | - def test_put_failure(self, bundle_streams, content, |
738 | - content_filename, pathname, faultCode, bundles=[]): |
739 | + |
740 | +class DashboardAPIPutFailureTests(DashboardAPITestCase): |
741 | + |
742 | + scenarios = [ |
743 | + ('store_to_personal_stream', { |
744 | + 'bundle_streams': [{'user': 'joe'}], |
745 | + 'content': '{"foobar": 5}', |
746 | + 'content_filename': 'test1.json', |
747 | + 'pathname': '/personal/joe/', |
748 | + 'faultCode': errors.FORBIDDEN, |
749 | + }), |
750 | + ('store_to_named_personal_stream', { |
751 | + 'bundle_streams': [{'user': 'joe', 'slug': 'some-name'}], |
752 | + 'content': '{"foobar": 5}', |
753 | + 'content_filename': 'test1.json', |
754 | + 'pathname': '/personal/joe/some-name/', |
755 | + 'faultCode': errors.FORBIDDEN, |
756 | + }), |
757 | + ('store_to_team_stream', { |
758 | + 'bundle_streams': [{'group': 'members'}], |
759 | + 'content': '{"foobar": 5}', |
760 | + 'content_filename': 'test1.json', |
761 | + 'pathname': '/team/members/', |
762 | + 'faultCode': errors.FORBIDDEN, |
763 | + }), |
764 | + ('store_to_named_team_stream', { |
765 | + 'bundle_streams': [{'group': 'members', 'slug': 'some-name'}], |
766 | + 'content': '{"foobar": 5}', |
767 | + 'content_filename': 'test1.json', |
768 | + 'pathname': '/team/members/some-name/', |
769 | + 'faultCode': errors.FORBIDDEN, |
770 | + }), |
771 | + ('store_to_missing_stream', { |
772 | + 'bundle_streams': [], |
773 | + 'content': '{"foobar": 5}', |
774 | + 'content_filename': 'test1.json', |
775 | + 'pathname': '/anonymous/', |
776 | + 'faultCode': errors.NOT_FOUND, |
777 | + }), |
778 | + ('store_duplicate', { |
779 | + 'bundle_streams': [], |
780 | + 'bundles': [('/anonymous/', 'test1.json', '{"foobar": 5}')], |
781 | + 'content': '{"foobar": 5}', |
782 | + 'content_filename': 'test1.json', |
783 | + 'pathname': '/anonymous/', |
784 | + 'faultCode': errors.CONFLICT, |
785 | + }), |
786 | + ] |
787 | + |
788 | + bundles = [] |
789 | + |
790 | + def test_put_failure(self): |
791 | with contextlib.nested( |
792 | - fixtures.created_bundle_streams(bundle_streams), |
793 | - fixtures.created_bundles(bundles)): |
794 | + fixtures.created_bundle_streams(self.bundle_streams), |
795 | + fixtures.created_bundles(self.bundles)): |
796 | try: |
797 | - self.xml_rpc_call("put", content, content_filename, |
798 | - pathname) |
799 | + self.xml_rpc_call("put", self.content, self.content_filename, |
800 | + self.pathname) |
801 | except xmlrpclib.Fault as ex: |
802 | - self.assertEqual(ex.faultCode, faultCode) |
803 | + self.assertEqual(ex.faultCode, self.faultCode) |
804 | else: |
805 | self.fail("Should have raised an exception") |
806 | + |
807 | + |
808 | +def suite(): |
809 | + import unittest |
810 | + from testscenarios.scenarios import generate_scenarios |
811 | + loader = unittest.TestLoader() |
812 | + test_suite = unittest.TestSuite() |
813 | + tests = loader.loadTestsFromName(__name__) |
814 | + test_suite.addTests(generate_scenarios(tests)) |
815 | + return test_suite |
Interesting.
While the code that removes the created resources is still there (see fixtures. create_ xxx) the code indeed works. Really nice, thank you :-)