~azzar1/unity/add-show-desktop-key

1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
1
from nose.tools import assert_equal, raises
2
1294.3.2 by William Grant
Router->Publisher
3
from ivle.webapp.publisher import (INF, InsufficientPathSegments, NoPath,
4
                                   NotFound, RouteConflict, Publisher, ROOT)
1294.2.1 by William Grant
Add an object-traversal-based router.
5
6
class Root(object):
7
    def __init__(self):
8
        self.subjects = {}
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
9
        self.users = {}
1294.2.1 by William Grant
Add an object-traversal-based router.
10
11
    def add_subject(self, subject):
12
        self.subjects[subject.name] = subject
13
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
14
    def add_user(self, user):
15
        self.users[user.login] = user
16
17
class User(object):
18
    def __init__(self, login):
19
        self.login = login
20
1294.2.1 by William Grant
Add an object-traversal-based router.
21
class Subject(object):
22
    def __init__(self, name, code):
23
        self.name = name
24
        self.code = code
25
        self.offerings = {}
26
27
    def add_offering(self, offering):
28
        assert self.name == offering.subject.name
29
        self.offerings[(offering.year, offering.semester)] = offering
30
31
class Offering(object):
32
    def __init__(self, subject, year, semester):
33
        self.subject = subject
34
        self.year = year
35
        self.semester = semester
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
36
        self.projects = {}
37
38
    def add_project(self, project):
39
        assert project.offering is self
40
        self.projects[project.name] = project
1294.2.1 by William Grant
Add an object-traversal-based router.
41
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
42
class OfferingFiles(object):
1294.2.22 by William Grant
Test named routes.
43
    def __init__(self, offering):
44
        self.offering = offering
45
1294.2.37 by William Grant
Test a route with infinitely many arguments.
46
class OfferingFile(object):
47
    def __init__(self, offeringfiles, path):
48
        self.offering = offeringfiles.offering
49
        self.path = path
50
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
51
class Project(object):
52
    def __init__(self, offering, name):
53
        self.offering = offering
54
        self.name = name
55
1294.2.37 by William Grant
Test a route with infinitely many arguments.
56
1294.2.1 by William Grant
Add an object-traversal-based router.
57
class View(object):
58
    def __init__(self, context):
59
        self.context = context
60
61
class RootIndex(View):
62
    pass
63
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
64
class UserServeView(View):
65
    pass
66
1294.2.1 by William Grant
Add an object-traversal-based router.
67
class SubjectIndex(View):
68
    pass
69
70
class SubjectEdit(View):
71
    pass
72
73
class OfferingIndex(View):
74
    pass
75
76
class OfferingEdit(View):
77
    pass
78
1294.2.2 by William Grant
Split out views from normal routes, and add a viewset concept.
79
class OfferingAPIIndex(View):
80
    pass
81
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
82
class OfferingFilesIndex(View):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
83
    pass
84
1294.2.37 by William Grant
Test a route with infinitely many arguments.
85
class OfferingFileIndex(View):
86
    pass
87
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
88
class ProjectIndex(View):
89
    pass
90
1294.2.46 by William Grant
Add tests for default deep views.
91
class OfferingProjects(View):
92
    pass
93
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
94
class OfferingAddProject(View):
95
    pass
96
1693 by William Grant
Add support for "really deep" (more than two segment) views.
97
class OfferingWorksheets(View):
98
    pass
99
100
class OfferingWorksheetMarks(View):
101
    pass
102
103
class OfferingWorksheetCSVMarks(View):
104
    pass
105
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
106
def root_to_subject_or_user(root, name):
107
    if name.startswith('~'):
108
        return root.users.get(name[1:])
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
109
    return root.subjects.get(name)
1294.2.1 by William Grant
Add an object-traversal-based router.
110
111
def subject_to_offering(subject, year, semester):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
112
    return subject.offerings.get((int(year), int(semester)))
1294.2.1 by William Grant
Add an object-traversal-based router.
113
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
114
def offering_to_files(offering):
115
    return OfferingFiles(offering)
1294.2.1 by William Grant
Add an object-traversal-based router.
116
1294.2.37 by William Grant
Test a route with infinitely many arguments.
117
def offering_files_to_file(offeringfiles, *path):
118
    return OfferingFile(offeringfiles, path)
119
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
120
def offering_to_project(offering, name):
121
    return offering.projects.get(name)
122
1294.2.1 by William Grant
Add an object-traversal-based router.
123
def subject_url(subject):
124
    return (ROOT, subject.name)
125
126
def offering_url(offering):
127
    return (offering.subject, (str(offering.year), str(offering.semester)))
128
1294.2.40 by William Grant
Test generation of URLs for named routes.
129
def offering_files_url(offeringfiles):
130
    return (offeringfiles.offering, '+files')
1294.2.22 by William Grant
Test named routes.
131
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
132
def project_url(project):
133
    return (project.offering, ('+projects', project.name))
1294.2.1 by William Grant
Add an object-traversal-based router.
134
135
class BaseTest(object):
136
    def setUp(self):
137
        r = Root()
138
        self.r = r
139
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
140
        # A user would be nice.
141
        r.add_user(User('jsmith'))
142
1294.2.1 by William Grant
Add an object-traversal-based router.
143
        # Give us some subjects...
144
        r.add_subject(Subject('info1', '600151'))
145
        r.add_subject(Subject('info2', '600152'))
146
        r.add_subject(Subject('info3', '600251'))
147
148
        # ... and some offerings.
149
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
150
                                         2008, 1))
151
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
152
                                         2008, 2))
153
        r.subjects['info1'].add_offering(Offering(self.r.subjects['info1'],
154
                                         2009, 1))
155
        r.subjects['info2'].add_offering(Offering(self.r.subjects['info2'],
156
                                         2008, 2))
157
        r.subjects['info2'].add_offering(Offering(self.r.subjects['info2'],
158
                                         2009, 1))
159
        r.subjects['info3'].add_offering(Offering(self.r.subjects['info3'],
160
                                         2009, 1))
161
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
162
        # A normal project...
163
        r.subjects['info1'].offerings[(2009, 1)].add_project(
164
            Project(r.subjects['info1'].offerings[(2009, 1)], 'p1')
165
            )
166
167
        # And one conflicting with a deep view, just to be nasty.
168
        r.subjects['info1'].offerings[(2009, 1)].add_project(
169
            Project(r.subjects['info1'].offerings[(2009, 1)], '+new')
170
            )
171
1294.2.1 by William Grant
Add an object-traversal-based router.
172
class TestResolution(BaseTest):
1294.2.10 by William Grant
Refactor resolution tests too.
173
    def setUp(self):
174
        super(TestResolution, self).setUp()
1294.3.2 by William Grant
Router->Publisher
175
        self.rtr = Publisher(root=self.r, viewset='browser')
1294.2.10 by William Grant
Refactor resolution tests too.
176
        self.rtr.add_set_switch('api', 'api')
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
177
        self.rtr.add_forward(Root, None, root_to_subject_or_user, 1)
1294.2.10 by William Grant
Refactor resolution tests too.
178
        self.rtr.add_forward(Subject, None, subject_to_offering, 2)
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
179
        self.rtr.add_forward(Offering, '+files', offering_to_files, 0)
1294.2.37 by William Grant
Test a route with infinitely many arguments.
180
        self.rtr.add_forward(OfferingFiles, None, offering_files_to_file, INF)
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
181
        self.rtr.add_forward(Offering, '+projects', offering_to_project, 1)
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
182
        self.rtr.add_view(User, None, UserServeView, viewset='browser')
1294.2.10 by William Grant
Refactor resolution tests too.
183
        self.rtr.add_view(Subject, '+index', SubjectIndex, viewset='browser')
184
        self.rtr.add_view(Subject, '+edit', SubjectEdit, viewset='browser')
185
        self.rtr.add_view(Offering, '+index', OfferingIndex, viewset='browser')
186
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
187
        self.rtr.add_view(OfferingFiles, '+index', OfferingFilesIndex,
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
188
                          viewset='browser')
1294.2.37 by William Grant
Test a route with infinitely many arguments.
189
        self.rtr.add_view(OfferingFile, '+index', OfferingFileIndex,
190
                          viewset='browser')
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
191
        self.rtr.add_view(Project, '+index', ProjectIndex, viewset='browser')
192
        self.rtr.add_view(Offering, ('+projects', '+new'), OfferingAddProject,
193
                          viewset='browser')
1294.2.46 by William Grant
Add tests for default deep views.
194
        self.rtr.add_view(Offering, ('+projects', '+index'), OfferingProjects,
195
                          viewset='browser')
1693 by William Grant
Add support for "really deep" (more than two segment) views.
196
        self.rtr.add_view(Offering, ('+worksheets', '+index'),
197
                          OfferingWorksheets, viewset='browser')
198
        self.rtr.add_view(Offering, ('+worksheets', '+marks', '+index'),
199
                          OfferingWorksheetMarks, viewset='browser')
200
        self.rtr.add_view(Offering, ('+worksheets', '+marks', 'marks.csv'),
201
                          OfferingWorksheetCSVMarks, viewset='browser')
1294.2.10 by William Grant
Refactor resolution tests too.
202
1294.2.23 by William Grant
Stop testing resolutions with views.
203
    def testOneRoute(self):
204
        assert_equal(self.rtr.resolve('/info1'),
205
                     (self.r.subjects['info1'], SubjectIndex, ())
206
                     )
207
        assert_equal(self.rtr.resolve('/info3'),
208
                     (self.r.subjects['info3'], SubjectIndex, ())
209
                     )
210
211
    def testTwoRoutes(self):
212
        assert_equal(self.rtr.resolve('/info1/2009/1'),
213
             (self.r.subjects['info1'].offerings[(2009, 1)], OfferingIndex, ())
214
             )
215
        assert_equal(self.rtr.resolve('/info2/2008/2'),
216
             (self.r.subjects['info2'].offerings[(2008, 2)], OfferingIndex, ())
217
             )
1294.2.10 by William Grant
Refactor resolution tests too.
218
1294.2.22 by William Grant
Test named routes.
219
    def testNamedRoute(self):
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
220
        assert_equal(type(self.rtr.resolve('/info1/2009/1/+files')[0]),
221
                     OfferingFiles
1294.2.22 by William Grant
Test named routes.
222
                    )
1294.2.36 by William Grant
Replace the tests' OfferingProjects with OfferingFiles.
223
        assert_equal(self.rtr.resolve('/info1/2009/1/+files')[0].offering,
1294.2.22 by William Grant
Test named routes.
224
                     self.r.subjects['info1'].offerings[(2009, 1)]
225
                    )
226
1294.2.23 by William Grant
Stop testing resolutions with views.
227
    def testNonDefaultView(self):
1294.2.10 by William Grant
Refactor resolution tests too.
228
        assert_equal(self.rtr.resolve('/info1/+edit'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
229
                     (self.r.subjects['info1'], SubjectEdit, ())
1294.2.10 by William Grant
Refactor resolution tests too.
230
                     )
1294.2.1 by William Grant
Add an object-traversal-based router.
231
1294.2.3 by William Grant
Add tests to complete coverage.
232
    def testDefaultView(self):
1294.2.10 by William Grant
Refactor resolution tests too.
233
        assert_equal(self.rtr.resolve('/info1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
234
                     (self.r.subjects['info1'], SubjectIndex, ())
235
                     )
236
237
    def testViewWithSubpath(self):
238
        assert_equal(self.rtr.resolve('/info1/+edit/foo/bar'),
1294.2.13 by William Grant
Fix view mistake in test.
239
                     (self.r.subjects['info1'], SubjectEdit, ('foo', 'bar'))
1294.2.10 by William Grant
Refactor resolution tests too.
240
                     )
241
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
242
    def testNoDefaultView(self):
243
        try:
244
            self.rtr.default = 'not+index'
245
            self.rtr.resolve('/info1')
246
        except NotFound, e:
247
            assert_equal(e.args, (self.r.subjects['info1'], '+index', ()))
248
        except:
249
            raise
250
        else:
251
            raise AssertionError('did not raise NotFound')
252
        finally:
253
            self.rtr.default = '+index'
254
255
    def testMissingView(self):
256
        try:
257
            self.rtr.resolve('/info1/+foo')
258
        except NotFound, e:
259
            assert_equal(e.args, (self.r.subjects['info1'], '+foo', ()))
260
        except:
261
            raise
262
        else:
263
            raise AssertionError('did not raise NotFound')
264
1294.2.10 by William Grant
Refactor resolution tests too.
265
    def testViewSetSeparation(self):
1294.2.35 by William Grant
Fix and expand tests to cover new NotFound cases.
266
        try:
267
            self.rtr.resolve('/api/info1/+edit')
268
        except NotFound, e:
269
            assert_equal(e.args, (self.r.subjects['info1'], '+edit', ()))
270
        except:
271
            raise
272
        else:
273
            raise AssertionError('did not raise NotFound')
274
275
    def testRouteReturningNone(self):
276
        try:
277
            self.rtr.resolve('/info9/+index')
278
        except NotFound, e:
279
            assert_equal(e.args, (self.r, 'info9', ('+index',)))
280
        except:
281
            raise
282
        else:
283
            raise AssertionError('did not raise NotFound')
1294.2.10 by William Grant
Refactor resolution tests too.
284
1294.2.37 by William Grant
Test a route with infinitely many arguments.
285
    def testRouteWithInfinitelyManyArguments(self):
286
        o, v, sp = self.rtr.resolve('/info1/2009/1/+files/foo/bar/baz')
287
288
        assert_equal(type(o), OfferingFile)
289
        assert_equal(o.path, ('foo', 'bar', 'baz'))
290
        assert_equal(o.offering, self.r.subjects['info1'].offerings[(2009, 1)])
291
        assert_equal(v, OfferingFileIndex)
292
        assert_equal(sp, ())
293
1294.2.38 by William Grant
Test behaviour when a nonexistent route is specified.
294
    def testMissingRoute(self):
295
        try:
296
            self.rtr.resolve('/info1/2009/1/+foo')
297
        except NotFound, e:
298
            assert_equal(e.args, (
299
                self.r.subjects['info1'].offerings[(2009, 1)],
300
                '+foo',
301
                ()
302
                ))
303
        except:
304
            raise
305
        else:
306
            raise AssertionError('did not raise NotFound')
307
1294.2.10 by William Grant
Refactor resolution tests too.
308
    def testAlternateViewSetWithDefault(self):
309
        assert_equal(self.rtr.resolve('/info1/2009/1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
310
             (self.r.subjects['info1'].offerings[(2009, 1)], OfferingIndex, ())
311
             )
1294.2.2 by William Grant
Split out views from normal routes, and add a viewset concept.
312
1294.2.10 by William Grant
Refactor resolution tests too.
313
        assert_equal(self.rtr.resolve('/api/info1/2009/1'),
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
314
          (self.r.subjects['info1'].offerings[(2009, 1)], OfferingAPIIndex, ())
315
          )
1294.2.3 by William Grant
Add tests to complete coverage.
316
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
317
    def testDeepView(self):
318
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects/+new'),
319
             (self.r.subjects['info1'].offerings[(2009, 1)],
320
              OfferingAddProject, ())
321
             )
322
1294.2.46 by William Grant
Add tests for default deep views.
323
    def testDefaultDeepView(self):
324
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects'),
325
             (self.r.subjects['info1'].offerings[(2009, 1)],
326
              OfferingProjects, ())
327
             )
328
1693 by William Grant
Add support for "really deep" (more than two segment) views.
329
    def testAnotherDefaultDeepView(self):
330
        assert_equal(self.rtr.resolve('/info1/2009/1/+worksheets'),
331
             (self.r.subjects['info1'].offerings[(2009, 1)],
332
              OfferingWorksheets, ())
333
             )
334
335
    def testReallyDeepView(self):
336
        assert_equal(
337
             self.rtr.resolve('/info1/2009/1/+worksheets/+marks/marks.csv'),
338
             (self.r.subjects['info1'].offerings[(2009, 1)],
339
              OfferingWorksheetCSVMarks, ())
340
             )
341
342
    def testDefaultReallyDeepView(self):
343
        assert_equal(self.rtr.resolve('/info1/2009/1/+worksheets/+marks'),
344
             (self.r.subjects['info1'].offerings[(2009, 1)],
345
              OfferingWorksheetMarks, ())
346
             )
347
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
348
    def testNamedRouteWithDeepView(self):
349
        assert_equal(self.rtr.resolve('/info1/2009/1/+projects/p1'),
350
             (self.r.subjects['info1'].offerings[(2009, 1)].projects['p1'],
351
              ProjectIndex, ())
352
             )
353
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
354
    def testNullPathView(self):
355
        """Verify that views can be placed immediately under an object.
356
357
        There are some cases in which it is useful for a view with a
358
        subpath to exist immediately under an object, with no name.
359
        """
360
        assert_equal(self.rtr.resolve('/~jsmith/foo/bar'),
361
             (self.r.users['jsmith'], UserServeView, ('foo', 'bar')))
362
1294.2.41 by William Grant
Test deep views (views with names consisting of multiple segments).
363
1294.2.1 by William Grant
Add an object-traversal-based router.
364
class TestGeneration(BaseTest):
1294.2.9 by William Grant
Refactor generation tests.
365
    def setUp(self):
366
        super(TestGeneration, self).setUp()
1294.3.2 by William Grant
Router->Publisher
367
        self.rtr = Publisher(root=self.r, viewset='browser')
1294.2.9 by William Grant
Refactor generation tests.
368
        self.rtr.add_set_switch('api', 'api')
369
        self.rtr.add_reverse(Subject, subject_url)
370
        self.rtr.add_reverse(Offering, offering_url)
1294.2.40 by William Grant
Test generation of URLs for named routes.
371
        self.rtr.add_reverse(OfferingFiles, offering_files_url)
1294.2.43 by William Grant
Test deep view generation.
372
        self.rtr.add_reverse(Project, project_url)
1294.2.9 by William Grant
Refactor generation tests.
373
        self.rtr.add_view(Subject, '+index', SubjectIndex, viewset='browser')
374
        self.rtr.add_view(Subject, '+edit', SubjectEdit, viewset='browser')
375
        self.rtr.add_view(Offering, '+index', OfferingIndex, viewset='browser')
376
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
1294.2.43 by William Grant
Test deep view generation.
377
        self.rtr.add_view(Project, '+index', ProjectIndex, viewset='browser')
378
        self.rtr.add_view(Offering, ('+projects', '+new'), OfferingAddProject,
379
                          viewset='browser')
1294.2.46 by William Grant
Add tests for default deep views.
380
        self.rtr.add_view(Offering, ('+projects', '+index'), OfferingProjects,
381
                          viewset='browser')
1294.2.9 by William Grant
Refactor generation tests.
382
1294.2.1 by William Grant
Add an object-traversal-based router.
383
    def testOneLevel(self):
1294.2.9 by William Grant
Refactor generation tests.
384
        assert_equal(self.rtr.generate(self.r.subjects['info1']), '/info1')
1294.2.1 by William Grant
Add an object-traversal-based router.
385
386
    def testTwoLevel(self):
1294.2.9 by William Grant
Refactor generation tests.
387
        assert_equal(
388
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)]),
389
            '/info1/2009/1'
390
            )
391
        assert_equal(
392
            self.rtr.generate(self.r.subjects['info2'].offerings[(2008, 2)]),
393
            '/info2/2008/2'
394
            )
1294.2.1 by William Grant
Add an object-traversal-based router.
395
1294.2.40 by William Grant
Test generation of URLs for named routes.
396
    def testNamedRoute(self):
397
        assert_equal(self.rtr.generate(
398
                OfferingFiles(self.r.subjects['info1'].offerings[(2009, 1)])),
399
                '/info1/2009/1/+files'
400
            )
401
1294.2.9 by William Grant
Refactor generation tests.
402
    def testView(self):
403
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit),
404
                     '/info1/+edit'
405
                     )
1294.2.1 by William Grant
Add an object-traversal-based router.
406
1294.2.4 by William Grant
Support generation of view URLs.
407
    def testDefaultView(self):
1294.2.9 by William Grant
Refactor generation tests.
408
        assert_equal(
409
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
410
                              OfferingIndex
411
                              ),
412
            '/info1/2009/1'
413
            )
1294.2.1 by William Grant
Add an object-traversal-based router.
414
1294.2.11 by William Grant
Revise generation and resolution tests to involve subpaths.
415
    def testViewWithSubpath(self):
416
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit,
417
                                       ('foo', 'bar')),
418
                     '/info1/+edit/foo/bar'
419
                     )
420
421
    def testViewWithStringSubpath(self):
422
        assert_equal(self.rtr.generate(self.r.subjects['info1'], SubjectEdit,
423
                                       'foo/bar'),
424
                     '/info1/+edit/foo/bar'
425
                     )
426
1294.2.9 by William Grant
Refactor generation tests.
427
    def testAlternateViewSetWithDefault(self):
428
        assert_equal(
429
            self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
430
                              OfferingAPIIndex
431
                              ),
432
            '/api/info1/2009/1'
433
            )
1294.2.4 by William Grant
Support generation of view URLs.
434
1294.2.43 by William Grant
Test deep view generation.
435
    def testDeepView(self):
436
        assert_equal(
437
            self.rtr.generate(
438
                self.r.subjects['info1'].offerings[(2009, 1)],
439
                OfferingAddProject
440
                ),
441
        '/info1/2009/1/+projects/+new'
442
        )
443
1294.2.46 by William Grant
Add tests for default deep views.
444
    def testDefaultDeepView(self):
445
        assert_equal(
446
            self.rtr.generate(
447
                self.r.subjects['info1'].offerings[(2009, 1)],
448
                OfferingProjects
449
                ),
450
        '/info1/2009/1/+projects'
451
        )
452
453
    def testDefaultDeepViewWithSubpath(self):
454
        assert_equal(
455
            self.rtr.generate(
456
                self.r.subjects['info1'].offerings[(2009, 1)],
457
                OfferingProjects, ('foo', 'bar')
458
                ),
459
        '/info1/2009/1/+projects/+index/foo/bar'
460
        )
461
1294.2.43 by William Grant
Test deep view generation.
462
    def testNamedRouteWithDeepView(self):
463
        assert_equal(
464
            self.rtr.generate(
465
                self.r.subjects['info1'].offerings[(2009, 1)].projects['p1'],
466
                ProjectIndex
467
                ),
468
        '/info1/2009/1/+projects/p1'
469
        )
470
1294.3.1 by William Grant
Allow reverse routes to return the real root too.
471
    def testRoot(self):
472
        assert_equal(self.rtr.generate(self.r), '/')
1294.2.43 by William Grant
Test deep view generation.
473
1294.2.1 by William Grant
Add an object-traversal-based router.
474
475
class TestErrors(BaseTest):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
476
    def setUp(self):
477
        super(TestErrors, self).setUp()
1294.3.2 by William Grant
Router->Publisher
478
        self.rtr = Publisher(root=self.r)
1294.2.136 by William Grant
Add publisher support for nameless views, directly under an object.
479
        self.rtr.add_forward(Root, None, root_to_subject_or_user, 1)
1294.2.6 by William Grant
Refactor the error tests, using a single router.
480
        self.rtr.add_forward(Subject, '+foo', lambda s: s.name + 'foo', 0)
481
        self.rtr.add_forward(Subject, None, subject_to_offering, 2)
482
        self.rtr.add_reverse(Subject, subject_url)
483
        self.rtr.add_reverse(Offering, offering_url)
484
        self.rtr.add_view(Offering, '+index', OfferingIndex)
485
        self.rtr.add_view(Offering, '+index', OfferingAPIIndex, viewset='api')
486
        self.rtr.add_set_switch('rest', 'rest')
487
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
488
    @raises(RouteConflict)
1294.2.1 by William Grant
Add an object-traversal-based router.
489
    def testForwardConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
490
        self.rtr.add_forward(Subject, '+foo', object(), 2)
1294.2.1 by William Grant
Add an object-traversal-based router.
491
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
492
    @raises(RouteConflict)
1294.2.1 by William Grant
Add an object-traversal-based router.
493
    def testReverseConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
494
        self.rtr.add_reverse(Subject, object())
1294.2.1 by William Grant
Add an object-traversal-based router.
495
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
496
    @raises(RouteConflict)
1294.2.3 by William Grant
Add tests to complete coverage.
497
    def testViewConflict(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
498
        self.rtr.add_view(Offering, '+index', object())
499
500
    @raises(RouteConflict)
501
    def testSetSwitchForwardConflict(self):
502
        self.rtr.add_set_switch('rest', 'foo')
503
504
    @raises(RouteConflict)
505
    def testSetSwitchReverseConflict(self):
506
        self.rtr.add_set_switch('bar', 'rest')
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
507
508
    @raises(NoPath)
1294.2.1 by William Grant
Add an object-traversal-based router.
509
    def testNoPath(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
510
        self.rtr.generate(object())
1294.2.1 by William Grant
Add an object-traversal-based router.
511
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
512
    @raises(NoPath)
1294.2.4 by William Grant
Support generation of view URLs.
513
    def testNoSetSwitch(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
514
        self.rtr.generate(self.r.subjects['info1'].offerings[(2009, 1)],
515
                          OfferingAPIIndex)
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
516
517
    @raises(NoPath)
1294.2.4 by William Grant
Support generation of view URLs.
518
    def testUnregisteredView(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
519
        self.rtr.generate(self.r.subjects['info1'], SubjectIndex)
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
520
521
    @raises(NotFound)
1294.2.1 by William Grant
Add an object-traversal-based router.
522
    def testNotFound(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
523
        self.rtr.resolve('/bar')
1294.2.1 by William Grant
Add an object-traversal-based router.
524
1294.2.5 by William Grant
Use nose.tools.raises in the error tests.
525
    @raises(InsufficientPathSegments)
1294.2.1 by William Grant
Add an object-traversal-based router.
526
    def testInsufficientPathSegments(self):
1294.2.6 by William Grant
Refactor the error tests, using a single router.
527
        self.rtr.resolve('/info1/foo')