Michael Merickel
2018-10-15 dd3cc81f75dcb5ff96e0751653071722a15f46c2
commit | author | age
c55903 1 # -*- coding: utf-8 -*-
CM 2
64aaf0 3 import datetime
0393f9 4 import gc
64c913 5 import locale
b99526 6 import os
5a7f9a 7 import unittest
CM 8
b60bdb 9 from pyramid.wsgi import wsgiapp
197f0c 10 from pyramid.view import view_config
56d0fe 11 from pyramid.static import static_view
b1cad5 12 from pyramid.testing import skip_on
f5b9e9 13 from pyramid.compat import (
CM 14     text_,
15     url_quote,
16     )
5a7f9a 17
CM 18 from zope.interface import Interface
684a2c 19 from webtest import TestApp
64aaf0 20
CM 21 # 5 years from now (more or less)
22 fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365)
64c913 23
CM 24 defaultlocale = locale.getdefaultlocale()[1]
5a7f9a 25
CM 26 class INothing(Interface):
27     pass
28
197f0c 29 @view_config(for_=INothing)
5a7f9a 30 @wsgiapp
CM 31 def wsgiapptest(environ, start_response):
32     """ """
33     return '123'
34
cba2e1 35 class WGSIAppPlusViewConfigTests(unittest.TestCase):
5a7f9a 36     def test_it(self):
e6fa66 37         from venusian import ATTACH_ATTR
5a7f9a 38         import types
a1d395 39         self.assertTrue(getattr(wsgiapptest, ATTACH_ATTR))
CM 40         self.assertTrue(type(wsgiapptest) is types.FunctionType)
5a7f9a 41         context = DummyContext()
CM 42         request = DummyRequest()
43         result = wsgiapptest(context, request)
44         self.assertEqual(result, '123')
45
58afb3 46     def test_scanned(self):
b60bdb 47         from pyramid.interfaces import IRequest
CM 48         from pyramid.interfaces import IView
49         from pyramid.interfaces import IViewClassifier
427a02 50         from pyramid.config import Configurator
dd3cc8 51         from . import test_integration
427a02 52         config = Configurator()
2aa86c 53         config.scan(test_integration)
c0d4a1 54         config.commit()
2aa86c 55         reg = config.registry
ff1213 56         view = reg.adapters.lookup(
CM 57             (IViewClassifier, IRequest, INothing), IView, name='')
661ea7 58         self.assertEqual(view.__original_view__, wsgiapptest)
5a7f9a 59
a49168 60 class IntegrationBase(object):
CM 61     root_factory = None
62     package = None
63     def setUp(self):
64         from pyramid.config import Configurator
65         config = Configurator(root_factory=self.root_factory,
66                               package=self.package)
67         config.include(self.package)
68         app = config.make_wsgi_app()
69         self.testapp = TestApp(app)
70         self.config = config
71
72     def tearDown(self):
73         self.config.end()
74
b99526 75 here = os.path.dirname(__file__)
CM 76
061907 77 class StaticAppBase(IntegrationBase):
a49168 78     def test_basic(self):
b368d7 79         res = self.testapp.get('/minimal.txt', status=200)
BJR 80         _assertBody(res.body, os.path.join(here, 'fixtures/minimal.txt'))
a49168 81
d5dc5d 82     def test_hidden(self):
CM 83         res = self.testapp.get('/static/.hiddenfile', status=200)
a0e8df 84         _assertBody(res.body, os.path.join(here, 'fixtures/static/.hiddenfile'))
d5dc5d 85
076060 86     if defaultlocale is not None: # pragma: no cover
54105d 87         # These tests are expected to fail on LANG=C systems due to decode
CM 88         # errors and on non-Linux systems due to git highchar handling
89         # vagaries
64c913 90         def test_highchars_in_pathelement(self):
5d9bf1 91             path = os.path.join(
MM 92                 here,
93                 text_('fixtures/static/héhé/index.html', 'utf-8'))
94             pathdir = os.path.dirname(path)
95             body = b'<html>hehe</html>\n'
96             try:
97                 os.makedirs(pathdir)
98                 with open(path, 'wb') as fp:
99                     fp.write(body)
100                 url = url_quote('/static/héhé/index.html')
101                 res = self.testapp.get(url, status=200)
102                 self.assertEqual(res.body, body)
103             finally:
104                 os.unlink(path)
105                 os.rmdir(pathdir)
d5dc5d 106
64c913 107         def test_highchars_in_filename(self):
5d9bf1 108             path = os.path.join(
MM 109                 here,
110                 text_('fixtures/static/héhé.html', 'utf-8'))
111             body = b'<html>hehe file</html>\n'
112             with open(path, 'wb') as fp:
113                 fp.write(body)
114             try:
115                 url = url_quote('/static/héhé.html')
116                 res = self.testapp.get(url, status=200)
117                 self.assertEqual(res.body, body)
118             finally:
119                 os.unlink(path)
d5dc5d 120
a49168 121     def test_not_modified(self):
CM 122         self.testapp.extra_environ = {
64aaf0 123             'HTTP_IF_MODIFIED_SINCE':httpdate(fiveyrsfuture)}
b368d7 124         res = self.testapp.get('/minimal.txt', status=304)
8e606d 125         self.assertEqual(res.body, b'')
a49168 126
CM 127     def test_file_in_subdir(self):
128         fn = os.path.join(here, 'fixtures/static/index.html')
129         res = self.testapp.get('/static/index.html', status=200)
a0e8df 130         _assertBody(res.body, fn)
a49168 131
CM 132     def test_directory_noslash_redir(self):
133         res = self.testapp.get('/static', status=301)
134         self.assertEqual(res.headers['Location'], 'http://localhost/static/')
135
136     def test_directory_noslash_redir_preserves_qs(self):
137         res = self.testapp.get('/static?a=1&b=2', status=301)
138         self.assertEqual(res.headers['Location'],
139                          'http://localhost/static/?a=1&b=2')
140
141     def test_directory_noslash_redir_with_scriptname(self):
142         self.testapp.extra_environ = {'SCRIPT_NAME':'/script_name'}
143         res = self.testapp.get('/static', status=301)
144         self.assertEqual(res.headers['Location'],
145                          'http://localhost/script_name/static/')
146
147     def test_directory_withslash(self):
148         fn = os.path.join(here, 'fixtures/static/index.html')
149         res = self.testapp.get('/static/', status=200)
a0e8df 150         _assertBody(res.body, fn)
a49168 151
CM 152     def test_range_inclusive(self):
153         self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1-2'}
154         res = self.testapp.get('/static/index.html', status=206)
8e606d 155         self.assertEqual(res.body, b'ht')
a49168 156
CM 157     def test_range_tilend(self):
158         self.testapp.extra_environ = {'HTTP_RANGE':'bytes=-5'}
159         res = self.testapp.get('/static/index.html', status=206)
80eac7 160         self.assertEqual(res.body, b'html>')
a49168 161
CM 162     def test_range_notbytes(self):
163         self.testapp.extra_environ = {'HTTP_RANGE':'kHz=-5'}
164         res = self.testapp.get('/static/index.html', status=200)
a0e8df 165         _assertBody(res.body,
CM 166                     os.path.join(here, 'fixtures/static/index.html'))
a49168 167
CM 168     def test_range_multiple(self):
169         res = self.testapp.get('/static/index.html',
9bd249 170                                [('HTTP_RANGE', 'bytes=10-11,11-12')],
a49168 171                                status=200)
a0e8df 172         _assertBody(res.body,
CM 173                     os.path.join(here, 'fixtures/static/index.html'))
a49168 174
CM 175     def test_range_oob(self):
176         self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1000-1002'}
177         self.testapp.get('/static/index.html', status=416)
178
179     def test_notfound(self):
180         self.testapp.get('/static/wontbefound.html', status=404)
181
66fe31 182     def test_oob_dotdotslash(self):
a49168 183         self.testapp.get('/static/../../test_integration.py', status=404)
66fe31 184
CM 185     def test_oob_dotdotslash_encoded(self):
186         self.testapp.get('/static/%2E%2E%2F/test_integration.py', status=404)
a49168 187
CM 188     def test_oob_slash(self):
189         self.testapp.get('/%2F/test_integration.py', status=404)
66fe31 190
d91dc7 191 class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase):
dd3cc8 192     package = 'tests.pkgs.eventonly'
d91dc7 193
CM 194     def test_sendfoo(self):
195         res = self.testapp.get('/sendfoo', status=200)
f55f9b 196         self.assertEqual(sorted(res.body.split()), [b'foo', b'fooyup'])
d91dc7 197
CM 198     def test_sendfoobar(self):
199         res = self.testapp.get('/sendfoobar', status=200)
200         self.assertEqual(sorted(res.body.split()),
f55f9b 201                          [b'foobar', b'foobar2', b'foobaryup', b'foobaryup2'])
d91dc7 202
061907 203 class TestStaticAppUsingAbsPath(StaticAppBase, unittest.TestCase):
dd3cc8 204     package = 'tests.pkgs.static_abspath'
a49168 205
061907 206 class TestStaticAppUsingAssetSpec(StaticAppBase, unittest.TestCase):
dd3cc8 207     package = 'tests.pkgs.static_assetspec'
a49168 208
CM 209 class TestStaticAppNoSubpath(unittest.TestCase):
210     staticapp = static_view(os.path.join(here, 'fixtures'), use_subpath=False)
c7446c 211     def _makeRequest(self, extra):
f2ef79 212         from pyramid.request import Request
8e606d 213         from io import BytesIO
f2ef79 214         kw = {'PATH_INFO':'',
CM 215               'SCRIPT_NAME':'',
216               'SERVER_NAME':'localhost',
217               'SERVER_PORT':'80',
218               'REQUEST_METHOD':'GET',
219               'wsgi.version':(1,0),
220               'wsgi.url_scheme':'http',
8e606d 221               'wsgi.input':BytesIO()}
f2ef79 222         kw.update(extra)
CM 223         request = Request(kw)
224         return request
225
226     def test_basic(self):
b368d7 227         request = self._makeRequest({'PATH_INFO':'/minimal.txt'})
f2ef79 228         context = DummyContext()
CM 229         result = self.staticapp(context, request)
230         self.assertEqual(result.status, '200 OK')
b368d7 231         _assertBody(result.body, os.path.join(here, 'fixtures/minimal.txt'))
29a850 232
bc9357 233 class TestStaticAppWithRoutePrefix(IntegrationBase, unittest.TestCase):
dd3cc8 234     package = 'tests.pkgs.static_routeprefix'
bc9357 235
CM 236     def test_includelevel1(self):
b368d7 237         res = self.testapp.get('/static/minimal.txt', status=200)
a0e8df 238         _assertBody(res.body,
b368d7 239                     os.path.join(here, 'fixtures/minimal.txt'))
bc9357 240
CM 241     def test_includelevel2(self):
242         res = self.testapp.get('/prefix/static/index.html', status=200)
a0e8df 243         _assertBody(res.body,
CM 244                     os.path.join(here, 'fixtures/static/index.html'))
bc9357 245
CM 246
a49168 247 class TestFixtureApp(IntegrationBase, unittest.TestCase):
dd3cc8 248     package = 'tests.pkgs.fixtureapp'
dbaa08 249     def test_another(self):
CM 250         res = self.testapp.get('/another.html', status=200)
8e606d 251         self.assertEqual(res.body, b'fixture')
1dc390 252
dbaa08 253     def test_root(self):
CM 254         res = self.testapp.get('/', status=200)
8e606d 255         self.assertEqual(res.body, b'fixture')
dbaa08 256
CM 257     def test_dummyskin(self):
258         self.testapp.get('/dummyskin.html', status=404)
259
260     def test_error(self):
261         res = self.testapp.get('/error.html', status=200)
8e606d 262         self.assertEqual(res.body, b'supressed')
dbaa08 263
CM 264     def test_protected(self):
a05353 265         self.testapp.get('/protected.html', status=403)
dbaa08 266
a49168 267 class TestStaticPermApp(IntegrationBase, unittest.TestCase):
dd3cc8 268     package = 'tests.pkgs.staticpermapp'
MM 269     root_factory = 'tests.pkgs.staticpermapp:RootFactory'
0b2629 270     def test_allowed(self):
CM 271         result = self.testapp.get('/allowed/index.html', status=200)
5dd253 272         _assertBody(result.body,
CM 273                     os.path.join(here, 'fixtures/static/index.html'))
0b2629 274
CM 275     def test_denied_via_acl_global_root_factory(self):
276         self.testapp.extra_environ = {'REMOTE_USER':'bob'}
277         self.testapp.get('/protected/index.html', status=403)
278
279     def test_allowed_via_acl_global_root_factory(self):
280         self.testapp.extra_environ = {'REMOTE_USER':'fred'}
281         result = self.testapp.get('/protected/index.html', status=200)
5dd253 282         _assertBody(result.body, 
CM 283                     os.path.join(here, 'fixtures/static/index.html'))
0b2629 284
CM 285     def test_denied_via_acl_local_root_factory(self):
286         self.testapp.extra_environ = {'REMOTE_USER':'fred'}
287         self.testapp.get('/factory_protected/index.html', status=403)
288
289     def test_allowed_via_acl_local_root_factory(self):
290         self.testapp.extra_environ = {'REMOTE_USER':'bob'}
291         result = self.testapp.get('/factory_protected/index.html', status=200)
5dd253 292         _assertBody(result.body,
CM 293                     os.path.join(here, 'fixtures/static/index.html'))
0b2629 294
a49168 295 class TestCCBug(IntegrationBase, unittest.TestCase):
74a8f6 296     # "unordered" as reported in IRC by author of
CM 297     # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/
dd3cc8 298     package = 'tests.pkgs.ccbugapp'
dbaa08 299     def test_rdf(self):
CM 300         res = self.testapp.get('/licenses/1/v1/rdf', status=200)
8e606d 301         self.assertEqual(res.body, b'rdf')
74a8f6 302
dbaa08 303     def test_juri(self):
CM 304         res = self.testapp.get('/licenses/1/v1/juri', status=200)
8e606d 305         self.assertEqual(res.body, b'juri')
dbaa08 306
a49168 307 class TestHybridApp(IntegrationBase, unittest.TestCase):
333bd0 308     # make sure views registered for a route "win" over views registered
CM 309     # without one, even though the context of the non-route view may
310     # be more specific than the route view.
dd3cc8 311     package = 'tests.pkgs.hybridapp'
dbaa08 312     def test_root(self):
CM 313         res = self.testapp.get('/', status=200)
8e606d 314         self.assertEqual(res.body, b'global')
333bd0 315
dbaa08 316     def test_abc(self):
CM 317         res = self.testapp.get('/abc', status=200)
8e606d 318         self.assertEqual(res.body, b'route')
dbaa08 319
CM 320     def test_def(self):
321         res = self.testapp.get('/def', status=200)
8e606d 322         self.assertEqual(res.body, b'route2')
dbaa08 323
CM 324     def test_ghi(self):
325         res = self.testapp.get('/ghi', status=200)
8e606d 326         self.assertEqual(res.body, b'global')
dbaa08 327
CM 328     def test_jkl(self):
329         self.testapp.get('/jkl', status=404)
330
331     def test_mno(self):
332         self.testapp.get('/mno', status=404)
333
334     def test_pqr_global2(self):
335         res = self.testapp.get('/pqr/global2', status=200)
8e606d 336         self.assertEqual(res.body, b'global2')
dbaa08 337
CM 338     def test_error(self):
339         res = self.testapp.get('/error', status=200)
8e606d 340         self.assertEqual(res.body, b'supressed')
dbaa08 341
CM 342     def test_error2(self):
343         res = self.testapp.get('/error2', status=200)
8e606d 344         self.assertEqual(res.body, b'supressed2')
dbaa08 345
CM 346     def test_error_sub(self):
347         res = self.testapp.get('/error_sub', status=200)
8e606d 348         self.assertEqual(res.body, b'supressed2')
dbaa08 349
a49168 350 class TestRestBugApp(IntegrationBase, unittest.TestCase):
98e0d0 351     # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515)
dd3cc8 352     package = 'tests.pkgs.restbugapp'
98e0d0 353     def test_it(self):
dbaa08 354         res = self.testapp.get('/pet', status=200)
8e606d 355         self.assertEqual(res.body, b'gotten')
98e0d0 356
a49168 357 class TestForbiddenAppHasResult(IntegrationBase, unittest.TestCase):
b32552 358     # test that forbidden exception has ACLDenied result attached
dd3cc8 359     package = 'tests.pkgs.forbiddenapp'
b32552 360     def test_it(self):
CM 361         res = self.testapp.get('/x', status=403)
8e606d 362         message, result = [x.strip() for x in res.body.split(b'\n')]
CM 363         self.assertTrue(message.endswith(b'failed permission check'))
a1d395 364         self.assertTrue(
8e606d 365             result.startswith(b"ACLDenied permission 'private' via ACE "
CM 366                               b"'<default deny>' in ACL "
367                               b"'<No ACL found on any object in resource "
368                               b"lineage>' on context"))
a1d395 369         self.assertTrue(
8e606d 370             result.endswith(b"for principals ['system.Everyone']"))
b32552 371
a49168 372 class TestViewDecoratorApp(IntegrationBase, unittest.TestCase):
dd3cc8 373     package = 'tests.pkgs.viewdecoratorapp'
89968d 374
dbaa08 375     def test_first(self):
CM 376         res = self.testapp.get('/first', status=200)
8e606d 377         self.assertTrue(b'OK' in res.body)
89968d 378
dbaa08 379     def test_second(self):
CM 380         res = self.testapp.get('/second', status=200)
8e606d 381         self.assertTrue(b'OK2' in res.body)
dbaa08 382
0db4a1 383 class TestNotFoundView(IntegrationBase, unittest.TestCase):
dd3cc8 384     package = 'tests.pkgs.notfoundview'
0db4a1 385
CM 386     def test_it(self):
387         res = self.testapp.get('/wontbefound', status=200)
388         self.assertTrue(b'generic_notfound' in res.body)
b5422e 389         res = self.testapp.get('/bar', status=307)
0db4a1 390         self.assertEqual(res.location, 'http://localhost/bar/')
CM 391         res = self.testapp.get('/bar/', status=200)
392         self.assertTrue(b'OK bar' in res.body)
b5422e 393         res = self.testapp.get('/foo', status=307)
0db4a1 394         self.assertEqual(res.location, 'http://localhost/foo/')
CM 395         res = self.testapp.get('/foo/', status=200)
396         self.assertTrue(b'OK foo2' in res.body)
397         res = self.testapp.get('/baz', status=200)
398         self.assertTrue(b'baz_notfound' in res.body)
a7fe30 399
CM 400 class TestForbiddenView(IntegrationBase, unittest.TestCase):
dd3cc8 401     package = 'tests.pkgs.forbiddenview'
a7fe30 402
CM 403     def test_it(self):
404         res = self.testapp.get('/foo', status=200)
405         self.assertTrue(b'foo_forbidden' in res.body)
406         res = self.testapp.get('/bar', status=200)
407         self.assertTrue(b'generic_forbidden' in res.body)
0db4a1 408         
a49168 409 class TestViewPermissionBug(IntegrationBase, unittest.TestCase):
bdddc9 410     # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html
dd3cc8 411     package = 'tests.pkgs.permbugapp'
dbaa08 412     def test_test(self):
CM 413         res = self.testapp.get('/test', status=200)
8e606d 414         self.assertTrue(b'ACLDenied' in res.body)
bdddc9 415
dbaa08 416     def test_x(self):
a05353 417         self.testapp.get('/x', status=403)
dbaa08 418
a49168 419 class TestDefaultViewPermissionBug(IntegrationBase, unittest.TestCase):
1ad1db 420     # default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html
dd3cc8 421     package = 'tests.pkgs.defpermbugapp'
dbaa08 422     def test_x(self):
a05353 423         res = self.testapp.get('/x', status=403)
8e606d 424         self.assertTrue(b'failed permission check' in res.body)
dbaa08 425
CM 426     def test_y(self):
a05353 427         res = self.testapp.get('/y', status=403)
8e606d 428         self.assertTrue(b'failed permission check' in res.body)
dbaa08 429
CM 430     def test_z(self):
431         res = self.testapp.get('/z', status=200)
8e606d 432         self.assertTrue(b'public' in res.body)
1ad1db 433
dd3cc8 434 from .pkgs.exceptionviewapp.models import AnException, NotAnException
ff1213 435 excroot = {'anexception':AnException(),
CM 436            'notanexception':NotAnException()}
437
a49168 438 class TestExceptionViewsApp(IntegrationBase, unittest.TestCase):
dd3cc8 439     package = 'tests.pkgs.exceptionviewapp'
ff1213 440     root_factory = lambda *arg: excroot
dbaa08 441     def test_root(self):
CM 442         res = self.testapp.get('/', status=200)
8e606d 443         self.assertTrue(b'maybe' in res.body)
ff1213 444
dbaa08 445     def test_notanexception(self):
CM 446         res = self.testapp.get('/notanexception', status=200)
8e606d 447         self.assertTrue(b'no' in res.body)
ff1213 448
dbaa08 449     def test_anexception(self):
CM 450         res = self.testapp.get('/anexception', status=200)
8e606d 451         self.assertTrue(b'yes' in res.body)
ff1213 452
dbaa08 453     def test_route_raise_exception(self):
CM 454         res = self.testapp.get('/route_raise_exception', status=200)
8e606d 455         self.assertTrue(b'yes' in res.body)
ff1213 456
dbaa08 457     def test_route_raise_exception2(self):
CM 458         res = self.testapp.get('/route_raise_exception2', status=200)
8e606d 459         self.assertTrue(b'yes' in res.body)
ff1213 460
dbaa08 461     def test_route_raise_exception3(self):
CM 462         res = self.testapp.get('/route_raise_exception3', status=200)
8e606d 463         self.assertTrue(b'whoa' in res.body)
dbaa08 464
CM 465     def test_route_raise_exception4(self):
466         res = self.testapp.get('/route_raise_exception4', status=200)
8e606d 467         self.assertTrue(b'whoa' in res.body)
ff1213 468
97ed56 469     def test_raise_httpexception(self):
CM 470         res = self.testapp.get('/route_raise_httpexception', status=200)
471         self.assertTrue(b'caught' in res.body)
472         
b5a3b0 473 class TestConflictApp(unittest.TestCase):
dd3cc8 474     package = 'tests.pkgs.conflictapp'
b5a3b0 475     def _makeConfig(self):
CM 476         from pyramid.config import Configurator
477         config = Configurator()
478         return config
479
480     def test_autoresolved_view(self):
481         config = self._makeConfig()
482         config.include(self.package)
483         app = config.make_wsgi_app()
484         self.testapp = TestApp(app)
485         res = self.testapp.get('/')
8e606d 486         self.assertTrue(b'a view' in res.body)
b5a3b0 487         res = self.testapp.get('/route')
8e606d 488         self.assertTrue(b'route view' in res.body)
b5a3b0 489
CM 490     def test_overridden_autoresolved_view(self):
491         from pyramid.response import Response
492         config = self._makeConfig()
493         config.include(self.package)
494         def thisview(request):
495             return Response('this view')
496         config.add_view(thisview)
497         app = config.make_wsgi_app()
498         self.testapp = TestApp(app)
499         res = self.testapp.get('/')
8e606d 500         self.assertTrue(b'this view' in res.body)
b5a3b0 501
CM 502     def test_overridden_route_view(self):
503         from pyramid.response import Response
504         config = self._makeConfig()
505         config.include(self.package)
506         def thisview(request):
507             return Response('this view')
508         config.add_view(thisview, route_name='aroute')
509         app = config.make_wsgi_app()
510         self.testapp = TestApp(app)
511         res = self.testapp.get('/route')
8e606d 512         self.assertTrue(b'this view' in res.body)
b5a3b0 513
CM 514     def test_nonoverridden_authorization_policy(self):
515         config = self._makeConfig()
516         config.include(self.package)
517         app = config.make_wsgi_app()
518         self.testapp = TestApp(app)
519         res = self.testapp.get('/protected', status=403)
8e606d 520         self.assertTrue(b'403 Forbidden' in res.body)
b5a3b0 521
CM 522     def test_overridden_authorization_policy(self):
523         config = self._makeConfig()
524         config.include(self.package)
525         from pyramid.testing import DummySecurityPolicy
526         config.set_authorization_policy(DummySecurityPolicy('fred'))
527         config.set_authentication_policy(DummySecurityPolicy(permissive=True))
528         app = config.make_wsgi_app()
529         self.testapp = TestApp(app)
530         res = self.testapp.get('/protected', status=200)
531         self.assertTrue('protected view' in res)
532
446967 533 class ImperativeIncludeConfigurationTest(unittest.TestCase):
CM 534     def setUp(self):
427a02 535         from pyramid.config import Configurator
CM 536         config = Configurator()
dd3cc8 537         from .pkgs.includeapp1.root import configure
446967 538         configure(config)
CM 539         app = config.make_wsgi_app()
540         self.testapp = TestApp(app)
541         self.config = config
542
543     def tearDown(self):
544         self.config.end()
545
546     def test_root(self):
547         res = self.testapp.get('/', status=200)
8e606d 548         self.assertTrue(b'root' in res.body)
446967 549
CM 550     def test_two(self):
551         res = self.testapp.get('/two', status=200)
8e606d 552         self.assertTrue(b'two' in res.body)
446967 553
CM 554     def test_three(self):
555         res = self.testapp.get('/three', status=200)
8e606d 556         self.assertTrue(b'three' in res.body)
446967 557
c5d172 558 class SelfScanAppTest(unittest.TestCase):
CM 559     def setUp(self):
dd3cc8 560         from .test_config.pkgs.selfscan import main
c5d172 561         config = main()
CM 562         app = config.make_wsgi_app()
563         self.testapp = TestApp(app)
564         self.config = config
565
566     def tearDown(self):
567         self.config.end()
568
569     def test_root(self):
570         res = self.testapp.get('/', status=200)
8e606d 571         self.assertTrue(b'root' in res.body)
c5d172 572
CM 573     def test_two(self):
574         res = self.testapp.get('/two', status=200)
8e606d 575         self.assertTrue(b'two' in res.body)
c5d172 576
44494c 577 class WSGIApp2AppTest(unittest.TestCase):
CM 578     def setUp(self):
dd3cc8 579         from .pkgs.wsgiapp2app import main
44494c 580         config = main()
CM 581         app = config.make_wsgi_app()
582         self.testapp = TestApp(app)
583         self.config = config
584
585     def tearDown(self):
586         self.config.end()
587
588     def test_hello(self):
589         res = self.testapp.get('/hello', status=200)
8e606d 590         self.assertTrue(b'Hello' in res.body)
44494c 591
37d2c2 592 class SubrequestAppTest(unittest.TestCase):
CM 593     def setUp(self):
dd3cc8 594         from .pkgs.subrequestapp import main
37d2c2 595         config = main()
CM 596         app = config.make_wsgi_app()
597         self.testapp = TestApp(app)
598         self.config = config
366a7c 599
37d2c2 600     def tearDown(self):
CM 601         self.config.end()
366a7c 602
7259e7 603     def test_one(self):
37d2c2 604         res = self.testapp.get('/view_one', status=200)
0bee84 605         self.assertTrue(b'This came from view_two, foo=bar' in res.body)
37d2c2 606
7259e7 607     def test_three(self):
CM 608         res = self.testapp.get('/view_three', status=500)
609         self.assertTrue(b'Bad stuff happened' in res.body)
610
611     def test_five(self):
612         res = self.testapp.get('/view_five', status=200)
613         self.assertTrue(b'Value error raised' in res.body)
614
37d2c2 615 class RendererScanAppTest(IntegrationBase, unittest.TestCase):
dd3cc8 616     package = 'tests.pkgs.rendererscanapp'
37d2c2 617     def test_root(self):
CM 618         res = self.testapp.get('/one', status=200)
619         self.assertTrue(b'One!' in res.body)
620
621     def test_two(self):
622         res = self.testapp.get('/two', status=200)
623         self.assertTrue(b'Two!' in res.body)
624
625     def test_rescan(self):
dd3cc8 626         self.config.scan('tests.pkgs.rendererscanapp')
37d2c2 627         app = self.config.make_wsgi_app()
CM 628         testapp = TestApp(app)
629         res = testapp.get('/one', status=200)
630         self.assertTrue(b'One!' in res.body)
631         res = testapp.get('/two', status=200)
632         self.assertTrue(b'Two!' in res.body)
33bcf6 633
49bcc8 634 class UnicodeInURLTest(unittest.TestCase):
MA 635     def _makeConfig(self):
636         from pyramid.config import Configurator
637         config = Configurator()
638         return config
639
640     def _makeTestApp(self, config):
641         app = config.make_wsgi_app()
642         return TestApp(app)
643
644     def test_unicode_in_url_404(self):
bc87ed 645         request_path = '/avalia%C3%A7%C3%A3o_participante'
MA 646         request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8')
49bcc8 647
MA 648         config = self._makeConfig()
649         testapp = self._makeTestApp(config)
650
651         res = testapp.get(request_path, status=404)
a99abf 652
MA 653         # Pyramid default 404 handler outputs:
654         # u'404 Not Found\n\nThe resource could not be found.\n\n\n'
655         # u'/avalia\xe7\xe3o_participante\n\n'
49bcc8 656         self.assertTrue(request_path_unicode in res.text)
MA 657
658     def test_unicode_in_url_200(self):
0c425d 659         request_path = '/avalia%C3%A7%C3%A3o_participante'
bc87ed 660         request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8')
49bcc8 661
MA 662         def myview(request):
663             return 'XXX'
664
665         config = self._makeConfig()
666         config.add_route('myroute', request_path_unicode)
667         config.add_view(myview, route_name='myroute', renderer='json')
668         testapp = self._makeTestApp(config)
669
670         res = testapp.get(request_path, status=200)
671
672         self.assertEqual(res.text, '"XXX"')
673
674
e10087 675 class AcceptContentTypeTest(unittest.TestCase):
684a2c 676     def _makeConfig(self):
e10087 677         def hello_view(request):
MA 678             return {'message': 'Hello!'}
679         from pyramid.config import Configurator
680         config = Configurator()
681         config.add_route('hello', '/hello')
684a2c 682         config.add_view(hello_view, route_name='hello',
MM 683                         accept='text/plain', renderer='string')
684         config.add_view(hello_view, route_name='hello',
685                         accept='application/json', renderer='json')
686         def hello_fallback_view(request):
687             request.response.content_type = 'text/x-fallback'
688             return 'hello fallback'
689         config.add_view(hello_fallback_view, route_name='hello',
690                         renderer='string')
691         return config
692
693     def _makeTestApp(self, config):
e10087 694         app = config.make_wsgi_app()
684a2c 695         return TestApp(app)
e10087 696
061907 697     def tearDown(self):
CM 698         import pyramid.config
684a2c 699         pyramid.config.global_registries.empty()
061907 700
684a2c 701     def test_client_side_ordering(self):
MM 702         config = self._makeConfig()
703         app = self._makeTestApp(config)
704         res = app.get('/hello', headers={
705             'Accept': 'application/json; q=1.0, text/plain; q=0.9',
706         }, status=200)
e10087 707         self.assertEqual(res.content_type, 'application/json')
684a2c 708         res = app.get('/hello', headers={
MM 709             'Accept': 'text/plain; q=0.9, application/json; q=1.0',
710         }, status=200)
e10087 711         self.assertEqual(res.content_type, 'application/json')
684a2c 712         res = app.get('/hello', headers={'Accept': 'application/*'}, status=200)
e10087 713         self.assertEqual(res.content_type, 'application/json')
684a2c 714         res = app.get('/hello', headers={'Accept': 'text/*'}, status=200)
e10087 715         self.assertEqual(res.content_type, 'text/plain')
684a2c 716         res = app.get('/hello', headers={'Accept': 'something/else'}, status=200)
MM 717         self.assertEqual(res.content_type, 'text/x-fallback')
e10087 718
684a2c 719     def test_default_server_side_ordering(self):
MM 720         config = self._makeConfig()
721         app = self._makeTestApp(config)
722         res = app.get('/hello', headers={
723             'Accept': 'application/json, text/plain',
724         }, status=200)
a3d3a2 725         self.assertEqual(res.content_type, 'text/plain')
684a2c 726         res = app.get('/hello', headers={
MM 727             'Accept': 'text/plain, application/json',
728         }, status=200)
729         self.assertEqual(res.content_type, 'text/plain')
730         res = app.get('/hello', headers={'Accept': '*/*'}, status=200)
731         self.assertEqual(res.content_type, 'text/plain')
732         res = app.get('/hello', status=200)
733         self.assertEqual(res.content_type, 'text/plain')
734         res = app.get('/hello', headers={'Accept': 'invalid'}, status=200)
735         self.assertEqual(res.content_type, 'text/plain')
736         res = app.get('/hello', headers={'Accept': 'something/else'}, status=200)
737         self.assertEqual(res.content_type, 'text/x-fallback')
a3d3a2 738
684a2c 739     def test_custom_server_side_ordering(self):
MM 740         config = self._makeConfig()
741         config.add_accept_view_order(
742             'application/json', weighs_more_than='text/plain')
743         app = self._makeTestApp(config)
744         res = app.get('/hello', headers={
745             'Accept': 'application/json, text/plain',
746         }, status=200)
747         self.assertEqual(res.content_type, 'application/json')
748         res = app.get('/hello', headers={
749             'Accept': 'text/plain, application/json',
750         }, status=200)
751         self.assertEqual(res.content_type, 'application/json')
752         res = app.get('/hello', headers={'Accept': '*/*'}, status=200)
753         self.assertEqual(res.content_type, 'application/json')
754         res = app.get('/hello', status=200)
755         self.assertEqual(res.content_type, 'application/json')
756         res = app.get('/hello', headers={'Accept': 'invalid'}, status=200)
757         self.assertEqual(res.content_type, 'application/json')
758         res = app.get('/hello', headers={'Accept': 'something/else'}, status=200)
759         self.assertEqual(res.content_type, 'text/x-fallback')
a3d3a2 760
4a9f4f 761     def test_deprecated_ranges_in_route_predicate(self):
MM 762         config = self._makeConfig()
763         config.add_route('foo', '/foo', accept='text/*')
764         config.add_view(lambda r: 'OK', route_name='foo', renderer='string')
765         app = self._makeTestApp(config)
766         res = app.get('/foo', headers={
767             'Accept': 'application/json; q=1.0, text/plain; q=0.9',
768         }, status=200)
a3d3a2 769         self.assertEqual(res.content_type, 'text/plain')
4a9f4f 770         self.assertEqual(res.body, b'OK')
MM 771         res = app.get('/foo', headers={
772             'Accept': 'application/json',
773         }, status=404)
774         self.assertEqual(res.content_type, 'application/json')
a3d3a2 775
4a9f4f 776     def test_deprecated_ranges_in_view_predicate(self):
MM 777         config = self._makeConfig()
778         config.add_route('foo', '/foo')
779         config.add_view(lambda r: 'OK', route_name='foo',
780                         accept='text/*', renderer='string')
781         app = self._makeTestApp(config)
782         res = app.get('/foo', headers={
783             'Accept': 'application/json; q=1.0, text/plain; q=0.9',
784         }, status=200)
a3d3a2 785         self.assertEqual(res.content_type, 'text/plain')
4a9f4f 786         self.assertEqual(res.body, b'OK')
MM 787         res = app.get('/foo', headers={
788             'Accept': 'application/json',
789         }, status=404)
790         self.assertEqual(res.content_type, 'application/json')
a3d3a2 791
e10087 792
e46105 793 class DummyContext(object):
5a7f9a 794     pass
CM 795
796 class DummyRequest:
797     subpath = ('__init__.py',)
d1209e 798     traversed = None
5a7f9a 799     environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)}
CM 800     def get_response(self, application):
801         return application(None, None)
802
a49168 803 def httpdate(ts):
CM 804     return ts.strftime("%a, %d %b %Y %H:%M:%S GMT")
a0e8df 805
CM 806 def read_(filename):
5dd253 807     with open(filename, 'rb') as fp:
a0e8df 808         val = fp.read()
CM 809         return val
810     
811 def _assertBody(body, filename):
f5b9e9 812     if defaultlocale is None: # pragma: no cover
64c913 813         # If system locale does not have an encoding then default to utf-8
CM 814         filename = filename.encode('utf-8')
5dd253 815     # strip both \n and \r for windows
956b99 816     body = body.replace(b'\r', b'')
CM 817     body = body.replace(b'\n', b'')
5dd253 818     data = read_(filename)
956b99 819     data = data.replace(b'\r', b'')
CM 820     data = data.replace(b'\n', b'')
5dd253 821     assert(body == data)
0393f9 822
KK 823
824 class MemoryLeaksTest(unittest.TestCase):
825
826     def tearDown(self):
827         import pyramid.config
828         pyramid.config.global_registries.empty()
829
830     def get_gc_count(self):
831         last_collected = 0
832         while True:
833             collected = gc.collect()
834             if collected == last_collected:
835                 break
836             last_collected = collected
837         return len(gc.get_objects())
838
b1cad5 839     @skip_on('pypy')
0393f9 840     def test_memory_leaks(self):
KK 841         from pyramid.config import Configurator
842         Configurator().make_wsgi_app()  # Initialize all global objects
843
844         initial_count = self.get_gc_count()
845         Configurator().make_wsgi_app()
846         current_count = self.get_gc_count()
847         self.assertEqual(current_count, initial_count)