Merge lp:~james-w/lava-dashboard/use-testscenarios into lp:~zyga/lava-dashboard/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
Reviewer Review Type Date Requested Status
Zygmunt Krynicki Approve
Review via email: mp+34919@code.launchpad.net

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.
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Interesting.

While the code that removes the created resources is still there (see fixtures.create_xxx) the code indeed works. Really nice, thank you :-)

review: Approve

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

Subscribers

People subscribed via source and target branches

to all changes: