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