From 3670c2cdb732d378ba6d38e72e7cd875ff726aa9 Mon Sep 17 00:00:00 2001 From: Michael Merickel Date: Sun, 14 Oct 2018 21:11:41 -0500 Subject: move tests out of the package --- src/pyramid/tests/__init__.py | 3 - src/pyramid/tests/fixtures/dummy.ini | 4 - src/pyramid/tests/fixtures/manifest.json | 4 - src/pyramid/tests/fixtures/manifest2.json | 4 - src/pyramid/tests/fixtures/minimal.jpg | Bin 631 -> 0 bytes src/pyramid/tests/fixtures/minimal.pdf | Bin 1054 -> 0 bytes src/pyramid/tests/fixtures/minimal.txt | 1 - src/pyramid/tests/fixtures/minimal.xml | 1 - src/pyramid/tests/fixtures/nonminimal.txt | 1 - src/pyramid/tests/fixtures/static/.hiddenfile | 2 - src/pyramid/tests/fixtures/static/arcs.svg.tgz | 73 - src/pyramid/tests/fixtures/static/index.html | 1 - .../tests/fixtures/static/subdir/index.html | 1 - src/pyramid/tests/pkgs/__init__.py | 1 - src/pyramid/tests/pkgs/ccbugapp/__init__.py | 16 - src/pyramid/tests/pkgs/conflictapp/__init__.py | 24 - src/pyramid/tests/pkgs/conflictapp/included.py | 6 - src/pyramid/tests/pkgs/defpermbugapp/__init__.py | 26 - src/pyramid/tests/pkgs/eventonly/__init__.py | 64 - .../tests/pkgs/exceptionviewapp/__init__.py | 31 - src/pyramid/tests/pkgs/exceptionviewapp/models.py | 18 - src/pyramid/tests/pkgs/exceptionviewapp/views.py | 24 - src/pyramid/tests/pkgs/fixtureapp/__init__.py | 12 - src/pyramid/tests/pkgs/fixtureapp/models.py | 8 - .../tests/pkgs/fixtureapp/subpackage/__init__.py | 1 - src/pyramid/tests/pkgs/fixtureapp/views.py | 22 - src/pyramid/tests/pkgs/forbiddenapp/__init__.py | 24 - src/pyramid/tests/pkgs/forbiddenview/__init__.py | 31 - src/pyramid/tests/pkgs/hybridapp/__init__.py | 39 - src/pyramid/tests/pkgs/hybridapp/views.py | 39 - src/pyramid/tests/pkgs/includeapp1/__init__.py | 1 - src/pyramid/tests/pkgs/includeapp1/root.py | 10 - src/pyramid/tests/pkgs/includeapp1/three.py | 10 - src/pyramid/tests/pkgs/includeapp1/two.py | 9 - src/pyramid/tests/pkgs/localeapp/__init__.py | 1 - src/pyramid/tests/pkgs/localeapp/locale/GARBAGE | 1 - .../tests/pkgs/localeapp/locale/be/LC_MESSAGES | 1 - .../localeapp/locale/de/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale/de/LC_MESSAGES/deformsite.po | 31 - .../locale/de_DE/LC_MESSAGES/deformsite.mo | Bin 531 -> 0 bytes .../locale/de_DE/LC_MESSAGES/deformsite.po | 26 - .../localeapp/locale/en/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale/en/LC_MESSAGES/deformsite.po | 31 - src/pyramid/tests/pkgs/localeapp/locale2/GARBAGE | 1 - .../tests/pkgs/localeapp/locale2/be/LC_MESSAGES | 1 - .../localeapp/locale2/de/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale2/de/LC_MESSAGES/deformsite.po | 31 - .../localeapp/locale2/en/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale2/en/LC_MESSAGES/deformsite.po | 31 - src/pyramid/tests/pkgs/localeapp/locale3/GARBAGE | 1 - .../tests/pkgs/localeapp/locale3/be/LC_MESSAGES | 1 - .../localeapp/locale3/de/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale3/de/LC_MESSAGES/deformsite.po | 31 - .../localeapp/locale3/en/LC_MESSAGES/deformsite.mo | Bin 543 -> 0 bytes .../localeapp/locale3/en/LC_MESSAGES/deformsite.po | 31 - src/pyramid/tests/pkgs/notfoundview/__init__.py | 30 - src/pyramid/tests/pkgs/permbugapp/__init__.py | 22 - src/pyramid/tests/pkgs/rendererscanapp/__init__.py | 9 - .../tests/pkgs/rendererscanapp/two/__init__.py | 6 - src/pyramid/tests/pkgs/restbugapp/__init__.py | 15 - src/pyramid/tests/pkgs/restbugapp/views.py | 15 - src/pyramid/tests/pkgs/static_abspath/__init__.py | 7 - .../tests/pkgs/static_assetspec/__init__.py | 3 - .../tests/pkgs/static_routeprefix/__init__.py | 7 - src/pyramid/tests/pkgs/staticpermapp/__init__.py | 25 - src/pyramid/tests/pkgs/subrequestapp/__init__.py | 52 - .../tests/pkgs/viewdecoratorapp/__init__.py | 3 - .../tests/pkgs/viewdecoratorapp/views/__init__.py | 1 - .../tests/pkgs/viewdecoratorapp/views/views.py | 12 - src/pyramid/tests/pkgs/wsgiapp2app/__init__.py | 17 - src/pyramid/tests/test_asset.py | 88 - src/pyramid/tests/test_authentication.py | 1738 ---------- src/pyramid/tests/test_authorization.py | 259 -- src/pyramid/tests/test_compat.py | 26 - src/pyramid/tests/test_config/__init__.py | 53 - .../tests/test_config/files/assets/dummy.txt | 1 - src/pyramid/tests/test_config/files/minimal.txt | 1 - .../tests/test_config/path/scanerror/__init__.py | 3 - .../test_config/path/scanerror/will_raise_error.py | 1 - src/pyramid/tests/test_config/pkgs/__init__.py | 2 - .../tests/test_config/pkgs/asset/__init__.py | 3 - .../test_config/pkgs/asset/subpackage/__init__.py | 1 - .../pkgs/asset/subpackage/templates/bar.pt | 0 .../tests/test_config/pkgs/scanextrakw/__init__.py | 14 - .../tests/test_config/pkgs/scannable/__init__.py | 96 - .../tests/test_config/pkgs/scannable/another.py | 69 - .../test_config/pkgs/scannable/pod/notinit.py | 6 - .../pkgs/scannable/subpackage/__init__.py | 6 - .../pkgs/scannable/subpackage/notinit.py | 6 - .../scannable/subpackage/subsubpackage/__init__.py | 6 - .../tests/test_config/pkgs/selfscan/__init__.py | 11 - .../tests/test_config/pkgs/selfscan/another.py | 6 - src/pyramid/tests/test_config/test_adapters.py | 365 -- src/pyramid/tests/test_config/test_assets.py | 945 ----- src/pyramid/tests/test_config/test_factories.py | 163 - src/pyramid/tests/test_config/test_i18n.py | 132 - src/pyramid/tests/test_config/test_init.py | 2068 ----------- src/pyramid/tests/test_config/test_rendering.py | 34 - src/pyramid/tests/test_config/test_routes.py | 297 -- src/pyramid/tests/test_config/test_security.py | 125 - src/pyramid/tests/test_config/test_settings.py | 582 ---- src/pyramid/tests/test_config/test_testing.py | 205 -- src/pyramid/tests/test_config/test_tweens.py | 410 --- src/pyramid/tests/test_config/test_util.py | 497 --- src/pyramid/tests/test_config/test_views.py | 3632 -------------------- src/pyramid/tests/test_csrf.py | 420 --- src/pyramid/tests/test_decorator.py | 26 - src/pyramid/tests/test_docs.py | 35 - src/pyramid/tests/test_encode.py | 86 - src/pyramid/tests/test_events.py | 332 -- src/pyramid/tests/test_exceptions.py | 92 - src/pyramid/tests/test_httpexceptions.py | 482 --- src/pyramid/tests/test_i18n.py | 508 --- src/pyramid/tests/test_integration.py | 848 ----- src/pyramid/tests/test_location.py | 40 - src/pyramid/tests/test_paster.py | 168 - src/pyramid/tests/test_path.py | 576 ---- src/pyramid/tests/test_predicates.py | 556 --- src/pyramid/tests/test_registry.py | 401 --- src/pyramid/tests/test_renderers.py | 705 ---- src/pyramid/tests/test_request.py | 588 ---- src/pyramid/tests/test_response.py | 214 -- src/pyramid/tests/test_router.py | 1410 -------- src/pyramid/tests/test_scaffolds/__init__.py | 1 - .../fixture_scaffold/+package+/.badfile | 0 .../fixture_scaffold/+package+/__init__.py_tmpl | 12 - .../fixture_scaffold/+package+/resources.py | 3 - .../fixture_scaffold/+package+/static/favicon.ico | Bin 1406 -> 0 bytes .../fixture_scaffold/+package+/static/footerbg.png | Bin 333 -> 0 bytes .../fixture_scaffold/+package+/static/headerbg.png | Bin 203 -> 0 bytes .../fixture_scaffold/+package+/static/ie6.css | 8 - .../fixture_scaffold/+package+/static/middlebg.png | Bin 2797 -> 0 bytes .../fixture_scaffold/+package+/static/pylons.css | 65 - .../+package+/static/pyramid-small.png | Bin 7044 -> 0 bytes .../fixture_scaffold/+package+/static/pyramid.png | Bin 33055 -> 0 bytes .../+package+/static/transparent.gif | Bin 49 -> 0 bytes .../+package+/templates/mytemplate.pt_tmpl | 76 - .../+package+/test_no_content.py_tmpl | 0 .../fixture_scaffold/+package+/tests.py_tmpl | 16 - .../fixture_scaffold/+package+/views.py_tmpl | 2 - .../fixture_scaffold/CHANGES.txt_tmpl | 4 - .../fixture_scaffold/MANIFEST.in_tmpl | 2 - .../fixture_scaffold/README.txt_tmpl | 1 - .../fixture_scaffold/development.ini_tmpl | 45 - .../fixture_scaffold/production.ini_tmpl | 44 - .../test_scaffolds/fixture_scaffold/setup.py_tmpl | 38 - src/pyramid/tests/test_scaffolds/test_copydir.py | 455 --- src/pyramid/tests/test_scaffolds/test_init.py | 21 - src/pyramid/tests/test_scaffolds/test_template.py | 155 - src/pyramid/tests/test_scripting.py | 221 -- src/pyramid/tests/test_scripts/__init__.py | 1 - src/pyramid/tests/test_scripts/dummy.py | 190 - src/pyramid/tests/test_scripts/pystartup.txt | 3 - src/pyramid/tests/test_scripts/test_common.py | 13 - src/pyramid/tests/test_scripts/test_pcreate.py | 309 -- src/pyramid/tests/test_scripts/test_pdistreport.py | 73 - src/pyramid/tests/test_scripts/test_prequest.py | 214 -- src/pyramid/tests/test_scripts/test_proutes.py | 792 ----- src/pyramid/tests/test_scripts/test_pserve.py | 131 - src/pyramid/tests/test_scripts/test_pshell.py | 398 --- src/pyramid/tests/test_scripts/test_ptweens.py | 62 - src/pyramid/tests/test_scripts/test_pviews.py | 501 --- src/pyramid/tests/test_security.py | 549 --- src/pyramid/tests/test_session.py | 754 ---- src/pyramid/tests/test_settings.py | 80 - src/pyramid/tests/test_static.py | 477 --- src/pyramid/tests/test_testing.py | 689 ---- src/pyramid/tests/test_threadlocal.py | 95 - src/pyramid/tests/test_traversal.py | 1221 ------- src/pyramid/tests/test_tweens.py | 88 - src/pyramid/tests/test_url.py | 1352 -------- src/pyramid/tests/test_urldispatch.py | 539 --- src/pyramid/tests/test_util.py | 1111 ------ src/pyramid/tests/test_view.py | 1071 ------ src/pyramid/tests/test_viewderivers.py | 1795 ---------- src/pyramid/tests/test_wsgi.py | 130 - tests/__init__.py | 3 + tests/fixtures/dummy.ini | 4 + tests/fixtures/manifest.json | 4 + tests/fixtures/manifest2.json | 4 + tests/fixtures/minimal.jpg | Bin 0 -> 631 bytes tests/fixtures/minimal.pdf | Bin 0 -> 1054 bytes tests/fixtures/minimal.txt | 1 + tests/fixtures/minimal.xml | 1 + tests/fixtures/nonminimal.txt | 1 + tests/fixtures/static/.hiddenfile | 2 + tests/fixtures/static/arcs.svg.tgz | 73 + tests/fixtures/static/index.html | 1 + tests/fixtures/static/subdir/index.html | 1 + tests/pkgs/__init__.py | 1 + tests/pkgs/ccbugapp/__init__.py | 16 + tests/pkgs/conflictapp/__init__.py | 24 + tests/pkgs/conflictapp/included.py | 6 + tests/pkgs/defpermbugapp/__init__.py | 26 + tests/pkgs/eventonly/__init__.py | 64 + tests/pkgs/exceptionviewapp/__init__.py | 31 + tests/pkgs/exceptionviewapp/models.py | 18 + tests/pkgs/exceptionviewapp/views.py | 24 + tests/pkgs/fixtureapp/__init__.py | 12 + tests/pkgs/fixtureapp/models.py | 8 + tests/pkgs/fixtureapp/subpackage/__init__.py | 1 + tests/pkgs/fixtureapp/views.py | 22 + tests/pkgs/forbiddenapp/__init__.py | 24 + tests/pkgs/forbiddenview/__init__.py | 31 + tests/pkgs/hybridapp/__init__.py | 39 + tests/pkgs/hybridapp/views.py | 39 + tests/pkgs/includeapp1/__init__.py | 1 + tests/pkgs/includeapp1/root.py | 10 + tests/pkgs/includeapp1/three.py | 10 + tests/pkgs/includeapp1/two.py | 9 + tests/pkgs/localeapp/__init__.py | 1 + tests/pkgs/localeapp/locale/GARBAGE | 1 + tests/pkgs/localeapp/locale/be/LC_MESSAGES | 1 + .../localeapp/locale/de/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale/de/LC_MESSAGES/deformsite.po | 31 + .../locale/de_DE/LC_MESSAGES/deformsite.mo | Bin 0 -> 531 bytes .../locale/de_DE/LC_MESSAGES/deformsite.po | 26 + .../localeapp/locale/en/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale/en/LC_MESSAGES/deformsite.po | 31 + tests/pkgs/localeapp/locale2/GARBAGE | 1 + tests/pkgs/localeapp/locale2/be/LC_MESSAGES | 1 + .../localeapp/locale2/de/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale2/de/LC_MESSAGES/deformsite.po | 31 + .../localeapp/locale2/en/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale2/en/LC_MESSAGES/deformsite.po | 31 + tests/pkgs/localeapp/locale3/GARBAGE | 1 + tests/pkgs/localeapp/locale3/be/LC_MESSAGES | 1 + .../localeapp/locale3/de/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale3/de/LC_MESSAGES/deformsite.po | 31 + .../localeapp/locale3/en/LC_MESSAGES/deformsite.mo | Bin 0 -> 543 bytes .../localeapp/locale3/en/LC_MESSAGES/deformsite.po | 31 + tests/pkgs/notfoundview/__init__.py | 30 + tests/pkgs/permbugapp/__init__.py | 22 + tests/pkgs/rendererscanapp/__init__.py | 9 + tests/pkgs/rendererscanapp/two/__init__.py | 6 + tests/pkgs/restbugapp/__init__.py | 15 + tests/pkgs/restbugapp/views.py | 15 + tests/pkgs/static_abspath/__init__.py | 7 + tests/pkgs/static_assetspec/__init__.py | 3 + tests/pkgs/static_routeprefix/__init__.py | 7 + tests/pkgs/staticpermapp/__init__.py | 25 + tests/pkgs/subrequestapp/__init__.py | 52 + tests/pkgs/viewdecoratorapp/__init__.py | 3 + tests/pkgs/viewdecoratorapp/views/__init__.py | 1 + tests/pkgs/viewdecoratorapp/views/views.py | 12 + tests/pkgs/wsgiapp2app/__init__.py | 17 + tests/test_asset.py | 88 + tests/test_authentication.py | 1738 ++++++++++ tests/test_authorization.py | 259 ++ tests/test_compat.py | 26 + tests/test_config/__init__.py | 53 + tests/test_config/files/assets/dummy.txt | 1 + tests/test_config/files/minimal.txt | 1 + tests/test_config/path/scanerror/__init__.py | 3 + .../test_config/path/scanerror/will_raise_error.py | 1 + tests/test_config/pkgs/__init__.py | 2 + tests/test_config/pkgs/asset/__init__.py | 3 + .../test_config/pkgs/asset/subpackage/__init__.py | 1 + .../pkgs/asset/subpackage/templates/bar.pt | 0 tests/test_config/pkgs/scanextrakw/__init__.py | 14 + tests/test_config/pkgs/scannable/__init__.py | 96 + tests/test_config/pkgs/scannable/another.py | 69 + tests/test_config/pkgs/scannable/pod/notinit.py | 6 + .../pkgs/scannable/subpackage/__init__.py | 6 + .../pkgs/scannable/subpackage/notinit.py | 6 + .../scannable/subpackage/subsubpackage/__init__.py | 6 + tests/test_config/pkgs/selfscan/__init__.py | 11 + tests/test_config/pkgs/selfscan/another.py | 6 + tests/test_config/test_adapters.py | 365 ++ tests/test_config/test_assets.py | 945 +++++ tests/test_config/test_factories.py | 163 + tests/test_config/test_i18n.py | 132 + tests/test_config/test_init.py | 2068 +++++++++++ tests/test_config/test_rendering.py | 34 + tests/test_config/test_routes.py | 297 ++ tests/test_config/test_security.py | 125 + tests/test_config/test_settings.py | 582 ++++ tests/test_config/test_testing.py | 205 ++ tests/test_config/test_tweens.py | 410 +++ tests/test_config/test_util.py | 497 +++ tests/test_config/test_views.py | 3632 ++++++++++++++++++++ tests/test_csrf.py | 420 +++ tests/test_decorator.py | 26 + tests/test_docs.py | 35 + tests/test_encode.py | 86 + tests/test_events.py | 332 ++ tests/test_exceptions.py | 92 + tests/test_httpexceptions.py | 482 +++ tests/test_i18n.py | 508 +++ tests/test_integration.py | 848 +++++ tests/test_location.py | 40 + tests/test_paster.py | 168 + tests/test_path.py | 576 ++++ tests/test_predicates.py | 556 +++ tests/test_registry.py | 401 +++ tests/test_renderers.py | 705 ++++ tests/test_request.py | 588 ++++ tests/test_response.py | 214 ++ tests/test_router.py | 1410 ++++++++ tests/test_scaffolds/__init__.py | 1 + .../fixture_scaffold/+package+/.badfile | 0 .../fixture_scaffold/+package+/__init__.py_tmpl | 12 + .../fixture_scaffold/+package+/resources.py | 3 + .../fixture_scaffold/+package+/static/favicon.ico | Bin 0 -> 1406 bytes .../fixture_scaffold/+package+/static/footerbg.png | Bin 0 -> 333 bytes .../fixture_scaffold/+package+/static/headerbg.png | Bin 0 -> 203 bytes .../fixture_scaffold/+package+/static/ie6.css | 8 + .../fixture_scaffold/+package+/static/middlebg.png | Bin 0 -> 2797 bytes .../fixture_scaffold/+package+/static/pylons.css | 65 + .../+package+/static/pyramid-small.png | Bin 0 -> 7044 bytes .../fixture_scaffold/+package+/static/pyramid.png | Bin 0 -> 33055 bytes .../+package+/static/transparent.gif | Bin 0 -> 49 bytes .../+package+/templates/mytemplate.pt_tmpl | 76 + .../+package+/test_no_content.py_tmpl | 0 .../fixture_scaffold/+package+/tests.py_tmpl | 16 + .../fixture_scaffold/+package+/views.py_tmpl | 2 + .../fixture_scaffold/CHANGES.txt_tmpl | 4 + .../fixture_scaffold/MANIFEST.in_tmpl | 2 + .../fixture_scaffold/README.txt_tmpl | 1 + .../fixture_scaffold/development.ini_tmpl | 45 + .../fixture_scaffold/production.ini_tmpl | 44 + .../test_scaffolds/fixture_scaffold/setup.py_tmpl | 38 + tests/test_scaffolds/test_copydir.py | 455 +++ tests/test_scaffolds/test_init.py | 21 + tests/test_scaffolds/test_template.py | 155 + tests/test_scripting.py | 221 ++ tests/test_scripts/__init__.py | 1 + tests/test_scripts/dummy.py | 190 + tests/test_scripts/pystartup.txt | 3 + tests/test_scripts/test_common.py | 13 + tests/test_scripts/test_pcreate.py | 309 ++ tests/test_scripts/test_pdistreport.py | 73 + tests/test_scripts/test_prequest.py | 214 ++ tests/test_scripts/test_proutes.py | 792 +++++ tests/test_scripts/test_pserve.py | 131 + tests/test_scripts/test_pshell.py | 398 +++ tests/test_scripts/test_ptweens.py | 62 + tests/test_scripts/test_pviews.py | 501 +++ tests/test_security.py | 549 +++ tests/test_session.py | 754 ++++ tests/test_settings.py | 80 + tests/test_static.py | 477 +++ tests/test_testing.py | 689 ++++ tests/test_threadlocal.py | 95 + tests/test_traversal.py | 1221 +++++++ tests/test_tweens.py | 88 + tests/test_url.py | 1352 ++++++++ tests/test_urldispatch.py | 539 +++ tests/test_util.py | 1111 ++++++ tests/test_view.py | 1071 ++++++ tests/test_viewderivers.py | 1795 ++++++++++ tests/test_wsgi.py | 130 + 352 files changed, 34099 insertions(+), 34099 deletions(-) delete mode 100644 src/pyramid/tests/__init__.py delete mode 100644 src/pyramid/tests/fixtures/dummy.ini delete mode 100644 src/pyramid/tests/fixtures/manifest.json delete mode 100644 src/pyramid/tests/fixtures/manifest2.json delete mode 100644 src/pyramid/tests/fixtures/minimal.jpg delete mode 100755 src/pyramid/tests/fixtures/minimal.pdf delete mode 100644 src/pyramid/tests/fixtures/minimal.txt delete mode 100644 src/pyramid/tests/fixtures/minimal.xml delete mode 100644 src/pyramid/tests/fixtures/nonminimal.txt delete mode 100644 src/pyramid/tests/fixtures/static/.hiddenfile delete mode 100644 src/pyramid/tests/fixtures/static/arcs.svg.tgz delete mode 100644 src/pyramid/tests/fixtures/static/index.html delete mode 100644 src/pyramid/tests/fixtures/static/subdir/index.html delete mode 100644 src/pyramid/tests/pkgs/__init__.py delete mode 100644 src/pyramid/tests/pkgs/ccbugapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/conflictapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/conflictapp/included.py delete mode 100644 src/pyramid/tests/pkgs/defpermbugapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/eventonly/__init__.py delete mode 100644 src/pyramid/tests/pkgs/exceptionviewapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/exceptionviewapp/models.py delete mode 100644 src/pyramid/tests/pkgs/exceptionviewapp/views.py delete mode 100644 src/pyramid/tests/pkgs/fixtureapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/fixtureapp/models.py delete mode 100644 src/pyramid/tests/pkgs/fixtureapp/subpackage/__init__.py delete mode 100644 src/pyramid/tests/pkgs/fixtureapp/views.py delete mode 100644 src/pyramid/tests/pkgs/forbiddenapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/forbiddenview/__init__.py delete mode 100644 src/pyramid/tests/pkgs/hybridapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/hybridapp/views.py delete mode 100644 src/pyramid/tests/pkgs/includeapp1/__init__.py delete mode 100644 src/pyramid/tests/pkgs/includeapp1/root.py delete mode 100644 src/pyramid/tests/pkgs/includeapp1/three.py delete mode 100644 src/pyramid/tests/pkgs/includeapp1/two.py delete mode 100644 src/pyramid/tests/pkgs/localeapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/GARBAGE delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/be/LC_MESSAGES delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/GARBAGE delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/be/LC_MESSAGES delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/GARBAGE delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/be/LC_MESSAGES delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo delete mode 100644 src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po delete mode 100644 src/pyramid/tests/pkgs/notfoundview/__init__.py delete mode 100644 src/pyramid/tests/pkgs/permbugapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/rendererscanapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/rendererscanapp/two/__init__.py delete mode 100644 src/pyramid/tests/pkgs/restbugapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/restbugapp/views.py delete mode 100644 src/pyramid/tests/pkgs/static_abspath/__init__.py delete mode 100644 src/pyramid/tests/pkgs/static_assetspec/__init__.py delete mode 100644 src/pyramid/tests/pkgs/static_routeprefix/__init__.py delete mode 100644 src/pyramid/tests/pkgs/staticpermapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/subrequestapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/viewdecoratorapp/__init__.py delete mode 100644 src/pyramid/tests/pkgs/viewdecoratorapp/views/__init__.py delete mode 100644 src/pyramid/tests/pkgs/viewdecoratorapp/views/views.py delete mode 100644 src/pyramid/tests/pkgs/wsgiapp2app/__init__.py delete mode 100644 src/pyramid/tests/test_asset.py delete mode 100644 src/pyramid/tests/test_authentication.py delete mode 100644 src/pyramid/tests/test_authorization.py delete mode 100644 src/pyramid/tests/test_compat.py delete mode 100644 src/pyramid/tests/test_config/__init__.py delete mode 100644 src/pyramid/tests/test_config/files/assets/dummy.txt delete mode 100644 src/pyramid/tests/test_config/files/minimal.txt delete mode 100644 src/pyramid/tests/test_config/path/scanerror/__init__.py delete mode 100644 src/pyramid/tests/test_config/path/scanerror/will_raise_error.py delete mode 100644 src/pyramid/tests/test_config/pkgs/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/asset/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/asset/subpackage/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt delete mode 100644 src/pyramid/tests/test_config/pkgs/scanextrakw/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/another.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/pod/notinit.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/subpackage/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/subpackage/notinit.py delete mode 100644 src/pyramid/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/selfscan/__init__.py delete mode 100644 src/pyramid/tests/test_config/pkgs/selfscan/another.py delete mode 100644 src/pyramid/tests/test_config/test_adapters.py delete mode 100644 src/pyramid/tests/test_config/test_assets.py delete mode 100644 src/pyramid/tests/test_config/test_factories.py delete mode 100644 src/pyramid/tests/test_config/test_i18n.py delete mode 100644 src/pyramid/tests/test_config/test_init.py delete mode 100644 src/pyramid/tests/test_config/test_rendering.py delete mode 100644 src/pyramid/tests/test_config/test_routes.py delete mode 100644 src/pyramid/tests/test_config/test_security.py delete mode 100644 src/pyramid/tests/test_config/test_settings.py delete mode 100644 src/pyramid/tests/test_config/test_testing.py delete mode 100644 src/pyramid/tests/test_config/test_tweens.py delete mode 100644 src/pyramid/tests/test_config/test_util.py delete mode 100644 src/pyramid/tests/test_config/test_views.py delete mode 100644 src/pyramid/tests/test_csrf.py delete mode 100644 src/pyramid/tests/test_decorator.py delete mode 100644 src/pyramid/tests/test_docs.py delete mode 100644 src/pyramid/tests/test_encode.py delete mode 100644 src/pyramid/tests/test_events.py delete mode 100644 src/pyramid/tests/test_exceptions.py delete mode 100644 src/pyramid/tests/test_httpexceptions.py delete mode 100644 src/pyramid/tests/test_i18n.py delete mode 100644 src/pyramid/tests/test_integration.py delete mode 100644 src/pyramid/tests/test_location.py delete mode 100644 src/pyramid/tests/test_paster.py delete mode 100644 src/pyramid/tests/test_path.py delete mode 100644 src/pyramid/tests/test_predicates.py delete mode 100644 src/pyramid/tests/test_registry.py delete mode 100644 src/pyramid/tests/test_renderers.py delete mode 100644 src/pyramid/tests/test_request.py delete mode 100644 src/pyramid/tests/test_response.py delete mode 100644 src/pyramid/tests/test_router.py delete mode 100644 src/pyramid/tests/test_scaffolds/__init__.py delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/.badfile delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/resources.py delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl delete mode 100644 src/pyramid/tests/test_scaffolds/test_copydir.py delete mode 100644 src/pyramid/tests/test_scaffolds/test_init.py delete mode 100644 src/pyramid/tests/test_scaffolds/test_template.py delete mode 100644 src/pyramid/tests/test_scripting.py delete mode 100644 src/pyramid/tests/test_scripts/__init__.py delete mode 100644 src/pyramid/tests/test_scripts/dummy.py delete mode 100644 src/pyramid/tests/test_scripts/pystartup.txt delete mode 100644 src/pyramid/tests/test_scripts/test_common.py delete mode 100644 src/pyramid/tests/test_scripts/test_pcreate.py delete mode 100644 src/pyramid/tests/test_scripts/test_pdistreport.py delete mode 100644 src/pyramid/tests/test_scripts/test_prequest.py delete mode 100644 src/pyramid/tests/test_scripts/test_proutes.py delete mode 100644 src/pyramid/tests/test_scripts/test_pserve.py delete mode 100644 src/pyramid/tests/test_scripts/test_pshell.py delete mode 100644 src/pyramid/tests/test_scripts/test_ptweens.py delete mode 100644 src/pyramid/tests/test_scripts/test_pviews.py delete mode 100644 src/pyramid/tests/test_security.py delete mode 100644 src/pyramid/tests/test_session.py delete mode 100644 src/pyramid/tests/test_settings.py delete mode 100644 src/pyramid/tests/test_static.py delete mode 100644 src/pyramid/tests/test_testing.py delete mode 100644 src/pyramid/tests/test_threadlocal.py delete mode 100644 src/pyramid/tests/test_traversal.py delete mode 100644 src/pyramid/tests/test_tweens.py delete mode 100644 src/pyramid/tests/test_url.py delete mode 100644 src/pyramid/tests/test_urldispatch.py delete mode 100644 src/pyramid/tests/test_util.py delete mode 100644 src/pyramid/tests/test_view.py delete mode 100644 src/pyramid/tests/test_viewderivers.py delete mode 100644 src/pyramid/tests/test_wsgi.py create mode 100644 tests/__init__.py create mode 100644 tests/fixtures/dummy.ini create mode 100644 tests/fixtures/manifest.json create mode 100644 tests/fixtures/manifest2.json create mode 100644 tests/fixtures/minimal.jpg create mode 100755 tests/fixtures/minimal.pdf create mode 100644 tests/fixtures/minimal.txt create mode 100644 tests/fixtures/minimal.xml create mode 100644 tests/fixtures/nonminimal.txt create mode 100644 tests/fixtures/static/.hiddenfile create mode 100644 tests/fixtures/static/arcs.svg.tgz create mode 100644 tests/fixtures/static/index.html create mode 100644 tests/fixtures/static/subdir/index.html create mode 100644 tests/pkgs/__init__.py create mode 100644 tests/pkgs/ccbugapp/__init__.py create mode 100644 tests/pkgs/conflictapp/__init__.py create mode 100644 tests/pkgs/conflictapp/included.py create mode 100644 tests/pkgs/defpermbugapp/__init__.py create mode 100644 tests/pkgs/eventonly/__init__.py create mode 100644 tests/pkgs/exceptionviewapp/__init__.py create mode 100644 tests/pkgs/exceptionviewapp/models.py create mode 100644 tests/pkgs/exceptionviewapp/views.py create mode 100644 tests/pkgs/fixtureapp/__init__.py create mode 100644 tests/pkgs/fixtureapp/models.py create mode 100644 tests/pkgs/fixtureapp/subpackage/__init__.py create mode 100644 tests/pkgs/fixtureapp/views.py create mode 100644 tests/pkgs/forbiddenapp/__init__.py create mode 100644 tests/pkgs/forbiddenview/__init__.py create mode 100644 tests/pkgs/hybridapp/__init__.py create mode 100644 tests/pkgs/hybridapp/views.py create mode 100644 tests/pkgs/includeapp1/__init__.py create mode 100644 tests/pkgs/includeapp1/root.py create mode 100644 tests/pkgs/includeapp1/three.py create mode 100644 tests/pkgs/includeapp1/two.py create mode 100644 tests/pkgs/localeapp/__init__.py create mode 100644 tests/pkgs/localeapp/locale/GARBAGE create mode 100644 tests/pkgs/localeapp/locale/be/LC_MESSAGES create mode 100644 tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale2/GARBAGE create mode 100644 tests/pkgs/localeapp/locale2/be/LC_MESSAGES create mode 100644 tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale3/GARBAGE create mode 100644 tests/pkgs/localeapp/locale3/be/LC_MESSAGES create mode 100644 tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo create mode 100644 tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po create mode 100644 tests/pkgs/notfoundview/__init__.py create mode 100644 tests/pkgs/permbugapp/__init__.py create mode 100644 tests/pkgs/rendererscanapp/__init__.py create mode 100644 tests/pkgs/rendererscanapp/two/__init__.py create mode 100644 tests/pkgs/restbugapp/__init__.py create mode 100644 tests/pkgs/restbugapp/views.py create mode 100644 tests/pkgs/static_abspath/__init__.py create mode 100644 tests/pkgs/static_assetspec/__init__.py create mode 100644 tests/pkgs/static_routeprefix/__init__.py create mode 100644 tests/pkgs/staticpermapp/__init__.py create mode 100644 tests/pkgs/subrequestapp/__init__.py create mode 100644 tests/pkgs/viewdecoratorapp/__init__.py create mode 100644 tests/pkgs/viewdecoratorapp/views/__init__.py create mode 100644 tests/pkgs/viewdecoratorapp/views/views.py create mode 100644 tests/pkgs/wsgiapp2app/__init__.py create mode 100644 tests/test_asset.py create mode 100644 tests/test_authentication.py create mode 100644 tests/test_authorization.py create mode 100644 tests/test_compat.py create mode 100644 tests/test_config/__init__.py create mode 100644 tests/test_config/files/assets/dummy.txt create mode 100644 tests/test_config/files/minimal.txt create mode 100644 tests/test_config/path/scanerror/__init__.py create mode 100644 tests/test_config/path/scanerror/will_raise_error.py create mode 100644 tests/test_config/pkgs/__init__.py create mode 100644 tests/test_config/pkgs/asset/__init__.py create mode 100644 tests/test_config/pkgs/asset/subpackage/__init__.py create mode 100644 tests/test_config/pkgs/asset/subpackage/templates/bar.pt create mode 100644 tests/test_config/pkgs/scanextrakw/__init__.py create mode 100644 tests/test_config/pkgs/scannable/__init__.py create mode 100644 tests/test_config/pkgs/scannable/another.py create mode 100644 tests/test_config/pkgs/scannable/pod/notinit.py create mode 100644 tests/test_config/pkgs/scannable/subpackage/__init__.py create mode 100644 tests/test_config/pkgs/scannable/subpackage/notinit.py create mode 100644 tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py create mode 100644 tests/test_config/pkgs/selfscan/__init__.py create mode 100644 tests/test_config/pkgs/selfscan/another.py create mode 100644 tests/test_config/test_adapters.py create mode 100644 tests/test_config/test_assets.py create mode 100644 tests/test_config/test_factories.py create mode 100644 tests/test_config/test_i18n.py create mode 100644 tests/test_config/test_init.py create mode 100644 tests/test_config/test_rendering.py create mode 100644 tests/test_config/test_routes.py create mode 100644 tests/test_config/test_security.py create mode 100644 tests/test_config/test_settings.py create mode 100644 tests/test_config/test_testing.py create mode 100644 tests/test_config/test_tweens.py create mode 100644 tests/test_config/test_util.py create mode 100644 tests/test_config/test_views.py create mode 100644 tests/test_csrf.py create mode 100644 tests/test_decorator.py create mode 100644 tests/test_docs.py create mode 100644 tests/test_encode.py create mode 100644 tests/test_events.py create mode 100644 tests/test_exceptions.py create mode 100644 tests/test_httpexceptions.py create mode 100644 tests/test_i18n.py create mode 100644 tests/test_integration.py create mode 100644 tests/test_location.py create mode 100644 tests/test_paster.py create mode 100644 tests/test_path.py create mode 100644 tests/test_predicates.py create mode 100644 tests/test_registry.py create mode 100644 tests/test_renderers.py create mode 100644 tests/test_request.py create mode 100644 tests/test_response.py create mode 100644 tests/test_router.py create mode 100644 tests/test_scaffolds/__init__.py create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/.badfile create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/resources.py create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/README.txt_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/development.ini_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/production.ini_tmpl create mode 100644 tests/test_scaffolds/fixture_scaffold/setup.py_tmpl create mode 100644 tests/test_scaffolds/test_copydir.py create mode 100644 tests/test_scaffolds/test_init.py create mode 100644 tests/test_scaffolds/test_template.py create mode 100644 tests/test_scripting.py create mode 100644 tests/test_scripts/__init__.py create mode 100644 tests/test_scripts/dummy.py create mode 100644 tests/test_scripts/pystartup.txt create mode 100644 tests/test_scripts/test_common.py create mode 100644 tests/test_scripts/test_pcreate.py create mode 100644 tests/test_scripts/test_pdistreport.py create mode 100644 tests/test_scripts/test_prequest.py create mode 100644 tests/test_scripts/test_proutes.py create mode 100644 tests/test_scripts/test_pserve.py create mode 100644 tests/test_scripts/test_pshell.py create mode 100644 tests/test_scripts/test_ptweens.py create mode 100644 tests/test_scripts/test_pviews.py create mode 100644 tests/test_security.py create mode 100644 tests/test_session.py create mode 100644 tests/test_settings.py create mode 100644 tests/test_static.py create mode 100644 tests/test_testing.py create mode 100644 tests/test_threadlocal.py create mode 100644 tests/test_traversal.py create mode 100644 tests/test_tweens.py create mode 100644 tests/test_url.py create mode 100644 tests/test_urldispatch.py create mode 100644 tests/test_util.py create mode 100644 tests/test_view.py create mode 100644 tests/test_viewderivers.py create mode 100644 tests/test_wsgi.py diff --git a/src/pyramid/tests/__init__.py b/src/pyramid/tests/__init__.py deleted file mode 100644 index a62c29f47..000000000 --- a/src/pyramid/tests/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ - -def dummy_extend(*args): - """used to test Configurator.extend""" diff --git a/src/pyramid/tests/fixtures/dummy.ini b/src/pyramid/tests/fixtures/dummy.ini deleted file mode 100644 index bc2281168..000000000 --- a/src/pyramid/tests/fixtures/dummy.ini +++ /dev/null @@ -1,4 +0,0 @@ -[app:myapp] -use = call:pyramid.tests.test_paster:make_dummyapp - -foo = %(bar)s diff --git a/src/pyramid/tests/fixtures/manifest.json b/src/pyramid/tests/fixtures/manifest.json deleted file mode 100644 index 0a43bc5e3..000000000 --- a/src/pyramid/tests/fixtures/manifest.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "css/main.css": "css/main-test.css", - "images/background.png": "images/background-a8169106.png" -} diff --git a/src/pyramid/tests/fixtures/manifest2.json b/src/pyramid/tests/fixtures/manifest2.json deleted file mode 100644 index fd6b9a7bb..000000000 --- a/src/pyramid/tests/fixtures/manifest2.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "css/main.css": "css/main-678b7c80.css", - "images/background.png": "images/background-a8169106.png" -} diff --git a/src/pyramid/tests/fixtures/minimal.jpg b/src/pyramid/tests/fixtures/minimal.jpg deleted file mode 100644 index 1cda9a53d..000000000 Binary files a/src/pyramid/tests/fixtures/minimal.jpg and /dev/null differ diff --git a/src/pyramid/tests/fixtures/minimal.pdf b/src/pyramid/tests/fixtures/minimal.pdf deleted file mode 100755 index e267be996..000000000 Binary files a/src/pyramid/tests/fixtures/minimal.pdf and /dev/null differ diff --git a/src/pyramid/tests/fixtures/minimal.txt b/src/pyramid/tests/fixtures/minimal.txt deleted file mode 100644 index 18832d351..000000000 --- a/src/pyramid/tests/fixtures/minimal.txt +++ /dev/null @@ -1 +0,0 @@ -Hello. diff --git a/src/pyramid/tests/fixtures/minimal.xml b/src/pyramid/tests/fixtures/minimal.xml deleted file mode 100644 index 1972c155d..000000000 --- a/src/pyramid/tests/fixtures/minimal.xml +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/pyramid/tests/fixtures/nonminimal.txt b/src/pyramid/tests/fixtures/nonminimal.txt deleted file mode 100644 index 9de95ec92..000000000 --- a/src/pyramid/tests/fixtures/nonminimal.txt +++ /dev/null @@ -1 +0,0 @@ -Hello, ${name}! diff --git a/src/pyramid/tests/fixtures/static/.hiddenfile b/src/pyramid/tests/fixtures/static/.hiddenfile deleted file mode 100644 index 86d345000..000000000 --- a/src/pyramid/tests/fixtures/static/.hiddenfile +++ /dev/null @@ -1,2 +0,0 @@ -I'm hidden - diff --git a/src/pyramid/tests/fixtures/static/arcs.svg.tgz b/src/pyramid/tests/fixtures/static/arcs.svg.tgz deleted file mode 100644 index 376c42ac8..000000000 --- a/src/pyramid/tests/fixtures/static/arcs.svg.tgz +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - diff --git a/src/pyramid/tests/fixtures/static/index.html b/src/pyramid/tests/fixtures/static/index.html deleted file mode 100644 index 0470710b2..000000000 --- a/src/pyramid/tests/fixtures/static/index.html +++ /dev/null @@ -1 +0,0 @@ -static \ No newline at end of file diff --git a/src/pyramid/tests/fixtures/static/subdir/index.html b/src/pyramid/tests/fixtures/static/subdir/index.html deleted file mode 100644 index bb84fad04..000000000 --- a/src/pyramid/tests/fixtures/static/subdir/index.html +++ /dev/null @@ -1 +0,0 @@ -subdir diff --git a/src/pyramid/tests/pkgs/__init__.py b/src/pyramid/tests/pkgs/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/src/pyramid/tests/pkgs/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/src/pyramid/tests/pkgs/ccbugapp/__init__.py b/src/pyramid/tests/pkgs/ccbugapp/__init__.py deleted file mode 100644 index afe21d4e0..000000000 --- a/src/pyramid/tests/pkgs/ccbugapp/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -from webob import Response - -def rdf_view(request): - """ """ - return Response('rdf') - -def juri_view(request): - """ """ - return Response('juri') - -def includeme(config): - config.add_route('rdf', 'licenses/:license_code/:license_version/rdf') - config.add_route('juri', - 'licenses/:license_code/:license_version/:jurisdiction') - config.add_view(rdf_view, route_name='rdf') - config.add_view(juri_view, route_name='juri') diff --git a/src/pyramid/tests/pkgs/conflictapp/__init__.py b/src/pyramid/tests/pkgs/conflictapp/__init__.py deleted file mode 100644 index 38116ab2f..000000000 --- a/src/pyramid/tests/pkgs/conflictapp/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from pyramid.response import Response -from pyramid.authentication import AuthTktAuthenticationPolicy -from pyramid.authorization import ACLAuthorizationPolicy - -def aview(request): - return Response('a view') - -def routeview(request): - return Response('route view') - -def protectedview(request): - return Response('protected view') - -def includeme(config): - # purposely sorta-randomly ordered (route comes after view naming it, - # authz comes after views) - config.add_view(aview) - config.add_view(protectedview, name='protected', permission='view') - config.add_view(routeview, route_name='aroute') - config.add_route('aroute', '/route') - config.set_authentication_policy(AuthTktAuthenticationPolicy( - 'seekri1t', hashalg='sha512')) - config.set_authorization_policy(ACLAuthorizationPolicy()) - config.include('pyramid.tests.pkgs.conflictapp.included') diff --git a/src/pyramid/tests/pkgs/conflictapp/included.py b/src/pyramid/tests/pkgs/conflictapp/included.py deleted file mode 100644 index 0b76fb2bc..000000000 --- a/src/pyramid/tests/pkgs/conflictapp/included.py +++ /dev/null @@ -1,6 +0,0 @@ -from webob import Response - -def bview(request): return Response('b view') - -def includeme(config): - config.add_view(bview) diff --git a/src/pyramid/tests/pkgs/defpermbugapp/__init__.py b/src/pyramid/tests/pkgs/defpermbugapp/__init__.py deleted file mode 100644 index 032e8c626..000000000 --- a/src/pyramid/tests/pkgs/defpermbugapp/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -from webob import Response -from pyramid.security import NO_PERMISSION_REQUIRED -from pyramid.view import view_config - -@view_config(name='x') -def x_view(request): # pragma: no cover - return Response('this is private!') - -@view_config(name='y', permission='private2') -def y_view(request): # pragma: no cover - return Response('this is private too!') - -@view_config(name='z', permission=NO_PERMISSION_REQUIRED) -def z_view(request): - return Response('this is public') - -def includeme(config): - from pyramid.authorization import ACLAuthorizationPolicy - from pyramid.authentication import AuthTktAuthenticationPolicy - authn_policy = AuthTktAuthenticationPolicy('seekt1t', hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() - config.scan('pyramid.tests.pkgs.defpermbugapp') - config._set_authentication_policy(authn_policy) - config._set_authorization_policy(authz_policy) - config.set_default_permission('private') - diff --git a/src/pyramid/tests/pkgs/eventonly/__init__.py b/src/pyramid/tests/pkgs/eventonly/__init__.py deleted file mode 100644 index 7ae93ada6..000000000 --- a/src/pyramid/tests/pkgs/eventonly/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -from pyramid.view import view_config -from pyramid.events import subscriber - -class Yup(object): - def __init__(self, val, config): - self.val = val - - def text(self): - return 'path_startswith = %s' % (self.val,) - - phash = text - - def __call__(self, event): - return getattr(event.response, 'yup', False) - -class Foo(object): - def __init__(self, response): - self.response = response - -class Bar(object): - pass - -@subscriber(Foo) -def foo(event): - event.response.text += 'foo ' - -@subscriber(Foo, yup=True) -def fooyup(event): - event.response.text += 'fooyup ' - -@subscriber([Foo, Bar]) -def foobar(event): - event.response.text += 'foobar ' - -@subscriber([Foo, Bar]) -def foobar2(event, context): - event.response.text += 'foobar2 ' - -@subscriber([Foo, Bar], yup=True) -def foobaryup(event): - event.response.text += 'foobaryup ' - -@subscriber([Foo, Bar], yup=True) -def foobaryup2(event, context): - event.response.text += 'foobaryup2 ' - -@view_config(name='sendfoo') -def sendfoo(request): - response = request.response - response.yup = True - request.registry.notify(Foo(response)) - return response - -@view_config(name='sendfoobar') -def sendfoobar(request): - response = request.response - response.yup = True - request.registry.notify(Foo(response), Bar()) - return response - -def includeme(config): - config.add_subscriber_predicate('yup', Yup) - config.scan('pyramid.tests.pkgs.eventonly') - diff --git a/src/pyramid/tests/pkgs/exceptionviewapp/__init__.py b/src/pyramid/tests/pkgs/exceptionviewapp/__init__.py deleted file mode 100644 index ffc1b47c6..000000000 --- a/src/pyramid/tests/pkgs/exceptionviewapp/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -from pyramid.httpexceptions import HTTPException - -def includeme(config): - config.add_route('route_raise_exception', 'route_raise_exception') - config.add_route('route_raise_httpexception', 'route_raise_httpexception') - config.add_route('route_raise_exception2', 'route_raise_exception2', - factory='.models.route_factory') - config.add_route('route_raise_exception3', 'route_raise_exception3', - factory='.models.route_factory2') - config.add_route('route_raise_exception4', 'route_raise_exception4') - config.add_view('.views.maybe') - config.add_view('.views.no', context='.models.NotAnException') - config.add_view('.views.yes', context=".models.AnException") - config.add_view('.views.raise_exception', name='raise_exception') - config.add_view('.views.raise_exception', - route_name='route_raise_exception') - config.add_view('.views.raise_exception', - route_name='route_raise_exception2') - config.add_view('.views.raise_exception', - route_name='route_raise_exception3') - config.add_view('.views.whoa', context='.models.AnException', - route_name='route_raise_exception3') - config.add_view('.views.raise_exception', - route_name='route_raise_exception4') - config.add_view('.views.whoa', context='.models.AnException', - route_name='route_raise_exception4') - config.add_view('.views.raise_httpexception', - route_name='route_raise_httpexception') - config.add_view('.views.catch_httpexception', context=HTTPException) - - diff --git a/src/pyramid/tests/pkgs/exceptionviewapp/models.py b/src/pyramid/tests/pkgs/exceptionviewapp/models.py deleted file mode 100644 index fe407badc..000000000 --- a/src/pyramid/tests/pkgs/exceptionviewapp/models.py +++ /dev/null @@ -1,18 +0,0 @@ - -class NotAnException(object): - pass - -class AnException(Exception): - pass - -class RouteContext(object): - pass - -class RouteContext2(object): - pass - -def route_factory(*arg): - return RouteContext() - -def route_factory2(*arg): - return RouteContext2() diff --git a/src/pyramid/tests/pkgs/exceptionviewapp/views.py b/src/pyramid/tests/pkgs/exceptionviewapp/views.py deleted file mode 100644 index 4953056bc..000000000 --- a/src/pyramid/tests/pkgs/exceptionviewapp/views.py +++ /dev/null @@ -1,24 +0,0 @@ -from webob import Response -from .models import AnException -from pyramid.httpexceptions import HTTPBadRequest - -def no(request): - return Response('no') - -def yes(request): - return Response('yes') - -def maybe(request): - return Response('maybe') - -def whoa(request): - return Response('whoa') - -def raise_exception(request): - raise AnException() - -def raise_httpexception(request): - raise HTTPBadRequest - -def catch_httpexception(request): - return Response('caught') diff --git a/src/pyramid/tests/pkgs/fixtureapp/__init__.py b/src/pyramid/tests/pkgs/fixtureapp/__init__.py deleted file mode 100644 index 27063aae2..000000000 --- a/src/pyramid/tests/pkgs/fixtureapp/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -def includeme(config): - config.add_view('.views.fixture_view') - config.add_view('.views.exception_view', context=RuntimeError) - config.add_view('.views.protected_view', name='protected.html') - config.add_view('.views.erroneous_view', name='error.html') - config.add_view('.views.fixture_view', name='dummyskin.html', - request_type='.views.IDummy') - from .models import fixture, IFixture - config.registry.registerUtility(fixture, IFixture) - config.add_view('.views.fixture_view', name='another.html') - - diff --git a/src/pyramid/tests/pkgs/fixtureapp/models.py b/src/pyramid/tests/pkgs/fixtureapp/models.py deleted file mode 100644 index d80d14bb3..000000000 --- a/src/pyramid/tests/pkgs/fixtureapp/models.py +++ /dev/null @@ -1,8 +0,0 @@ -from zope.interface import Interface - -class IFixture(Interface): - pass - -def fixture(): - """ """ - diff --git a/src/pyramid/tests/pkgs/fixtureapp/subpackage/__init__.py b/src/pyramid/tests/pkgs/fixtureapp/subpackage/__init__.py deleted file mode 100644 index d3173e636..000000000 --- a/src/pyramid/tests/pkgs/fixtureapp/subpackage/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#package diff --git a/src/pyramid/tests/pkgs/fixtureapp/views.py b/src/pyramid/tests/pkgs/fixtureapp/views.py deleted file mode 100644 index cbfc5a574..000000000 --- a/src/pyramid/tests/pkgs/fixtureapp/views.py +++ /dev/null @@ -1,22 +0,0 @@ -from zope.interface import Interface -from webob import Response -from pyramid.httpexceptions import HTTPForbidden - -def fixture_view(context, request): - """ """ - return Response('fixture') - -def erroneous_view(context, request): - """ """ - raise RuntimeError() - -def exception_view(context, request): - """ """ - return Response('supressed') - -def protected_view(context, request): - """ """ - raise HTTPForbidden() - -class IDummy(Interface): - pass diff --git a/src/pyramid/tests/pkgs/forbiddenapp/__init__.py b/src/pyramid/tests/pkgs/forbiddenapp/__init__.py deleted file mode 100644 index c378126fc..000000000 --- a/src/pyramid/tests/pkgs/forbiddenapp/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from webob import Response -from pyramid.httpexceptions import HTTPForbidden -from pyramid.compat import bytes_ - -def x_view(request): # pragma: no cover - return Response('this is private!') - -def forbidden_view(context, request): - msg = context.message - result = context.result - message = msg + '\n' + str(result) - resp = HTTPForbidden() - resp.body = bytes_(message) - return resp - -def includeme(config): - from pyramid.authentication import AuthTktAuthenticationPolicy - from pyramid.authorization import ACLAuthorizationPolicy - authn_policy = AuthTktAuthenticationPolicy('seekr1t', hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() - config._set_authentication_policy(authn_policy) - config._set_authorization_policy(authz_policy) - config.add_view(x_view, name='x', permission='private') - config.add_view(forbidden_view, context=HTTPForbidden) diff --git a/src/pyramid/tests/pkgs/forbiddenview/__init__.py b/src/pyramid/tests/pkgs/forbiddenview/__init__.py deleted file mode 100644 index 45fb8380b..000000000 --- a/src/pyramid/tests/pkgs/forbiddenview/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -from pyramid.view import forbidden_view_config, view_config -from pyramid.response import Response -from pyramid.authentication import AuthTktAuthenticationPolicy -from pyramid.authorization import ACLAuthorizationPolicy - -@forbidden_view_config(route_name='foo') -def foo_forbidden(request): # pragma: no cover - return Response('foo_forbidden') - -@forbidden_view_config() -def forbidden(request): - return Response('generic_forbidden') - -@view_config(route_name='foo') -def foo(request): # pragma: no cover - return Response('OK foo') - -@view_config(route_name='bar') -def bar(request): # pragma: no cover - return Response('OK bar') - -def includeme(config): - authn_policy = AuthTktAuthenticationPolicy('seekri1', hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() - config.set_authentication_policy(authn_policy) - config.set_authorization_policy(authz_policy) - config.set_default_permission('a') - config.add_route('foo', '/foo') - config.add_route('bar', '/bar') - config.scan('pyramid.tests.pkgs.forbiddenview') - diff --git a/src/pyramid/tests/pkgs/hybridapp/__init__.py b/src/pyramid/tests/pkgs/hybridapp/__init__.py deleted file mode 100644 index 1cc2dde83..000000000 --- a/src/pyramid/tests/pkgs/hybridapp/__init__.py +++ /dev/null @@ -1,39 +0,0 @@ -def includeme(config): - # - config.add_route('route', 'abc') - config.add_view('.views.route_view', route_name='route') - # - config.add_view('.views.global_view', - context='pyramid.traversal.DefaultRootFactory') - config.add_view('.views.global2_view', - context='pyramid.traversal.DefaultRootFactory', - name='global2') - config.add_route('route2', 'def') - # - config.add_view('.views.route2_view', route_name='route2') - - # - config.add_route('route3', 'ghi', use_global_views=True) - # - config.add_route('route4', 'jkl') - # - config.add_route('route5', 'mno/*traverse') - # - config.add_route('route6', 'pqr/*traverse', use_global_views=True) - config.add_route('route7', 'error') - config.add_view('.views.erroneous_view', route_name='route7') - config.add_route('route8', 'error2') - config.add_view('.views.erroneous_view', route_name='route8') - # - config.add_view('.views.exception_view', context=RuntimeError) - # - config.add_view('.views.exception2_view', context=RuntimeError, - route_name='route8') - config.add_route('route9', 'error_sub') - config.add_view('.views.erroneous_sub_view', route_name='route9') - # - config.add_view('.views.exception2_view', context='.views.SuperException', - route_name='route9') - # - config.add_view('.views.exception_view', context='.views.SubException') diff --git a/src/pyramid/tests/pkgs/hybridapp/views.py b/src/pyramid/tests/pkgs/hybridapp/views.py deleted file mode 100644 index 135ef8290..000000000 --- a/src/pyramid/tests/pkgs/hybridapp/views.py +++ /dev/null @@ -1,39 +0,0 @@ -from webob import Response - -def route_view(request): - """ """ - return Response('route') - -def global_view(request): - """ """ - return Response('global') - -def global2_view(request): - """ """ - return Response('global2') - -def route2_view(request): - """ """ - return Response('route2') - -def exception_view(request): - """ """ - return Response('supressed') - -def exception2_view(request): - """ """ - return Response('supressed2') - -def erroneous_view(request): - """ """ - raise RuntimeError() - -def erroneous_sub_view(request): - """ """ - raise SubException() - -class SuperException(Exception): - """ """ - -class SubException(SuperException): - """ """ diff --git a/src/pyramid/tests/pkgs/includeapp1/__init__.py b/src/pyramid/tests/pkgs/includeapp1/__init__.py deleted file mode 100644 index eaeeb7ef6..000000000 --- a/src/pyramid/tests/pkgs/includeapp1/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# include app diff --git a/src/pyramid/tests/pkgs/includeapp1/root.py b/src/pyramid/tests/pkgs/includeapp1/root.py deleted file mode 100644 index f56203cfa..000000000 --- a/src/pyramid/tests/pkgs/includeapp1/root.py +++ /dev/null @@ -1,10 +0,0 @@ -from pyramid.response import Response - -def aview(request): - return Response('root') - -def configure(config): - config.add_view(aview) - config.include('pyramid.tests.pkgs.includeapp1.two.configure') - config.commit() - diff --git a/src/pyramid/tests/pkgs/includeapp1/three.py b/src/pyramid/tests/pkgs/includeapp1/three.py deleted file mode 100644 index e7131bcf5..000000000 --- a/src/pyramid/tests/pkgs/includeapp1/three.py +++ /dev/null @@ -1,10 +0,0 @@ -from pyramid.response import Response - -def aview(request): - return Response('three') - -def configure(config): - config.add_view(aview, name='three') - config.include('pyramid.tests.pkgs.includeapp1.two.configure') # should not cycle - config.add_view(aview) # will be overridden by root when resolved - diff --git a/src/pyramid/tests/pkgs/includeapp1/two.py b/src/pyramid/tests/pkgs/includeapp1/two.py deleted file mode 100644 index 99b0f883a..000000000 --- a/src/pyramid/tests/pkgs/includeapp1/two.py +++ /dev/null @@ -1,9 +0,0 @@ -from pyramid.response import Response - -def aview(request): - return Response('two') - -def configure(config): - config.add_view(aview, name='two') - config.include('pyramid.tests.pkgs.includeapp1.three.configure') - config.add_view(aview) # will be overridden by root when resolved diff --git a/src/pyramid/tests/pkgs/localeapp/__init__.py b/src/pyramid/tests/pkgs/localeapp/__init__.py deleted file mode 100644 index 1a35cdb4a..000000000 --- a/src/pyramid/tests/pkgs/localeapp/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# a file diff --git a/src/pyramid/tests/pkgs/localeapp/locale/GARBAGE b/src/pyramid/tests/pkgs/localeapp/locale/GARBAGE deleted file mode 100644 index 032c55584..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale/GARBAGE +++ /dev/null @@ -1 +0,0 @@ -Garbage file. diff --git a/src/pyramid/tests/pkgs/localeapp/locale/be/LC_MESSAGES b/src/pyramid/tests/pkgs/localeapp/locale/be/LC_MESSAGES deleted file mode 100644 index 909cf6a3b..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale/be/LC_MESSAGES +++ /dev/null @@ -1 +0,0 @@ -busted. diff --git a/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo deleted file mode 100644 index e3b2b0881..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po deleted file mode 100644 index be055bed9..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,26 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "different" diff --git a/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/GARBAGE b/src/pyramid/tests/pkgs/localeapp/locale2/GARBAGE deleted file mode 100644 index 032c55584..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale2/GARBAGE +++ /dev/null @@ -1 +0,0 @@ -Garbage file. diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/be/LC_MESSAGES b/src/pyramid/tests/pkgs/localeapp/locale2/be/LC_MESSAGES deleted file mode 100644 index 909cf6a3b..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale2/be/LC_MESSAGES +++ /dev/null @@ -1 +0,0 @@ -busted. diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/GARBAGE b/src/pyramid/tests/pkgs/localeapp/locale3/GARBAGE deleted file mode 100644 index 032c55584..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale3/GARBAGE +++ /dev/null @@ -1 +0,0 @@ -Garbage file. diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/be/LC_MESSAGES b/src/pyramid/tests/pkgs/localeapp/locale3/be/LC_MESSAGES deleted file mode 100644 index 909cf6a3b..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale3/be/LC_MESSAGES +++ /dev/null @@ -1 +0,0 @@ -busted. diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo b/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo deleted file mode 100644 index 2924a5eb5..000000000 Binary files a/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo and /dev/null differ diff --git a/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po b/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po deleted file mode 100644 index 17f87bc19..000000000 --- a/src/pyramid/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po +++ /dev/null @@ -1,31 +0,0 @@ -# German translations for deformsite. -# Copyright (C) 2010 ORGANIZATION -# This file is distributed under the same license as the deformsite project. -# FIRST AUTHOR , 2010. -# -msgid "" -msgstr "" -"Project-Id-Version: deformsite 0.0\n" -"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2010-04-22 14:17+0400\n" -"PO-Revision-Date: 2010-04-22 14:17-0400\n" -"Last-Translator: FULL NAME \n" -"Language-Team: de \n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 0.9.5\n" - -#: deformsite/__init__.py:458 -msgid "Approve" -msgstr "Genehmigen" - -#: deformsite/__init__.py:459 -msgid "Show approval" -msgstr "Zeigen Genehmigung" - -#: deformsite/__init__.py:466 -msgid "Submit" -msgstr "Beugen" - diff --git a/src/pyramid/tests/pkgs/notfoundview/__init__.py b/src/pyramid/tests/pkgs/notfoundview/__init__.py deleted file mode 100644 index ae148ea8c..000000000 --- a/src/pyramid/tests/pkgs/notfoundview/__init__.py +++ /dev/null @@ -1,30 +0,0 @@ -from pyramid.view import notfound_view_config, view_config -from pyramid.response import Response - -@notfound_view_config(route_name='foo', append_slash=True) -def foo_notfound(request): # pragma: no cover - return Response('foo_notfound') - -@notfound_view_config(route_name='baz') -def baz_notfound(request): - return Response('baz_notfound') - -@notfound_view_config(append_slash=True) -def notfound(request): - return Response('generic_notfound') - -@view_config(route_name='bar') -def bar(request): - return Response('OK bar') - -@view_config(route_name='foo2') -def foo2(request): - return Response('OK foo2') - -def includeme(config): - config.add_route('foo', '/foo') - config.add_route('foo2', '/foo/') - config.add_route('bar', '/bar/') - config.add_route('baz', '/baz') - config.scan('pyramid.tests.pkgs.notfoundview') - diff --git a/src/pyramid/tests/pkgs/permbugapp/__init__.py b/src/pyramid/tests/pkgs/permbugapp/__init__.py deleted file mode 100644 index 4868427a5..000000000 --- a/src/pyramid/tests/pkgs/permbugapp/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -from pyramid.compat import escape -from pyramid.security import view_execution_permitted -from pyramid.response import Response - -def x_view(request): # pragma: no cover - return Response('this is private!') - -def test(context, request): - # should return false - msg = 'Allow ./x? %s' % repr(view_execution_permitted( - context, request, 'x')) - return Response(escape(msg)) - -def includeme(config): - from pyramid.authentication import AuthTktAuthenticationPolicy - from pyramid.authorization import ACLAuthorizationPolicy - authn_policy = AuthTktAuthenticationPolicy('seekt1t', hashalg='sha512') - authz_policy = ACLAuthorizationPolicy() - config.set_authentication_policy(authn_policy) - config.set_authorization_policy(authz_policy) - config.add_view(test, name='test') - config.add_view(x_view, name='x', permission='private') diff --git a/src/pyramid/tests/pkgs/rendererscanapp/__init__.py b/src/pyramid/tests/pkgs/rendererscanapp/__init__.py deleted file mode 100644 index f3276a063..000000000 --- a/src/pyramid/tests/pkgs/rendererscanapp/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -from pyramid.view import view_config - -@view_config(name='one', renderer='json') -def one(request): - return {'name':'One!'} - -def includeme(config): - config.scan() - diff --git a/src/pyramid/tests/pkgs/rendererscanapp/two/__init__.py b/src/pyramid/tests/pkgs/rendererscanapp/two/__init__.py deleted file mode 100644 index 6f575dd83..000000000 --- a/src/pyramid/tests/pkgs/rendererscanapp/two/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config - -@view_config(name='two', renderer='json') -def two(request): - return {'nameagain':'Two!'} - diff --git a/src/pyramid/tests/pkgs/restbugapp/__init__.py b/src/pyramid/tests/pkgs/restbugapp/__init__.py deleted file mode 100644 index 9ad79e32e..000000000 --- a/src/pyramid/tests/pkgs/restbugapp/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -def includeme(config): - config.add_route('gameactions_pet_get_pets', '/pet', - request_method='GET') - config.add_route('gameactions_pet_care_for_pet', '/pet', - request_method='POST') - config.add_view('.views.PetRESTView', - route_name='gameactions_pet_get_pets', - attr='GET', - permission='view', - renderer='json') - config.add_view('.views.PetRESTView', - route_name='gameactions_pet_care_for_pet', - attr='POST', - permission='view', - renderer='json') diff --git a/src/pyramid/tests/pkgs/restbugapp/views.py b/src/pyramid/tests/pkgs/restbugapp/views.py deleted file mode 100644 index 2ace59fa9..000000000 --- a/src/pyramid/tests/pkgs/restbugapp/views.py +++ /dev/null @@ -1,15 +0,0 @@ -from pyramid.response import Response - -class BaseRESTView(object): - def __init__(self, context, request): - self.context = context - self.request = request - -class PetRESTView(BaseRESTView): - """ REST Controller to control action of an avatar """ - def __init__(self, context, request): - super(PetRESTView, self).__init__(context, request) - - def GET(self): - return Response('gotten') - diff --git a/src/pyramid/tests/pkgs/static_abspath/__init__.py b/src/pyramid/tests/pkgs/static_abspath/__init__.py deleted file mode 100644 index 812cca467..000000000 --- a/src/pyramid/tests/pkgs/static_abspath/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -import os - -def includeme(config): - here = here = os.path.dirname(__file__) - fixtures = os.path.normpath(os.path.join(here, '..', '..', 'fixtures')) - config.add_static_view('/', fixtures) - diff --git a/src/pyramid/tests/pkgs/static_assetspec/__init__.py b/src/pyramid/tests/pkgs/static_assetspec/__init__.py deleted file mode 100644 index cd6195397..000000000 --- a/src/pyramid/tests/pkgs/static_assetspec/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -def includeme(config): - config.add_static_view('/', 'pyramid.tests:fixtures') - diff --git a/src/pyramid/tests/pkgs/static_routeprefix/__init__.py b/src/pyramid/tests/pkgs/static_routeprefix/__init__.py deleted file mode 100644 index 9b539380a..000000000 --- a/src/pyramid/tests/pkgs/static_routeprefix/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -def includeme(config): - config.add_static_view('/static', 'pyramid.tests:fixtures') - config.include(includeme2, route_prefix='/prefix') - -def includeme2(config): - config.add_static_view('/static', 'pyramid.tests:fixtures/static') - diff --git a/src/pyramid/tests/pkgs/staticpermapp/__init__.py b/src/pyramid/tests/pkgs/staticpermapp/__init__.py deleted file mode 100644 index cc690d937..000000000 --- a/src/pyramid/tests/pkgs/staticpermapp/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -class RootFactory(object): - __acl__ = [('Allow', 'fred', 'view')] - def __init__(self, request): - pass - -class LocalRootFactory(object): - __acl__ = [('Allow', 'bob', 'view')] - def __init__(self, request): - pass - - -def includeme(config): - from pyramid.authentication import RemoteUserAuthenticationPolicy - from pyramid.authorization import ACLAuthorizationPolicy - authn_policy = RemoteUserAuthenticationPolicy() - authz_policy = ACLAuthorizationPolicy() - config._set_authentication_policy(authn_policy) - config._set_authorization_policy(authz_policy) - config.add_static_view('allowed', 'pyramid.tests:fixtures/static/') - config.add_static_view('protected', 'pyramid.tests:fixtures/static/', - permission='view') - config.add_static_view('factory_protected', - 'pyramid.tests:fixtures/static/', - permission='view', - factory=LocalRootFactory) diff --git a/src/pyramid/tests/pkgs/subrequestapp/__init__.py b/src/pyramid/tests/pkgs/subrequestapp/__init__.py deleted file mode 100644 index e4b1d386a..000000000 --- a/src/pyramid/tests/pkgs/subrequestapp/__init__.py +++ /dev/null @@ -1,52 +0,0 @@ -from pyramid.config import Configurator -from pyramid.request import Request - -def view_one(request): - subreq = Request.blank('/view_two') - response = request.invoke_subrequest(subreq, use_tweens=False) - return response - -def view_two(request): - # check that request.foo is valid for a subrequest - return 'This came from view_two, foo=%s' % (request.foo,) - -def view_three(request): - subreq = Request.blank('/view_four') - try: - return request.invoke_subrequest(subreq, use_tweens=True) - except: # pragma: no cover - request.response.body = b'Value error raised' - return request.response - -def view_four(request): - raise ValueError('foo') - -def view_five(request): - subreq = Request.blank('/view_four') - try: - return request.invoke_subrequest(subreq, use_tweens=False) - except ValueError: - request.response.body = b'Value error raised' - return request.response - -def excview(request): - request.response.status_int = 500 - request.response.body = b'Bad stuff happened' - return request.response - -def main(): - config = Configurator() - config.add_route('one', '/view_one') - config.add_route('two', '/view_two') - config.add_route('three', '/view_three') - config.add_route('four', '/view_four') - config.add_route('five', '/view_five') - config.add_view(excview, context=Exception) - config.add_view(view_one, route_name='one') - config.add_view(view_two, route_name='two', renderer='string') - config.add_view(view_three, route_name='three') - config.add_view(view_four, route_name='four') - config.add_view(view_five, route_name='five') - config.add_request_method(lambda r: 'bar', 'foo', property=True) - return config - diff --git a/src/pyramid/tests/pkgs/viewdecoratorapp/__init__.py b/src/pyramid/tests/pkgs/viewdecoratorapp/__init__.py deleted file mode 100644 index 5fa98062a..000000000 --- a/src/pyramid/tests/pkgs/viewdecoratorapp/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -def includeme(config): - config.scan('pyramid.tests.pkgs.viewdecoratorapp') - diff --git a/src/pyramid/tests/pkgs/viewdecoratorapp/views/__init__.py b/src/pyramid/tests/pkgs/viewdecoratorapp/views/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/src/pyramid/tests/pkgs/viewdecoratorapp/views/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/src/pyramid/tests/pkgs/viewdecoratorapp/views/views.py b/src/pyramid/tests/pkgs/viewdecoratorapp/views/views.py deleted file mode 100644 index 18ec78847..000000000 --- a/src/pyramid/tests/pkgs/viewdecoratorapp/views/views.py +++ /dev/null @@ -1,12 +0,0 @@ -from pyramid.view import view_config - -@view_config(renderer='json', name='first') -def first(request): - return {'result':'OK1'} - -@view_config( - renderer='json', - name='second') -def second(request): - return {'result':'OK2'} - diff --git a/src/pyramid/tests/pkgs/wsgiapp2app/__init__.py b/src/pyramid/tests/pkgs/wsgiapp2app/__init__.py deleted file mode 100644 index e2024198e..000000000 --- a/src/pyramid/tests/pkgs/wsgiapp2app/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -from pyramid.view import view_config -from pyramid.wsgi import wsgiapp2 - -@view_config(name='hello', renderer='string') -@wsgiapp2 -def hello(environ, start_response): - assert environ['PATH_INFO'] == '/' - assert environ['SCRIPT_NAME'] == '/hello' - response_headers = [('Content-Type', 'text/plain')] - start_response('200 OK', response_headers) - return [b'Hello!'] - -def main(): - from pyramid.config import Configurator - c = Configurator() - c.scan() - return c diff --git a/src/pyramid/tests/test_asset.py b/src/pyramid/tests/test_asset.py deleted file mode 100644 index d3ebd5f7d..000000000 --- a/src/pyramid/tests/test_asset.py +++ /dev/null @@ -1,88 +0,0 @@ -import unittest -import os - -here = os.path.abspath(os.path.dirname(__file__)) - -class Test_resolve_asset_spec(unittest.TestCase): - def _callFUT(self, spec, package_name='__main__'): - from pyramid.resource import resolve_asset_spec - return resolve_asset_spec(spec, package_name) - - def test_abspath(self): - package_name, filename = self._callFUT(here, 'apackage') - self.assertEqual(filename, here) - self.assertEqual(package_name, None) - - def test_rel_spec(self): - pkg = 'pyramid.tests' - path = 'test_asset.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'pyramid.tests') - self.assertEqual(filename, 'test_asset.py') - - def test_abs_spec(self): - pkg = 'pyramid.tests' - path = 'pyramid.nottests:test_asset.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'pyramid.nottests') - self.assertEqual(filename, 'test_asset.py') - - def test_package_name_is_None(self): - pkg = None - path = 'test_asset.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, None) - self.assertEqual(filename, 'test_asset.py') - - def test_package_name_is_package_object(self): - import pyramid.tests - pkg = pyramid.tests - path = 'test_asset.py' - package_name, filename = self._callFUT(path, pkg) - self.assertEqual(package_name, 'pyramid.tests') - self.assertEqual(filename, 'test_asset.py') - - -class Test_abspath_from_asset_spec(unittest.TestCase): - def _callFUT(self, spec, pname='__main__'): - from pyramid.resource import abspath_from_asset_spec - return abspath_from_asset_spec(spec, pname) - - def test_pname_is_None_before_resolve_asset_spec(self): - result = self._callFUT('abc', None) - self.assertEqual(result, 'abc') - - def test_pname_is_None_after_resolve_asset_spec(self): - result = self._callFUT('/abc', '__main__') - self.assertEqual(result, '/abc') - - def test_pkgrelative(self): - result = self._callFUT('abc', 'pyramid.tests') - self.assertEqual(result, os.path.join(here, 'abc')) - -class Test_asset_spec_from_abspath(unittest.TestCase): - def _callFUT(self, abspath, package): - from pyramid.asset import asset_spec_from_abspath - return asset_spec_from_abspath(abspath, package) - - def test_package_name_is_main(self): - pkg = DummyPackage('__main__') - result = self._callFUT('abspath', pkg) - self.assertEqual(result, 'abspath') - - def test_abspath_startswith_package_path(self): - abspath = os.path.join(here, 'fixtureapp') - pkg = DummyPackage('pyramid.tests') - pkg.__file__ = 'file' - result = self._callFUT(abspath, pkg) - self.assertEqual(result, 'pyramid:fixtureapp') - - def test_abspath_doesnt_startwith_package_path(self): - pkg = DummyPackage('pyramid.tests') - result = self._callFUT(here, pkg) - self.assertEqual(result, here) - -class DummyPackage: - def __init__(self, name): - self.__name__ = name - diff --git a/src/pyramid/tests/test_authentication.py b/src/pyramid/tests/test_authentication.py deleted file mode 100644 index 4efd76f2b..000000000 --- a/src/pyramid/tests/test_authentication.py +++ /dev/null @@ -1,1738 +0,0 @@ -import unittest -import warnings -from pyramid import testing -from pyramid.compat import ( - text_, - bytes_, - ) - -class TestCallbackAuthenticationPolicyDebugging(unittest.TestCase): - def setUp(self): - from pyramid.interfaces import IDebugLogger - self.config = testing.setUp() - self.config.registry.registerUtility(self, IDebugLogger) - self.messages = [] - - def tearDown(self): - del self.config - - def debug(self, msg): - self.messages.append(msg) - - def _makeOne(self, userid=None, callback=None): - from pyramid.authentication import CallbackAuthenticationPolicy - class MyAuthenticationPolicy(CallbackAuthenticationPolicy): - def unauthenticated_userid(self, request): - return userid - policy = MyAuthenticationPolicy() - policy.debug = True - policy.callback = callback - return policy - - def test_authenticated_userid_no_unauthenticated_userid(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' - 'authenticated_userid: call to unauthenticated_userid returned ' - 'None; returning None') - - def test_authenticated_userid_no_callback(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='fred') - self.assertEqual(policy.authenticated_userid(request), 'fred') - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "authenticated_userid: there was no groupfinder callback; " - "returning 'fred'") - - def test_authenticated_userid_with_callback_fail(self): - request = DummyRequest(registry=self.config.registry) - def callback(userid, request): - return None - policy = self._makeOne(userid='fred', callback=callback) - self.assertEqual(policy.authenticated_userid(request), None) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' - 'authenticated_userid: groupfinder callback returned None; ' - 'returning None') - - def test_authenticated_userid_with_callback_success(self): - request = DummyRequest(registry=self.config.registry) - def callback(userid, request): - return [] - policy = self._makeOne(userid='fred', callback=callback) - self.assertEqual(policy.authenticated_userid(request), 'fred') - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "authenticated_userid: groupfinder callback returned []; " - "returning 'fred'") - - def test_authenticated_userid_fails_cleaning_as_Authenticated(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='system.Authenticated') - self.assertEqual(policy.authenticated_userid(request), None) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "authenticated_userid: use of userid 'system.Authenticated' is " - "disallowed by any built-in Pyramid security policy, returning " - "None") - - def test_authenticated_userid_fails_cleaning_as_Everyone(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='system.Everyone') - self.assertEqual(policy.authenticated_userid(request), None) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "authenticated_userid: use of userid 'system.Everyone' is " - "disallowed by any built-in Pyramid security policy, returning " - "None") - - def test_effective_principals_no_unauthenticated_userid(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), - ['system.Everyone']) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: unauthenticated_userid returned None; " - "returning ['system.Everyone']") - - def test_effective_principals_no_callback(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='fred') - self.assertEqual( - policy.effective_principals(request), - ['system.Everyone', 'system.Authenticated', 'fred']) - self.assertEqual(len(self.messages), 2) - self.assertEqual( - self.messages[0], - 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' - 'effective_principals: groupfinder callback is None, so groups ' - 'is []') - self.assertEqual( - self.messages[1], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: returning effective principals: " - "['system.Everyone', 'system.Authenticated', 'fred']") - - def test_effective_principals_with_callback_fail(self): - request = DummyRequest(registry=self.config.registry) - def callback(userid, request): - return None - policy = self._makeOne(userid='fred', callback=callback) - self.assertEqual( - policy.effective_principals(request), ['system.Everyone']) - self.assertEqual(len(self.messages), 2) - self.assertEqual( - self.messages[0], - 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' - 'effective_principals: groupfinder callback returned None as ' - 'groups') - self.assertEqual( - self.messages[1], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: returning effective principals: " - "['system.Everyone']") - - def test_effective_principals_with_callback_success(self): - request = DummyRequest(registry=self.config.registry) - def callback(userid, request): - return [] - policy = self._makeOne(userid='fred', callback=callback) - self.assertEqual( - policy.effective_principals(request), - ['system.Everyone', 'system.Authenticated', 'fred']) - self.assertEqual(len(self.messages), 2) - self.assertEqual( - self.messages[0], - 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' - 'effective_principals: groupfinder callback returned [] as groups') - self.assertEqual( - self.messages[1], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: returning effective principals: " - "['system.Everyone', 'system.Authenticated', 'fred']") - - def test_effective_principals_with_unclean_principal_Authenticated(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='system.Authenticated') - self.assertEqual( - policy.effective_principals(request), - ['system.Everyone']) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: unauthenticated_userid returned disallowed " - "'system.Authenticated'; returning ['system.Everyone'] as if it " - "was None") - - def test_effective_principals_with_unclean_principal_Everyone(self): - request = DummyRequest(registry=self.config.registry) - policy = self._makeOne(userid='system.Everyone') - self.assertEqual( - policy.effective_principals(request), - ['system.Everyone']) - self.assertEqual(len(self.messages), 1) - self.assertEqual( - self.messages[0], - "pyramid.tests.test_authentication.MyAuthenticationPolicy." - "effective_principals: unauthenticated_userid returned disallowed " - "'system.Everyone'; returning ['system.Everyone'] as if it " - "was None") - -class TestRepozeWho1AuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import RepozeWho1AuthenticationPolicy - return RepozeWho1AuthenticationPolicy - - def _makeOne(self, identifier_name='auth_tkt', callback=None): - return self._getTargetClass()(identifier_name, callback) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne()) - - def test_unauthenticated_userid_returns_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), 'fred') - - def test_authenticated_userid_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_authenticated_userid_repoze_who_userid_is_None(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':None}}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_with_callback_returns_None(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - def callback(identity, request): - return None - policy = self._makeOne(callback=callback) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_with_callback_returns_something(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - def callback(identity, request): - return ['agroup'] - policy = self._makeOne(callback=callback) - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_authenticated_userid_unclean_principal_Authenticated(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'system.Authenticated'}} - ) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_unclean_principal_Everyone(self): - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'system.Everyone'}} - ) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_effective_principals_None(self): - from pyramid.security import Everyone - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_userid_only(self): - from pyramid.security import Everyone - from pyramid.security import Authenticated - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred'}}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred']) - - def test_effective_principals_userid_and_groups(self): - from pyramid.security import Everyone - from pyramid.security import Authenticated - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred', - 'groups':['quux', 'biz']}}) - def callback(identity, request): - return identity['groups'] - policy = self._makeOne(callback=callback) - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred', 'quux', 'biz']) - - def test_effective_principals_userid_callback_returns_None(self): - from pyramid.security import Everyone - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'fred', - 'groups':['quux', 'biz']}}) - def callback(identity, request): - return None - policy = self._makeOne(callback=callback) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_repoze_who_userid_is_None(self): - from pyramid.security import Everyone - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':None}} - ) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_repoze_who_userid_is_unclean_Everyone(self): - from pyramid.security import Everyone - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'system.Everyone'}} - ) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_repoze_who_userid_is_unclean_Authenticated( - self): - from pyramid.security import Everyone - request = DummyRequest( - {'repoze.who.identity':{'repoze.who.userid':'system.Authenticated'}} - ) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_remember_no_plugins(self): - request = DummyRequest({}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_remember(self): - authtkt = DummyWhoPlugin() - request = DummyRequest( - {'repoze.who.plugins':{'auth_tkt':authtkt}}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result[0], request.environ) - self.assertEqual(result[1], {'repoze.who.userid':'fred'}) - - def test_remember_kwargs(self): - authtkt = DummyWhoPlugin() - request = DummyRequest( - {'repoze.who.plugins':{'auth_tkt':authtkt}}) - policy = self._makeOne() - result = policy.remember(request, 'fred', max_age=23) - self.assertEqual(result[1], {'repoze.who.userid':'fred', 'max_age': 23}) - - def test_forget_no_plugins(self): - request = DummyRequest({}) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result, []) - - def test_forget(self): - authtkt = DummyWhoPlugin() - request = DummyRequest( - {'repoze.who.plugins':{'auth_tkt':authtkt}, - 'repoze.who.identity':{'repoze.who.userid':'fred'}, - }) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result[0], request.environ) - self.assertEqual(result[1], request.environ['repoze.who.identity']) - -class TestRemoteUserAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import RemoteUserAuthenticationPolicy - return RemoteUserAuthenticationPolicy - - def _makeOne(self, environ_key='REMOTE_USER', callback=None): - return self._getTargetClass()(environ_key, callback) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne()) - - def test_unauthenticated_userid_returns_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), 'fred') - - def test_authenticated_userid_None(self): - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_None(self): - from pyramid.security import Everyone - request = DummyRequest({}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals(self): - from pyramid.security import Everyone - from pyramid.security import Authenticated - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred']) - - def test_remember(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_forget(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(result, []) - -class TestAuthTktAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import AuthTktAuthenticationPolicy - return AuthTktAuthenticationPolicy - - def _makeOne(self, callback, cookieidentity, **kw): - inst = self._getTargetClass()('secret', callback, **kw) - inst.cookie = DummyCookieHelper(cookieidentity) - return inst - - def setUp(self): - self.warnings = warnings.catch_warnings() - self.warnings.__enter__() - warnings.simplefilter('ignore', DeprecationWarning) - - def tearDown(self): - self.warnings.__exit__(None, None, None) - - def test_allargs(self): - # pass all known args - inst = self._getTargetClass()( - 'secret', callback=None, cookie_name=None, secure=False, - include_ip=False, timeout=None, reissue_time=None, - hashalg='sha512', samesite=None, - ) - self.assertEqual(inst.callback, None) - - def test_hashalg_override(self): - # important to ensure hashalg is passed to cookie helper - inst = self._getTargetClass()('secret', hashalg='sha512') - self.assertEqual(inst.cookie.hashalg, 'sha512') - - def test_unauthenticated_userid_returns_None(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid(self): - request = DummyRequest({'REMOTE_USER':'fred'}) - policy = self._makeOne(None, {'userid':'fred'}) - self.assertEqual(policy.unauthenticated_userid(request), 'fred') - - def test_authenticated_userid_no_cookie_identity(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_callback_returns_None(self): - request = DummyRequest({}) - def callback(userid, request): - return None - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest({}) - def callback(userid, request): - return True - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_no_cookie_identity(self): - from pyramid.security import Everyone - request = DummyRequest({}) - policy = self._makeOne(None, None) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_callback_returns_None(self): - from pyramid.security import Everyone - request = DummyRequest({}) - def callback(userid, request): - return None - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals(self): - from pyramid.security import Everyone - from pyramid.security import Authenticated - request = DummyRequest({}) - def callback(userid, request): - return ['group.foo'] - policy = self._makeOne(callback, {'userid':'fred'}) - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred', 'group.foo']) - - def test_remember(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.remember(request, 'fred') - self.assertEqual(result, []) - - def test_remember_with_extra_kargs(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.remember(request, 'fred', a=1, b=2) - self.assertEqual(policy.cookie.kw, {'a':1, 'b':2}) - self.assertEqual(result, []) - - def test_forget(self): - request = DummyRequest({}) - policy = self._makeOne(None, None) - result = policy.forget(request) - self.assertEqual(result, []) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne(None, None)) - -class TestAuthTktCookieHelper(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import AuthTktCookieHelper - return AuthTktCookieHelper - - def _makeOne(self, *arg, **kw): - helper = self._getTargetClass()(*arg, **kw) - # laziness after moving auth_tkt classes and funcs into - # authentication module - auth_tkt = DummyAuthTktModule() - helper.auth_tkt = auth_tkt - helper.AuthTicket = auth_tkt.AuthTicket - helper.parse_ticket = auth_tkt.parse_ticket - helper.BadTicket = auth_tkt.BadTicket - return helper - - def _makeRequest(self, cookie=None, ipv6=False): - environ = {'wsgi.version': (1,0)} - - if ipv6 is False: - environ['REMOTE_ADDR'] = '1.1.1.1' - else: - environ['REMOTE_ADDR'] = '::1' - environ['SERVER_NAME'] = 'localhost' - return DummyRequest(environ, cookie=cookie) - - def _cookieValue(self, cookie): - items = cookie.value.split('/') - D = {} - for item in items: - k, v = item.split('=', 1) - D[k] = v - return D - - def _parseHeaders(self, headers): - return [ self._parseHeader(header) for header in headers ] - - def _parseHeader(self, header): - cookie = self._parseCookie(header[1]) - return cookie - - def _parseCookie(self, cookie): - from pyramid.compat import SimpleCookie - cookies = SimpleCookie() - cookies.load(cookie) - return cookies.get('auth_tkt') - - def test_init_cookie_str_reissue_invalid(self): - self.assertRaises(ValueError, self._makeOne, 'secret', reissue_time='invalid value') - - def test_init_cookie_str_timeout_invalid(self): - self.assertRaises(ValueError, self._makeOne, 'secret', timeout='invalid value') - - def test_init_cookie_str_max_age_invalid(self): - self.assertRaises(ValueError, self._makeOne, 'secret', max_age='invalid value') - - def test_identify_nocookie(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.identify(request) - self.assertEqual(result, None) - - def test_identify_cookie_value_is_None(self): - helper = self._makeOne('secret') - request = self._makeRequest(None) - result = helper.identify(request) - self.assertEqual(result, None) - - def test_identify_good_cookie_include_ip(self): - helper = self._makeOne('secret', include_ip=True) - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'userid') - self.assertEqual(result['userdata'], '') - self.assertEqual(result['timestamp'], 0) - self.assertEqual(helper.auth_tkt.value, 'ticket') - self.assertEqual(helper.auth_tkt.remote_addr, '1.1.1.1') - self.assertEqual(helper.auth_tkt.secret, 'secret') - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_include_ipv6(self): - helper = self._makeOne('secret', include_ip=True) - request = self._makeRequest('ticket', ipv6=True) - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'userid') - self.assertEqual(result['userdata'], '') - self.assertEqual(result['timestamp'], 0) - self.assertEqual(helper.auth_tkt.value, 'ticket') - self.assertEqual(helper.auth_tkt.remote_addr, '::1') - self.assertEqual(helper.auth_tkt.secret, 'secret') - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_dont_include_ip(self): - helper = self._makeOne('secret', include_ip=False) - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'userid') - self.assertEqual(result['userdata'], '') - self.assertEqual(result['timestamp'], 0) - self.assertEqual(helper.auth_tkt.value, 'ticket') - self.assertEqual(helper.auth_tkt.remote_addr, '0.0.0.0') - self.assertEqual(helper.auth_tkt.secret, 'secret') - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_int_useridtype(self): - helper = self._makeOne('secret', include_ip=False) - helper.auth_tkt.userid = '1' - helper.auth_tkt.user_data = 'userid_type:int' - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 1) - self.assertEqual(result['userdata'], 'userid_type:int') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:int') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_nonuseridtype_user_data(self): - helper = self._makeOne('secret', include_ip=False) - helper.auth_tkt.userid = '1' - helper.auth_tkt.user_data = 'bogus:int' - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], '1') - self.assertEqual(result['userdata'], 'bogus:int') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'bogus:int') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_unknown_useridtype(self): - helper = self._makeOne('secret', include_ip=False) - helper.auth_tkt.userid = 'abc' - helper.auth_tkt.user_data = 'userid_type:unknown' - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], 'abc') - self.assertEqual(result['userdata'], 'userid_type:unknown') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:unknown') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_b64str_useridtype(self): - from base64 import b64encode - helper = self._makeOne('secret', include_ip=False) - helper.auth_tkt.userid = b64encode(b'encoded').strip() - helper.auth_tkt.user_data = 'userid_type:b64str' - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], b'encoded') - self.assertEqual(result['userdata'], 'userid_type:b64str') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64str') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_good_cookie_b64unicode_useridtype(self): - from base64 import b64encode - helper = self._makeOne('secret', include_ip=False) - helper.auth_tkt.userid = b64encode(b'\xc3\xa9ncoded').strip() - helper.auth_tkt.user_data = 'userid_type:b64unicode' - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(len(result), 4) - self.assertEqual(result['tokens'], ()) - self.assertEqual(result['userid'], text_(b'\xc3\xa9ncoded', 'utf-8')) - self.assertEqual(result['userdata'], 'userid_type:b64unicode') - self.assertEqual(result['timestamp'], 0) - environ = request.environ - self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) - self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64unicode') - self.assertEqual(environ['AUTH_TYPE'],'cookie') - - def test_identify_bad_cookie(self): - helper = self._makeOne('secret', include_ip=True) - helper.auth_tkt.parse_raise = True - request = self._makeRequest('ticket') - result = helper.identify(request) - self.assertEqual(result, None) - - def test_identify_cookie_timeout(self): - helper = self._makeOne('secret', timeout=1) - self.assertEqual(helper.timeout, 1) - - def test_identify_cookie_str_timeout(self): - helper = self._makeOne('secret', timeout='1') - self.assertEqual(helper.timeout, 1) - - def test_identify_cookie_timeout_aged(self): - import time - helper = self._makeOne('secret', timeout=10) - now = time.time() - helper.auth_tkt.timestamp = now - 1 - helper.now = now + 10 - helper.auth_tkt.tokens = (text_('a'), ) - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertFalse(result) - - def test_identify_cookie_reissue(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time=0) - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - helper.auth_tkt.tokens = (text_('a'), ) - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](request, response) - self.assertEqual(len(response.headerlist), 3) - self.assertEqual(response.headerlist[0][0], 'Set-Cookie') - - def test_identify_cookie_str_reissue(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time='0') - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - helper.auth_tkt.tokens = (text_('a'), ) - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](request, response) - self.assertEqual(len(response.headerlist), 3) - self.assertEqual(response.headerlist[0][0], 'Set-Cookie') - - def test_identify_cookie_reissue_already_reissued_this_request(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time=0) - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - request = self._makeRequest('bogus') - request._authtkt_reissued = True - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 0) - - def test_identify_cookie_reissue_notyet(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time=10) - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 0) - - def test_identify_cookie_reissue_revoked_by_forget(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time=0) - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - result = helper.forget(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](request, response) - self.assertEqual(len(response.headerlist), 0) - - def test_identify_cookie_reissue_revoked_by_remember(self): - import time - helper = self._makeOne('secret', timeout=10, reissue_time=0) - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - result = helper.remember(request, 'bob') - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](request, response) - self.assertEqual(len(response.headerlist), 0) - - def test_identify_cookie_reissue_with_tokens_default(self): - # see https://github.com/Pylons/pyramid/issues#issue/108 - import time - helper = self._makeOne('secret', timeout=10, reissue_time=0) - auth_tkt = DummyAuthTktModule(tokens=['']) - helper.auth_tkt = auth_tkt - helper.AuthTicket = auth_tkt.AuthTicket - helper.parse_ticket = auth_tkt.parse_ticket - helper.BadTicket = auth_tkt.BadTicket - now = time.time() - helper.auth_tkt.timestamp = now - helper.now = now + 1 - request = self._makeRequest('bogus') - result = helper.identify(request) - self.assertTrue(result) - self.assertEqual(len(request.callbacks), 1) - response = DummyResponse() - request.callbacks[0](None, response) - self.assertEqual(len(response.headerlist), 3) - self.assertEqual(response.headerlist[0][0], 'Set-Cookie') - self.assertTrue("/tokens=/" in response.headerlist[0][1]) - - def test_remember(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/; SameSite=Lax')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith( - '; Domain=.localhost; Path=/; SameSite=Lax')) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_nondefault_samesite(self): - helper = self._makeOne('secret', samesite='Strict') - request = self._makeRequest() - result = helper.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Strict')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/; SameSite=Strict')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith( - '; Domain=.localhost; Path=/; SameSite=Strict')) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_None_samesite(self): - helper = self._makeOne('secret', samesite=None) - request = self._makeRequest() - result = helper.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/')) # no samesite - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith( - '; Domain=.localhost; Path=/')) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_include_ip(self): - helper = self._makeOne('secret', include_ip=True) - request = self._makeRequest() - result = helper.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/; SameSite=Lax')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith( - '; Domain=.localhost; Path=/; SameSite=Lax')) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_path(self): - helper = self._makeOne('secret', include_ip=True, - path="/cgi-bin/app.cgi/") - request = self._makeRequest() - result = helper.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith( - '; Path=/cgi-bin/app.cgi/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/cgi-bin/app.cgi/; SameSite=Lax')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue(result[2][1].endswith( - '; Domain=.localhost; Path=/cgi-bin/app.cgi/; SameSite=Lax')) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_http_only(self): - helper = self._makeOne('secret', include_ip=True, http_only=True) - request = self._makeRequest() - result = helper.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; HttpOnly; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue('; HttpOnly' in result[1][1]) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue('; HttpOnly' in result[2][1]) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_secure(self): - helper = self._makeOne('secret', include_ip=True, secure=True) - request = self._makeRequest() - result = helper.remember(request, 'other') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue('; secure' in result[0][1]) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue('; secure' in result[1][1]) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue('; secure' in result[2][1]) - self.assertTrue(result[2][1].startswith('auth_tkt=')) - - def test_remember_wild_domain_disabled(self): - helper = self._makeOne('secret', wild_domain=False) - request = self._makeRequest() - result = helper.remember(request, 'other') - self.assertEqual(len(result), 2) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue(result[1][1].endswith( - '; Domain=localhost; Path=/; SameSite=Lax')) - self.assertTrue(result[1][1].startswith('auth_tkt=')) - - def test_remember_parent_domain(self): - helper = self._makeOne('secret', parent_domain=True) - request = self._makeRequest() - request.domain = 'www.example.com' - result = helper.remember(request, 'other') - self.assertEqual(len(result), 1) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith( - '; Domain=.example.com; Path=/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - def test_remember_parent_domain_supercedes_wild_domain(self): - helper = self._makeOne('secret', parent_domain=True, wild_domain=True) - request = self._makeRequest() - request.domain = 'www.example.com' - result = helper.remember(request, 'other') - self.assertEqual(len(result), 1) - self.assertTrue(result[0][1].endswith( - '; Domain=.example.com; Path=/; SameSite=Lax')) - - def test_remember_explicit_domain(self): - helper = self._makeOne('secret', domain='pyramid.bazinga') - request = self._makeRequest() - request.domain = 'www.example.com' - result = helper.remember(request, 'other') - self.assertEqual(len(result), 1) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue(result[0][1].endswith( - '; Domain=pyramid.bazinga; Path=/; SameSite=Lax')) - self.assertTrue(result[0][1].startswith('auth_tkt=')) - - def test_remember_domain_supercedes_parent_and_wild_domain(self): - helper = self._makeOne('secret', domain='pyramid.bazinga', - parent_domain=True, wild_domain=True) - request = self._makeRequest() - request.domain = 'www.example.com' - result = helper.remember(request, 'other') - self.assertEqual(len(result), 1) - self.assertTrue(result[0][1].endswith( - '; Domain=pyramid.bazinga; Path=/; SameSite=Lax')) - - def test_remember_binary_userid(self): - import base64 - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, b'userid') - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], - text_(base64.b64encode(b'userid').strip())) - self.assertEqual(val['user_data'], 'userid_type:b64str') - - def test_remember_int_userid(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 1) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], '1') - self.assertEqual(val['user_data'], 'userid_type:int') - - def test_remember_long_userid(self): - from pyramid.compat import long - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, long(1)) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], '1') - self.assertEqual(val['user_data'], 'userid_type:int') - - def test_remember_unicode_userid(self): - import base64 - helper = self._makeOne('secret') - request = self._makeRequest() - userid = text_(b'\xc2\xa9', 'utf-8') - result = helper.remember(request, userid) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - val = self._cookieValue(values[0]) - self.assertEqual(val['userid'], - text_(base64.b64encode(userid.encode('utf-8')))) - self.assertEqual(val['user_data'], 'userid_type:b64unicode') - - def test_remember_insane_userid(self): - helper = self._makeOne('secret') - request = self._makeRequest() - userid = object() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter('always', RuntimeWarning) - result = helper.remember(request, userid) - self.assertTrue(str(w[-1].message).startswith('userid is of type')) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - value = values[0] - self.assertTrue('userid' in value.value) - - def test_remember_max_age(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 'userid', max_age=500) - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - - self.assertEqual(values[0]['max-age'], '500') - self.assertTrue(values[0]['expires']) - - def test_remember_str_max_age(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 'userid', max_age='500') - values = self._parseHeaders(result) - self.assertEqual(len(result), 3) - - self.assertEqual(values[0]['max-age'], '500') - self.assertTrue(values[0]['expires']) - - def test_remember_str_max_age_invalid(self): - helper = self._makeOne('secret') - request = self._makeRequest() - self.assertRaises(ValueError, helper.remember, request, 'userid', max_age='invalid value') - - def test_remember_tokens(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 'other', tokens=('foo', 'bar')) - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - self.assertTrue("/tokens=foo|bar/" in result[0][1]) - - self.assertEqual(result[1][0], 'Set-Cookie') - self.assertTrue("/tokens=foo|bar/" in result[1][1]) - - self.assertEqual(result[2][0], 'Set-Cookie') - self.assertTrue("/tokens=foo|bar/" in result[2][1]) - - def test_remember_samesite_nondefault(self): - helper = self._makeOne('secret', samesite='Strict') - request = self._makeRequest() - result = helper.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - cookieval = result[0][1] - self.assertTrue('SameSite=Strict' in - [x.strip() for x in cookieval.split(';')], cookieval) - - self.assertEqual(result[1][0], 'Set-Cookie') - cookieval = result[1][1] - self.assertTrue('SameSite=Strict' in - [x.strip() for x in cookieval.split(';')], cookieval) - - self.assertEqual(result[2][0], 'Set-Cookie') - cookieval = result[2][1] - self.assertTrue('SameSite=Strict' in - [x.strip() for x in cookieval.split(';')], cookieval) - - def test_remember_samesite_default(self): - helper = self._makeOne('secret') - request = self._makeRequest() - result = helper.remember(request, 'userid') - self.assertEqual(len(result), 3) - - self.assertEqual(result[0][0], 'Set-Cookie') - cookieval = result[0][1] - self.assertTrue('SameSite=Lax' in - [x.strip() for x in cookieval.split(';')], cookieval) - - self.assertEqual(result[1][0], 'Set-Cookie') - cookieval = result[1][1] - self.assertTrue('SameSite=Lax' in - [x.strip() for x in cookieval.split(';')], cookieval) - - self.assertEqual(result[2][0], 'Set-Cookie') - cookieval = result[2][1] - self.assertTrue('SameSite=Lax' in - [x.strip() for x in cookieval.split(';')], cookieval) - - def test_remember_unicode_but_ascii_token(self): - helper = self._makeOne('secret') - request = self._makeRequest() - la = text_(b'foo', 'utf-8') - result = helper.remember(request, 'other', tokens=(la,)) - # tokens must be str type on both Python 2 and 3 - self.assertTrue("/tokens=foo/" in result[0][1]) - - def test_remember_nonascii_token(self): - helper = self._makeOne('secret') - request = self._makeRequest() - la = text_(b'La Pe\xc3\xb1a', 'utf-8') - self.assertRaises(ValueError, helper.remember, request, 'other', - tokens=(la,)) - - def test_remember_invalid_token_format(self): - helper = self._makeOne('secret') - request = self._makeRequest() - self.assertRaises(ValueError, helper.remember, request, 'other', - tokens=('foo bar',)) - self.assertRaises(ValueError, helper.remember, request, 'other', - tokens=('1bar',)) - - def test_forget(self): - helper = self._makeOne('secret') - request = self._makeRequest() - headers = helper.forget(request) - self.assertEqual(len(headers), 3) - name, value = headers[0] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual( - value, - 'auth_tkt=; Max-Age=0; Path=/; ' - 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' - ) - name, value = headers[1] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual( - value, - 'auth_tkt=; Domain=localhost; Max-Age=0; Path=/; ' - 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' - ) - name, value = headers[2] - self.assertEqual(name, 'Set-Cookie') - self.assertEqual( - value, - 'auth_tkt=; Domain=.localhost; Max-Age=0; Path=/; ' - 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' - ) - -class TestAuthTicket(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.authentication import AuthTicket - return AuthTicket(*arg, **kw) - - def test_ctor_with_tokens(self): - ticket = self._makeOne('secret', 'userid', 'ip', tokens=('a', 'b')) - self.assertEqual(ticket.tokens, 'a,b') - - def test_ctor_with_time(self): - ticket = self._makeOne('secret', 'userid', 'ip', time='time') - self.assertEqual(ticket.time, 'time') - - def test_digest(self): - ticket = self._makeOne('secret', 'userid', '0.0.0.0', time=10) - result = ticket.digest() - self.assertEqual(result, '126fd6224912187ee9ffa80e0b81420c') - - def test_digest_sha512(self): - ticket = self._makeOne('secret', 'userid', '0.0.0.0', - time=10, hashalg='sha512') - result = ticket.digest() - self.assertEqual(result, '74770b2e0d5b1a54c2a466ec567a40f7d7823576aa49'\ - '3c65fc3445e9b44097f4a80410319ef8cb256a2e60b9'\ - 'c2002e48a9e33a3e8ee4379352c04ef96d2cb278') - - def test_cookie_value(self): - ticket = self._makeOne('secret', 'userid', '0.0.0.0', time=10, - tokens=('a', 'b')) - result = ticket.cookie_value() - self.assertEqual(result, - '66f9cc3e423dc57c91df696cf3d1f0d80000000auserid!a,b!') - - def test_ipv4(self): - ticket = self._makeOne('secret', 'userid', '198.51.100.1', - time=10, hashalg='sha256') - result = ticket.cookie_value() - self.assertEqual(result, 'b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b'\ - '798400ecdade8d76c530000000auserid!') - - def test_ipv6(self): - ticket = self._makeOne('secret', 'userid', '2001:db8::1', - time=10, hashalg='sha256') - result = ticket.cookie_value() - self.assertEqual(result, 'd025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c8'\ - '5becf8760cd7a2fa4910000000auserid!') - -class TestBadTicket(unittest.TestCase): - def _makeOne(self, msg, expected=None): - from pyramid.authentication import BadTicket - return BadTicket(msg, expected) - - def test_it(self): - exc = self._makeOne('msg', expected=True) - self.assertEqual(exc.expected, True) - self.assertTrue(isinstance(exc, Exception)) - -class Test_parse_ticket(unittest.TestCase): - def _callFUT(self, secret, ticket, ip, hashalg='md5'): - from pyramid.authentication import parse_ticket - return parse_ticket(secret, ticket, ip, hashalg) - - def _assertRaisesBadTicket(self, secret, ticket, ip, hashalg='md5'): - from pyramid.authentication import BadTicket - self.assertRaises(BadTicket,self._callFUT, secret, ticket, ip, hashalg) - - def test_bad_timestamp(self): - ticket = 'x' * 64 - self._assertRaisesBadTicket('secret', ticket, 'ip') - - def test_bad_userid_or_data(self): - ticket = 'x' * 32 + '11111111' + 'x' * 10 - self._assertRaisesBadTicket('secret', ticket, 'ip') - - def test_digest_sig_incorrect(self): - ticket = 'x' * 32 + '11111111' + 'a!b!c' - self._assertRaisesBadTicket('secret', ticket, '0.0.0.0') - - def test_correct_with_user_data(self): - ticket = text_('66f9cc3e423dc57c91df696cf3d1f0d80000000auserid!a,b!') - result = self._callFUT('secret', ticket, '0.0.0.0') - self.assertEqual(result, (10, 'userid', ['a', 'b'], '')) - - def test_correct_with_user_data_sha512(self): - ticket = text_('7d947cdef99bad55f8e3382a8bd089bb9dd0547f7925b7d189adc1' - '160cab0ec0e6888faa41eba641a18522b26f19109f3ffafb769767' - 'ba8a26d02aaeae56599a0000000auserid!a,b!') - result = self._callFUT('secret', ticket, '0.0.0.0', 'sha512') - self.assertEqual(result, (10, 'userid', ['a', 'b'], '')) - - def test_ipv4(self): - ticket = text_('b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b798400ecd' - 'ade8d76c530000000auserid!') - result = self._callFUT('secret', ticket, '198.51.100.1', 'sha256') - self.assertEqual(result, (10, 'userid', [''], '')) - - def test_ipv6(self): - ticket = text_('d025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c85becf8760' - 'cd7a2fa4910000000auserid!') - result = self._callFUT('secret', ticket, '2001:db8::1', 'sha256') - self.assertEqual(result, (10, 'userid', [''], '')) - -class TestSessionAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import SessionAuthenticationPolicy - return SessionAuthenticationPolicy - - def _makeOne(self, callback=None, prefix=''): - return self._getTargetClass()(prefix=prefix, callback=callback) - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IAuthenticationPolicy - verifyObject(IAuthenticationPolicy, self._makeOne()) - - def test_unauthenticated_userid_returns_None(self): - request = DummyRequest() - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid(self): - request = DummyRequest(session={'userid':'fred'}) - policy = self._makeOne() - self.assertEqual(policy.unauthenticated_userid(request), 'fred') - - def test_authenticated_userid_no_cookie_identity(self): - request = DummyRequest() - policy = self._makeOne() - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid_callback_returns_None(self): - request = DummyRequest(session={'userid':'fred'}) - def callback(userid, request): - return None - policy = self._makeOne(callback) - self.assertEqual(policy.authenticated_userid(request), None) - - def test_authenticated_userid(self): - request = DummyRequest(session={'userid':'fred'}) - def callback(userid, request): - return True - policy = self._makeOne(callback) - self.assertEqual(policy.authenticated_userid(request), 'fred') - - def test_effective_principals_no_identity(self): - from pyramid.security import Everyone - request = DummyRequest() - policy = self._makeOne() - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals_callback_returns_None(self): - from pyramid.security import Everyone - request = DummyRequest(session={'userid':'fred'}) - def callback(userid, request): - return None - policy = self._makeOne(callback) - self.assertEqual(policy.effective_principals(request), [Everyone]) - - def test_effective_principals(self): - from pyramid.security import Everyone - from pyramid.security import Authenticated - request = DummyRequest(session={'userid':'fred'}) - def callback(userid, request): - return ['group.foo'] - policy = self._makeOne(callback) - self.assertEqual(policy.effective_principals(request), - [Everyone, Authenticated, 'fred', 'group.foo']) - - def test_remember(self): - request = DummyRequest() - policy = self._makeOne() - result = policy.remember(request, 'fred') - self.assertEqual(request.session.get('userid'), 'fred') - self.assertEqual(result, []) - - def test_forget(self): - request = DummyRequest(session={'userid':'fred'}) - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(request.session.get('userid'), None) - self.assertEqual(result, []) - - def test_forget_no_identity(self): - request = DummyRequest() - policy = self._makeOne() - result = policy.forget(request) - self.assertEqual(request.session.get('userid'), None) - self.assertEqual(result, []) - -class TestBasicAuthAuthenticationPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.authentication import BasicAuthAuthenticationPolicy as cls - return cls - - def _makeOne(self, check): - return self._getTargetClass()(check, realm='SomeRealm') - - def test_class_implements_IAuthenticationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthenticationPolicy - verifyClass(IAuthenticationPolicy, self._getTargetClass()) - - def test_unauthenticated_userid(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic %s' % base64.b64encode( - bytes_('chrisr:password')).decode('ascii') - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), 'chrisr') - - def test_unauthenticated_userid_no_credentials(self): - request = testing.DummyRequest() - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_bad_header(self): - request = testing.DummyRequest() - request.headers['Authorization'] = '...' - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid_not_basic(self): - request = testing.DummyRequest() - request.headers['Authorization'] = 'Complicated things' - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_unauthenticated_userid_corrupt_base64(self): - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic chrisr:password' - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_authenticated_userid(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic %s' % base64.b64encode( - bytes_('chrisr:password')).decode('ascii') - def check(username, password, request): - return [] - policy = self._makeOne(check) - self.assertEqual(policy.authenticated_userid(request), 'chrisr') - - def test_authenticated_userid_utf8(self): - import base64 - request = testing.DummyRequest() - inputs = (b'm\xc3\xb6rk\xc3\xb6:' - b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') - request.headers['Authorization'] = 'Basic %s' % ( - base64.b64encode(inputs.encode('utf-8')).decode('latin-1')) - def check(username, password, request): - return [] - policy = self._makeOne(check) - self.assertEqual(policy.authenticated_userid(request), - b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) - - def test_authenticated_userid_latin1(self): - import base64 - request = testing.DummyRequest() - inputs = (b'm\xc3\xb6rk\xc3\xb6:' - b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') - request.headers['Authorization'] = 'Basic %s' % ( - base64.b64encode(inputs.encode('latin-1')).decode('latin-1')) - def check(username, password, request): - return [] - policy = self._makeOne(check) - self.assertEqual(policy.authenticated_userid(request), - b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) - - def test_unauthenticated_userid_invalid_payload(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic %s' % base64.b64encode( - bytes_('chrisrpassword')).decode('ascii') - policy = self._makeOne(None) - self.assertEqual(policy.unauthenticated_userid(request), None) - - def test_remember(self): - policy = self._makeOne(None) - self.assertEqual(policy.remember(None, None), []) - - def test_forget(self): - policy = self._makeOne(None) - self.assertEqual(policy.forget(None), [ - ('WWW-Authenticate', 'Basic realm="SomeRealm"')]) - - -class TestExtractHTTPBasicCredentials(unittest.TestCase): - def _get_func(self): - from pyramid.authentication import extract_http_basic_credentials - return extract_http_basic_credentials - - def test_no_auth_header(self): - request = testing.DummyRequest() - fn = self._get_func() - - self.assertIsNone(fn(request)) - - def test_invalid_payload(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic %s' % base64.b64encode( - bytes_('chrisrpassword')).decode('ascii') - fn = self._get_func() - self.assertIsNone(fn(request)) - - def test_not_a_basic_auth_scheme(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'OtherScheme %s' % base64.b64encode( - bytes_('chrisr:password')).decode('ascii') - fn = self._get_func() - self.assertIsNone(fn(request)) - - def test_no_base64_encoding(self): - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic ...' - fn = self._get_func() - self.assertIsNone(fn(request)) - - def test_latin1_payload(self): - import base64 - request = testing.DummyRequest() - inputs = (b'm\xc3\xb6rk\xc3\xb6:' - b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') - request.headers['Authorization'] = 'Basic %s' % ( - base64.b64encode(inputs.encode('latin-1')).decode('latin-1')) - fn = self._get_func() - self.assertEqual(fn(request), ( - b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8'), - b'm\xc3\xb6rk\xc3\xb6password'.decode('utf-8') - )) - - def test_utf8_payload(self): - import base64 - request = testing.DummyRequest() - inputs = (b'm\xc3\xb6rk\xc3\xb6:' - b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') - request.headers['Authorization'] = 'Basic %s' % ( - base64.b64encode(inputs.encode('utf-8')).decode('latin-1')) - fn = self._get_func() - self.assertEqual(fn(request), ( - b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8'), - b'm\xc3\xb6rk\xc3\xb6password'.decode('utf-8') - )) - - def test_namedtuple_return(self): - import base64 - request = testing.DummyRequest() - request.headers['Authorization'] = 'Basic %s' % base64.b64encode( - bytes_('chrisr:pass')).decode('ascii') - fn = self._get_func() - result = fn(request) - - self.assertEqual(result.username, 'chrisr') - self.assertEqual(result.password, 'pass') - -class DummyContext: - pass - -class DummyCookies(object): - def __init__(self, cookie): - self.cookie = cookie - - def get(self, name): - return self.cookie - -class DummyRequest: - domain = 'localhost' - def __init__(self, environ=None, session=None, registry=None, cookie=None): - self.environ = environ or {} - self.session = session or {} - self.registry = registry - self.callbacks = [] - self.cookies = DummyCookies(cookie) - - def add_response_callback(self, callback): - self.callbacks.append(callback) - -class DummyWhoPlugin: - def remember(self, environ, identity): - return environ, identity - - def forget(self, environ, identity): - return environ, identity - -class DummyCookieHelper: - def __init__(self, result): - self.result = result - - def identify(self, *arg, **kw): - return self.result - - def remember(self, *arg, **kw): - self.kw = kw - return [] - - def forget(self, *arg): - return [] - -class DummyAuthTktModule(object): - def __init__(self, timestamp=0, userid='userid', tokens=(), user_data='', - parse_raise=False, hashalg="md5"): - self.timestamp = timestamp - self.userid = userid - self.tokens = tokens - self.user_data = user_data - self.parse_raise = parse_raise - self.hashalg = hashalg - def parse_ticket(secret, value, remote_addr, hashalg): - self.secret = secret - self.value = value - self.remote_addr = remote_addr - if self.parse_raise: - raise self.BadTicket() - return self.timestamp, self.userid, self.tokens, self.user_data - self.parse_ticket = parse_ticket - - class AuthTicket(object): - def __init__(self, secret, userid, remote_addr, **kw): - self.secret = secret - self.userid = userid - self.remote_addr = remote_addr - self.kw = kw - - def cookie_value(self): - result = { - 'secret':self.secret, - 'userid':self.userid, - 'remote_addr':self.remote_addr - } - result.update(self.kw) - tokens = result.pop('tokens', None) - if tokens is not None: - tokens = '|'.join(tokens) - result['tokens'] = tokens - items = sorted(result.items()) - new_items = [] - for k, v in items: - if isinstance(v, bytes): - v = text_(v) - new_items.append((k,v)) - result = '/'.join(['%s=%s' % (k, v) for k,v in new_items ]) - return result - self.AuthTicket = AuthTicket - - class BadTicket(Exception): - pass - -class DummyResponse: - def __init__(self): - self.headerlist = [] - diff --git a/src/pyramid/tests/test_authorization.py b/src/pyramid/tests/test_authorization.py deleted file mode 100644 index 05cd3b4f8..000000000 --- a/src/pyramid/tests/test_authorization.py +++ /dev/null @@ -1,259 +0,0 @@ -import unittest - -from pyramid.testing import cleanUp - -class TestACLAuthorizationPolicy(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from pyramid.authorization import ACLAuthorizationPolicy - return ACLAuthorizationPolicy - - def _makeOne(self): - return self._getTargetClass()() - - def test_class_implements_IAuthorizationPolicy(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IAuthorizationPolicy - verifyClass(IAuthorizationPolicy, self._getTargetClass()) - - def test_instance_implements_IAuthorizationPolicy(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IAuthorizationPolicy - verifyObject(IAuthorizationPolicy, self._makeOne()) - - def test_permits_no_acl(self): - context = DummyContext() - policy = self._makeOne() - self.assertEqual(policy.permits(context, [], 'view'), False) - - def test_permits(self): - from pyramid.security import Deny - from pyramid.security import Allow - from pyramid.security import Everyone - from pyramid.security import Authenticated - from pyramid.security import ALL_PERMISSIONS - from pyramid.security import DENY_ALL - root = DummyContext() - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ - (Allow, Authenticated, VIEW), - ] - community.__acl__ = [ - (Allow, 'fred', ALL_PERMISSIONS), - (Allow, 'wilma', VIEW), - DENY_ALL, - ] - blog.__acl__ = [ - (Allow, 'barney', MEMBER_PERMS), - (Allow, 'wilma', VIEW), - ] - - policy = self._makeOne() - - result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) - self.assertEqual(result.acl, blog.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], - 'delete') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'fred'], 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - result = policy.permits(blog, [Everyone, Authenticated, 'fred'], - 'doesntevenexistyet') - self.assertEqual(result, True) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(blog, [Everyone, Authenticated, 'barney'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, blog) - self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) - result = policy.permits(blog, [Everyone, Authenticated, 'barney'], - 'administer') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(root, [Everyone, Authenticated, 'someguy'], - 'view') - self.assertEqual(result, True) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) - result = policy.permits(blog, - [Everyone, Authenticated, 'someguy'], 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, community) - self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) - self.assertEqual(result.acl, community.__acl__) - - result = policy.permits(root, [Everyone], 'view') - self.assertEqual(result, False) - self.assertEqual(result.context, root) - self.assertEqual(result.ace, '') - self.assertEqual(result.acl, root.__acl__) - - context = DummyContext() - result = policy.permits(context, [Everyone], 'view') - self.assertEqual(result, False) - self.assertEqual(result.ace, '') - self.assertEqual( - result.acl, - '') - - def test_permits_string_permissions_in_acl(self): - from pyramid.security import Allow - root = DummyContext() - root.__acl__ = [ - (Allow, 'wilma', 'view_stuff'), - ] - - policy = self._makeOne() - - result = policy.permits(root, ['wilma'], 'view') - # would be True if matching against 'view_stuff' instead of against - # ['view_stuff'] - self.assertEqual(result, False) - - def test_principals_allowed_by_permission_direct(self): - from pyramid.security import Allow - from pyramid.security import DENY_ALL - context = DummyContext() - acl = [ (Allow, 'chrism', ('read', 'write')), - DENY_ALL, - (Allow, 'other', 'read') ] - context.__acl__ = acl - policy = self._makeOne() - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, ['chrism']) - - def test_principals_allowed_by_permission_callable_acl(self): - from pyramid.security import Allow - from pyramid.security import DENY_ALL - context = DummyContext() - acl = lambda: [ (Allow, 'chrism', ('read', 'write')), - DENY_ALL, - (Allow, 'other', 'read') ] - context.__acl__ = acl - policy = self._makeOne() - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, ['chrism']) - - def test_principals_allowed_by_permission_string_permission(self): - from pyramid.security import Allow - context = DummyContext() - acl = [ (Allow, 'chrism', 'read_it')] - context.__acl__ = acl - policy = self._makeOne() - result = policy.principals_allowed_by_permission(context, 'read') - # would be ['chrism'] if 'read' were compared against 'read_it' instead - # of against ['read_it'] - self.assertEqual(list(result), []) - - def test_principals_allowed_by_permission(self): - from pyramid.security import Allow - from pyramid.security import Deny - from pyramid.security import DENY_ALL - from pyramid.security import ALL_PERMISSIONS - root = DummyContext(__name__='', __parent__=None) - community = DummyContext(__name__='community', __parent__=root) - blog = DummyContext(__name__='blog', __parent__=community) - root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), - (Allow, 'other', ('read',)), - (Allow, 'jim', ALL_PERMISSIONS)] - community.__acl__ = [ (Deny, 'flooz', 'read'), - (Allow, 'flooz', 'read'), - (Allow, 'mork', 'read'), - (Deny, 'jim', 'read'), - (Allow, 'someguy', 'manage')] - blog.__acl__ = [ (Allow, 'fred', 'read'), - DENY_ALL] - - policy = self._makeOne() - - result = sorted(policy.principals_allowed_by_permission(blog, 'read')) - self.assertEqual(result, ['fred']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - self.assertEqual(result, ['chrism', 'mork', 'other']) - result = sorted(policy.principals_allowed_by_permission(community, - 'read')) - result = sorted(policy.principals_allowed_by_permission(root, 'read')) - self.assertEqual(result, ['chrism', 'jim', 'other']) - - def test_principals_allowed_by_permission_no_acls(self): - context = DummyContext() - policy = self._makeOne() - result = sorted(policy.principals_allowed_by_permission(context,'read')) - self.assertEqual(result, []) - - def test_principals_allowed_by_permission_deny_not_permission_in_acl(self): - from pyramid.security import Deny - from pyramid.security import Everyone - context = DummyContext() - acl = [ (Deny, Everyone, 'write') ] - context.__acl__ = acl - policy = self._makeOne() - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, []) - - def test_principals_allowed_by_permission_deny_permission_in_acl(self): - from pyramid.security import Deny - from pyramid.security import Everyone - context = DummyContext() - acl = [ (Deny, Everyone, 'read') ] - context.__acl__ = acl - policy = self._makeOne() - result = sorted( - policy.principals_allowed_by_permission(context, 'read')) - self.assertEqual(result, []) - - def test_callable_acl(self): - from pyramid.security import Allow - context = DummyContext() - fn = lambda self: [(Allow, 'bob', 'read')] - context.__acl__ = fn.__get__(context, context.__class__) - policy = self._makeOne() - result = policy.permits(context, ['bob'], 'read') - self.assertTrue(result) - - -class DummyContext: - def __init__(self, *arg, **kw): - self.__dict__.update(kw) - - -VIEW = 'view' -EDIT = 'edit' -CREATE = 'create' -DELETE = 'delete' -MODERATE = 'moderate' -ADMINISTER = 'administer' -COMMENT = 'comment' - -GUEST_PERMS = (VIEW, COMMENT) -MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) -MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) -ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) - diff --git a/src/pyramid/tests/test_compat.py b/src/pyramid/tests/test_compat.py deleted file mode 100644 index 23ccce82e..000000000 --- a/src/pyramid/tests/test_compat.py +++ /dev/null @@ -1,26 +0,0 @@ -import unittest -from pyramid.compat import is_unbound_method - -class TestUnboundMethods(unittest.TestCase): - def test_old_style_bound(self): - self.assertFalse(is_unbound_method(OldStyle().run)) - - def test_new_style_bound(self): - self.assertFalse(is_unbound_method(NewStyle().run)) - - def test_old_style_unbound(self): - self.assertTrue(is_unbound_method(OldStyle.run)) - - def test_new_style_unbound(self): - self.assertTrue(is_unbound_method(NewStyle.run)) - - def test_normal_func_unbound(self): - def func(): return 'OK' - - self.assertFalse(is_unbound_method(func)) - -class OldStyle: - def run(self): return 'OK' - -class NewStyle(object): - def run(self): return 'OK' diff --git a/src/pyramid/tests/test_config/__init__.py b/src/pyramid/tests/test_config/__init__.py deleted file mode 100644 index 81d9f4965..000000000 --- a/src/pyramid/tests/test_config/__init__.py +++ /dev/null @@ -1,53 +0,0 @@ -# package - -from zope.interface import implementer -from zope.interface import Interface - -class IFactory(Interface): - pass - -def dummy_tween_factory(handler, registry): pass - -def dummy_tween_factory2(handler, registry): pass - -def dummy_include(config): - config.registry.included = True - config.action('discrim', None, config.package) - -def dummy_include2(config): - config.registry.also_included = True - config.action('discrim', None, config.package) - -includeme = dummy_include - -class DummyContext: - pass - -@implementer(IFactory) -class DummyFactory(object): - def __call__(self): - """ """ - -def dummyfactory(request): - """ """ - -class IDummy(Interface): - pass - -def dummy_view(request): - return 'OK' - -def dummy_extend(config, discrim): - config.action(discrim, None, config.package) - -def dummy_extend2(config, discrim): - config.action(discrim, None, config.registry) - -from functools import partial -dummy_partial = partial(dummy_extend, discrim='partial') - -class DummyCallable(object): - def __call__(self, config, discrim): - config.action(discrim, None, config.package) -dummy_callable = DummyCallable() - diff --git a/src/pyramid/tests/test_config/files/assets/dummy.txt b/src/pyramid/tests/test_config/files/assets/dummy.txt deleted file mode 100644 index 18832d351..000000000 --- a/src/pyramid/tests/test_config/files/assets/dummy.txt +++ /dev/null @@ -1 +0,0 @@ -Hello. diff --git a/src/pyramid/tests/test_config/files/minimal.txt b/src/pyramid/tests/test_config/files/minimal.txt deleted file mode 100644 index 19fe66dfa..000000000 --- a/src/pyramid/tests/test_config/files/minimal.txt +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/src/pyramid/tests/test_config/path/scanerror/__init__.py b/src/pyramid/tests/test_config/path/scanerror/__init__.py deleted file mode 100644 index 86770ad89..000000000 --- a/src/pyramid/tests/test_config/path/scanerror/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# scan error package - - diff --git a/src/pyramid/tests/test_config/path/scanerror/will_raise_error.py b/src/pyramid/tests/test_config/path/scanerror/will_raise_error.py deleted file mode 100644 index 9098ff1fe..000000000 --- a/src/pyramid/tests/test_config/path/scanerror/will_raise_error.py +++ /dev/null @@ -1 +0,0 @@ -import wont.exist diff --git a/src/pyramid/tests/test_config/pkgs/__init__.py b/src/pyramid/tests/test_config/pkgs/__init__.py deleted file mode 100644 index ed88d78b4..000000000 --- a/src/pyramid/tests/test_config/pkgs/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# package - diff --git a/src/pyramid/tests/test_config/pkgs/asset/__init__.py b/src/pyramid/tests/test_config/pkgs/asset/__init__.py deleted file mode 100644 index db5619fbc..000000000 --- a/src/pyramid/tests/test_config/pkgs/asset/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# package - - diff --git a/src/pyramid/tests/test_config/pkgs/asset/subpackage/__init__.py b/src/pyramid/tests/test_config/pkgs/asset/subpackage/__init__.py deleted file mode 100644 index d3173e636..000000000 --- a/src/pyramid/tests/test_config/pkgs/asset/subpackage/__init__.py +++ /dev/null @@ -1 +0,0 @@ -#package diff --git a/src/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt b/src/pyramid/tests/test_config/pkgs/asset/subpackage/templates/bar.pt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/pyramid/tests/test_config/pkgs/scanextrakw/__init__.py b/src/pyramid/tests/test_config/pkgs/scanextrakw/__init__.py deleted file mode 100644 index ce5e07238..000000000 --- a/src/pyramid/tests/test_config/pkgs/scanextrakw/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -import venusian - -def foo(wrapped): - def bar(scanner, name, wrapped): - scanner.config.a = scanner.a - venusian.attach(wrapped, bar) - return wrapped - -@foo -def hello(): - pass - -hello() # appease coverage - diff --git a/src/pyramid/tests/test_config/pkgs/scannable/__init__.py b/src/pyramid/tests/test_config/pkgs/scannable/__init__.py deleted file mode 100644 index 562413a41..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/__init__.py +++ /dev/null @@ -1,96 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(renderer=null_renderer) -def grokked(context, request): - return 'grokked' - -@view_config(request_method='POST', renderer=null_renderer) -def grokked_post(context, request): - return 'grokked_post' - -@view_config(name='stacked2', renderer=null_renderer) -@view_config(name='stacked1', renderer=null_renderer) -def stacked(context, request): - return 'stacked' - -class stacked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'stacked_class' - -stacked_class = view_config(name='stacked_class1', - renderer=null_renderer)(stacked_class) -stacked_class = view_config(name='stacked_class2', - renderer=null_renderer)(stacked_class) - -class oldstyle_grokked_class: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'oldstyle_grokked_class' - -oldstyle_grokked_class = view_config(name='oldstyle_grokked_class', - renderer=null_renderer)( - oldstyle_grokked_class) - -class grokked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'grokked_class' - -grokked_class = view_config(name='grokked_class', - renderer=null_renderer)(grokked_class) - -class Foo(object): - def __call__(self, context, request): - return 'grokked_instance' - -grokked_instance = Foo() -grokked_instance = view_config(name='grokked_instance', - renderer=null_renderer)(grokked_instance) - -class Base(object): - @view_config(name='basemethod', renderer=null_renderer) - def basemethod(self): - """ """ - -class MethodViews(Base): - def __init__(self, context, request): - self.context = context - self.request = request - - @view_config(name='method1', renderer=null_renderer) - def method1(self): - return 'method1' - - @view_config(name='method2', renderer=null_renderer) - def method2(self): - return 'method2' - - @view_config(name='stacked_method2', renderer=null_renderer) - @view_config(name='stacked_method1', renderer=null_renderer) - def stacked(self): - return 'stacked_method' - -# ungrokkable - -A = 1 -B = {} - -def stuff(): - """ """ - -class Whatever(object): - pass - -class Whatever2: - pass diff --git a/src/pyramid/tests/test_config/pkgs/scannable/another.py b/src/pyramid/tests/test_config/pkgs/scannable/another.py deleted file mode 100644 index 529821b5c..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/another.py +++ /dev/null @@ -1,69 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(name='another', renderer=null_renderer) -def grokked(context, request): - return 'another_grokked' - -@view_config(request_method='POST', name='another', renderer=null_renderer) -def grokked_post(context, request): - return 'another_grokked_post' - -@view_config(name='another_stacked2', renderer=null_renderer) -@view_config(name='another_stacked1', renderer=null_renderer) -def stacked(context, request): - return 'another_stacked' - -class stacked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_stacked_class' - -stacked_class = view_config(name='another_stacked_class1', - renderer=null_renderer)(stacked_class) -stacked_class = view_config(name='another_stacked_class2', - renderer=null_renderer)(stacked_class) - -class oldstyle_grokked_class: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_oldstyle_grokked_class' - -oldstyle_grokked_class = view_config(name='another_oldstyle_grokked_class', - renderer=null_renderer)( - oldstyle_grokked_class) - -class grokked_class(object): - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'another_grokked_class' - -grokked_class = view_config(name='another_grokked_class', - renderer=null_renderer)(grokked_class) - -class Foo(object): - def __call__(self, context, request): - return 'another_grokked_instance' - -grokked_instance = Foo() -grokked_instance = view_config(name='another_grokked_instance', - renderer=null_renderer)( - grokked_instance) - -# ungrokkable - -A = 1 -B = {} - -def stuff(): - """ """ - diff --git a/src/pyramid/tests/test_config/pkgs/scannable/pod/notinit.py b/src/pyramid/tests/test_config/pkgs/scannable/pod/notinit.py deleted file mode 100644 index 91dcd161b..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/pod/notinit.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(name='pod_notinit', renderer=null_renderer) -def subpackage_notinit(context, request): - return 'pod_notinit' diff --git a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/__init__.py b/src/pyramid/tests/test_config/pkgs/scannable/subpackage/__init__.py deleted file mode 100644 index 9e0ddacbd..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(name='subpackage_init', renderer=null_renderer) -def subpackage_init(context, request): - return 'subpackage_init' diff --git a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/notinit.py b/src/pyramid/tests/test_config/pkgs/scannable/subpackage/notinit.py deleted file mode 100644 index f7edd0c68..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/notinit.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(name='subpackage_notinit', renderer=null_renderer) -def subpackage_notinit(context, request): - return 'subpackage_notinit' diff --git a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py b/src/pyramid/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py deleted file mode 100644 index fdda0dffe..000000000 --- a/src/pyramid/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config -from pyramid.renderers import null_renderer - -@view_config(name='subsubpackage_init', renderer=null_renderer) -def subpackage_init(context, request): - return 'subsubpackage_init' diff --git a/src/pyramid/tests/test_config/pkgs/selfscan/__init__.py b/src/pyramid/tests/test_config/pkgs/selfscan/__init__.py deleted file mode 100644 index 779ea3eed..000000000 --- a/src/pyramid/tests/test_config/pkgs/selfscan/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -from pyramid.view import view_config - -@view_config(renderer='string') -def abc(request): - return 'root' - -def main(): - from pyramid.config import Configurator - c = Configurator() - c.scan() - return c diff --git a/src/pyramid/tests/test_config/pkgs/selfscan/another.py b/src/pyramid/tests/test_config/pkgs/selfscan/another.py deleted file mode 100644 index a30ad3297..000000000 --- a/src/pyramid/tests/test_config/pkgs/selfscan/another.py +++ /dev/null @@ -1,6 +0,0 @@ -from pyramid.view import view_config - -@view_config(name='two', renderer='string') -def two(request): - return 'two' - diff --git a/src/pyramid/tests/test_config/test_adapters.py b/src/pyramid/tests/test_config/test_adapters.py deleted file mode 100644 index ab5d6ef61..000000000 --- a/src/pyramid/tests/test_config/test_adapters.py +++ /dev/null @@ -1,365 +0,0 @@ -import unittest - -from pyramid.compat import PY2 -from pyramid.tests.test_config import IDummy - -class AdaptersConfiguratorMixinTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_add_subscriber_defaults(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne(autocommit=True) - config.add_subscriber(subscriber) - event = Event() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 2) - - def test_add_subscriber_iface_specified(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne(autocommit=True) - config.add_subscriber(subscriber, IEvent) - event = Event() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_add_subscriber_dottednames(self): - import pyramid.tests.test_config - from pyramid.interfaces import INewRequest - config = self._makeOne(autocommit=True) - config.add_subscriber('pyramid.tests.test_config', - 'pyramid.interfaces.INewRequest') - handlers = list(config.registry.registeredHandlers()) - self.assertEqual(len(handlers), 1) - handler = handlers[0] - self.assertEqual(handler.handler, pyramid.tests.test_config) - self.assertEqual(handler.required, (INewRequest,)) - - def test_add_object_event_subscriber(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - object = 'foo' - event = Event() - L = [] - def subscriber(object, event): - L.append(event) - config = self._makeOne(autocommit=True) - config.add_subscriber(subscriber, (Interface, IEvent)) - config.registry.subscribers((event.object, event), None) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.subscribers((event.object, IDummy), None) - self.assertEqual(len(L), 1) - - def test_add_subscriber_with_specific_type_and_predicates_True(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne(autocommit=True) - predlist = config.get_predlist('subscriber') - jam_predicate = predicate_maker('jam') - jim_predicate = predicate_maker('jim') - predlist.add('jam', jam_predicate) - predlist.add('jim', jim_predicate) - config.add_subscriber(subscriber, IEvent, jam=True, jim=True) - event = Event() - event.jam = True - event.jim = True - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_add_subscriber_with_default_type_predicates_True(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): - L.append(event) - config = self._makeOne(autocommit=True) - predlist = config.get_predlist('subscriber') - jam_predicate = predicate_maker('jam') - jim_predicate = predicate_maker('jim') - predlist.add('jam', jam_predicate) - predlist.add('jim', jim_predicate) - config.add_subscriber(subscriber, jam=True, jim=True) - event = Event() - event.jam = True - event.jim = True - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_add_subscriber_with_specific_type_and_predicates_False(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): L.append(event) - config = self._makeOne(autocommit=True) - predlist = config.get_predlist('subscriber') - jam_predicate = predicate_maker('jam') - jim_predicate = predicate_maker('jim') - predlist.add('jam', jam_predicate) - predlist.add('jim', jim_predicate) - config.add_subscriber(subscriber, IEvent, jam=True, jim=True) - event = Event() - event.jam = True - event.jim = False - config.registry.notify(event) - self.assertEqual(len(L), 0) - - def test_add_subscriber_with_default_type_predicates_False(self): - from zope.interface import implementer - from zope.interface import Interface - class IEvent(Interface): - pass - @implementer(IEvent) - class Event: - pass - L = [] - def subscriber(event): L.append(event) - config = self._makeOne(autocommit=True) - predlist = config.get_predlist('subscriber') - jam_predicate = predicate_maker('jam') - jim_predicate = predicate_maker('jim') - predlist.add('jam', jam_predicate) - predlist.add('jim', jim_predicate) - config.add_subscriber(subscriber, jam=True, jim=True) - event = Event() - event.jam = False - event.jim = True - config.registry.notify(event) - self.assertEqual(len(L), 0) - - def test_add_subscriber_predicate(self): - config = self._makeOne() - L = [] - def add_predicate(type, name, factory, weighs_less_than=None, - weighs_more_than=None): - self.assertEqual(type, 'subscriber') - self.assertEqual(name, 'name') - self.assertEqual(factory, 'factory') - self.assertEqual(weighs_more_than, 1) - self.assertEqual(weighs_less_than, 2) - L.append(1) - config._add_predicate = add_predicate - config.add_subscriber_predicate('name', 'factory', 1, 2) - self.assertTrue(L) - - def test_add_response_adapter(self): - from pyramid.interfaces import IResponse - config = self._makeOne(autocommit=True) - class Adapter(object): - def __init__(self, other): - self.other = other - config.add_response_adapter(Adapter, str) - result = config.registry.queryAdapter('foo', IResponse) - self.assertTrue(result.other, 'foo') - - def test_add_response_adapter_self(self): - from pyramid.interfaces import IResponse - config = self._makeOne(autocommit=True) - class Adapter(object): - pass - config.add_response_adapter(None, Adapter) - adapter = Adapter() - result = config.registry.queryAdapter(adapter, IResponse) - self.assertTrue(result is adapter) - - def test_add_response_adapter_dottednames(self): - from pyramid.interfaces import IResponse - config = self._makeOne(autocommit=True) - if PY2: - str_name = '__builtin__.str' - else: - str_name = 'builtins.str' - config.add_response_adapter('pyramid.response.Response', str_name) - result = config.registry.queryAdapter('foo', IResponse) - self.assertTrue(result.body, b'foo') - - def test_add_traverser_dotted_names(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser( - 'pyramid.tests.test_config.test_adapters.DummyTraverser', - 'pyramid.tests.test_config.test_adapters.DummyIface') - iface = DummyIface() - traverser = config.registry.getAdapter(iface, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - self.assertEqual(traverser.root, iface) - - def test_add_traverser_default_iface_means_Interface(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser(DummyTraverser) - traverser = config.registry.getAdapter(None, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - - def test_add_traverser_nondefault_iface(self): - from pyramid.interfaces import ITraverser - config = self._makeOne(autocommit=True) - config.add_traverser(DummyTraverser, DummyIface) - iface = DummyIface() - traverser = config.registry.getAdapter(iface, ITraverser) - self.assertEqual(traverser.__class__, DummyTraverser) - self.assertEqual(traverser.root, iface) - - def test_add_traverser_introspectables(self): - config = self._makeOne() - config.add_traverser(DummyTraverser, DummyIface) - actions = config.action_state.actions - self.assertEqual(len(actions), 1) - intrs = actions[0]['introspectables'] - self.assertEqual(len(intrs), 1) - intr = intrs[0] - self.assertEqual(intr.type_name, 'traverser') - self.assertEqual(intr.discriminator, ('traverser', DummyIface)) - self.assertEqual(intr.category_name, 'traversers') - self.assertEqual(intr.title, 'traverser for %r' % DummyIface) - self.assertEqual(intr['adapter'], DummyTraverser) - self.assertEqual(intr['iface'], DummyIface) - - def test_add_resource_url_adapter_dotted_names(self): - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter( - 'pyramid.tests.test_config.test_adapters.DummyResourceURL', - 'pyramid.tests.test_config.test_adapters.DummyIface', - ) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - - def test_add_resource_url_default_resource_iface_means_Interface(self): - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter(DummyResourceURL) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - - def test_add_resource_url_nodefault_resource_iface(self): - from zope.interface import Interface - from pyramid.interfaces import IResourceURL - config = self._makeOne(autocommit=True) - config.add_resource_url_adapter(DummyResourceURL, DummyIface) - iface = DummyIface() - adapter = config.registry.getMultiAdapter((iface, iface), - IResourceURL) - self.assertEqual(adapter.__class__, DummyResourceURL) - self.assertEqual(adapter.resource, iface) - self.assertEqual(adapter.request, iface) - bad_result = config.registry.queryMultiAdapter( - (Interface, Interface), - IResourceURL, - ) - self.assertEqual(bad_result, None) - - def test_add_resource_url_adapter_introspectables(self): - config = self._makeOne() - config.add_resource_url_adapter(DummyResourceURL, DummyIface) - actions = config.action_state.actions - self.assertEqual(len(actions), 1) - intrs = actions[0]['introspectables'] - self.assertEqual(len(intrs), 1) - intr = intrs[0] - self.assertEqual(intr.type_name, 'resource url adapter') - self.assertEqual(intr.discriminator, - ('resource url adapter', DummyIface)) - self.assertEqual(intr.category_name, 'resource url adapters') - self.assertEqual( - intr.title, - "resource url adapter for resource iface " - "" - ) - self.assertEqual(intr['adapter'], DummyResourceURL) - self.assertEqual(intr['resource_iface'], DummyIface) - -class Test_eventonly(unittest.TestCase): - def _callFUT(self, callee): - from pyramid.config.adapters import eventonly - return eventonly(callee) - - def test_defaults(self): - def acallable(event, a=1, b=2): pass - self.assertTrue(self._callFUT(acallable)) - -class DummyTraverser(object): - def __init__(self, root): - self.root = root - -class DummyIface(object): - pass - -class DummyResourceURL(object): - def __init__(self, resource, request): - self.resource = resource - self.request = request - -def predicate_maker(name): - class Predicate(object): - def __init__(self, val, config): - self.val = val - def phash(self): - return 'phash' - text = phash - def __call__(self, event): - return getattr(event, name, None) == self.val - return Predicate - diff --git a/src/pyramid/tests/test_config/test_assets.py b/src/pyramid/tests/test_config/test_assets.py deleted file mode 100644 index 842c73da6..000000000 --- a/src/pyramid/tests/test_config/test_assets.py +++ /dev/null @@ -1,945 +0,0 @@ -import os.path -import unittest -from pyramid.testing import cleanUp - -# we use this folder -here = os.path.dirname(os.path.abspath(__file__)) - -class TestAssetsConfiguratorMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_override_asset_samename(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, 'a', 'a') - - def test_override_asset_directory_with_file(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo/', - 'pyramid.tests.test_config.pkgs.asset:foo.pt') - - def test_override_asset_file_with_directory(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo.pt', - 'pyramid.tests.test_config.pkgs.asset:templates/') - - def test_override_asset_file_with_package(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo.pt', - 'pyramid.tests.test_config.pkgs.asset') - - def test_override_asset_file_with_file(self): - from pyramid.config.assets import PackageAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset:templates/foo.pt', - 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/bar.pt', - _override=override) - from pyramid.tests.test_config.pkgs import asset - from pyramid.tests.test_config.pkgs.asset import subpackage - self.assertEqual(override.package, asset) - self.assertEqual(override.path, 'templates/foo.pt') - source = override.source - self.assertTrue(isinstance(source, PackageAssetSource)) - self.assertEqual(source.package, subpackage) - self.assertEqual(source.prefix, 'templates/bar.pt') - - resource_name = '' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_package_with_package(self): - from pyramid.config.assets import PackageAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset', - 'pyramid.tests.test_config.pkgs.asset.subpackage', - _override=override) - from pyramid.tests.test_config.pkgs import asset - from pyramid.tests.test_config.pkgs.asset import subpackage - self.assertEqual(override.package, asset) - self.assertEqual(override.path, '') - source = override.source - self.assertTrue(isinstance(source, PackageAssetSource)) - self.assertEqual(source.package, subpackage) - self.assertEqual(source.prefix, '') - - resource_name = 'templates/bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_directory_with_directory(self): - from pyramid.config.assets import PackageAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset:templates/', - 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/', - _override=override) - from pyramid.tests.test_config.pkgs import asset - from pyramid.tests.test_config.pkgs.asset import subpackage - self.assertEqual(override.package, asset) - self.assertEqual(override.path, 'templates/') - source = override.source - self.assertTrue(isinstance(source, PackageAssetSource)) - self.assertEqual(source.package, subpackage) - self.assertEqual(source.prefix, 'templates/') - - resource_name = 'bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_directory_with_package(self): - from pyramid.config.assets import PackageAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset:templates/', - 'pyramid.tests.test_config.pkgs.asset.subpackage', - _override=override) - from pyramid.tests.test_config.pkgs import asset - from pyramid.tests.test_config.pkgs.asset import subpackage - self.assertEqual(override.package, asset) - self.assertEqual(override.path, 'templates/') - source = override.source - self.assertTrue(isinstance(source, PackageAssetSource)) - self.assertEqual(source.package, subpackage) - self.assertEqual(source.prefix, '') - - resource_name = 'templates/bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_package_with_directory(self): - from pyramid.config.assets import PackageAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset', - 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/', - _override=override) - from pyramid.tests.test_config.pkgs import asset - from pyramid.tests.test_config.pkgs.asset import subpackage - self.assertEqual(override.package, asset) - self.assertEqual(override.path, '') - source = override.source - self.assertTrue(isinstance(source, PackageAssetSource)) - self.assertEqual(source.package, subpackage) - self.assertEqual(source.prefix, 'templates/') - - resource_name = 'bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_directory_with_absfile(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo/', - os.path.join(here, 'pkgs', 'asset', 'foo.pt')) - - def test_override_asset_file_with_absdirectory(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo.pt', - abspath) - - def test_override_asset_file_with_missing_abspath(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.override_asset, - 'a:foo.pt', - os.path.join(here, 'wont_exist')) - - def test_override_asset_file_with_absfile(self): - from pyramid.config.assets import FSAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', - 'templates', 'bar.pt') - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset:templates/foo.pt', - abspath, - _override=override) - from pyramid.tests.test_config.pkgs import asset - self.assertEqual(override.package, asset) - self.assertEqual(override.path, 'templates/foo.pt') - source = override.source - self.assertTrue(isinstance(source, FSAssetSource)) - self.assertEqual(source.prefix, abspath) - - resource_name = '' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_directory_with_absdirectory(self): - from pyramid.config.assets import FSAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset:templates/', - abspath, - _override=override) - from pyramid.tests.test_config.pkgs import asset - self.assertEqual(override.package, asset) - self.assertEqual(override.path, 'templates/') - source = override.source - self.assertTrue(isinstance(source, FSAssetSource)) - self.assertEqual(source.prefix, abspath) - - resource_name = 'bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test_override_asset_package_with_absdirectory(self): - from pyramid.config.assets import FSAssetSource - config = self._makeOne(autocommit=True) - override = DummyUnderOverride() - abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') - config.override_asset( - 'pyramid.tests.test_config.pkgs.asset', - abspath, - _override=override) - from pyramid.tests.test_config.pkgs import asset - self.assertEqual(override.package, asset) - self.assertEqual(override.path, '') - source = override.source - self.assertTrue(isinstance(source, FSAssetSource)) - self.assertEqual(source.prefix, abspath) - - resource_name = 'bar.pt' - expected = os.path.join(here, 'pkgs', 'asset', - 'subpackage', 'templates', 'bar.pt') - self.assertEqual(override.source.get_filename(resource_name), - expected) - - def test__override_not_yet_registered(self): - from pyramid.interfaces import IPackageOverrides - package = DummyPackage('package') - source = DummyAssetSource() - config = self._makeOne() - config._override(package, 'path', source, - PackageOverrides=DummyPackageOverrides) - overrides = config.registry.queryUtility(IPackageOverrides, - name='package') - self.assertEqual(overrides.inserted, [('path', source)]) - self.assertEqual(overrides.package, package) - - def test__override_already_registered(self): - from pyramid.interfaces import IPackageOverrides - package = DummyPackage('package') - source = DummyAssetSource() - overrides = DummyPackageOverrides(package) - config = self._makeOne() - config.registry.registerUtility(overrides, IPackageOverrides, - name='package') - config._override(package, 'path', source, - PackageOverrides=DummyPackageOverrides) - self.assertEqual(overrides.inserted, [('path', source)]) - self.assertEqual(overrides.package, package) - - -class TestOverrideProvider(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from pyramid.config.assets import OverrideProvider - return OverrideProvider - - def _makeOne(self, module): - klass = self._getTargetClass() - return klass(module) - - def _registerOverrides(self, overrides, name='pyramid.tests.test_config'): - from pyramid.interfaces import IPackageOverrides - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - reg.registerUtility(overrides, IPackageOverrides, name=name) - - def test_get_resource_filename_no_overrides(self): - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_get_resource_stream_no_overrides(self): - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - with provider.get_resource_stream(None, resource_name) as result: - _assertBody(result.read(), os.path.join(here, resource_name)) - - def test_get_resource_string_no_overrides(self): - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.get_resource_string(None, resource_name) - _assertBody(result, os.path.join(here, resource_name)) - - def test_has_resource_no_overrides(self): - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.has_resource(resource_name) - self.assertEqual(result, True) - - def test_resource_isdir_no_overrides(self): - file_resource_name = 'test_assets.py' - directory_resource_name = 'files' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_isdir(file_resource_name) - self.assertEqual(result, False) - result = provider.resource_isdir(directory_resource_name) - self.assertEqual(result, True) - - def test_resource_listdir_no_overrides(self): - resource_name = 'files' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_listdir(resource_name) - self.assertTrue(result) - - def test_get_resource_filename_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - expected = os.path.join(here, resource_name) - result = provider.get_resource_filename(None, resource_name) - self.assertEqual(result, expected) - - def test_get_resource_stream_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - with provider.get_resource_stream(None, resource_name) as result: - _assertBody(result.read(), os.path.join(here, resource_name)) - - def test_get_resource_string_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.get_resource_string(None, resource_name) - _assertBody(result, os.path.join(here, resource_name)) - - def test_has_resource_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'test_assets.py' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.has_resource(resource_name) - self.assertEqual(result, True) - - def test_resource_isdir_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'files' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_isdir(resource_name) - self.assertEqual(result, True) - - def test_resource_listdir_override_returns_None(self): - overrides = DummyOverrides(None) - self._registerOverrides(overrides) - resource_name = 'files' - import pyramid.tests.test_config - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_listdir(resource_name) - self.assertTrue(result) - - def test_get_resource_filename_override_returns_value(self): - overrides = DummyOverrides('value') - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - result = provider.get_resource_filename(None, 'test_assets.py') - self.assertEqual(result, 'value') - - def test_get_resource_stream_override_returns_value(self): - from io import BytesIO - overrides = DummyOverrides(BytesIO(b'value')) - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - with provider.get_resource_stream(None, 'test_assets.py') as stream: - self.assertEqual(stream.getvalue(), b'value') - - def test_get_resource_string_override_returns_value(self): - overrides = DummyOverrides('value') - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - result = provider.get_resource_string(None, 'test_assets.py') - self.assertEqual(result, 'value') - - def test_has_resource_override_returns_True(self): - overrides = DummyOverrides(True) - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - result = provider.has_resource('test_assets.py') - self.assertEqual(result, True) - - def test_resource_isdir_override_returns_False(self): - overrides = DummyOverrides(False) - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_isdir('files') - self.assertEqual(result, False) - - def test_resource_listdir_override_returns_values(self): - overrides = DummyOverrides(['a']) - import pyramid.tests.test_config - self._registerOverrides(overrides) - provider = self._makeOne(pyramid.tests.test_config) - result = provider.resource_listdir('files') - self.assertEqual(result, ['a']) - -class TestPackageOverrides(unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.assets import PackageOverrides - return PackageOverrides - - def _makeOne(self, package=None, pkg_resources=None): - if package is None: - package = DummyPackage('package') - klass = self._getTargetClass() - if pkg_resources is None: - pkg_resources = DummyPkgResources() - return klass(package, pkg_resources=pkg_resources) - - def test_class_conforms_to_IPackageOverrides(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IPackageOverrides - verifyClass(IPackageOverrides, self._getTargetClass()) - - def test_instance_conforms_to_IPackageOverrides(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IPackageOverrides - verifyObject(IPackageOverrides, self._makeOne()) - - def test_class_conforms_to_IPEP302Loader(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IPEP302Loader - verifyClass(IPEP302Loader, self._getTargetClass()) - - def test_instance_conforms_to_IPEP302Loader(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IPEP302Loader - verifyObject(IPEP302Loader, self._makeOne()) - - def test_ctor_package_already_has_loader_of_different_type(self): - package = DummyPackage('package') - loader = package.__loader__ = DummyLoader() - po = self._makeOne(package) - self.assertTrue(package.__loader__ is po) - self.assertTrue(po.real_loader is loader) - - def test_ctor_package_already_has_loader_of_same_type(self): - package = DummyPackage('package') - package.__loader__ = self._makeOne(package) - po = self._makeOne(package) - self.assertEqual(package.__loader__, po) - - def test_ctor_sets_loader(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertEqual(package.__loader__, po) - - def test_ctor_registers_loader_type(self): - from pyramid.config.assets import OverrideProvider - dummy_pkg_resources = DummyPkgResources() - package = DummyPackage('package') - po = self._makeOne(package, dummy_pkg_resources) - self.assertEqual(dummy_pkg_resources.registered, [(po.__class__, - OverrideProvider)]) - - def test_ctor_sets_local_state(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertEqual(po.overrides, []) - self.assertEqual(po.overridden_package_name, 'package') - - def test_insert_directory(self): - from pyramid.config.assets import DirectoryOverride - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = [None] - po.insert('foo/', DummyAssetSource()) - self.assertEqual(len(po.overrides), 2) - override = po.overrides[0] - self.assertEqual(override.__class__, DirectoryOverride) - - def test_insert_file(self): - from pyramid.config.assets import FileOverride - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = [None] - po.insert('foo.pt', DummyAssetSource()) - self.assertEqual(len(po.overrides), 2) - override = po.overrides[0] - self.assertEqual(override.__class__, FileOverride) - - def test_insert_emptystring(self): - # XXX is this a valid case for a directory? - from pyramid.config.assets import DirectoryOverride - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = [None] - source = DummyAssetSource() - po.insert('', source) - self.assertEqual(len(po.overrides), 2) - override = po.overrides[0] - self.assertEqual(override.__class__, DirectoryOverride) - - def test_filtered_sources(self): - overrides = [ DummyOverride(None), DummyOverride('foo')] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(list(po.filtered_sources('whatever')), ['foo']) - - def test_get_filename(self): - source = DummyAssetSource(filename='foo.pt') - overrides = [ DummyOverride(None), DummyOverride((source, ''))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - result = po.get_filename('whatever') - self.assertEqual(result, 'foo.pt') - self.assertEqual(source.resource_name, '') - - def test_get_filename_file_doesnt_exist(self): - source = DummyAssetSource(filename=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.get_filename('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - def test_get_stream(self): - source = DummyAssetSource(stream='a stream?') - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.get_stream('whatever'), 'a stream?') - self.assertEqual(source.resource_name, 'foo.pt') - - def test_get_stream_file_doesnt_exist(self): - source = DummyAssetSource(stream=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.get_stream('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - def test_get_string(self): - source = DummyAssetSource(string='a string') - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.get_string('whatever'), 'a string') - self.assertEqual(source.resource_name, 'foo.pt') - - def test_get_string_file_doesnt_exist(self): - source = DummyAssetSource(string=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.get_string('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - def test_has_resource(self): - source = DummyAssetSource(exists=True) - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.has_resource('whatever'), True) - self.assertEqual(source.resource_name, 'foo.pt') - - def test_has_resource_file_doesnt_exist(self): - source = DummyAssetSource(exists=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.has_resource('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - def test_isdir_false(self): - source = DummyAssetSource(isdir=False) - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.isdir('whatever'), False) - self.assertEqual(source.resource_name, 'foo.pt') - - def test_isdir_true(self): - source = DummyAssetSource(isdir=True) - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.isdir('whatever'), True) - self.assertEqual(source.resource_name, 'foo.pt') - - def test_isdir_doesnt_exist(self): - source = DummyAssetSource(isdir=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.isdir('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - def test_listdir(self): - source = DummyAssetSource(listdir=True) - overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.listdir('whatever'), True) - self.assertEqual(source.resource_name, 'foo.pt') - - def test_listdir_doesnt_exist(self): - source = DummyAssetSource(listdir=None) - overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] - package = DummyPackage('package') - po = self._makeOne(package) - po.overrides = overrides - self.assertEqual(po.listdir('whatever'), None) - self.assertEqual(source.resource_name, 'wont_exist') - - # PEP 302 __loader__ extensions: use the "real" __loader__, if present. - def test_get_data_pkg_has_no___loader__(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertRaises(NotImplementedError, po.get_data, 'whatever') - - def test_get_data_pkg_has___loader__(self): - package = DummyPackage('package') - loader = package.__loader__ = DummyLoader() - po = self._makeOne(package) - self.assertEqual(po.get_data('whatever'), b'DEADBEEF') - self.assertEqual(loader._got_data, 'whatever') - - def test_is_package_pkg_has_no___loader__(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertRaises(NotImplementedError, po.is_package, 'whatever') - - def test_is_package_pkg_has___loader__(self): - package = DummyPackage('package') - loader = package.__loader__ = DummyLoader() - po = self._makeOne(package) - self.assertTrue(po.is_package('whatever')) - self.assertEqual(loader._is_package, 'whatever') - - def test_get_code_pkg_has_no___loader__(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertRaises(NotImplementedError, po.get_code, 'whatever') - - def test_get_code_pkg_has___loader__(self): - package = DummyPackage('package') - loader = package.__loader__ = DummyLoader() - po = self._makeOne(package) - self.assertEqual(po.get_code('whatever'), b'DEADBEEF') - self.assertEqual(loader._got_code, 'whatever') - - def test_get_source_pkg_has_no___loader__(self): - package = DummyPackage('package') - po = self._makeOne(package) - self.assertRaises(NotImplementedError, po.get_source, 'whatever') - - def test_get_source_pkg_has___loader__(self): - package = DummyPackage('package') - loader = package.__loader__ = DummyLoader() - po = self._makeOne(package) - self.assertEqual(po.get_source('whatever'), 'def foo():\n pass') - self.assertEqual(loader._got_source, 'whatever') - -class AssetSourceIntegrationTests(object): - - def test_get_filename(self): - source = self._makeOne('') - self.assertEqual(source.get_filename('test_assets.py'), - os.path.join(here, 'test_assets.py')) - - def test_get_filename_with_prefix(self): - source = self._makeOne('test_assets.py') - self.assertEqual(source.get_filename(''), - os.path.join(here, 'test_assets.py')) - - def test_get_filename_file_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.get_filename('wont_exist'), None) - - def test_get_stream(self): - source = self._makeOne('') - with source.get_stream('test_assets.py') as stream: - _assertBody(stream.read(), os.path.join(here, 'test_assets.py')) - - def test_get_stream_with_prefix(self): - source = self._makeOne('test_assets.py') - with source.get_stream('') as stream: - _assertBody(stream.read(), os.path.join(here, 'test_assets.py')) - - def test_get_stream_file_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.get_stream('wont_exist'), None) - - def test_get_string(self): - source = self._makeOne('') - _assertBody(source.get_string('test_assets.py'), - os.path.join(here, 'test_assets.py')) - - def test_get_string_with_prefix(self): - source = self._makeOne('test_assets.py') - _assertBody(source.get_string(''), - os.path.join(here, 'test_assets.py')) - - def test_get_string_file_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.get_string('wont_exist'), None) - - def test_exists(self): - source = self._makeOne('') - self.assertEqual(source.exists('test_assets.py'), True) - - def test_exists_with_prefix(self): - source = self._makeOne('test_assets.py') - self.assertEqual(source.exists(''), True) - - def test_exists_file_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.exists('wont_exist'), None) - - def test_isdir_false(self): - source = self._makeOne('') - self.assertEqual(source.isdir('test_assets.py'), False) - - def test_isdir_true(self): - source = self._makeOne('') - self.assertEqual(source.isdir('files'), True) - - def test_isdir_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.isdir('wont_exist'), None) - - def test_listdir(self): - source = self._makeOne('') - self.assertTrue(source.listdir('files')) - - def test_listdir_doesnt_exist(self): - source = self._makeOne('') - self.assertEqual(source.listdir('wont_exist'), None) - -class TestPackageAssetSource(AssetSourceIntegrationTests, unittest.TestCase): - - def _getTargetClass(self): - from pyramid.config.assets import PackageAssetSource - return PackageAssetSource - - def _makeOne(self, prefix, package='pyramid.tests.test_config'): - klass = self._getTargetClass() - return klass(package, prefix) - -class TestFSAssetSource(AssetSourceIntegrationTests, unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.assets import FSAssetSource - return FSAssetSource - - def _makeOne(self, prefix, base_prefix=here): - klass = self._getTargetClass() - return klass(os.path.join(base_prefix, prefix)) - -class TestDirectoryOverride(unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.assets import DirectoryOverride - return DirectoryOverride - - def _makeOne(self, path, source): - klass = self._getTargetClass() - return klass(path, source) - - def test_it_match(self): - source = DummyAssetSource() - o = self._makeOne('foo/', source) - result = o('foo/something.pt') - self.assertEqual(result, (source, 'something.pt')) - - def test_it_no_match(self): - source = DummyAssetSource() - o = self._makeOne('foo/', source) - result = o('baz/notfound.pt') - self.assertEqual(result, None) - -class TestFileOverride(unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.assets import FileOverride - return FileOverride - - def _makeOne(self, path, source): - klass = self._getTargetClass() - return klass(path, source) - - def test_it_match(self): - source = DummyAssetSource() - o = self._makeOne('foo.pt', source) - result = o('foo.pt') - self.assertEqual(result, (source, '')) - - def test_it_no_match(self): - source = DummyAssetSource() - o = self._makeOne('foo.pt', source) - result = o('notfound.pt') - self.assertEqual(result, None) - -class DummyOverride: - def __init__(self, result): - self.result = result - - def __call__(self, resource_name): - return self.result - -class DummyOverrides: - def __init__(self, result): - self.result = result - - def get_filename(self, resource_name): - return self.result - - listdir = isdir = has_resource = get_stream = get_string = get_filename - -class DummyPackageOverrides: - def __init__(self, package): - self.package = package - self.inserted = [] - - def insert(self, path, source): - self.inserted.append((path, source)) - -class DummyPkgResources: - def __init__(self): - self.registered = [] - - def register_loader_type(self, typ, inst): - self.registered.append((typ, inst)) - -class DummyPackage: - def __init__(self, name): - self.__name__ = name - -class DummyAssetSource: - def __init__(self, **kw): - self.kw = kw - - def get_filename(self, resource_name): - self.resource_name = resource_name - return self.kw['filename'] - - def get_stream(self, resource_name): - self.resource_name = resource_name - return self.kw['stream'] - - def get_string(self, resource_name): - self.resource_name = resource_name - return self.kw['string'] - - def exists(self, resource_name): - self.resource_name = resource_name - return self.kw['exists'] - - def isdir(self, resource_name): - self.resource_name = resource_name - return self.kw['isdir'] - - def listdir(self, resource_name): - self.resource_name = resource_name - return self.kw['listdir'] - -class DummyLoader: - _got_data = _is_package = None - def get_data(self, path): - self._got_data = path - return b'DEADBEEF' - def is_package(self, fullname): - self._is_package = fullname - return True - def get_code(self, fullname): - self._got_code = fullname - return b'DEADBEEF' - def get_source(self, fullname): - self._got_source = fullname - return 'def foo():\n pass' - -class DummyUnderOverride: - def __call__(self, package, path, source, _info=''): - self.package = package - self.path = path - self.source = source - -def read_(src): - with open(src, 'rb') as f: - contents = f.read() - return contents - -def _assertBody(body, filename): - # strip both \n and \r for windows - body = body.replace(b'\r', b'') - body = body.replace(b'\n', b'') - data = read_(filename) - data = data.replace(b'\r', b'') - data = data.replace(b'\n', b'') - assert(body == data) diff --git a/src/pyramid/tests/test_config/test_factories.py b/src/pyramid/tests/test_config/test_factories.py deleted file mode 100644 index 7e6ea0476..000000000 --- a/src/pyramid/tests/test_config/test_factories.py +++ /dev/null @@ -1,163 +0,0 @@ -import unittest - -from pyramid.tests.test_config import dummyfactory - -class TestFactoriesMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_set_request_factory(self): - from pyramid.interfaces import IRequestFactory - config = self._makeOne(autocommit=True) - factory = object() - config.set_request_factory(factory) - self.assertEqual(config.registry.getUtility(IRequestFactory), factory) - - def test_set_request_factory_dottedname(self): - from pyramid.interfaces import IRequestFactory - config = self._makeOne(autocommit=True) - config.set_request_factory( - 'pyramid.tests.test_config.dummyfactory') - self.assertEqual(config.registry.getUtility(IRequestFactory), - dummyfactory) - - def test_set_response_factory(self): - from pyramid.interfaces import IResponseFactory - config = self._makeOne(autocommit=True) - factory = lambda r: object() - config.set_response_factory(factory) - self.assertEqual(config.registry.getUtility(IResponseFactory), factory) - - def test_set_response_factory_dottedname(self): - from pyramid.interfaces import IResponseFactory - config = self._makeOne(autocommit=True) - config.set_response_factory( - 'pyramid.tests.test_config.dummyfactory') - self.assertEqual(config.registry.getUtility(IResponseFactory), - dummyfactory) - - def test_set_root_factory(self): - from pyramid.interfaces import IRootFactory - config = self._makeOne() - config.set_root_factory(dummyfactory) - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(IRootFactory), dummyfactory) - - def test_set_root_factory_as_None(self): - from pyramid.interfaces import IRootFactory - from pyramid.traversal import DefaultRootFactory - config = self._makeOne() - config.set_root_factory(None) - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(IRootFactory), - DefaultRootFactory) - - def test_set_root_factory_dottedname(self): - from pyramid.interfaces import IRootFactory - config = self._makeOne() - config.set_root_factory('pyramid.tests.test_config.dummyfactory') - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(IRootFactory), dummyfactory) - - def test_set_session_factory(self): - from pyramid.interfaces import ISessionFactory - config = self._makeOne() - config.set_session_factory(dummyfactory) - self.assertEqual(config.registry.queryUtility(ISessionFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(ISessionFactory), - dummyfactory) - - def test_set_session_factory_dottedname(self): - from pyramid.interfaces import ISessionFactory - config = self._makeOne() - config.set_session_factory('pyramid.tests.test_config.dummyfactory') - self.assertEqual(config.registry.queryUtility(ISessionFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(ISessionFactory), - dummyfactory) - - def test_add_request_method_with_callable(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - callable = lambda x: None - config.add_request_method(callable, name='foo') - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.methods) - - def test_add_request_method_with_unnamed_callable(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - def foo(self): pass - config.add_request_method(foo) - exts = config.registry.getUtility(IRequestExtensions) - self.assertTrue('foo' in exts.methods) - - def test_set_multiple_request_methods_conflict(self): - from pyramid.exceptions import ConfigurationConflictError - config = self._makeOne() - def foo(self): pass - def bar(self): pass - config.add_request_method(foo, name='bar') - config.add_request_method(bar, name='bar') - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_request_method_with_None_callable(self): - from pyramid.interfaces import IRequestExtensions - config = self._makeOne(autocommit=True) - config.add_request_method(name='foo') - exts = config.registry.queryUtility(IRequestExtensions) - self.assertTrue(exts is None) - - def test_add_request_method_with_None_callable_conflict(self): - from pyramid.exceptions import ConfigurationConflictError - config = self._makeOne() - def bar(self): pass - config.add_request_method(name='foo') - config.add_request_method(bar, name='foo') - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_request_method_with_None_callable_and_no_name(self): - config = self._makeOne(autocommit=True) - self.assertRaises(AttributeError, config.add_request_method) - - def test_add_request_method_with_text_type_name(self): - from pyramid.interfaces import IRequestExtensions - from pyramid.compat import text_, PY2 - from pyramid.exceptions import ConfigurationError - - config = self._makeOne(autocommit=True) - def boomshaka(r): pass - - def get_bad_name(): - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' - - config.add_request_method(boomshaka, name=name) - - self.assertRaises(ConfigurationError, get_bad_name) - - def test_set_execution_policy(self): - from pyramid.interfaces import IExecutionPolicy - config = self._makeOne(autocommit=True) - def dummy_policy(environ, router): pass - config.set_execution_policy(dummy_policy) - registry = config.registry - result = registry.queryUtility(IExecutionPolicy) - self.assertEqual(result, dummy_policy) - - def test_set_execution_policy_to_None(self): - from pyramid.interfaces import IExecutionPolicy - from pyramid.router import default_execution_policy - config = self._makeOne(autocommit=True) - config.set_execution_policy(None) - registry = config.registry - result = registry.queryUtility(IExecutionPolicy) - self.assertEqual(result, default_execution_policy) diff --git a/src/pyramid/tests/test_config/test_i18n.py b/src/pyramid/tests/test_config/test_i18n.py deleted file mode 100644 index c10ab6bdb..000000000 --- a/src/pyramid/tests/test_config/test_i18n.py +++ /dev/null @@ -1,132 +0,0 @@ -import os -import unittest - -from pyramid.tests.test_config import dummyfactory - -here = os.path.dirname(__file__) -locale = os.path.abspath( - os.path.join(here, '..', 'pkgs', 'localeapp', 'locale')) -locale2 = os.path.abspath( - os.path.join(here, '..', 'pkgs', 'localeapp', 'locale2')) -locale3 = os.path.abspath( - os.path.join(here, '..', 'pkgs', 'localeapp', 'locale3')) - -class TestI18NConfiguratorMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_set_locale_negotiator(self): - from pyramid.interfaces import ILocaleNegotiator - config = self._makeOne(autocommit=True) - def negotiator(request): pass - config.set_locale_negotiator(negotiator) - self.assertEqual(config.registry.getUtility(ILocaleNegotiator), - negotiator) - - def test_set_locale_negotiator_dottedname(self): - from pyramid.interfaces import ILocaleNegotiator - config = self._makeOne(autocommit=True) - config.set_locale_negotiator( - 'pyramid.tests.test_config.dummyfactory') - self.assertEqual(config.registry.getUtility(ILocaleNegotiator), - dummyfactory) - - def test_add_translation_dirs_missing_dir(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - config.add_translation_dirs('/wont/exist/on/my/system') - self.assertRaises(ConfigurationError, config.commit) - - def test_add_translation_dirs_no_specs(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne() - config.add_translation_dirs() - self.assertEqual(config.registry.queryUtility(ITranslationDirectories), - None) - - def test_add_translation_dirs_asset_spec(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale]) - - def test_add_translation_dirs_asset_spec_existing_translation_dirs(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - directories = ['abc'] - config.registry.registerUtility(directories, ITranslationDirectories) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - result = config.registry.getUtility(ITranslationDirectories) - self.assertEqual(result, [locale, 'abc']) - - def test_add_translation_dirs_multiple_specs(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', - 'pyramid.tests.pkgs.localeapp:locale2') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale, locale2]) - - def test_add_translation_dirs_multiple_specs_multiple_calls(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', - 'pyramid.tests.pkgs.localeapp:locale2') - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale3, locale, locale2]) - - def test_add_translation_dirs_override_multiple_specs_multiple_calls(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', - 'pyramid.tests.pkgs.localeapp:locale2') - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3', - override=True) - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale, locale2, locale3]) - - def test_add_translation_dirs_invalid_kwargs(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - with self.assertRaises(TypeError): - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', - foo=1) - - def test_add_translation_dirs_abspath(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs(locale) - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale]) - - def test_add_translation_dirs_uses_override_out_of_order(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne() - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - config.override_asset('pyramid.tests.pkgs.localeapp:locale/', - 'pyramid.tests.pkgs.localeapp:locale2/') - config.commit() - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale2]) - - def test_add_translation_dirs_doesnt_use_override_w_autocommit(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - config.override_asset('pyramid.tests.pkgs.localeapp:locale/', - 'pyramid.tests.pkgs.localeapp:locale2/') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale]) - - def test_add_translation_dirs_uses_override_w_autocommit(self): - from pyramid.interfaces import ITranslationDirectories - config = self._makeOne(autocommit=True) - config.override_asset('pyramid.tests.pkgs.localeapp:locale/', - 'pyramid.tests.pkgs.localeapp:locale2/') - config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') - self.assertEqual(config.registry.getUtility(ITranslationDirectories), - [locale2]) diff --git a/src/pyramid/tests/test_config/test_init.py b/src/pyramid/tests/test_config/test_init.py deleted file mode 100644 index 76a3d703d..000000000 --- a/src/pyramid/tests/test_config/test_init.py +++ /dev/null @@ -1,2068 +0,0 @@ -import unittest - -import os - -from pyramid.compat import im_func -from pyramid.testing import skip_on - -from pyramid.tests.test_config import dummy_tween_factory -from pyramid.tests.test_config import dummy_include -from pyramid.tests.test_config import dummy_extend -from pyramid.tests.test_config import dummy_extend2 -from pyramid.tests.test_config import IDummy -from pyramid.tests.test_config import DummyContext - -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationConflictError - -from pyramid.interfaces import IRequest - -class ConfiguratorTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def _getViewCallable(self, config, ctx_iface=None, request_iface=None, - name='', exception_view=False): - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - if exception_view: # pragma: no cover - classifier = IExceptionViewClassifier - else: - classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - if request_iface is None: - request_iface = IRequest - return config.registry.adapters.lookup( - (classifier, request_iface, ctx_iface), IView, name=name, - default=None) - - def _registerEventListener(self, config, event_iface=None): - if event_iface is None: # pragma: no cover - from zope.interface import Interface - event_iface = Interface - L = [] - def subscriber(*event): - L.extend(event) - config.registry.registerHandler(subscriber, (event_iface,)) - return L - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def test_ctor_no_registry(self): - import sys - from pyramid.interfaces import ISettings - from pyramid.config import Configurator - from pyramid.interfaces import IRendererFactory - config = Configurator() - this_pkg = sys.modules['pyramid.tests.test_config'] - self.assertTrue(config.registry.getUtility(ISettings)) - self.assertEqual(config.package, this_pkg) - config.commit() - self.assertTrue(config.registry.getUtility(IRendererFactory, 'json')) - self.assertTrue(config.registry.getUtility(IRendererFactory, 'string')) - - def test_begin(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - config.manager = manager - config.begin() - self.assertEqual(manager.pushed, - {'registry':config.registry, 'request':None}) - self.assertEqual(manager.popped, False) - - def test_begin_with_request(self): - from pyramid.config import Configurator - config = Configurator() - request = object() - manager = DummyThreadLocalManager() - config.manager = manager - config.begin(request=request) - self.assertEqual(manager.pushed, - {'registry':config.registry, 'request':request}) - self.assertEqual(manager.popped, False) - - def test_begin_overrides_request(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - req = object() - # set it up for auto-propagation - pushed = {'registry': config.registry, 'request': None} - manager.pushed = pushed - config.manager = manager - config.begin(req) - self.assertTrue(manager.pushed is not pushed) - self.assertEqual(manager.pushed['request'], req) - self.assertEqual(manager.pushed['registry'], config.registry) - - def test_begin_propagates_request_for_same_registry(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - req = object() - pushed = {'registry': config.registry, 'request': req} - manager.pushed = pushed - config.manager = manager - config.begin() - self.assertTrue(manager.pushed is not pushed) - self.assertEqual(manager.pushed['request'], req) - self.assertEqual(manager.pushed['registry'], config.registry) - - def test_begin_does_not_propagate_request_for_diff_registry(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - req = object() - pushed = {'registry': object(), 'request': req} - manager.pushed = pushed - config.manager = manager - config.begin() - self.assertTrue(manager.pushed is not pushed) - self.assertEqual(manager.pushed['request'], None) - self.assertEqual(manager.pushed['registry'], config.registry) - - def test_end(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - pushed = manager.pushed - config.manager = manager - config.end() - self.assertEqual(manager.pushed, pushed) - self.assertEqual(manager.popped, True) - - def test_context_manager(self): - from pyramid.config import Configurator - config = Configurator() - manager = DummyThreadLocalManager() - config.manager = manager - view = lambda r: None - with config as ctx: - self.assertTrue(config is ctx) - self.assertEqual(manager.pushed, - {'registry': config.registry, 'request': None}) - self.assertFalse(manager.popped) - config.add_view(view) - self.assertTrue(manager.popped) - config.add_view(view) # did not raise a conflict because of commit - config.commit() - - def test_ctor_with_package_registry(self): - import sys - from pyramid.config import Configurator - pkg = sys.modules['pyramid'] - config = Configurator(package=pkg) - self.assertEqual(config.package, pkg) - - def test_ctor_noreg_custom_settings(self): - from pyramid.interfaces import ISettings - settings = {'reload_templates':True, - 'mysetting':True} - config = self._makeOne(settings=settings) - settings = config.registry.getUtility(ISettings) - self.assertEqual(settings['reload_templates'], True) - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['mysetting'], True) - - def test_ctor_noreg_debug_logger_None_default(self): - from pyramid.interfaces import IDebugLogger - config = self._makeOne() - logger = config.registry.getUtility(IDebugLogger) - self.assertEqual(logger.name, 'pyramid.tests.test_config') - - def test_ctor_noreg_debug_logger_non_None(self): - from pyramid.interfaces import IDebugLogger - logger = object() - config = self._makeOne(debug_logger=logger) - result = config.registry.getUtility(IDebugLogger) - self.assertEqual(logger, result) - - def test_ctor_authentication_policy(self): - from pyramid.interfaces import IAuthenticationPolicy - policy = object() - config = self._makeOne(authentication_policy=policy) - config.commit() - result = config.registry.getUtility(IAuthenticationPolicy) - self.assertEqual(policy, result) - - def test_ctor_authorization_policy_only(self): - policy = object() - config = self._makeOne(authorization_policy=policy) - self.assertRaises(ConfigurationExecutionError, config.commit) - - def test_ctor_no_root_factory(self): - from pyramid.interfaces import IRootFactory - config = self._makeOne() - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - - def test_ctor_with_root_factory(self): - from pyramid.interfaces import IRootFactory - factory = object() - config = self._makeOne(root_factory=factory) - self.assertEqual(config.registry.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(config.registry.queryUtility(IRootFactory), factory) - - def test_ctor_alternate_renderers(self): - from pyramid.interfaces import IRendererFactory - renderer = object() - config = self._makeOne(renderers=[('yeah', renderer)]) - config.commit() - self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'), - renderer) - - def test_ctor_default_renderers(self): - from pyramid.interfaces import IRendererFactory - from pyramid.renderers import json_renderer_factory - config = self._makeOne() - self.assertEqual(config.registry.getUtility(IRendererFactory, 'json'), - json_renderer_factory) - - def test_ctor_default_permission(self): - from pyramid.interfaces import IDefaultPermission - config = self._makeOne(default_permission='view') - config.commit() - self.assertEqual(config.registry.getUtility(IDefaultPermission), 'view') - - def test_ctor_session_factory(self): - from pyramid.interfaces import ISessionFactory - factory = object() - config = self._makeOne(session_factory=factory) - self.assertEqual(config.registry.queryUtility(ISessionFactory), None) - config.commit() - self.assertEqual(config.registry.getUtility(ISessionFactory), factory) - - def test_ctor_default_view_mapper(self): - from pyramid.interfaces import IViewMapperFactory - mapper = object() - config = self._makeOne(default_view_mapper=mapper) - config.commit() - self.assertEqual(config.registry.getUtility(IViewMapperFactory), - mapper) - - def test_ctor_httpexception_view_default(self): - from pyramid.interfaces import IExceptionResponse - from pyramid.httpexceptions import default_exceptionresponse_view - from pyramid.interfaces import IRequest - config = self._makeOne() - view = self._getViewCallable(config, - ctx_iface=IExceptionResponse, - request_iface=IRequest) - self.assertTrue(view.__wraps__ is default_exceptionresponse_view) - - def test_ctor_exceptionresponse_view_None(self): - from pyramid.interfaces import IExceptionResponse - from pyramid.interfaces import IRequest - config = self._makeOne(exceptionresponse_view=None) - view = self._getViewCallable(config, - ctx_iface=IExceptionResponse, - request_iface=IRequest) - self.assertTrue(view is None) - - def test_ctor_exceptionresponse_view_custom(self): - from pyramid.interfaces import IExceptionResponse - from pyramid.interfaces import IRequest - def exceptionresponse_view(context, request): pass - config = self._makeOne(exceptionresponse_view=exceptionresponse_view) - view = self._getViewCallable(config, - ctx_iface=IExceptionResponse, - request_iface=IRequest) - self.assertTrue(view.__wraps__ is exceptionresponse_view) - - def test_ctor_with_introspection(self): - config = self._makeOne(introspection=False) - self.assertEqual(config.introspection, False) - - def test_ctor_default_webob_response_adapter_registered(self): - from webob import Response as WebobResponse - response = WebobResponse() - from pyramid.interfaces import IResponse - config = self._makeOne(autocommit=True) - result = config.registry.queryAdapter(response, IResponse) - self.assertEqual(result, response) - - def test_with_package_module(self): - from pyramid.tests.test_config import test_init - import pyramid.tests - config = self._makeOne() - newconfig = config.with_package(test_init) - self.assertEqual(newconfig.package, pyramid.tests.test_config) - - def test_with_package_package(self): - import pyramid.tests.test_config - config = self._makeOne() - newconfig = config.with_package(pyramid.tests.test_config) - self.assertEqual(newconfig.package, pyramid.tests.test_config) - - def test_with_package(self): - import pyramid.tests - config = self._makeOne() - config.basepath = 'basepath' - config.info = 'info' - config.includepath = ('spec',) - config.autocommit = True - config.route_prefix = 'prefix' - newconfig = config.with_package(pyramid.tests) - self.assertEqual(newconfig.package, pyramid.tests) - self.assertEqual(newconfig.registry, config.registry) - self.assertEqual(newconfig.autocommit, True) - self.assertEqual(newconfig.route_prefix, 'prefix') - self.assertEqual(newconfig.info, 'info') - self.assertEqual(newconfig.basepath, 'basepath') - self.assertEqual(newconfig.includepath, ('spec',)) - - def test_maybe_dotted_string_success(self): - import pyramid.tests.test_config - config = self._makeOne() - result = config.maybe_dotted('pyramid.tests.test_config') - self.assertEqual(result, pyramid.tests.test_config) - - def test_maybe_dotted_string_fail(self): - config = self._makeOne() - self.assertRaises(ImportError, config.maybe_dotted, 'cant.be.found') - - def test_maybe_dotted_notstring_success(self): - import pyramid.tests.test_config - config = self._makeOne() - result = config.maybe_dotted(pyramid.tests.test_config) - self.assertEqual(result, pyramid.tests.test_config) - - def test_absolute_asset_spec_already_absolute(self): - import pyramid.tests.test_config - config = self._makeOne(package=pyramid.tests.test_config) - result = config.absolute_asset_spec('already:absolute') - self.assertEqual(result, 'already:absolute') - - def test_absolute_asset_spec_notastring(self): - import pyramid.tests.test_config - config = self._makeOne(package=pyramid.tests.test_config) - result = config.absolute_asset_spec(None) - self.assertEqual(result, None) - - def test_absolute_asset_spec_relative(self): - import pyramid.tests.test_config - config = self._makeOne(package=pyramid.tests.test_config) - result = config.absolute_asset_spec('files') - self.assertEqual(result, 'pyramid.tests.test_config:files') - - def test__fix_registry_has_listeners(self): - reg = DummyRegistry() - config = self._makeOne(reg) - config._fix_registry() - self.assertEqual(reg.has_listeners, True) - - def test__fix_registry_notify(self): - reg = DummyRegistry() - config = self._makeOne(reg) - config._fix_registry() - self.assertEqual(reg.notify(1), None) - self.assertEqual(reg.events, (1,)) - - def test__fix_registry_queryAdapterOrSelf(self): - from zope.interface import Interface - from zope.interface import implementer - class IFoo(Interface): - pass - @implementer(IFoo) - class Foo(object): - pass - class Bar(object): - pass - adaptation = () - foo = Foo() - bar = Bar() - reg = DummyRegistry(adaptation) - config = self._makeOne(reg) - config._fix_registry() - self.assertTrue(reg.queryAdapterOrSelf(foo, IFoo) is foo) - self.assertTrue(reg.queryAdapterOrSelf(bar, IFoo) is adaptation) - - def test__fix_registry_registerSelfAdapter(self): - reg = DummyRegistry() - config = self._makeOne(reg) - config._fix_registry() - reg.registerSelfAdapter('required', 'provided', name='abc') - self.assertEqual(len(reg.adapters), 1) - args, kw = reg.adapters[0] - self.assertEqual(args[0]('abc'), 'abc') - self.assertEqual(kw, - {'info': '', 'provided': 'provided', - 'required': 'required', 'name': 'abc', 'event': True}) - - def test__fix_registry_adds__lock(self): - reg = DummyRegistry() - config = self._makeOne(reg) - config._fix_registry() - self.assertTrue(hasattr(reg, '_lock')) - - def test__fix_registry_adds_clear_view_lookup_cache(self): - reg = DummyRegistry() - config = self._makeOne(reg) - self.assertFalse(hasattr(reg, '_clear_view_lookup_cache')) - config._fix_registry() - self.assertFalse(hasattr(reg, '_view_lookup_cache')) - reg._clear_view_lookup_cache() - self.assertEqual(reg._view_lookup_cache, {}) - - def test_setup_registry_calls_fix_registry(self): - reg = DummyRegistry() - config = self._makeOne(reg) - config.add_view = lambda *arg, **kw: False - config._add_tween = lambda *arg, **kw: False - config.setup_registry() - self.assertEqual(reg.has_listeners, True) - - def test_setup_registry_registers_default_exceptionresponse_views(self): - from webob.exc import WSGIHTTPException - from pyramid.interfaces import IExceptionResponse - from pyramid.view import default_exceptionresponse_view - reg = DummyRegistry() - config = self._makeOne(reg) - views = [] - config.add_view = lambda *arg, **kw: views.append((arg, kw)) - config.add_default_view_predicates = lambda *arg: None - config._add_tween = lambda *arg, **kw: False - config.setup_registry() - self.assertEqual(views[0], ((default_exceptionresponse_view,), - {'context':IExceptionResponse})) - self.assertEqual(views[1], ((default_exceptionresponse_view,), - {'context':WSGIHTTPException})) - - def test_setup_registry_registers_default_view_predicates(self): - reg = DummyRegistry() - config = self._makeOne(reg) - vp_called = [] - config.add_view = lambda *arg, **kw: None - config.add_default_view_predicates = lambda *arg: vp_called.append(True) - config._add_tween = lambda *arg, **kw: False - config.setup_registry() - self.assertTrue(vp_called) - - def test_setup_registry_registers_default_webob_iresponse_adapter(self): - from webob import Response - from pyramid.interfaces import IResponse - config = self._makeOne() - config.setup_registry() - response = Response() - self.assertTrue( - config.registry.queryAdapter(response, IResponse) is response) - - def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.httpexceptions import HTTPNotFound - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg, autocommit=True) - config.setup_registry() # registers IExceptionResponse default view - def myview(context, request): - return 'OK' - config.add_view(myview, context=HTTPNotFound, renderer=null_renderer) - request = self._makeRequest(config) - view = self._getViewCallable(config, - ctx_iface=implementedBy(HTTPNotFound), - request_iface=IRequest) - result = view(None, request) - self.assertEqual(result, 'OK') - - def test_setup_registry_custom_settings(self): - from pyramid.registry import Registry - from pyramid.interfaces import ISettings - settings = {'reload_templates':True, - 'mysetting':True} - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(settings=settings) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['reload_templates'], True) - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['mysetting'], True) - - def test_setup_registry_debug_logger_None_default(self): - from pyramid.registry import Registry - from pyramid.interfaces import IDebugLogger - reg = Registry() - config = self._makeOne(reg) - config.setup_registry() - logger = reg.getUtility(IDebugLogger) - self.assertEqual(logger.name, 'pyramid.tests.test_config') - - def test_setup_registry_debug_logger_non_None(self): - from pyramid.registry import Registry - from pyramid.interfaces import IDebugLogger - logger = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(debug_logger=logger) - result = reg.getUtility(IDebugLogger) - self.assertEqual(logger, result) - - def test_setup_registry_debug_logger_name(self): - from pyramid.registry import Registry - from pyramid.interfaces import IDebugLogger - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(debug_logger='foo') - result = reg.getUtility(IDebugLogger) - self.assertEqual(result.name, 'foo') - - def test_setup_registry_authentication_policy(self): - from pyramid.registry import Registry - from pyramid.interfaces import IAuthenticationPolicy - policy = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(authentication_policy=policy) - config.commit() - result = reg.getUtility(IAuthenticationPolicy) - self.assertEqual(policy, result) - - def test_setup_registry_authentication_policy_dottedname(self): - from pyramid.registry import Registry - from pyramid.interfaces import IAuthenticationPolicy - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(authentication_policy='pyramid.tests.test_config') - config.commit() - result = reg.getUtility(IAuthenticationPolicy) - import pyramid.tests.test_config - self.assertEqual(result, pyramid.tests.test_config) - - def test_setup_registry_authorization_policy_dottedname(self): - from pyramid.registry import Registry - from pyramid.interfaces import IAuthorizationPolicy - reg = Registry() - config = self._makeOne(reg) - dummy = object() - config.setup_registry(authentication_policy=dummy, - authorization_policy='pyramid.tests.test_config') - config.commit() - result = reg.getUtility(IAuthorizationPolicy) - import pyramid.tests.test_config - self.assertEqual(result, pyramid.tests.test_config) - - def test_setup_registry_authorization_policy_only(self): - from pyramid.registry import Registry - policy = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(authorization_policy=policy) - config = self.assertRaises(ConfigurationExecutionError, config.commit) - - def test_setup_registry_no_default_root_factory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRootFactory - reg = Registry() - config = self._makeOne(reg) - config.setup_registry() - config.commit() - self.assertEqual(reg.queryUtility(IRootFactory), None) - - def test_setup_registry_dottedname_root_factory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRootFactory - reg = Registry() - config = self._makeOne(reg) - import pyramid.tests.test_config - config.setup_registry(root_factory='pyramid.tests.test_config') - self.assertEqual(reg.queryUtility(IRootFactory), None) - config.commit() - self.assertEqual(reg.getUtility(IRootFactory), - pyramid.tests.test_config) - - def test_setup_registry_locale_negotiator_dottedname(self): - from pyramid.registry import Registry - from pyramid.interfaces import ILocaleNegotiator - reg = Registry() - config = self._makeOne(reg) - import pyramid.tests.test_config - config.setup_registry(locale_negotiator='pyramid.tests.test_config') - self.assertEqual(reg.queryUtility(ILocaleNegotiator), None) - config.commit() - utility = reg.getUtility(ILocaleNegotiator) - self.assertEqual(utility, pyramid.tests.test_config) - - def test_setup_registry_locale_negotiator(self): - from pyramid.registry import Registry - from pyramid.interfaces import ILocaleNegotiator - reg = Registry() - config = self._makeOne(reg) - negotiator = object() - config.setup_registry(locale_negotiator=negotiator) - self.assertEqual(reg.queryUtility(ILocaleNegotiator), None) - config.commit() - utility = reg.getUtility(ILocaleNegotiator) - self.assertEqual(utility, negotiator) - - def test_setup_registry_request_factory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRequestFactory - reg = Registry() - config = self._makeOne(reg) - factory = object() - config.setup_registry(request_factory=factory) - self.assertEqual(reg.queryUtility(IRequestFactory), None) - config.commit() - utility = reg.getUtility(IRequestFactory) - self.assertEqual(utility, factory) - - def test_setup_registry_response_factory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IResponseFactory - reg = Registry() - config = self._makeOne(reg) - factory = lambda r: object() - config.setup_registry(response_factory=factory) - self.assertEqual(reg.queryUtility(IResponseFactory), None) - config.commit() - utility = reg.getUtility(IResponseFactory) - self.assertEqual(utility, factory) - - def test_setup_registry_request_factory_dottedname(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRequestFactory - reg = Registry() - config = self._makeOne(reg) - import pyramid.tests.test_config - config.setup_registry(request_factory='pyramid.tests.test_config') - self.assertEqual(reg.queryUtility(IRequestFactory), None) - config.commit() - utility = reg.getUtility(IRequestFactory) - self.assertEqual(utility, pyramid.tests.test_config) - - def test_setup_registry_alternate_renderers(self): - from pyramid.registry import Registry - from pyramid.interfaces import IRendererFactory - renderer = object() - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(renderers=[('yeah', renderer)]) - config.commit() - self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), - renderer) - - def test_setup_registry_default_permission(self): - from pyramid.registry import Registry - from pyramid.interfaces import IDefaultPermission - reg = Registry() - config = self._makeOne(reg) - config.setup_registry(default_permission='view') - config.commit() - self.assertEqual(reg.getUtility(IDefaultPermission), 'view') - - def test_setup_registry_includes(self): - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg) - settings = { - 'pyramid.includes': -"""pyramid.tests.test_config.dummy_include -pyramid.tests.test_config.dummy_include2""", - } - config.setup_registry(settings=settings) - self.assertTrue(reg.included) - self.assertTrue(reg.also_included) - - def test_setup_registry_includes_spaces(self): - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg) - settings = { - 'pyramid.includes': -"""pyramid.tests.test_config.dummy_include pyramid.tests.test_config.dummy_include2""", - } - config.setup_registry(settings=settings) - self.assertTrue(reg.included) - self.assertTrue(reg.also_included) - - def test_setup_registry_tweens(self): - from pyramid.interfaces import ITweens - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg) - settings = { - 'pyramid.tweens': - 'pyramid.tests.test_config.dummy_tween_factory' - } - config.setup_registry(settings=settings) - config.commit() - tweens = config.registry.getUtility(ITweens) - self.assertEqual( - tweens.explicit, - [('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory)]) - - def test_introspector_decorator(self): - inst = self._makeOne() - default = inst.introspector - self.assertTrue(hasattr(default, 'add')) - self.assertEqual(inst.introspector, inst.registry.introspector) - introspector = object() - inst.introspector = introspector - new = inst.introspector - self.assertTrue(new is introspector) - self.assertEqual(inst.introspector, inst.registry.introspector) - del inst.introspector - default = inst.introspector - self.assertFalse(default is new) - self.assertTrue(hasattr(default, 'add')) - - def test_make_wsgi_app(self): - import pyramid.config - from pyramid.router import Router - from pyramid.interfaces import IApplicationCreated - manager = DummyThreadLocalManager() - config = self._makeOne() - subscriber = self._registerEventListener(config, IApplicationCreated) - config.manager = manager - app = config.make_wsgi_app() - self.assertEqual(app.__class__, Router) - self.assertEqual(manager.pushed['registry'], config.registry) - self.assertEqual(manager.pushed['request'], None) - self.assertTrue(manager.popped) - self.assertEqual(pyramid.config.global_registries.last, app.registry) - self.assertEqual(len(subscriber), 1) - self.assertTrue(IApplicationCreated.providedBy(subscriber[0])) - pyramid.config.global_registries.empty() - - def test_include_with_dotted_name(self): - from pyramid.tests import test_config - config = self._makeOne() - config.include('pyramid.tests.test_config.dummy_include') - after = config.action_state - actions = after.actions - self.assertEqual(len(actions), 1) - action = after.actions[0] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_include_with_python_callable(self): - from pyramid.tests import test_config - config = self._makeOne() - config.include(dummy_include) - after = config.action_state - actions = after.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_include_with_module_defaults_to_includeme(self): - from pyramid.tests import test_config - config = self._makeOne() - config.include('pyramid.tests.test_config') - after = config.action_state - actions = after.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_include_with_module_defaults_to_includeme_missing(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.include, 'pyramid.tests') - - def test_include_with_route_prefix(self): - root_config = self._makeOne(autocommit=True) - def dummy_subapp(config): - self.assertEqual(config.route_prefix, 'root') - root_config.include(dummy_subapp, route_prefix='root') - - def test_include_with_nested_route_prefix(self): - root_config = self._makeOne(autocommit=True, route_prefix='root') - def dummy_subapp2(config): - self.assertEqual(config.route_prefix, 'root/nested') - def dummy_subapp3(config): - self.assertEqual(config.route_prefix, 'root/nested/nested2') - config.include(dummy_subapp4) - def dummy_subapp4(config): - self.assertEqual(config.route_prefix, 'root/nested/nested2') - def dummy_subapp(config): - self.assertEqual(config.route_prefix, 'root/nested') - config.include(dummy_subapp2) - config.include(dummy_subapp3, route_prefix='nested2') - - root_config.include(dummy_subapp, route_prefix='nested') - - def test_include_with_missing_source_file(self): - from pyramid.exceptions import ConfigurationError - import inspect - config = self._makeOne() - class DummyInspect(object): - def getmodule(self, c): - return inspect.getmodule(c) - def getsourcefile(self, c): - return None - config.inspect = DummyInspect() - try: - config.include('pyramid.tests.test_config.dummy_include') - except ConfigurationError as e: - self.assertEqual( - e.args[0], - "No source file for module 'pyramid.tests.test_config' (.py " - "file must exist, refusing to use orphan .pyc or .pyo file).") - else: # pragma: no cover - raise AssertionError - - def test_include_constant_root_package(self): - from pyramid import tests - from pyramid.tests import test_config - config = self._makeOne(root_package=tests) - results = {} - def include(config): - results['package'] = config.package - results['root_package'] = config.root_package - config.include(include) - self.assertEqual(results['root_package'], tests) - self.assertEqual(results['package'], test_config) - - def test_include_threadlocals_active(self): - from pyramid.tests import test_config - from pyramid.threadlocal import get_current_registry - stack = [] - def include(config): - stack.append(get_current_registry()) - config = self._makeOne() - config.include(include) - self.assertTrue(stack[0] is config.registry) - - def test_action_branching_kw_is_None(self): - config = self._makeOne(autocommit=True) - self.assertEqual(config.action('discrim'), None) - - def test_action_branching_kw_is_not_None(self): - config = self._makeOne(autocommit=True) - self.assertEqual(config.action('discrim', kw={'a':1}), None) - - def test_action_autocommit_with_introspectables(self): - from pyramid.config.util import ActionInfo - config = self._makeOne(autocommit=True) - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual(len(intr.registered), 1) - self.assertEqual(intr.registered[0][0], config.introspector) - self.assertEqual(intr.registered[0][1].__class__, ActionInfo) - - def test_action_autocommit_with_introspectables_introspection_off(self): - config = self._makeOne(autocommit=True) - config.introspection = False - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual(len(intr.registered), 0) - - def test_action_branching_nonautocommit_with_config_info(self): - config = self._makeOne(autocommit=False) - config.info = 'abc' - state = DummyActionState() - state.autocommit = False - config.action_state = state - config.action('discrim', kw={'a':1}) - self.assertEqual( - state.actions, - [((), - {'args': (), - 'callable': None, - 'discriminator': 'discrim', - 'includepath': (), - 'info': 'abc', - 'introspectables': (), - 'kw': {'a': 1}, - 'order': 0})]) - - def test_action_branching_nonautocommit_without_config_info(self): - config = self._makeOne(autocommit=False) - config.info = '' - config._ainfo = ['z'] - state = DummyActionState() - config.action_state = state - state.autocommit = False - config.action('discrim', kw={'a':1}) - self.assertEqual( - state.actions, - [((), - {'args': (), - 'callable': None, - 'discriminator': 'discrim', - 'includepath': (), - 'info': 'z', - 'introspectables': (), - 'kw': {'a': 1}, - 'order': 0})]) - - def test_action_branching_nonautocommit_with_introspectables(self): - config = self._makeOne(autocommit=False) - config.info = '' - config._ainfo = [] - state = DummyActionState() - config.action_state = state - state.autocommit = False - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual( - state.actions[0][1]['introspectables'], (intr,)) - - def test_action_nonautocommit_with_introspectables_introspection_off(self): - config = self._makeOne(autocommit=False) - config.info = '' - config._ainfo = [] - config.introspection = False - state = DummyActionState() - config.action_state = state - state.autocommit = False - intr = DummyIntrospectable() - config.action('discrim', introspectables=(intr,)) - self.assertEqual( - state.actions[0][1]['introspectables'], ()) - - def test_scan_integration(self): - from zope.interface import alsoProvides - from pyramid.interfaces import IRequest - from pyramid.view import render_view_to_response - import pyramid.tests.test_config.pkgs.scannable as package - config = self._makeOne(autocommit=True) - config.scan(package) - - ctx = DummyContext() - req = DummyRequest() - alsoProvides(req, IRequest) - req.registry = config.registry - - req.method = 'GET' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked') - - req.method = 'POST' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked_post') - - result= render_view_to_response(ctx, req, 'grokked_class') - self.assertEqual(result, 'grokked_class') - - result= render_view_to_response(ctx, req, 'grokked_instance') - self.assertEqual(result, 'grokked_instance') - - result= render_view_to_response(ctx, req, 'oldstyle_grokked_class') - self.assertEqual(result, 'oldstyle_grokked_class') - - req.method = 'GET' - result = render_view_to_response(ctx, req, 'another') - self.assertEqual(result, 'another_grokked') - - req.method = 'POST' - result = render_view_to_response(ctx, req, 'another') - self.assertEqual(result, 'another_grokked_post') - - result= render_view_to_response(ctx, req, 'another_grokked_class') - self.assertEqual(result, 'another_grokked_class') - - result= render_view_to_response(ctx, req, 'another_grokked_instance') - self.assertEqual(result, 'another_grokked_instance') - - result= render_view_to_response(ctx, req, - 'another_oldstyle_grokked_class') - self.assertEqual(result, 'another_oldstyle_grokked_class') - - result = render_view_to_response(ctx, req, 'stacked1') - self.assertEqual(result, 'stacked') - - result = render_view_to_response(ctx, req, 'stacked2') - self.assertEqual(result, 'stacked') - - result = render_view_to_response(ctx, req, 'another_stacked1') - self.assertEqual(result, 'another_stacked') - - result = render_view_to_response(ctx, req, 'another_stacked2') - self.assertEqual(result, 'another_stacked') - - result = render_view_to_response(ctx, req, 'stacked_class1') - self.assertEqual(result, 'stacked_class') - - result = render_view_to_response(ctx, req, 'stacked_class2') - self.assertEqual(result, 'stacked_class') - - result = render_view_to_response(ctx, req, 'another_stacked_class1') - self.assertEqual(result, 'another_stacked_class') - - result = render_view_to_response(ctx, req, 'another_stacked_class2') - self.assertEqual(result, 'another_stacked_class') - - # NB: on Jython, a class without an __init__ apparently accepts - # any number of arguments without raising a TypeError, so the next - # assertion may fail there. We don't support Jython at the moment, - # this is just a note to a future self. - - self.assertRaises(TypeError, - render_view_to_response, ctx, req, 'basemethod') - - result = render_view_to_response(ctx, req, 'method1') - self.assertEqual(result, 'method1') - - result = render_view_to_response(ctx, req, 'method2') - self.assertEqual(result, 'method2') - - result = render_view_to_response(ctx, req, 'stacked_method1') - self.assertEqual(result, 'stacked_method') - - result = render_view_to_response(ctx, req, 'stacked_method2') - self.assertEqual(result, 'stacked_method') - - result = render_view_to_response(ctx, req, 'subpackage_init') - self.assertEqual(result, 'subpackage_init') - - result = render_view_to_response(ctx, req, 'subpackage_notinit') - self.assertEqual(result, 'subpackage_notinit') - - result = render_view_to_response(ctx, req, 'subsubpackage_init') - self.assertEqual(result, 'subsubpackage_init') - - result = render_view_to_response(ctx, req, 'pod_notinit') - self.assertEqual(result, None) - - def test_scan_integration_with_ignore(self): - from zope.interface import alsoProvides - from pyramid.interfaces import IRequest - from pyramid.view import render_view_to_response - import pyramid.tests.test_config.pkgs.scannable as package - config = self._makeOne(autocommit=True) - config.scan(package, - ignore='pyramid.tests.test_config.pkgs.scannable.another') - - ctx = DummyContext() - req = DummyRequest() - alsoProvides(req, IRequest) - req.registry = config.registry - - req.method = 'GET' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked') - - # ignored - v = render_view_to_response(ctx, req, 'another_stacked_class2') - self.assertEqual(v, None) - - def test_scan_integration_dottedname_package(self): - from zope.interface import alsoProvides - from pyramid.interfaces import IRequest - from pyramid.view import render_view_to_response - config = self._makeOne(autocommit=True) - config.scan('pyramid.tests.test_config.pkgs.scannable') - - ctx = DummyContext() - req = DummyRequest() - alsoProvides(req, IRequest) - req.registry = config.registry - - req.method = 'GET' - result = render_view_to_response(ctx, req, '') - self.assertEqual(result, 'grokked') - - def test_scan_integration_with_extra_kw(self): - config = self._makeOne(autocommit=True) - config.scan('pyramid.tests.test_config.pkgs.scanextrakw', a=1) - self.assertEqual(config.a, 1) - - def test_scan_integration_with_onerror(self): - # fancy sys.path manipulation here to appease "setup.py test" which - # fails miserably when it can't import something in the package - import sys - try: - here = os.path.dirname(__file__) - path = os.path.join(here, 'path') - sys.path.append(path) - config = self._makeOne(autocommit=True) - class FooException(Exception): - pass - def onerror(name): - raise FooException - self.assertRaises(FooException, config.scan, 'scanerror', - onerror=onerror) - finally: - sys.path.remove(path) - - def test_scan_integration_conflict(self): - from pyramid.tests.test_config.pkgs import selfscan - from pyramid.config import Configurator - c = Configurator() - c.scan(selfscan) - c.scan(selfscan) - try: - c.commit() - except ConfigurationConflictError as why: - def scanconflicts(e): - conflicts = e._conflicts.values() - for conflict in conflicts: - for confinst in conflict: - yield confinst.src - which = list(scanconflicts(why)) - self.assertEqual(len(which), 4) - self.assertTrue("@view_config(renderer='string')" in which) - self.assertTrue("@view_config(name='two', renderer='string')" in - which) - - @skip_on('py3') - def test_hook_zca(self): - from zope.component import getSiteManager - def foo(): - '123' - try: - config = self._makeOne() - config.hook_zca() - config.begin() - sm = getSiteManager() - self.assertEqual(sm, config.registry) - finally: - getSiteManager.reset() - - @skip_on('py3') - def test_unhook_zca(self): - from zope.component import getSiteManager - def foo(): - '123' - try: - getSiteManager.sethook(foo) - config = self._makeOne() - config.unhook_zca() - sm = getSiteManager() - self.assertNotEqual(sm, '123') - finally: - getSiteManager.reset() - - def test_commit_conflict_simple(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - config.add_view(view1) - config.add_view(view2) - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_commit_conflict_resolved_with_include(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - def includeme(config): - config.add_view(view2) - config.add_view(view1) - config.include(includeme) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view1') - - def test_commit_conflict_with_two_includes(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - def includeme1(config): - config.add_view(view1) - def includeme2(config): - config.add_view(view2) - config.include(includeme1) - config.include(includeme2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'includeme1') - self.assertEqual(c2, 'includeme2') - else: #pragma: no cover - raise AssertionError - - def test_commit_conflict_resolved_with_two_includes_and_local(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - def view3(request): pass - def includeme1(config): - config.add_view(view1) - def includeme2(config): - config.add_view(view2) - config.include(includeme1) - config.include(includeme2) - config.add_view(view3) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view3') - - def test_autocommit_no_conflicts(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - def view1(request): pass - def view2(request): pass - def view3(request): pass - config.add_view(view1, renderer=null_renderer) - config.add_view(view2, renderer=null_renderer) - config.add_view(view3, renderer=null_renderer) - config.commit() - registeredview = self._getViewCallable(config) - self.assertEqual(registeredview.__name__, 'view3') - - def test_conflict_set_notfound_view(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - config.set_notfound_view(view1) - config.set_notfound_view(view2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'test_conflict_set_notfound_view') - self.assertEqual(c2, 'test_conflict_set_notfound_view') - else: # pragma: no cover - raise AssertionError - - def test_conflict_set_forbidden_view(self): - config = self._makeOne() - def view1(request): pass - def view2(request): pass - config.set_forbidden_view(view1) - config.set_forbidden_view(view2) - try: - config.commit() - except ConfigurationConflictError as why: - c1, c2 = _conflictFunctions(why) - self.assertEqual(c1, 'test_conflict_set_forbidden_view') - self.assertEqual(c2, 'test_conflict_set_forbidden_view') - else: # pragma: no cover - raise AssertionError - - def test___getattr__missing_when_directives_exist(self): - config = self._makeOne() - directives = {} - config.registry._directives = directives - self.assertRaises(AttributeError, config.__getattr__, 'wontexist') - - def test___getattr__missing_when_directives_dont_exist(self): - config = self._makeOne() - self.assertRaises(AttributeError, config.__getattr__, 'wontexist') - - def test___getattr__matches(self): - config = self._makeOne() - def foo(config): pass - directives = {'foo':(foo, True)} - config.registry._directives = directives - foo_meth = config.foo - self.assertTrue(getattr(foo_meth, im_func).__docobj__ is foo) - - def test___getattr__matches_no_action_wrap(self): - config = self._makeOne() - def foo(config): pass - directives = {'foo':(foo, False)} - config.registry._directives = directives - foo_meth = config.foo - self.assertTrue(getattr(foo_meth, im_func) is foo) - -class TestConfigurator_add_directive(unittest.TestCase): - - def setUp(self): - from pyramid.config import Configurator - self.config = Configurator() - - def test_extend_with_dotted_name(self): - from pyramid.tests import test_config - config = self.config - config.add_directive( - 'dummy_extend', 'pyramid.tests.test_config.dummy_extend') - self.assertTrue(hasattr(config, 'dummy_extend')) - config.dummy_extend('discrim') - after = config.action_state - action = after.actions[-1] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_add_directive_with_partial(self): - from pyramid.tests import test_config - config = self.config - config.add_directive( - 'dummy_partial', 'pyramid.tests.test_config.dummy_partial') - self.assertTrue(hasattr(config, 'dummy_partial')) - config.dummy_partial() - after = config.action_state - action = after.actions[-1] - self.assertEqual(action['discriminator'], 'partial') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_add_directive_with_custom_callable(self): - from pyramid.tests import test_config - config = self.config - config.add_directive( - 'dummy_callable', 'pyramid.tests.test_config.dummy_callable') - self.assertTrue(hasattr(config, 'dummy_callable')) - config.dummy_callable('discrim') - after = config.action_state - action = after.actions[-1] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_extend_with_python_callable(self): - from pyramid.tests import test_config - config = self.config - config.add_directive( - 'dummy_extend', dummy_extend) - self.assertTrue(hasattr(config, 'dummy_extend')) - config.dummy_extend('discrim') - after = config.action_state - action = after.actions[-1] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], test_config) - - def test_extend_same_name_doesnt_conflict(self): - config = self.config - config.add_directive( - 'dummy_extend', dummy_extend) - config.add_directive( - 'dummy_extend', dummy_extend2) - self.assertTrue(hasattr(config, 'dummy_extend')) - config.dummy_extend('discrim') - after = config.action_state - action = after.actions[-1] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], config.registry) - - def test_extend_action_method_successful(self): - config = self.config - config.add_directive( - 'dummy_extend', dummy_extend) - config.dummy_extend('discrim') - config.dummy_extend('discrim') - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_directive_persists_across_configurator_creations(self): - config = self.config - config.add_directive('dummy_extend', dummy_extend) - config2 = config.with_package('pyramid.tests') - config2.dummy_extend('discrim') - after = config2.action_state - actions = after.actions - self.assertEqual(len(actions), 1) - action = actions[0] - self.assertEqual(action['discriminator'], 'discrim') - self.assertEqual(action['callable'], None) - self.assertEqual(action['args'], config2.package) - -class TestConfigurator__add_predicate(unittest.TestCase): - def _makeOne(self): - from pyramid.config import Configurator - return Configurator() - - def test_factory_as_object(self): - config = self._makeOne() - - def _fakeAction(discriminator, callable=None, args=(), kw=None, - order=0, introspectables=(), **extra): - self.assertEqual(len(introspectables), 1) - self.assertEqual(introspectables[0]['name'], 'testing') - self.assertEqual(introspectables[0]['factory'], DummyPredicate) - - config.action = _fakeAction - config._add_predicate('route', 'testing', DummyPredicate) - - def test_factory_as_dotted_name(self): - config = self._makeOne() - - def _fakeAction(discriminator, callable=None, args=(), - kw=None, order=0, introspectables=(), **extra): - self.assertEqual(len(introspectables), 1) - self.assertEqual(introspectables[0]['name'], 'testing') - self.assertEqual(introspectables[0]['factory'], DummyPredicate) - - config.action = _fakeAction - config._add_predicate( - 'route', - 'testing', - 'pyramid.tests.test_config.test_init.DummyPredicate' - ) - -class TestActionState(unittest.TestCase): - def _makeOne(self): - from pyramid.config import ActionState - return ActionState() - - def test_it(self): - c = self._makeOne() - self.assertEqual(c.actions, []) - - def test_action_simple(self): - from pyramid.tests.test_config import dummyfactory as f - c = self._makeOne() - c.actions = [] - c.action(1, f, (1,), {'x':1}) - self.assertEqual( - c.actions, - [{'args': (1,), - 'callable': f, - 'discriminator': 1, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {'x': 1}, - 'order': 0}]) - c.action(None) - self.assertEqual( - c.actions, - [{'args': (1,), - 'callable': f, - 'discriminator': 1, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {'x': 1}, - 'order': 0}, - - {'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {}, - 'order': 0},]) - - def test_action_with_includepath(self): - c = self._makeOne() - c.actions = [] - c.action(None, includepath=('abc',)) - self.assertEqual( - c.actions, - [{'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': ('abc',), - 'info': None, - 'introspectables': (), - 'kw': {}, - 'order': 0}]) - - def test_action_with_info(self): - c = self._makeOne() - c.action(None, info='abc') - self.assertEqual( - c.actions, - [{'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': 'abc', - 'introspectables': (), - 'kw': {}, - 'order': 0}]) - - def test_action_with_includepath_and_info(self): - c = self._makeOne() - c.action(None, includepath=('spec',), info='bleh') - self.assertEqual( - c.actions, - [{'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': ('spec',), - 'info': 'bleh', - 'introspectables': (), - 'kw': {}, - 'order': 0}]) - - def test_action_with_order(self): - c = self._makeOne() - c.actions = [] - c.action(None, order=99999) - self.assertEqual( - c.actions, - [{'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': None, - 'introspectables': (), - 'kw': {}, - 'order': 99999}]) - - def test_action_with_introspectables(self): - c = self._makeOne() - c.actions = [] - intr = DummyIntrospectable() - c.action(None, introspectables=(intr,)) - self.assertEqual( - c.actions, - [{'args': (), - 'callable': None, - 'discriminator': None, - 'includepath': (), - 'info': None, - 'introspectables': (intr,), - 'kw': {}, - 'order': 0}]) - - def test_processSpec(self): - c = self._makeOne() - self.assertTrue(c.processSpec('spec')) - self.assertFalse(c.processSpec('spec')) - - def test_execute_actions_tuples(self): - output = [] - def f(*a, **k): - output.append((a, k)) - c = self._makeOne() - c.actions = [ - (1, f, (1,)), - (1, f, (11,), {}, ('x', )), - (2, f, (2,)), - (None, None), - ] - c.execute_actions() - self.assertEqual(output, [((1,), {}), ((2,), {})]) - - def test_execute_actions_dicts(self): - output = [] - def f(*a, **k): - output.append((a, k)) - c = self._makeOne() - c.actions = [ - {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{}, - 'order':0, 'includepath':(), 'info':None, - 'introspectables':()}, - {'discriminator':1, 'callable':f, 'args':(11,), 'kw':{}, - 'includepath':('x',), 'order': 0, 'info':None, - 'introspectables':()}, - {'discriminator':2, 'callable':f, 'args':(2,), 'kw':{}, - 'order':0, 'includepath':(), 'info':None, - 'introspectables':()}, - {'discriminator':None, 'callable':None, 'args':(), 'kw':{}, - 'order':0, 'includepath':(), 'info':None, - 'introspectables':()}, - ] - c.execute_actions() - self.assertEqual(output, [((1,), {}), ((2,), {})]) - - def test_execute_actions_with_introspectables(self): - output = [] - def f(*a, **k): - output.append((a, k)) - c = self._makeOne() - intr = DummyIntrospectable() - c.actions = [ - {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{}, - 'order':0, 'includepath':(), 'info':None, - 'introspectables':(intr,)}, - ] - introspector = object() - c.execute_actions(introspector=introspector) - self.assertEqual(output, [((1,), {})]) - self.assertEqual(intr.registered, [(introspector, None)]) - - def test_execute_actions_with_introspectable_no_callable(self): - c = self._makeOne() - intr = DummyIntrospectable() - c.actions = [ - {'discriminator':1, 'callable':None, 'args':(1,), 'kw':{}, - 'order':0, 'includepath':(), 'info':None, - 'introspectables':(intr,)}, - ] - introspector = object() - c.execute_actions(introspector=introspector) - self.assertEqual(intr.registered, [(introspector, None)]) - - def test_execute_actions_error(self): - output = [] - def f(*a, **k): - output.append(('f', a, k)) - def bad(): - raise NotImplementedError - c = self._makeOne() - c.actions = [ - (1, f, (1,)), - (1, f, (11,), {}, ('x', )), - (2, f, (2,)), - (3, bad, (), {}, (), 'oops') - ] - self.assertRaises(ConfigurationExecutionError, c.execute_actions) - self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})]) - - def test_reentrant_action(self): - output = [] - c = self._makeOne() - def f(*a, **k): - output.append(('f', a, k)) - c.actions.append((3, g, (8,), {})) - def g(*a, **k): - output.append(('g', a, k)) - c.actions = [ - (1, f, (1,)), - ] - c.execute_actions() - self.assertEqual(output, [('f', (1,), {}), ('g', (8,), {})]) - - def test_reentrant_action_with_deferred_discriminator(self): - # see https://github.com/Pylons/pyramid/issues/2697 - from pyramid.registry import Deferred - output = [] - c = self._makeOne() - def f(*a, **k): - output.append(('f', a, k)) - c.actions.append((4, g, (4,), {}, (), None, 2)) - def g(*a, **k): - output.append(('g', a, k)) - def h(*a, **k): - output.append(('h', a, k)) - def discrim(): - self.assertEqual(output, [('f', (1,), {}), ('g', (2,), {})]) - return 3 - d = Deferred(discrim) - c.actions = [ - (d, h, (3,), {}, (), None, 1), # order 1 - (1, f, (1,)), # order 0 - (2, g, (2,)), # order 0 - ] - c.execute_actions() - self.assertEqual(output, [ - ('f', (1,), {}), ('g', (2,), {}), ('h', (3,), {}), ('g', (4,), {})]) - - def test_reentrant_action_error(self): - from pyramid.exceptions import ConfigurationError - c = self._makeOne() - def f(*a, **k): - c.actions.append((3, g, (8,), {}, (), None, -1)) - def g(*a, **k): pass - c.actions = [ - (1, f, (1,)), - ] - self.assertRaises(ConfigurationError, c.execute_actions) - - def test_reentrant_action_without_clear(self): - c = self._makeOne() - def f(*a, **k): - c.actions.append((3, g, (8,))) - def g(*a, **k): pass - c.actions = [ - (1, f, (1,)), - ] - c.execute_actions(clear=False) - self.assertEqual(c.actions, [ - (1, f, (1,)), - (3, g, (8,)), - ]) - - def test_executing_conflicting_action_across_orders(self): - from pyramid.exceptions import ConfigurationConflictError - c = self._makeOne() - def f(*a, **k): pass - def g(*a, **k): pass - c.actions = [ - (1, f, (1,), {}, (), None, -1), - (1, g, (2,)), - ] - self.assertRaises(ConfigurationConflictError, c.execute_actions) - - def test_executing_conflicting_action_across_reentrant_orders(self): - from pyramid.exceptions import ConfigurationConflictError - c = self._makeOne() - def f(*a, **k): - c.actions.append((1, g, (8,))) - def g(*a, **k): pass - c.actions = [ - (1, f, (1,), {}, (), None, -1), - ] - self.assertRaises(ConfigurationConflictError, c.execute_actions) - -class Test_reentrant_action_functional(unittest.TestCase): - def _makeConfigurator(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_functional(self): - def add_auto_route(config, name, view): - def register(): - config.add_view(route_name=name, view=view) - config.add_route(name, '/' + name) - config.action( - ('auto route', name), register, order=-30 - ) - config = self._makeConfigurator() - config.add_directive('add_auto_route', add_auto_route) - def my_view(request): return request.response - config.add_auto_route('foo', my_view) - config.commit() - from pyramid.interfaces import IRoutesMapper - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, 'foo') - self.assertEqual(route.path, '/foo') - - def test_deferred_discriminator(self): - # see https://github.com/Pylons/pyramid/issues/2697 - from pyramid.config import PHASE0_CONFIG - config = self._makeConfigurator() - def deriver(view, info): return view - deriver.options = ('foo',) - config.add_view_deriver(deriver, 'foo_view') - # add_view uses a deferred discriminator and will fail if executed - # prior to add_view_deriver executing its action - config.add_view(lambda r: r.response, name='', foo=1) - def dummy_action(): - # trigger a re-entrant action - config.action(None, lambda: None) - config.action(None, dummy_action, order=PHASE0_CONFIG) - config.commit() - -class Test_resolveConflicts(unittest.TestCase): - def _callFUT(self, actions): - from pyramid.config import resolveConflicts - return resolveConflicts(actions) - - def test_it_success_tuples(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (None, f), - (1, f, (1,), {}, (), 'first'), - (1, f, (2,), {}, ('x',), 'second'), - (1, f, (3,), {}, ('y',), 'third'), - (4, f, (4,), {}, ('y',), 'should be last', 99999), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ]) - result = list(result) - self.assertEqual( - result, - [{'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0}, - - {'info': 'first', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 0}, - - {'info': None, - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': ('y',), - 'order': 0}, - - {'info': None, - 'args': (5,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': ('y',), - 'order': 0}, - - {'info': 'should be last', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': ('y',), - 'order': 99999} - ] - ) - - def test_it_success_dicts(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (None, f), - (1, f, (1,), {}, (), 'first'), - (1, f, (2,), {}, ('x',), 'second'), - (1, f, (3,), {}, ('y',), 'third'), - (4, f, (4,), {}, ('y',), 'should be last', 99999), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ]) - result = list(result) - self.assertEqual( - result, - [{'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0}, - - {'info': 'first', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 0}, - - {'info': None, - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': ('y',), - 'order': 0}, - - {'info': None, - 'args': (5,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': ('y',), - 'order': 0}, - - {'info': 'should be last', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': ('y',), - 'order': 99999} - ] - ) - - def test_it_conflict(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (None, f), - (1, f, (2,), {}, ('x',), 'eek'), # will conflict - (1, f, (3,), {}, ('y',), 'ack'), # will conflict - (4, f, (4,), {}, ('y',)), - (3, f, (3,), {}, ('y',)), - (None, f, (5,), {}, ('y',)), - ]) - self.assertRaises(ConfigurationConflictError, list, result) - - def test_it_with_actions_grouped_by_order(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (None, f), # X - (1, f, (1,), {}, (), 'third', 10), # X - (1, f, (2,), {}, ('x',), 'fourth', 10), - (1, f, (3,), {}, ('y',), 'fifth', 10), - (2, f, (1,), {}, (), 'sixth', 10), # X - (3, f, (1,), {}, (), 'seventh', 10), # X - (5, f, (4,), {}, ('y',), 'eighth', 99999), # X - (4, f, (3,), {}, (), 'first', 5), # X - (4, f, (5,), {}, ('y',), 'second', 5), - ]) - result = list(result) - self.assertEqual(len(result), 6) - # resolved actions should be grouped by (order, i) - self.assertEqual( - result, - [{'info': None, - 'args': (), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': None, - 'includepath': (), - 'order': 0}, - - {'info': 'first', - 'args': (3,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 4, - 'includepath': (), - 'order': 5}, - - {'info': 'third', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': (), - 'order': 10}, - - {'info': 'sixth', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 2, - 'includepath': (), - 'order': 10}, - - {'info': 'seventh', - 'args': (1,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 3, - 'includepath': (), - 'order': 10}, - - {'info': 'eighth', - 'args': (4,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 5, - 'includepath': ('y',), - 'order': 99999} - ] - ) - - def test_override_success_across_orders(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (1, f, (2,), {}, ('x',), 'eek', 0), - (1, f, (3,), {}, ('x', 'y'), 'ack', 10), - ]) - result = list(result) - self.assertEqual(result, [ - {'info': 'eek', - 'args': (2,), - 'callable': f, - 'introspectables': (), - 'kw': {}, - 'discriminator': 1, - 'includepath': ('x',), - 'order': 0}, - ]) - - def test_conflicts_across_orders(self): - from pyramid.tests.test_config import dummyfactory as f - result = self._callFUT([ - (1, f, (2,), {}, ('x', 'y'), 'eek', 0), - (1, f, (3,), {}, ('x'), 'ack', 10), - ]) - self.assertRaises(ConfigurationConflictError, list, result) - -class TestGlobalRegistriesIntegration(unittest.TestCase): - def setUp(self): - from pyramid.config import global_registries - global_registries.empty() - - tearDown = setUp - - def _makeConfigurator(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_global_registries_empty(self): - from pyramid.config import global_registries - self.assertEqual(global_registries.last, None) - - def test_global_registries(self): - from pyramid.config import global_registries - config1 = self._makeConfigurator() - config1.make_wsgi_app() - self.assertEqual(global_registries.last, config1.registry) - config2 = self._makeConfigurator() - config2.make_wsgi_app() - self.assertEqual(global_registries.last, config2.registry) - self.assertEqual(list(global_registries), - [config1.registry, config2.registry]) - global_registries.remove(config2.registry) - self.assertEqual(global_registries.last, config1.registry) - -class DummyRequest: - subpath = () - matchdict = None - request_iface = IRequest - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.params = {} - self.cookies = {} - -class DummyThreadLocalManager(object): - def __init__(self): - self.pushed = {'registry': None, 'request': None} - self.popped = False - def push(self, d): - self.pushed = d - def get(self): - return self.pushed - def pop(self): - self.popped = True - -from zope.interface import implementer -@implementer(IDummy) -class DummyEvent: - pass - -class DummyRegistry(object): - def __init__(self, adaptation=None, util=None): - self.utilities = [] - self.adapters = [] - self.adaptation = adaptation - self.util = util - def subscribers(self, events, name): - self.events = events - return events - def registerUtility(self, *arg, **kw): - self.utilities.append((arg, kw)) - def registerAdapter(self, *arg, **kw): - self.adapters.append((arg, kw)) - def queryAdapter(self, *arg, **kw): - return self.adaptation - def queryUtility(self, *arg, **kw): - return self.util - -from zope.interface import Interface -class IOther(Interface): - pass - -def _conflictFunctions(e): - conflicts = e._conflicts.values() - for conflict in conflicts: - for confinst in conflict: - yield confinst.function - -class DummyActionState(object): - autocommit = False - info = '' - def __init__(self): - self.actions = [] - def action(self, *arg, **kw): - self.actions.append((arg, kw)) - -class DummyIntrospectable(object): - def __init__(self): - self.registered = [] - def register(self, introspector, action_info): - self.registered.append((introspector, action_info)) - -class DummyPredicate(object): - pass diff --git a/src/pyramid/tests/test_config/test_rendering.py b/src/pyramid/tests/test_config/test_rendering.py deleted file mode 100644 index cede64d3a..000000000 --- a/src/pyramid/tests/test_config/test_rendering.py +++ /dev/null @@ -1,34 +0,0 @@ -import unittest - -class TestRenderingConfiguratorMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_add_default_renderers(self): - from pyramid.config.rendering import DEFAULT_RENDERERS - from pyramid.interfaces import IRendererFactory - config = self._makeOne(autocommit=True) - config.add_default_renderers() - for name, impl in DEFAULT_RENDERERS: - self.assertTrue( - config.registry.queryUtility(IRendererFactory, name) is not None - ) - - def test_add_renderer(self): - from pyramid.interfaces import IRendererFactory - config = self._makeOne(autocommit=True) - renderer = object() - config.add_renderer('name', renderer) - self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), - renderer) - - def test_add_renderer_dottedname_factory(self): - from pyramid.interfaces import IRendererFactory - config = self._makeOne(autocommit=True) - import pyramid.tests.test_config - config.add_renderer('name', 'pyramid.tests.test_config') - self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), - pyramid.tests.test_config) - diff --git a/src/pyramid/tests/test_config/test_routes.py b/src/pyramid/tests/test_config/test_routes.py deleted file mode 100644 index 9f4ce9bc6..000000000 --- a/src/pyramid/tests/test_config/test_routes.py +++ /dev/null @@ -1,297 +0,0 @@ -import unittest - -from pyramid.tests.test_config import dummyfactory -from pyramid.tests.test_config import DummyContext -from pyramid.compat import text_ - -class RoutesConfiguratorMixinTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def _assertRoute(self, config, name, path, num_predicates=0): - from pyramid.interfaces import IRoutesMapper - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, name) - self.assertEqual(route.path, path) - self.assertEqual(len(routes[0].predicates), num_predicates) - return route - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def test_get_routes_mapper_not_yet_registered(self): - config = self._makeOne() - mapper = config.get_routes_mapper() - self.assertEqual(mapper.routelist, []) - - def test_get_routes_mapper_already_registered(self): - from pyramid.interfaces import IRoutesMapper - config = self._makeOne() - mapper = object() - config.registry.registerUtility(mapper, IRoutesMapper) - result = config.get_routes_mapper() - self.assertEqual(result, mapper) - - def test_add_route_defaults(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path') - self._assertRoute(config, 'name', 'path') - - def test_add_route_with_route_prefix(self): - config = self._makeOne(autocommit=True) - config.route_prefix = 'root' - config.add_route('name', 'path') - self._assertRoute(config, 'name', 'root/path') - - def test_add_route_discriminator(self): - config = self._makeOne() - config.add_route('name', 'path') - self.assertEqual(config.action_state.actions[-1]['discriminator'], - ('route', 'name')) - - def test_add_route_with_factory(self): - config = self._makeOne(autocommit=True) - factory = object() - config.add_route('name', 'path', factory=factory) - route = self._assertRoute(config, 'name', 'path') - self.assertEqual(route.factory, factory) - - def test_add_route_with_static(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path/{foo}', static=True) - mapper = config.get_routes_mapper() - self.assertEqual(len(mapper.get_routes()), 0) - self.assertEqual(mapper.generate('name', {"foo":"a"}), '/path/a') - - def test_add_route_with_factory_dottedname(self): - config = self._makeOne(autocommit=True) - config.add_route( - 'name', 'path', - factory='pyramid.tests.test_config.dummyfactory') - route = self._assertRoute(config, 'name', 'path') - self.assertEqual(route.factory, dummyfactory) - - def test_add_route_with_xhr(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', xhr=True) - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.is_xhr = True - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.is_xhr = False - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_request_method(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', request_method='GET') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.method = 'GET' - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.method = 'POST' - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_path_info(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', path_info='/foo') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.upath_info = '/foo' - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.upath_info = '/' - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_path_info_highorder(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', - path_info=text_(b'/La Pe\xc3\xb1a', 'utf-8')) - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.upath_info = text_(b'/La Pe\xc3\xb1a', 'utf-8') - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.upath_info = text_('/') - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_path_info_regex(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', - path_info=text_(br'/La Pe\w*', 'utf-8')) - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.upath_info = text_(b'/La Pe\xc3\xb1a', 'utf-8') - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.upath_info = text_('/') - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_request_param(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', request_param='abc') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.params = {'abc':'123'} - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.params = {} - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_custom_predicates(self): - import warnings - config = self._makeOne(autocommit=True) - def pred1(context, request): pass - def pred2(context, request): pass - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - config.add_route('name', 'path', custom_predicates=(pred1, pred2)) - self.assertEqual(len(w), 1) - route = self._assertRoute(config, 'name', 'path', 2) - self.assertEqual(len(route.predicates), 2) - - def test_add_route_with_header(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', header='Host') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.headers = {'Host':'example.com'} - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.headers = {} - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_accept(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', accept='text/xml') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.accept = DummyAccept('text/xml') - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = DummyAccept('text/html') - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_accept_list(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', accept=['text/xml', 'text/plain']) - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.accept = DummyAccept('text/xml') - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = DummyAccept('text/plain') - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = DummyAccept('text/html') - self.assertEqual(predicate(None, request), False) - - def test_add_route_with_wildcard_accept(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'path', accept='text/*') - route = self._assertRoute(config, 'name', 'path', 1) - predicate = route.predicates[0] - request = self._makeRequest(config) - request.accept = DummyAccept('text/xml', contains=True) - self.assertEqual(predicate(None, request), True) - request = self._makeRequest(config) - request.accept = DummyAccept('application/json', contains=False) - self.assertEqual(predicate(None, request), False) - - def test_add_route_no_pattern_with_path(self): - config = self._makeOne(autocommit=True) - config.add_route('name', path='path') - self._assertRoute(config, 'name', 'path') - - def test_add_route_no_path_no_pattern(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_route, 'name') - - def test_add_route_with_pregenerator(self): - config = self._makeOne(autocommit=True) - config.add_route('name', 'pattern', pregenerator='123') - route = self._assertRoute(config, 'name', 'pattern') - self.assertEqual(route.pregenerator, '123') - - def test_add_route_no_view_with_view_attr(self): - config = self._makeOne(autocommit=True) - from pyramid.exceptions import ConfigurationError - try: - config.add_route('name', '/pattern', view_attr='abc') - except ConfigurationError: - pass - else: # pragma: no cover - raise AssertionError - - def test_add_route_no_view_with_view_context(self): - config = self._makeOne(autocommit=True) - from pyramid.exceptions import ConfigurationError - try: - config.add_route('name', '/pattern', view_context=DummyContext) - except ConfigurationError: - pass - else: # pragma: no cover - raise AssertionError - - def test_add_route_no_view_with_view_permission(self): - config = self._makeOne(autocommit=True) - from pyramid.exceptions import ConfigurationError - try: - config.add_route('name', '/pattern', view_permission='edit') - except ConfigurationError: - pass - else: # pragma: no cover - raise AssertionError - - def test_add_route_no_view_with_view_renderer(self): - config = self._makeOne(autocommit=True) - from pyramid.exceptions import ConfigurationError - try: - config.add_route('name', '/pattern', view_renderer='json') - except ConfigurationError: - pass - else: # pragma: no cover - raise AssertionError - -class DummyRequest: - subpath = () - matchdict = None - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.params = {} - self.cookies = {} - -class DummyAccept(object): - def __init__(self, *matches, **kw): - self.matches = list(matches) - self.contains = kw.pop('contains', False) - - def acceptable_offers(self, offers): - results = [] - for match in self.matches: - if match in offers: - results.append((match, 1.0)) - return results - - def __contains__(self, value): - return self.contains diff --git a/src/pyramid/tests/test_config/test_security.py b/src/pyramid/tests/test_config/test_security.py deleted file mode 100644 index 5db8e21fc..000000000 --- a/src/pyramid/tests/test_config/test_security.py +++ /dev/null @@ -1,125 +0,0 @@ -import unittest - -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationError - -class ConfiguratorSecurityMethodsTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_set_authentication_policy_no_authz_policy(self): - config = self._makeOne() - policy = object() - config.set_authentication_policy(policy) - self.assertRaises(ConfigurationExecutionError, config.commit) - - def test_set_authentication_policy_no_authz_policy_autocommit(self): - config = self._makeOne(autocommit=True) - policy = object() - self.assertRaises(ConfigurationError, - config.set_authentication_policy, policy) - - def test_set_authentication_policy_with_authz_policy(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - config = self._makeOne() - authn_policy = object() - authz_policy = object() - config.registry.registerUtility(authz_policy, IAuthorizationPolicy) - config.set_authentication_policy(authn_policy) - config.commit() - self.assertEqual( - config.registry.getUtility(IAuthenticationPolicy), authn_policy) - - def test_set_authentication_policy_with_authz_policy_autocommit(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - config = self._makeOne(autocommit=True) - authn_policy = object() - authz_policy = object() - config.registry.registerUtility(authz_policy, IAuthorizationPolicy) - config.set_authentication_policy(authn_policy) - config.commit() - self.assertEqual( - config.registry.getUtility(IAuthenticationPolicy), authn_policy) - - def test_set_authorization_policy_no_authn_policy(self): - config = self._makeOne() - policy = object() - config.set_authorization_policy(policy) - self.assertRaises(ConfigurationExecutionError, config.commit) - - def test_set_authorization_policy_no_authn_policy_autocommit(self): - from pyramid.interfaces import IAuthorizationPolicy - config = self._makeOne(autocommit=True) - policy = object() - config.set_authorization_policy(policy) - self.assertEqual( - config.registry.getUtility(IAuthorizationPolicy), policy) - - def test_set_authorization_policy_with_authn_policy(self): - from pyramid.interfaces import IAuthorizationPolicy - from pyramid.interfaces import IAuthenticationPolicy - config = self._makeOne() - authn_policy = object() - authz_policy = object() - config.registry.registerUtility(authn_policy, IAuthenticationPolicy) - config.set_authorization_policy(authz_policy) - config.commit() - self.assertEqual( - config.registry.getUtility(IAuthorizationPolicy), authz_policy) - - def test_set_authorization_policy_with_authn_policy_autocommit(self): - from pyramid.interfaces import IAuthorizationPolicy - from pyramid.interfaces import IAuthenticationPolicy - config = self._makeOne(autocommit=True) - authn_policy = object() - authz_policy = object() - config.registry.registerUtility(authn_policy, IAuthenticationPolicy) - config.set_authorization_policy(authz_policy) - self.assertEqual( - config.registry.getUtility(IAuthorizationPolicy), authz_policy) - - def test_set_default_permission(self): - from pyramid.interfaces import IDefaultPermission - config = self._makeOne(autocommit=True) - config.set_default_permission('view') - self.assertEqual(config.registry.getUtility(IDefaultPermission), - 'view') - - def test_add_permission(self): - config = self._makeOne(autocommit=True) - config.add_permission('perm') - cat = config.registry.introspector.get_category('permissions') - self.assertEqual(len(cat), 1) - D = cat[0] - intr = D['introspectable'] - self.assertEqual(intr['value'], 'perm') - - def test_set_default_csrf_options(self): - from pyramid.interfaces import IDefaultCSRFOptions - config = self._makeOne(autocommit=True) - config.set_default_csrf_options() - result = config.registry.getUtility(IDefaultCSRFOptions) - self.assertEqual(result.require_csrf, True) - self.assertEqual(result.token, 'csrf_token') - self.assertEqual(result.header, 'X-CSRF-Token') - self.assertEqual(list(sorted(result.safe_methods)), - ['GET', 'HEAD', 'OPTIONS', 'TRACE']) - self.assertTrue(result.callback is None) - - def test_changing_set_default_csrf_options(self): - from pyramid.interfaces import IDefaultCSRFOptions - config = self._makeOne(autocommit=True) - def callback(request): return True - config.set_default_csrf_options( - require_csrf=False, token='DUMMY', header=None, - safe_methods=('PUT',), callback=callback) - result = config.registry.getUtility(IDefaultCSRFOptions) - self.assertEqual(result.require_csrf, False) - self.assertEqual(result.token, 'DUMMY') - self.assertEqual(result.header, None) - self.assertEqual(list(sorted(result.safe_methods)), ['PUT']) - self.assertTrue(result.callback is callback) diff --git a/src/pyramid/tests/test_config/test_settings.py b/src/pyramid/tests/test_config/test_settings.py deleted file mode 100644 index a3afd24e7..000000000 --- a/src/pyramid/tests/test_config/test_settings.py +++ /dev/null @@ -1,582 +0,0 @@ -import unittest - - -class TestSettingsConfiguratorMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test__set_settings_as_None(self): - config = self._makeOne() - settings = config._set_settings(None) - self.assertTrue(settings) - - def test__set_settings_does_not_uses_original_dict(self): - config = self._makeOne() - dummy = {} - result = config._set_settings(dummy) - self.assertTrue(dummy is not result) - self.assertNotIn('pyramid.debug_all', dummy) - - def test__set_settings_as_dictwithvalues(self): - config = self._makeOne() - settings = config._set_settings({'a':'1'}) - self.assertEqual(settings['a'], '1') - - def test_get_settings_nosettings(self): - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg) - self.assertEqual(config.get_settings(), None) - - def test_get_settings_withsettings(self): - settings = {'a':1} - config = self._makeOne() - config.registry.settings = settings - self.assertEqual(config.get_settings(), settings) - - def test_add_settings_settings_already_registered(self): - from pyramid.registry import Registry - reg = Registry() - config = self._makeOne(reg) - config._set_settings({'a':1}) - config.add_settings({'b':2}) - settings = reg.settings - self.assertEqual(settings['a'], 1) - self.assertEqual(settings['b'], 2) - - def test_add_settings_settings_not_yet_registered(self): - from pyramid.registry import Registry - from pyramid.interfaces import ISettings - reg = Registry() - config = self._makeOne(reg) - config.add_settings({'a':1}) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - - def test_add_settings_settings_None(self): - from pyramid.registry import Registry - from pyramid.interfaces import ISettings - reg = Registry() - config = self._makeOne(reg) - config.add_settings(None, a=1) - settings = reg.getUtility(ISettings) - self.assertEqual(settings['a'], 1) - - def test_settings_parameter_dict_is_never_updated(self): - class ReadOnlyDict(dict): - def __readonly__(self, *args, **kwargs): # pragma: no cover - raise RuntimeError("Cannot modify ReadOnlyDict") - __setitem__ = __readonly__ - __delitem__ = __readonly__ - pop = __readonly__ - popitem = __readonly__ - clear = __readonly__ - update = __readonly__ - setdefault = __readonly__ - del __readonly__ - - initial = ReadOnlyDict() - config = self._makeOne(settings=initial) - config._set_settings({'a': '1'}) - - -class TestSettings(unittest.TestCase): - - def _getTargetClass(self): - from pyramid.config.settings import Settings - return Settings - - def _makeOne(self, d=None, environ=None): - if environ is None: - environ = {} - klass = self._getTargetClass() - return klass(d, _environ_=environ) - - def test_noargs(self): - settings = self._makeOne() - self.assertEqual(settings['debug_authorization'], False) - self.assertEqual(settings['debug_notfound'], False) - self.assertEqual(settings['debug_routematch'], False) - self.assertEqual(settings['reload_templates'], False) - self.assertEqual(settings['reload_resources'], False) - - self.assertEqual(settings['pyramid.debug_authorization'], False) - self.assertEqual(settings['pyramid.debug_notfound'], False) - self.assertEqual(settings['pyramid.debug_routematch'], False) - self.assertEqual(settings['pyramid.reload_templates'], False) - self.assertEqual(settings['pyramid.reload_resources'], False) - - def test_prevent_http_cache(self): - settings = self._makeOne({}) - self.assertEqual(settings['prevent_http_cache'], False) - self.assertEqual(settings['pyramid.prevent_http_cache'], False) - result = self._makeOne({'prevent_http_cache':'false'}) - self.assertEqual(result['prevent_http_cache'], False) - self.assertEqual(result['pyramid.prevent_http_cache'], False) - result = self._makeOne({'prevent_http_cache':'t'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - result = self._makeOne({'prevent_http_cache':'1'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - result = self._makeOne({'pyramid.prevent_http_cache':'t'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - result = self._makeOne({}, {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - result = self._makeOne({'prevent_http_cache':'false', - 'pyramid.prevent_http_cache':'1'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - result = self._makeOne({'prevent_http_cache':'false', - 'pyramid.prevent_http_cache':'f'}, - {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) - self.assertEqual(result['prevent_http_cache'], True) - self.assertEqual(result['pyramid.prevent_http_cache'], True) - - def test_prevent_cachebust(self): - settings = self._makeOne({}) - self.assertEqual(settings['prevent_cachebust'], False) - self.assertEqual(settings['pyramid.prevent_cachebust'], False) - result = self._makeOne({'prevent_cachebust':'false'}) - self.assertEqual(result['prevent_cachebust'], False) - self.assertEqual(result['pyramid.prevent_cachebust'], False) - result = self._makeOne({'prevent_cachebust':'t'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - result = self._makeOne({'prevent_cachebust':'1'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - result = self._makeOne({'pyramid.prevent_cachebust':'t'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - result = self._makeOne({}, {'PYRAMID_PREVENT_CACHEBUST':'1'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - result = self._makeOne({'prevent_cachebust':'false', - 'pyramid.prevent_cachebust':'1'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - result = self._makeOne({'prevent_cachebust':'false', - 'pyramid.prevent_cachebust':'f'}, - {'PYRAMID_PREVENT_CACHEBUST':'1'}) - self.assertEqual(result['prevent_cachebust'], True) - self.assertEqual(result['pyramid.prevent_cachebust'], True) - - def test_reload_templates(self): - settings = self._makeOne({}) - self.assertEqual(settings['reload_templates'], False) - self.assertEqual(settings['pyramid.reload_templates'], False) - result = self._makeOne({'reload_templates':'false'}) - self.assertEqual(result['reload_templates'], False) - self.assertEqual(result['pyramid.reload_templates'], False) - result = self._makeOne({'reload_templates':'t'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - result = self._makeOne({'reload_templates':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - result = self._makeOne({'pyramid.reload_templates':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - result = self._makeOne({}, {'PYRAMID_RELOAD_TEMPLATES':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - result = self._makeOne({'reload_templates':'false', - 'pyramid.reload_templates':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - result = self._makeOne({'reload_templates':'false'}, - {'PYRAMID_RELOAD_TEMPLATES':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - - def test_reload_resources(self): - # alias for reload_assets - result = self._makeOne({}) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - result = self._makeOne({'reload_resources':'false'}) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - result = self._makeOne({'reload_resources':'t'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_resources':'1'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'pyramid.reload_resources':'1'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({}, {'PYRAMID_RELOAD_RESOURCES':'1'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_resources':'false', - 'pyramid.reload_resources':'1'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_resources':'false', - 'pyramid.reload_resources':'false'}, - {'PYRAMID_RELOAD_RESOURCES':'1'}) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - - def test_reload_assets(self): - # alias for reload_resources - result = self._makeOne({}) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - result = self._makeOne({'reload_assets':'false'}) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - result = self._makeOne({'reload_assets':'t'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - result = self._makeOne({'reload_assets':'1'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - result = self._makeOne({'pyramid.reload_assets':'1'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - result = self._makeOne({}, {'PYRAMID_RELOAD_ASSETS':'1'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - result = self._makeOne({'reload_assets':'false', - 'pyramid.reload_assets':'1'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - result = self._makeOne({'reload_assets':'false', - 'pyramid.reload_assets':'false'}, - {'PYRAMID_RELOAD_ASSETS':'1'}) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - - def test_reload_all(self): - result = self._makeOne({}) - self.assertEqual(result['reload_templates'], False) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['pyramid.reload_templates'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - result = self._makeOne({'reload_all':'false'}) - self.assertEqual(result['reload_templates'], False) - self.assertEqual(result['reload_resources'], False) - self.assertEqual(result['reload_assets'], False) - self.assertEqual(result['pyramid.reload_templates'], False) - self.assertEqual(result['pyramid.reload_resources'], False) - self.assertEqual(result['pyramid.reload_assets'], False) - result = self._makeOne({'reload_all':'t'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_all':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'pyramid.reload_all':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({}, {'PYRAMID_RELOAD_ALL':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_all':'false', - 'pyramid.reload_all':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - result = self._makeOne({'reload_all':'false', - 'pyramid.reload_all':'false'}, - {'PYRAMID_RELOAD_ALL':'1'}) - self.assertEqual(result['reload_templates'], True) - self.assertEqual(result['reload_resources'], True) - self.assertEqual(result['reload_assets'], True) - self.assertEqual(result['pyramid.reload_templates'], True) - self.assertEqual(result['pyramid.reload_resources'], True) - self.assertEqual(result['pyramid.reload_assets'], True) - - def test_debug_authorization(self): - result = self._makeOne({}) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['pyramid.debug_authorization'], False) - result = self._makeOne({'debug_authorization':'false'}) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['pyramid.debug_authorization'], False) - result = self._makeOne({'debug_authorization':'t'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - result = self._makeOne({'debug_authorization':'1'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - result = self._makeOne({'pyramid.debug_authorization':'1'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - result = self._makeOne({}, {'PYRAMID_DEBUG_AUTHORIZATION':'1'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - result = self._makeOne({'debug_authorization':'false', - 'pyramid.debug_authorization':'1'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - result = self._makeOne({'debug_authorization':'false', - 'pyramid.debug_authorization':'false'}, - {'PYRAMID_DEBUG_AUTHORIZATION':'1'}) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - - def test_debug_notfound(self): - result = self._makeOne({}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['pyramid.debug_notfound'], False) - result = self._makeOne({'debug_notfound':'false'}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['pyramid.debug_notfound'], False) - result = self._makeOne({'debug_notfound':'t'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - result = self._makeOne({'debug_notfound':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - result = self._makeOne({'pyramid.debug_notfound':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - result = self._makeOne({}, {'PYRAMID_DEBUG_NOTFOUND':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - result = self._makeOne({'debug_notfound':'false', - 'pyramid.debug_notfound':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - result = self._makeOne({'debug_notfound':'false', - 'pyramid.debug_notfound':'false'}, - {'PYRAMID_DEBUG_NOTFOUND':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - - def test_debug_routematch(self): - result = self._makeOne({}) - self.assertEqual(result['debug_routematch'], False) - self.assertEqual(result['pyramid.debug_routematch'], False) - result = self._makeOne({'debug_routematch':'false'}) - self.assertEqual(result['debug_routematch'], False) - self.assertEqual(result['pyramid.debug_routematch'], False) - result = self._makeOne({'debug_routematch':'t'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - result = self._makeOne({'debug_routematch':'1'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - result = self._makeOne({'pyramid.debug_routematch':'1'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - result = self._makeOne({}, {'PYRAMID_DEBUG_ROUTEMATCH':'1'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - result = self._makeOne({'debug_routematch':'false', - 'pyramid.debug_routematch':'1'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - result = self._makeOne({'debug_routematch':'false', - 'pyramid.debug_routematch':'false'}, - {'PYRAMID_DEBUG_ROUTEMATCH':'1'}) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - - def test_debug_templates(self): - result = self._makeOne({}) - self.assertEqual(result['debug_templates'], False) - self.assertEqual(result['pyramid.debug_templates'], False) - result = self._makeOne({'debug_templates':'false'}) - self.assertEqual(result['debug_templates'], False) - self.assertEqual(result['pyramid.debug_templates'], False) - result = self._makeOne({'debug_templates':'t'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_templates':'1'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'pyramid.debug_templates':'1'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({}, {'PYRAMID_DEBUG_TEMPLATES':'1'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_templates':'false', - 'pyramid.debug_templates':'1'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_templates':'false', - 'pyramid.debug_templates':'false'}, - {'PYRAMID_DEBUG_TEMPLATES':'1'}) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - - def test_debug_all(self): - result = self._makeOne({}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_routematch'], False) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['debug_templates'], False) - self.assertEqual(result['pyramid.debug_notfound'], False) - self.assertEqual(result['pyramid.debug_routematch'], False) - self.assertEqual(result['pyramid.debug_authorization'], False) - self.assertEqual(result['pyramid.debug_templates'], False) - result = self._makeOne({'debug_all':'false'}) - self.assertEqual(result['debug_notfound'], False) - self.assertEqual(result['debug_routematch'], False) - self.assertEqual(result['debug_authorization'], False) - self.assertEqual(result['debug_templates'], False) - self.assertEqual(result['pyramid.debug_notfound'], False) - self.assertEqual(result['pyramid.debug_routematch'], False) - self.assertEqual(result['pyramid.debug_authorization'], False) - self.assertEqual(result['pyramid.debug_templates'], False) - result = self._makeOne({'debug_all':'t'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_all':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'pyramid.debug_all':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({}, {'PYRAMID_DEBUG_ALL':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_all':'false', - 'pyramid.debug_all':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - result = self._makeOne({'debug_all':'false', - 'pyramid.debug_all':'false'}, - {'PYRAMID_DEBUG_ALL':'1'}) - self.assertEqual(result['debug_notfound'], True) - self.assertEqual(result['debug_routematch'], True) - self.assertEqual(result['debug_authorization'], True) - self.assertEqual(result['debug_templates'], True) - self.assertEqual(result['pyramid.debug_notfound'], True) - self.assertEqual(result['pyramid.debug_routematch'], True) - self.assertEqual(result['pyramid.debug_authorization'], True) - self.assertEqual(result['pyramid.debug_templates'], True) - - def test_default_locale_name(self): - result = self._makeOne({}) - self.assertEqual(result['default_locale_name'], 'en') - self.assertEqual(result['pyramid.default_locale_name'], 'en') - result = self._makeOne({'default_locale_name':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - self.assertEqual(result['pyramid.default_locale_name'], 'abc') - result = self._makeOne({'pyramid.default_locale_name':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - self.assertEqual(result['pyramid.default_locale_name'], 'abc') - result = self._makeOne({}, {'PYRAMID_DEFAULT_LOCALE_NAME':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - self.assertEqual(result['pyramid.default_locale_name'], 'abc') - result = self._makeOne({'default_locale_name':'def', - 'pyramid.default_locale_name':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - self.assertEqual(result['pyramid.default_locale_name'], 'abc') - result = self._makeOne({'default_locale_name':'def', - 'pyramid.default_locale_name':'ghi'}, - {'PYRAMID_DEFAULT_LOCALE_NAME':'abc'}) - self.assertEqual(result['default_locale_name'], 'abc') - self.assertEqual(result['pyramid.default_locale_name'], 'abc') - - def test_csrf_trusted_origins(self): - result = self._makeOne({}) - self.assertEqual(result['pyramid.csrf_trusted_origins'], []) - result = self._makeOne({'pyramid.csrf_trusted_origins': 'example.com'}) - self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) - result = self._makeOne({'pyramid.csrf_trusted_origins': ['example.com']}) - self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) - result = self._makeOne({'pyramid.csrf_trusted_origins': ( - 'example.com foo.example.com\nasdf.example.com')}) - self.assertEqual(result['pyramid.csrf_trusted_origins'], [ - 'example.com', 'foo.example.com', 'asdf.example.com']) - - def test_originals_kept(self): - result = self._makeOne({'a':'i am so a'}) - self.assertEqual(result['a'], 'i am so a') - - diff --git a/src/pyramid/tests/test_config/test_testing.py b/src/pyramid/tests/test_config/test_testing.py deleted file mode 100644 index 05561bfe9..000000000 --- a/src/pyramid/tests/test_config/test_testing.py +++ /dev/null @@ -1,205 +0,0 @@ -import unittest - -from pyramid.compat import text_ -from pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin -from pyramid.tests.test_config import IDummy - -class TestingConfiguratorMixinTests(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_testing_securitypolicy(self): - from pyramid.testing import DummySecurityPolicy - config = self._makeOne(autocommit=True) - config.testing_securitypolicy('user', ('group1', 'group2'), - permissive=False) - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - ut = config.registry.getUtility(IAuthenticationPolicy) - self.assertTrue(isinstance(ut, DummySecurityPolicy)) - ut = config.registry.getUtility(IAuthorizationPolicy) - self.assertEqual(ut.userid, 'user') - self.assertEqual(ut.groupids, ('group1', 'group2')) - self.assertEqual(ut.permissive, False) - - def test_testing_securitypolicy_remember_result(self): - from pyramid.security import remember - config = self._makeOne(autocommit=True) - pol = config.testing_securitypolicy( - 'user', ('group1', 'group2'), - permissive=False, remember_result=True) - request = DummyRequest() - request.registry = config.registry - val = remember(request, 'fred') - self.assertEqual(pol.remembered, 'fred') - self.assertEqual(val, True) - - def test_testing_securitypolicy_forget_result(self): - from pyramid.security import forget - config = self._makeOne(autocommit=True) - pol = config.testing_securitypolicy( - 'user', ('group1', 'group2'), - permissive=False, forget_result=True) - request = DummyRequest() - request.registry = config.registry - val = forget(request) - self.assertEqual(pol.forgotten, True) - self.assertEqual(val, True) - - def test_testing_resources(self): - from pyramid.traversal import find_resource - from pyramid.interfaces import ITraverser - ob1 = object() - ob2 = object() - resources = {'/ob1':ob1, '/ob2':ob2} - config = self._makeOne(autocommit=True) - config.testing_resources(resources) - adapter = config.registry.getAdapter(None, ITraverser) - result = adapter(DummyRequest({'PATH_INFO':'/ob1'})) - self.assertEqual(result['context'], ob1) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (text_('ob1'),)) - self.assertEqual(result['virtual_root'], ob1) - self.assertEqual(result['virtual_root_path'], ()) - result = adapter(DummyRequest({'PATH_INFO':'/ob2'})) - self.assertEqual(result['context'], ob2) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (text_('ob2'),)) - self.assertEqual(result['virtual_root'], ob2) - self.assertEqual(result['virtual_root_path'], ()) - self.assertRaises(KeyError, adapter, DummyRequest({'PATH_INFO':'/ob3'})) - try: - config.begin() - self.assertEqual(find_resource(None, '/ob1'), ob1) - finally: - config.end() - - def test_testing_add_subscriber_single(self): - config = self._makeOne(autocommit=True) - L = config.testing_add_subscriber(IDummy) - event = DummyEvent() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_testing_add_subscriber_dottedname(self): - config = self._makeOne(autocommit=True) - L = config.testing_add_subscriber( - 'pyramid.tests.test_config.test_init.IDummy') - event = DummyEvent() - config.registry.notify(event) - self.assertEqual(len(L), 1) - self.assertEqual(L[0], event) - config.registry.notify(object()) - self.assertEqual(len(L), 1) - - def test_testing_add_subscriber_multiple(self): - from zope.interface import Interface - config = self._makeOne(autocommit=True) - L = config.testing_add_subscriber((Interface, IDummy)) - event = DummyEvent() - event.object = 'foo' - # the below is the equivalent of z.c.event.objectEventNotify(event) - config.registry.subscribers((event.object, event), None) - self.assertEqual(len(L), 2) - self.assertEqual(L[0], 'foo') - self.assertEqual(L[1], event) - - def test_testing_add_subscriber_defaults(self): - config = self._makeOne(autocommit=True) - L = config.testing_add_subscriber() - event = object() - config.registry.notify(event) - self.assertEqual(L[-1], event) - event2 = object() - config.registry.notify(event2) - self.assertEqual(L[-1], event2) - - def test_testing_add_renderer(self): - config = self._makeOne(autocommit=True) - renderer = config.testing_add_renderer('templates/foo.pt') - from pyramid.testing import DummyTemplateRenderer - self.assertTrue(isinstance(renderer, DummyTemplateRenderer)) - from pyramid.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - render_to_response( - 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) - renderer.assert_(foo=1) - renderer.assert_(bar=2) - renderer.assert_(request=request) - - def test_testing_add_renderer_twice(self): - config = self._makeOne(autocommit=True) - renderer1 = config.testing_add_renderer('templates/foo.pt') - renderer2 = config.testing_add_renderer('templates/bar.pt') - from pyramid.testing import DummyTemplateRenderer - self.assertTrue(isinstance(renderer1, DummyTemplateRenderer)) - self.assertTrue(isinstance(renderer2, DummyTemplateRenderer)) - from pyramid.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - render_to_response( - 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) - renderer1.assert_(foo=1) - renderer1.assert_(bar=2) - renderer1.assert_(request=request) - render_to_response( - 'templates/bar.pt', {'foo':1, 'bar':2}, request=request) - renderer2.assert_(foo=1) - renderer2.assert_(bar=2) - renderer2.assert_(request=request) - - def test_testing_add_renderer_explicitrenderer(self): - config = self._makeOne(autocommit=True) - class E(Exception): pass - def renderer(kw, system): - self.assertEqual(kw, {'foo':1, 'bar':2}) - raise E - renderer = config.testing_add_renderer('templates/foo.pt', renderer) - from pyramid.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - try: - render_to_response( - 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) - except E: - pass - else: # pragma: no cover - raise AssertionError - - def test_testing_add_template(self): - config = self._makeOne(autocommit=True) - renderer = config.testing_add_template('templates/foo.pt') - from pyramid.testing import DummyTemplateRenderer - self.assertTrue(isinstance(renderer, DummyTemplateRenderer)) - from pyramid.renderers import render_to_response - # must provide request to pass in registry (this is a functest) - request = DummyRequest() - request.registry = config.registry - render_to_response('templates/foo.pt', dict(foo=1, bar=2), - request=request) - renderer.assert_(foo=1) - renderer.assert_(bar=2) - renderer.assert_(request=request) - -from zope.interface import implementer -@implementer(IDummy) -class DummyEvent: - pass - -class DummyRequest(AuthenticationAPIMixin, AuthorizationAPIMixin): - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - diff --git a/src/pyramid/tests/test_config/test_tweens.py b/src/pyramid/tests/test_config/test_tweens.py deleted file mode 100644 index 9c3433468..000000000 --- a/src/pyramid/tests/test_config/test_tweens.py +++ /dev/null @@ -1,410 +0,0 @@ -import unittest - -from pyramid.tests.test_config import dummy_tween_factory -from pyramid.tests.test_config import dummy_tween_factory2 - -from pyramid.exceptions import ConfigurationConflictError - -class TestTweensConfiguratorMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_add_tweens_names_distinct(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - def factory1(handler, registry): return handler - def factory2(handler, registry): return handler - config = self._makeOne() - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory') - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory2') - config.commit() - tweens = config.registry.queryUtility(ITweens) - implicit = tweens.implicit() - self.assertEqual( - implicit, - [ - ('pyramid.tests.test_config.dummy_tween_factory2', - dummy_tween_factory2), - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tweens.excview_tween_factory', - excview_tween_factory), - ] - ) - - def test_add_tweens_names_with_underover(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - from pyramid.tweens import MAIN - config = self._makeOne() - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory', - over=MAIN) - config.add_tween( - 'pyramid.tests.test_config.dummy_tween_factory2', - over=MAIN, - under='pyramid.tests.test_config.dummy_tween_factory') - config.commit() - tweens = config.registry.queryUtility(ITweens) - implicit = tweens.implicit() - self.assertEqual( - implicit, - [ - ('pyramid.tweens.excview_tween_factory', excview_tween_factory), - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tests.test_config.dummy_tween_factory2', - dummy_tween_factory2), - ]) - - def test_add_tweens_names_with_under_nonstringoriter(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises( - ConfigurationError, config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=False) - - def test_add_tweens_names_with_over_nonstringoriter(self): - from pyramid.exceptions import ConfigurationError - config = self._makeOne() - self.assertRaises( - ConfigurationError, config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=False) - - def test_add_tween_dottedname(self): - from pyramid.interfaces import ITweens - from pyramid.tweens import excview_tween_factory - config = self._makeOne() - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - config.commit() - tweens = config.registry.queryUtility(ITweens) - self.assertEqual( - tweens.implicit(), - [ - ('pyramid.tests.test_config.dummy_tween_factory', - dummy_tween_factory), - ('pyramid.tweens.excview_tween_factory', - excview_tween_factory), - ]) - - def test_add_tween_instance(self): - from pyramid.exceptions import ConfigurationError - class ATween(object): pass - atween = ATween() - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, atween) - - def test_add_tween_unsuitable(self): - from pyramid.exceptions import ConfigurationError - import pyramid.tests.test_config - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, - pyramid.tests.test_config) - - def test_add_tween_name_ingress(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, INGRESS) - - def test_add_tween_name_main(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises(ConfigurationError, config.add_tween, MAIN) - - def test_add_tweens_conflict(self): - config = self._makeOne() - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - config.add_tween('pyramid.tests.test_config.dummy_tween_factory') - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_tween_over_ingress(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=INGRESS) - - def test_add_tween_over_ingress_iterable(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import INGRESS - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - over=('a', INGRESS)) - - def test_add_tween_under_main(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=MAIN) - - def test_add_tween_under_main_iterable(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - config = self._makeOne() - self.assertRaises( - ConfigurationError, - config.add_tween, - 'pyramid.tests.test_config.dummy_tween_factory', - under=('a', MAIN)) - -class TestTweens(unittest.TestCase): - def _makeOne(self): - from pyramid.config.tweens import Tweens - return Tweens() - - def test_add_explicit(self): - tweens = self._makeOne() - tweens.add_explicit('name', 'factory') - self.assertEqual(tweens.explicit, [('name', 'factory')]) - tweens.add_explicit('name2', 'factory2') - self.assertEqual(tweens.explicit, [('name', 'factory'), - ('name2', 'factory2')]) - - def test_add_implicit(self): - tweens = self._makeOne() - tweens.add_implicit('name', 'factory') - tweens.add_implicit('name2', 'factory2') - self.assertEqual(tweens.sorter.sorted(), - [('name2', 'factory2'), - ('name', 'factory')]) - - def test___call___explicit(self): - tweens = self._makeOne() - def factory1(handler, registry): - return handler - def factory2(handler, registry): - return '123' - tweens.explicit = [('name', factory1), ('name', factory2)] - self.assertEqual(tweens(None, None), '123') - - def test___call___implicit(self): - tweens = self._makeOne() - def factory1(handler, registry): - return handler - def factory2(handler, registry): - return '123' - tweens.add_implicit('name2', factory2) - tweens.add_implicit('name1', factory1) - self.assertEqual(tweens(None, None), '123') - - def test_implicit_ordering_1(self): - tweens = self._makeOne() - tweens.add_implicit('name1', 'factory1') - tweens.add_implicit('name2', 'factory2') - self.assertEqual(tweens.implicit(), - [ - ('name2', 'factory2'), - ('name1', 'factory1'), - ]) - - def test_implicit_ordering_2(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - tweens.add_implicit('name1', 'factory1') - tweens.add_implicit('name2', 'factory2', over=MAIN) - self.assertEqual(tweens.implicit(), - [ - ('name1', 'factory1'), - ('name2', 'factory2'), - ]) - - def test_implicit_ordering_3(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('auth', 'auth_factory', under='browserid') - add('dbt', 'dbt_factory') - add('retry', 'retry_factory', over='txnmgr', under='exceptionview') - add('browserid', 'browserid_factory') - add('txnmgr', 'txnmgr_factory', under='exceptionview') - add('exceptionview', 'excview_factory', over=MAIN) - self.assertEqual(tweens.implicit(), - [ - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('dbt', 'dbt_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ]) - - def test_implicit_ordering_4(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('auth', 'auth_factory', under='browserid') - add('retry', 'retry_factory', over='txnmgr', under='exceptionview') - add('browserid', 'browserid_factory') - add('txnmgr', 'txnmgr_factory', under='exceptionview') - add('dbt', 'dbt_factory') - self.assertEqual(tweens.implicit(), - [ - ('dbt', 'dbt_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ]) - - def test_implicit_ordering_5(self): - from pyramid.tweens import MAIN, INGRESS - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('auth', 'auth_factory', under=INGRESS) - add('retry', 'retry_factory', over='txnmgr', under='exceptionview') - add('browserid', 'browserid_factory', under=INGRESS) - add('txnmgr', 'txnmgr_factory', under='exceptionview', over=MAIN) - add('dbt', 'dbt_factory') - self.assertEqual(tweens.implicit(), - [ - ('dbt', 'dbt_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ]) - - def test_implicit_ordering_missing_over_partial(self): - from pyramid.exceptions import ConfigurationError - tweens = self._makeOne() - add = tweens.add_implicit - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', under='browserid') - add('retry', 'retry_factory', over='txnmgr', under='exceptionview') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, tweens.implicit) - - def test_implicit_ordering_missing_under_partial(self): - from pyramid.exceptions import ConfigurationError - tweens = self._makeOne() - add = tweens.add_implicit - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', under='txnmgr') - add('retry', 'retry_factory', over='dbt', under='exceptionview') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, tweens.implicit) - - def test_implicit_ordering_missing_over_and_under_partials(self): - from pyramid.exceptions import ConfigurationError - tweens = self._makeOne() - add = tweens.add_implicit - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', under='browserid') - add('retry', 'retry_factory', over='foo', under='txnmgr') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, tweens.implicit) - - def test_implicit_ordering_missing_over_partial_with_fallback(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('auth', 'auth_factory', under='browserid') - add('retry', 'retry_factory', over=('txnmgr',MAIN), - under='exceptionview') - add('browserid', 'browserid_factory') - add('dbt', 'dbt_factory') - self.assertEqual(tweens.implicit(), - [ - ('dbt', 'dbt_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_implicit_ordering_missing_under_partial_with_fallback(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('auth', 'auth_factory', under=('txnmgr','browserid')) - add('retry', 'retry_factory', under='exceptionview') - add('browserid', 'browserid_factory') - add('dbt', 'dbt_factory') - self.assertEqual(tweens.implicit(), - [ - ('dbt', 'dbt_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_implicit_ordering_with_partial_fallbacks(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=('wontbethere', MAIN)) - add('retry', 'retry_factory', under='exceptionview') - add('browserid', 'browserid_factory', over=('wont2', 'exceptionview')) - self.assertEqual(tweens.implicit(), - [ - ('browserid', 'browserid_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_implicit_ordering_with_multiple_matching_fallbacks(self): - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('retry', 'retry_factory', under='exceptionview') - add('browserid', 'browserid_factory', over=('retry', 'exceptionview')) - self.assertEqual(tweens.implicit(), - [ - ('browserid', 'browserid_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_implicit_ordering_with_missing_fallbacks(self): - from pyramid.exceptions import ConfigurationError - from pyramid.tweens import MAIN - tweens = self._makeOne() - add = tweens.add_implicit - add('exceptionview', 'excview_factory', over=MAIN) - add('retry', 'retry_factory', under='exceptionview') - add('browserid', 'browserid_factory', over=('txnmgr', 'auth')) - self.assertRaises(ConfigurationError, tweens.implicit) - - def test_implicit_ordering_conflict_direct(self): - from pyramid.exceptions import CyclicDependencyError - tweens = self._makeOne() - add = tweens.add_implicit - add('browserid', 'browserid_factory') - add('auth', 'auth_factory', over='browserid', under='browserid') - self.assertRaises(CyclicDependencyError, tweens.implicit) - - def test_implicit_ordering_conflict_indirect(self): - from pyramid.exceptions import CyclicDependencyError - tweens = self._makeOne() - add = tweens.add_implicit - add('browserid', 'browserid_factory') - add('auth', 'auth_factory', over='browserid') - add('dbt', 'dbt_factory', under='browserid', over='auth') - self.assertRaises(CyclicDependencyError, tweens.implicit) - diff --git a/src/pyramid/tests/test_config/test_util.py b/src/pyramid/tests/test_config/test_util.py deleted file mode 100644 index 540f3d14c..000000000 --- a/src/pyramid/tests/test_config/test_util.py +++ /dev/null @@ -1,497 +0,0 @@ -import unittest - -from pyramid.compat import text_ - -class TestActionInfo(unittest.TestCase): - def _getTargetClass(self): - from pyramid.config.util import ActionInfo - return ActionInfo - - def _makeOne(self, filename, lineno, function, linerepr): - return self._getTargetClass()(filename, lineno, function, linerepr) - - def test_class_conforms(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IActionInfo - verifyClass(IActionInfo, self._getTargetClass()) - - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IActionInfo - verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f')) - - def test_ctor(self): - inst = self._makeOne('filename', 10, 'function', 'src') - self.assertEqual(inst.file, 'filename') - self.assertEqual(inst.line, 10) - self.assertEqual(inst.function, 'function') - self.assertEqual(inst.src, 'src') - - def test___str__(self): - inst = self._makeOne('filename', 0, 'function', ' linerepr ') - self.assertEqual(str(inst), - "Line 0 of file filename:\n linerepr ") - - -class TestPredicateList(unittest.TestCase): - - def _makeOne(self): - from pyramid.config.util import PredicateList - from pyramid import predicates - inst = PredicateList() - for name, factory in ( - ('xhr', predicates.XHRPredicate), - ('request_method', predicates.RequestMethodPredicate), - ('path_info', predicates.PathInfoPredicate), - ('request_param', predicates.RequestParamPredicate), - ('header', predicates.HeaderPredicate), - ('accept', predicates.AcceptPredicate), - ('containment', predicates.ContainmentPredicate), - ('request_type', predicates.RequestTypePredicate), - ('match_param', predicates.MatchParamPredicate), - ('custom', predicates.CustomPredicate), - ('traverse', predicates.TraversePredicate), - ): - inst.add(name, factory) - return inst - - def _callFUT(self, **kw): - inst = self._makeOne() - config = DummyConfigurator() - return inst.make(config, **kw) - - def test_ordering_xhr_and_request_method_trump_only_containment(self): - order1, _, _ = self._callFUT(xhr=True, request_method='GET') - order2, _, _ = self._callFUT(containment=True) - self.assertTrue(order1 < order2) - - def test_ordering_number_of_predicates(self): - from pyramid.config.util import predvalseq - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=predvalseq([DummyCustomPredicate()]), - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=predvalseq([DummyCustomPredicate()]), - ) - order3, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - ) - order4, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - containment='containment', - ) - order5, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - accept='accept', - ) - order6, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - header='header', - ) - order7, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - match_param='foo=bar', - ) - order8, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - ) - order9, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order10, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order11, _, _ = self._callFUT( - xhr='xhr', - ) - order12, _, _ = self._callFUT( - ) - self.assertEqual(order1, order2) - self.assertTrue(order3 > order2) - self.assertTrue(order4 > order3) - self.assertTrue(order5 > order4) - self.assertTrue(order6 > order5) - self.assertTrue(order7 > order6) - self.assertTrue(order8 > order7) - self.assertTrue(order9 > order8) - self.assertTrue(order10 > order9) - self.assertTrue(order11 > order10) - self.assertTrue(order12 > order10) - - def test_ordering_importance_of_predicates(self): - from pyramid.config.util import predvalseq - order1, _, _ = self._callFUT( - xhr='xhr', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - ) - order3, _, _ = self._callFUT( - path_info='path_info', - ) - order4, _, _ = self._callFUT( - request_param='param', - ) - order5, _, _ = self._callFUT( - header='header', - ) - order6, _, _ = self._callFUT( - accept='accept', - ) - order7, _, _ = self._callFUT( - containment='containment', - ) - order8, _, _ = self._callFUT( - request_type='request_type', - ) - order9, _, _ = self._callFUT( - match_param='foo=bar', - ) - order10, _, _ = self._callFUT( - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 > order2) - self.assertTrue(order2 > order3) - self.assertTrue(order3 > order4) - self.assertTrue(order4 > order5) - self.assertTrue(order5 > order6) - self.assertTrue(order6 > order7) - self.assertTrue(order7 > order8) - self.assertTrue(order8 > order9) - self.assertTrue(order9 > order10) - - def test_ordering_importance_and_number(self): - from pyramid.config.util import predvalseq - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order2, _, _ = self._callFUT( - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 > order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order2, _, _ = self._callFUT( - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 < order2) - - order1, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - ) - order2, _, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - custom=predvalseq([DummyCustomPredicate()]), - ) - self.assertTrue(order1 > order2) - - def test_different_custom_predicates_with_same_hash(self): - from pyramid.config.util import predvalseq - class PredicateWithHash(object): - def __hash__(self): - return 1 - a = PredicateWithHash() - b = PredicateWithHash() - _, _, a_phash = self._callFUT(custom=predvalseq([a])) - _, _, b_phash = self._callFUT(custom=predvalseq([b])) - self.assertEqual(a_phash, b_phash) - - def test_traverse_has_remainder_already(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'traverse':'abc'} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'traverse':'abc'}) - - def test_traverse_matches(self): - order, predicates, phash = self._callFUT(traverse='/1/:a/:b') - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'match':{'a':'a', 'b':'b'}} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'match': - {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) - - def test_traverse_matches_with_highorder_chars(self): - order, predicates, phash = self._callFUT( - traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) - self.assertEqual(len(predicates), 1) - pred = predicates[0] - info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} - request = DummyRequest() - result = pred(info, request) - self.assertEqual(result, True) - self.assertEqual( - info['match']['traverse'], - (text_(b'La Pe\xc3\xb1a', 'utf-8'), - text_(b'Qu\xc3\xa9bec', 'utf-8')) - ) - - def test_custom_predicates_can_affect_traversal(self): - from pyramid.config.util import predvalseq - def custom(info, request): - m = info['match'] - m['dummy'] = 'foo' - return True - _, predicates, _ = self._callFUT( - custom=predvalseq([custom]), - traverse='/1/:dummy/:a') - self.assertEqual(len(predicates), 2) - info = {'match':{'a':'a'}} - request = DummyRequest() - self.assertTrue(all([p(info, request) for p in predicates])) - self.assertEqual(info, {'match': - {'a':'a', 'dummy':'foo', - 'traverse':('1', 'foo', 'a')}}) - - def test_predicate_text_is_correct(self): - from pyramid.config.util import predvalseq - _, predicates, _ = self._callFUT( - xhr='xhr', - request_method='request_method', - path_info='path_info', - request_param='param', - header='header', - accept='accept', - containment='containment', - request_type='request_type', - custom=predvalseq( - [ - DummyCustomPredicate(), - DummyCustomPredicate.classmethod_predicate, - DummyCustomPredicate.classmethod_predicate_no_text, - ] - ), - match_param='foo=bar') - self.assertEqual(predicates[0].text(), 'xhr = True') - self.assertEqual(predicates[1].text(), - "request_method = request_method") - self.assertEqual(predicates[2].text(), 'path_info = path_info') - self.assertEqual(predicates[3].text(), 'request_param param') - self.assertEqual(predicates[4].text(), 'header header') - self.assertEqual(predicates[5].text(), 'accept = accept') - self.assertEqual(predicates[6].text(), 'containment = containment') - self.assertEqual(predicates[7].text(), 'request_type = request_type') - self.assertEqual(predicates[8].text(), "match_param foo=bar") - self.assertEqual(predicates[9].text(), 'custom predicate') - self.assertEqual(predicates[10].text(), 'classmethod predicate') - self.assertTrue(predicates[11].text().startswith('custom predicate')) - - def test_match_param_from_string(self): - _, predicates, _ = self._callFUT(match_param='foo=bar') - request = DummyRequest() - request.matchdict = {'foo':'bar', 'baz':'bum'} - self.assertTrue(predicates[0](Dummy(), request)) - - def test_match_param_from_string_fails(self): - _, predicates, _ = self._callFUT(match_param='foo=bar') - request = DummyRequest() - request.matchdict = {'foo':'bum', 'baz':'bum'} - self.assertFalse(predicates[0](Dummy(), request)) - - def test_match_param_from_dict(self): - _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum')) - request = DummyRequest() - request.matchdict = {'foo':'bar', 'baz':'bum'} - self.assertTrue(predicates[0](Dummy(), request)) - - def test_match_param_from_dict_fails(self): - _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum')) - request = DummyRequest() - request.matchdict = {'foo':'bar', 'baz':'foo'} - self.assertFalse(predicates[0](Dummy(), request)) - - def test_request_method_sequence(self): - _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD')) - request = DummyRequest() - request.method = 'HEAD' - self.assertTrue(predicates[0](Dummy(), request)) - request.method = 'GET' - self.assertTrue(predicates[0](Dummy(), request)) - request.method = 'POST' - self.assertFalse(predicates[0](Dummy(), request)) - - def test_request_method_ordering_hashes_same(self): - hash1, _, __= self._callFUT(request_method=('GET', 'HEAD')) - hash2, _, __= self._callFUT(request_method=('HEAD', 'GET')) - self.assertEqual(hash1, hash2) - hash1, _, __= self._callFUT(request_method=('GET',)) - hash2, _, __= self._callFUT(request_method='GET') - self.assertEqual(hash1, hash2) - - def test_unknown_predicate(self): - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, self._callFUT, unknown=1) - - def test_predicate_close_matches(self): - from pyramid.exceptions import ConfigurationError - with self.assertRaises(ConfigurationError) as context: - self._callFUT(method='GET') - expected_msg = ( - "Unknown predicate values: {'method': 'GET'} " - "(did you mean request_method)" - ) - self.assertEqual(context.exception.args[0], expected_msg) - - def test_notted(self): - from pyramid.config import not_ - from pyramid.testing import DummyRequest - request = DummyRequest() - _, predicates, _ = self._callFUT( - xhr='xhr', - request_method=not_('POST'), - header=not_('header'), - ) - self.assertEqual(predicates[0].text(), 'xhr = True') - self.assertEqual(predicates[1].text(), - "!request_method = POST") - self.assertEqual(predicates[2].text(), '!header header') - self.assertEqual(predicates[1](None, request), True) - self.assertEqual(predicates[2](None, request), True) - -class TestDeprecatedPredicates(unittest.TestCase): - def test_it(self): - import warnings - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - from pyramid.config.predicates import XHRPredicate - self.assertEqual(len(w), 1) - -class Test_sort_accept_offers(unittest.TestCase): - def _callFUT(self, offers, order=None): - from pyramid.config.util import sort_accept_offers - return sort_accept_offers(offers, order) - - def test_default_specificities(self): - result = self._callFUT(['text/html', 'text/html;charset=utf8']) - self.assertEqual(result, [ - 'text/html;charset=utf8', 'text/html', - ]) - - def test_specific_type_order(self): - result = self._callFUT( - ['text/html', 'application/json', 'text/html;charset=utf8', 'text/plain'], - ['application/json', 'text/html'], - ) - self.assertEqual(result, [ - 'application/json', 'text/html;charset=utf8', 'text/html', 'text/plain', - ]) - - def test_params_order(self): - result = self._callFUT( - ['text/html;charset=utf8', 'text/html;charset=latin1', 'text/html;foo=bar'], - ['text/html;charset=latin1', 'text/html;charset=utf8'], - ) - self.assertEqual(result, [ - 'text/html;charset=latin1', 'text/html;charset=utf8', 'text/html;foo=bar', - ]) - - def test_params_inherit_type_prefs(self): - result = self._callFUT( - ['text/html;charset=utf8', 'text/plain;charset=latin1'], - ['text/plain', 'text/html'], - ) - self.assertEqual(result, ['text/plain;charset=latin1', 'text/html;charset=utf8']) - -class DummyCustomPredicate(object): - def __init__(self): - self.__text__ = 'custom predicate' - - def classmethod_predicate(*args): pass - classmethod_predicate.__text__ = 'classmethod predicate' - classmethod_predicate = classmethod(classmethod_predicate) - - @classmethod - def classmethod_predicate_no_text(*args): pass # pragma: no cover - -class Dummy(object): - def __init__(self, **kw): - self.__dict__.update(**kw) - -class DummyRequest: - subpath = () - matchdict = None - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.params = {} - self.cookies = {} - -class DummyConfigurator(object): - def maybe_dotted(self, thing): - return thing diff --git a/src/pyramid/tests/test_config/test_views.py b/src/pyramid/tests/test_config/test_views.py deleted file mode 100644 index 6565a35d5..000000000 --- a/src/pyramid/tests/test_config/test_views.py +++ /dev/null @@ -1,3632 +0,0 @@ -import os -import unittest -from pyramid import testing - -from pyramid.tests.test_config import IDummy - -from pyramid.tests.test_config import dummy_view - -from pyramid.compat import ( - im_func, - text_, - ) -from pyramid.exceptions import ConfigurationError -from pyramid.exceptions import ConfigurationExecutionError -from pyramid.exceptions import ConfigurationConflictError - -class TestViewsConfigurationMixin(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - config.set_default_csrf_options(require_csrf=False) - return config - - def _getViewCallable(self, config, ctx_iface=None, exc_iface=None, - request_iface=None, name=''): - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - if exc_iface: - classifier = IExceptionViewClassifier - ctx_iface = exc_iface - else: - classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - if request_iface is None: - request_iface = IRequest - return config.registry.adapters.lookup( - (classifier, request_iface, ctx_iface), IView, name=name, - default=None) - - def _registerRenderer(self, config, name='.txt'): - from pyramid.interfaces import IRendererFactory - class Renderer: - def __init__(self, info): - self.__class__.info = info - def __call__(self, *arg): - return b'Hello!' - config.registry.registerUtility(Renderer, IRendererFactory, name=name) - return Renderer - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def _assertNotFound(self, wrapper, *arg): - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, wrapper, *arg) - - def _getRouteRequestIface(self, config, name): - from pyramid.interfaces import IRouteRequest - iface = config.registry.getUtility(IRouteRequest, name) - return iface - - def _assertRoute(self, config, name, path, num_predicates=0): - from pyramid.interfaces import IRoutesMapper - mapper = config.registry.getUtility(IRoutesMapper) - routes = mapper.get_routes() - route = routes[0] - self.assertEqual(len(routes), 1) - self.assertEqual(route.name, name) - self.assertEqual(route.path, path) - self.assertEqual(len(routes[0].predicates), num_predicates) - return route - - def test_add_view_view_callable_None_no_renderer(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, config.add_view) - - def test_add_view_with_request_type_and_route_name(self): - config = self._makeOne(autocommit=True) - view = lambda *arg: 'OK' - self.assertRaises(ConfigurationError, config.add_view, view, '', None, - None, True, True) - - def test_add_view_with_request_type(self): - from pyramid.renderers import null_renderer - from zope.interface import directlyProvides - from pyramid.interfaces import IRequest - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, - request_type='pyramid.interfaces.IRequest', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = DummyRequest() - self._assertNotFound(wrapper, None, request) - directlyProvides(request, IRequest) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - - def test_add_view_view_callable_None_with_renderer(self): - config = self._makeOne(autocommit=True) - self._registerRenderer(config, name='dummy') - config.add_view(renderer='dummy') - view = self._getViewCallable(config) - self.assertTrue(b'Hello!' in view(None, None).body) - - def test_add_view_with_tmpl_renderer_factory_introspector_missing(self): - config = self._makeOne(autocommit=True) - config.introspection = False - config.introspector = None - config.add_view(renderer='dummy.pt') - view = self._getViewCallable(config) - self.assertRaises(ValueError, view, None, None) - - def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self): - config = self._makeOne(autocommit=True) - introspector = DummyIntrospector() - config.introspector = introspector - config.add_view(renderer='dummy.pt') - self.assertFalse(('renderer factories', '.pt') in - introspector.related[-1]) - view = self._getViewCallable(config) - self.assertRaises(ValueError, view, None, None) - - def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self): - config = self._makeOne(autocommit=True) - introspector = DummyIntrospector(True) - config.introspector = introspector - def dummy_factory(helper): - return lambda val, system_vals: 'Hello!' - config.add_renderer('.pt', dummy_factory) - config.add_view(renderer='dummy.pt') - self.assertTrue( - ('renderer factories', '.pt') in introspector.related[-1]) - view = self._getViewCallable(config) - self.assertTrue(b'Hello!' in view(None, None).body) - - def test_add_view_wrapped_view_is_decorated(self): - def view(request): # request-only wrapper - """ """ - config = self._makeOne(autocommit=True) - config.add_view(view=view) - wrapper = self._getViewCallable(config) - self.assertEqual(wrapper.__module__, view.__module__) - self.assertEqual(wrapper.__name__, view.__name__) - self.assertEqual(wrapper.__doc__, view.__doc__) - self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0], - 'view') - - def test_add_view_view_callable_dottedname(self): - from pyramid.renderers import null_renderer - config = self._makeOne(autocommit=True) - config.add_view(view='pyramid.tests.test_config.dummy_view', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_with_function_callable(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_function_callable_requestonly(self): - from pyramid.renderers import null_renderer - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_name(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, name='abc', renderer=null_renderer) - wrapper = self._getViewCallable(config, name='abc') - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_name_unicode(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - config.add_view(view=view, name=name, renderer=null_renderer) - wrapper = self._getViewCallable(config, name=name) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_decorator(self): - from pyramid.renderers import null_renderer - def view(request): - """ ABC """ - return 'OK' - def view_wrapper(fn): - def inner(context, request): - return fn(context, request) - return inner - config = self._makeOne(autocommit=True) - config.add_view(view=view, decorator=view_wrapper, - renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertFalse(wrapper is view) - self.assertEqual(wrapper.__doc__, view.__doc__) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_with_decorator_tuple(self): - from pyramid.renderers import null_renderer - def view(request): - """ ABC """ - return 'OK' - def view_wrapper1(fn): - def inner(context, request): - return 'wrapped1' + fn(context, request) - return inner - def view_wrapper2(fn): - def inner(context, request): - return 'wrapped2' + fn(context, request) - return inner - config = self._makeOne(autocommit=True) - config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1), - renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertFalse(wrapper is view) - self.assertEqual(wrapper.__doc__, view.__doc__) - result = wrapper(None, None) - self.assertEqual(result, 'wrapped2wrapped1OK') - - def test_add_view_with_http_cache(self): - import datetime - from pyramid.response import Response - response = Response('OK') - def view(request): - """ ABC """ - return response - config = self._makeOne(autocommit=True) - config.add_view(view=view, http_cache=(86400, {'public':True})) - wrapper = self._getViewCallable(config) - self.assertFalse(wrapper is view) - self.assertEqual(wrapper.__doc__, view.__doc__) - request = testing.DummyRequest() - when = datetime.datetime.utcnow() + datetime.timedelta(days=1) - result = wrapper(None, request) - self.assertEqual(result, response) - headers = dict(response.headerlist) - self.assertEqual(headers['Cache-Control'], 'max-age=86400, public') - expires = parse_httpdate(headers['Expires']) - assert_similar_datetime(expires, when) - - def test_add_view_as_instance(self): - from pyramid.renderers import null_renderer - class AView: - def __call__(self, context, request): - """ """ - return 'OK' - view = AView() - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_instancemethod(self): - from pyramid.renderers import null_renderer - class View: - def index(self, context, request): - return 'OK' - view = View() - config=self._makeOne(autocommit=True) - config.add_view(view=view.index, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_instancemethod_requestonly(self): - from pyramid.renderers import null_renderer - class View: - def index(self, request): - return 'OK' - view = View() - config=self._makeOne(autocommit=True) - config.add_view(view=view.index, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_instance_requestonly(self): - from pyramid.renderers import null_renderer - class AView: - def __call__(self, request): - """ """ - return 'OK' - view = AView() - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - result = wrapper(None, None) - self.assertEqual(result, 'OK') - - def test_add_view_as_oldstyle_class(self): - from pyramid.renderers import null_renderer - class view: - def __init__(self, context, request): - self.context = context - self.request = request - - def __call__(self): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - self.assertEqual(request.__view__.__class__, view) - - def test_add_view_as_oldstyle_class_requestonly(self): - from pyramid.renderers import null_renderer - class view: - def __init__(self, request): - self.request = request - - def __call__(self): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - self.assertEqual(request.__view__.__class__, view) - - def test_add_view_context_as_class(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - view = lambda *arg: 'OK' - class Foo: - pass - config = self._makeOne(autocommit=True) - config.add_view(context=Foo, view=view, renderer=null_renderer) - foo = implementedBy(Foo) - wrapper = self._getViewCallable(config, foo) - self.assertEqual(wrapper, view) - - def test_add_view_context_as_iface(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(context=IDummy, view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_context_as_dottedname(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(context='pyramid.tests.test_config.IDummy', - view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_for__as_dottedname(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(for_='pyramid.tests.test_config.IDummy', - view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_for_as_class(self): - # ``for_`` is older spelling for ``context`` - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - view = lambda *arg: 'OK' - class Foo: - pass - config = self._makeOne(autocommit=True) - config.add_view(for_=Foo, view=view, renderer=null_renderer) - foo = implementedBy(Foo) - wrapper = self._getViewCallable(config, foo) - self.assertEqual(wrapper, view) - - def test_add_view_for_as_iface(self): - # ``for_`` is older spelling for ``context`` - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(for_=IDummy, view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_context_trumps_for(self): - # ``for_`` is older spelling for ``context`` - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - class Foo: - pass - config.add_view(context=IDummy, for_=Foo, view=view, - renderer=null_renderer) - wrapper = self._getViewCallable(config, IDummy) - self.assertEqual(wrapper, view) - - def test_add_view_register_secured_view(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import ISecuredView - from pyramid.interfaces import IViewClassifier - view = lambda *arg: 'OK' - view.__call_permissive__ = view - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - wrapper = config.registry.adapters.lookup( - (IViewClassifier, IRequest, Interface), - ISecuredView, name='', default=None) - self.assertEqual(wrapper, view) - - def test_add_view_exception_register_secured_view(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IExceptionViewClassifier - view = lambda *arg: 'OK' - view.__call_permissive__ = view - config = self._makeOne(autocommit=True) - config.add_view(view=view, context=RuntimeError, renderer=null_renderer) - wrapper = config.registry.adapters.lookup( - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='', default=None) - self.assertEqual(wrapper, view) - - def test_add_view_same_phash_overrides_existing_single_view(self): - from pyramid.renderers import null_renderer - from hashlib import md5 - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - phash = md5() - phash.update(b'xhr = True') - view = lambda *arg: 'NOT OK' - view.__phash__ = phash.hexdigest() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, xhr=True, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_same_phash_overrides_existing_single_view(self): - from pyramid.renderers import null_renderer - from hashlib import md5 - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IMultiView - phash = md5() - phash.update(b'xhr = True') - view = lambda *arg: 'NOT OK' - view.__phash__ = phash.hexdigest() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, xhr=True, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_default_phash_overrides_no_phash(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_default_phash_overrides_no_phash(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_default_phash_overrides_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - view.__phash__ = DEFAULT_PHASH - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_default_phash_overrides_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'NOT OK' - view.__phash__ = DEFAULT_PHASH - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - def newview(context, request): - return 'OK' - config.add_view(view=newview, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertFalse(IMultiView.providedBy(wrapper)) - request = DummyRequest() - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_multiview_replaces_existing_view(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_exc_multiview_replaces_existing_view(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_multiview_replaces_existing_securedview(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import ISecuredView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), - ISecuredView, name='') - config.add_view(view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_exc_multiview_replaces_existing_securedview(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import ISecuredView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - ISecuredView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - ISecuredView, name='') - config.add_view(view=view, context=RuntimeError, renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_with_accept_multiview_replaces_existing_view(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view2, accept='text/html', renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK2') - - def test_add_view_mixed_case_replaces_existing_view(self): - from pyramid.renderers import null_renderer - def view(context, request): return 'OK' - def view2(context, request): return 'OK2' - def view3(context, request): return 'OK3' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - config.add_view(view=view2, accept='text/html', renderer=null_renderer) - config.add_view(view=view3, accept='text/HTML', renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.media_views.items()),1) - self.assertFalse('text/HTML' in wrapper.media_views) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK3') - - def test_add_views_with_accept_multiview_replaces_existing(self): - from pyramid.renderers import null_renderer - def view(context, request): return 'OK' - def view2(context, request): return 'OK2' - def view3(context, request): return 'OK3' - config = self._makeOne(autocommit=True) - config.add_view(view=view, renderer=null_renderer) - config.add_view(view=view2, accept='text/html', renderer=null_renderer) - config.add_view(view=view3, accept='text/html', renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertEqual(len(wrapper.media_views['text/html']), 1) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK3') - - def test_add_view_exc_with_accept_multiview_replaces_existing_view(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view2, accept='text/html', context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK') - request = DummyRequest() - request.accept = DummyAccept('text/html', 'text/html') - self.assertEqual(wrapper(None, request), 'OK2') - - def test_add_view_multiview_replaces_existing_view_with___accept__(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - view.__accept__ = 'text/html' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view2, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK2') - request = DummyRequest() - request.accept = DummyAccept('text/html') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - def view(context, request): - return 'OK' - def view2(context, request): - return 'OK2' - view.__accept__ = 'text/html' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.registry.registerAdapter( - view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IView, name='') - config.add_view(view=view2, context=RuntimeError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual(len(wrapper.views), 1) - self.assertEqual(len(wrapper.media_views), 1) - self.assertEqual(wrapper(None, None), 'OK2') - request = DummyRequest() - request.accept = DummyAccept('text/html') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_multiview_replaces_multiview(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - view = DummyMultiView() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2, renderer=null_renderer) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - self.assertEqual([(x[0], x[2]) for x in wrapper.views], [(view2, None)]) - self.assertEqual(wrapper(None, None), 'OK1') - - def test_add_view_exc_multiview_replaces_multiviews(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - hot_view = DummyMultiView() - exc_view = DummyMultiView() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - hot_view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - config.registry.registerAdapter( - exc_view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2, context=RuntimeError, - renderer=null_renderer) - hot_wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(hot_wrapper)) - self.assertEqual([(x[0], x[2]) for x in hot_wrapper.views], [(view2, None)]) - self.assertEqual(hot_wrapper(None, None), 'OK1') - - exc_wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(exc_wrapper)) - self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)]) - self.assertEqual(exc_wrapper(None, None), 'OK1') - - def test_add_view_exc_multiview_replaces_only_exc_multiview(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - hot_view = DummyMultiView() - exc_view = DummyMultiView() - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - hot_view, - (IViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - config.registry.registerAdapter( - exc_view, - (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), - IMultiView, name='') - view2 = lambda *arg: 'OK2' - config.add_view(view=view2, context=RuntimeError, exception_only=True, - renderer=null_renderer) - hot_wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(hot_wrapper)) - self.assertEqual(len(hot_wrapper.views), 0) - self.assertEqual(hot_wrapper(None, None), 'OK1') - - exc_wrapper = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError)) - self.assertTrue(IMultiView.providedBy(exc_wrapper)) - self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)]) - self.assertEqual(exc_wrapper(None, None), 'OK1') - - def test_add_view_multiview_context_superclass_then_subclass(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - class ISuper(Interface): - pass - class ISub(ISuper): - pass - view = lambda *arg: 'OK' - view2 = lambda *arg: 'OK2' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, ISuper), IView, name='') - config.add_view(view=view2, for_=ISub, renderer=null_renderer) - wrapper = self._getViewCallable(config, ctx_iface=ISuper, - request_iface=IRequest) - self.assertFalse(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK') - wrapper = self._getViewCallable(config, ctx_iface=ISub, - request_iface=IRequest) - self.assertFalse(IMultiView.providedBy(wrapper)) - self.assertEqual(wrapper(None, None), 'OK2') - - def test_add_view_multiview_exception_superclass_then_subclass(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - class Super(Exception): - pass - class Sub(Super): - pass - view = lambda *arg: 'OK' - view2 = lambda *arg: 'OK2' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Super), IView, name='') - config.registry.registerAdapter( - view, (IExceptionViewClassifier, IRequest, Super), IView, name='') - config.add_view(view=view2, for_=Sub, renderer=null_renderer) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(Super), request_iface=IRequest) - wrapper_exc_view = self._getViewCallable( - config, exc_iface=implementedBy(Super), request_iface=IRequest) - self.assertEqual(wrapper_exc_view, wrapper) - self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) - self.assertEqual(wrapper_exc_view(None, None), 'OK') - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(Sub), request_iface=IRequest) - wrapper_exc_view = self._getViewCallable( - config, exc_iface=implementedBy(Sub), request_iface=IRequest) - self.assertEqual(wrapper_exc_view, wrapper) - self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) - self.assertEqual(wrapper_exc_view(None, None), 'OK2') - - def test_add_view_multiview_call_ordering(self): - from pyramid.renderers import null_renderer as nr - from zope.interface import directlyProvides - def view1(context, request): return 'view1' - def view2(context, request): return 'view2' - def view3(context, request): return 'view3' - def view4(context, request): return 'view4' - def view5(context, request): return 'view5' - def view6(context, request): return 'view6' - def view7(context, request): return 'view7' - def view8(context, request): return 'view8' - config = self._makeOne(autocommit=True) - config.add_view(view=view1, renderer=nr) - config.add_view(view=view2, request_method='POST', renderer=nr) - config.add_view(view=view3,request_param='param', renderer=nr) - config.add_view(view=view4, containment=IDummy, renderer=nr) - config.add_view(view=view5, request_method='POST', - request_param='param', renderer=nr) - config.add_view(view=view6, request_method='POST', containment=IDummy, - renderer=nr) - config.add_view(view=view7, request_param='param', containment=IDummy, - renderer=nr) - config.add_view(view=view8, request_method='POST',request_param='param', - containment=IDummy, renderer=nr) - - - wrapper = self._getViewCallable(config) - - ctx = DummyContext() - request = self._makeRequest(config) - request.method = 'GET' - request.params = {} - self.assertEqual(wrapper(ctx, request), 'view1') - - ctx = DummyContext() - request = self._makeRequest(config) - request.params = {} - request.method = 'POST' - self.assertEqual(wrapper(ctx, request), 'view2') - - ctx = DummyContext() - request = self._makeRequest(config) - request.params = {'param':'1'} - request.method = 'GET' - self.assertEqual(wrapper(ctx, request), 'view3') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'GET' - request.params = {} - self.assertEqual(wrapper(ctx, request), 'view4') - - ctx = DummyContext() - request = self._makeRequest(config) - request.method = 'POST' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view5') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.params = {} - request.method = 'POST' - self.assertEqual(wrapper(ctx, request), 'view6') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'GET' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view7') - - ctx = DummyContext() - directlyProvides(ctx, IDummy) - request = self._makeRequest(config) - request.method = 'POST' - request.params = {'param':'1'} - self.assertEqual(wrapper(ctx, request), 'view8') - - def test_view_with_most_specific_predicate(self): - from pyramid.renderers import null_renderer as nr - from pyramid.router import Router - - class OtherBase(object): pass - class Int1(object): pass - class Int2(object): pass - - class Resource(OtherBase, Int1, Int2): - def __init__(self, request): pass - - def unknown(context, request): return 'unknown' - def view(context, request): return 'hello' - - config = self._makeOne(autocommit=True) - config.add_route('root', '/', factory=Resource) - config.add_view(unknown, route_name='root', renderer=nr) - config.add_view( - view, renderer=nr, route_name='root', - context=Int1, request_method='GET' - ) - config.add_view( - view=view, renderer=nr, route_name='root', - context=Int2, request_method='POST' - ) - request = self._makeRequest(config) - request.method = 'POST' - request.params = {} - router = Router(config.registry) - response = router.handle_request(request) - self.assertEqual(response, 'hello') - - def test_view_with_most_specific_predicate_with_mismatch(self): - from pyramid.renderers import null_renderer as nr - from pyramid.router import Router - - class OtherBase(object): pass - class Int1(object): pass - class Int2(object): pass - - class Resource(OtherBase, Int1, Int2): - def __init__(self, request): pass - - def unknown(context, request): return 'unknown' - def view(context, request): return 'hello' - - config = self._makeOne(autocommit=True) - config.add_route('root', '/', factory=Resource) - - config.add_view( - unknown, - route_name='root', - renderer=nr, - request_method=('POST',), - xhr=True, - ) - - config.add_view( - view, renderer=nr, route_name='root', - context=Int1, request_method='GET' - ) - config.add_view( - view=view, renderer=nr, route_name='root', - context=Int2, request_method='POST' - ) - request = self._makeRequest(config) - request.method = 'POST' - request.params = {} - router = Router(config.registry) - response = router.handle_request(request) - self.assertEqual(response, 'hello') - - def test_add_view_multiview___discriminator__(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - class IFoo(Interface): - pass - class IBar(Interface): - pass - @implementer(IFoo) - class Foo(object): - pass - @implementer(IBar) - class Bar(object): - pass - foo = Foo() - bar = Bar() - - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - view = lambda *arg: 'OK' - view.__phash__ = 'abc' - config = self._makeOne(autocommit=True) - config.registry.registerAdapter( - view, (IViewClassifier, IRequest, Interface), IView, name='') - config.add_view(view=view, renderer=null_renderer, - containment=IFoo) - config.add_view(view=view, renderer=null_renderer, - containment=IBar) - wrapper = self._getViewCallable(config) - self.assertTrue(IMultiView.providedBy(wrapper)) - request = self._makeRequest(config) - self.assertNotEqual( - wrapper.__discriminator__(foo, request), - wrapper.__discriminator__(bar, request), - ) - - def test_add_view_with_template_renderer(self): - from pyramid.tests import test_config - from pyramid.interfaces import ISettings - class view(object): - def __init__(self, context, request): - self.request = request - self.context = context - - def __call__(self): - return {'a':'1'} - config = self._makeOne(autocommit=True) - renderer = self._registerRenderer(config) - fixture = 'pyramid.tests.test_config:files/minimal.txt' - config.introspection = False - config.add_view(view=view, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, b'Hello!') - settings = config.registry.queryUtility(ISettings) - result = renderer.info - self.assertEqual(result.registry, config.registry) - self.assertEqual(result.type, '.txt') - self.assertEqual(result.package, test_config) - self.assertEqual(result.name, fixture) - self.assertEqual(result.settings, settings) - - def test_add_view_with_default_renderer(self): - class view(object): - def __init__(self, context, request): - self.request = request - self.context = context - - def __call__(self): - return {'a':'1'} - config = self._makeOne(autocommit=True) - class moo(object): - def __init__(self, *arg, **kw): - pass - def __call__(self, *arg, **kw): - return b'moo' - config.add_renderer(None, moo) - config.add_view(view=view) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, b'moo') - - def test_add_view_with_template_renderer_no_callable(self): - from pyramid.tests import test_config - from pyramid.interfaces import ISettings - config = self._makeOne(autocommit=True) - renderer = self._registerRenderer(config) - fixture = 'pyramid.tests.test_config:files/minimal.txt' - config.introspection = False - config.add_view(view=None, renderer=fixture) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - result = wrapper(None, request) - self.assertEqual(result.body, b'Hello!') - settings = config.registry.queryUtility(ISettings) - result = renderer.info - self.assertEqual(result.registry, config.registry) - self.assertEqual(result.type, '.txt') - self.assertEqual(result.package, test_config) - self.assertEqual(result.name, fixture) - self.assertEqual(result.settings, settings) - - def test_add_view_with_request_type_as_iface(self): - from pyramid.renderers import null_renderer - from zope.interface import directlyProvides - def view(context, request): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(request_type=IDummy, view=view, renderer=null_renderer) - wrapper = self._getViewCallable(config, None) - request = self._makeRequest(config) - directlyProvides(request, IDummy) - result = wrapper(None, request) - self.assertEqual(result, 'OK') - - def test_add_view_with_request_type_as_noniface(self): - view = lambda *arg: 'OK' - config = self._makeOne() - self.assertRaises(ConfigurationError, - config.add_view, view, '', None, None, object) - - def test_add_view_with_route_name(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view(view=view, route_name='foo', renderer=null_renderer) - request_iface = self._getRouteRequestIface(config, 'foo') - self.assertNotEqual(request_iface, None) - wrapper = self._getViewCallable(config, request_iface=request_iface) - self.assertNotEqual(wrapper, None) - self.assertEqual(wrapper(None, None), 'OK') - - def test_add_view_with_nonexistant_route_name(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, route_name='foo', renderer=null_renderer) - self.assertRaises(ConfigurationExecutionError, config.commit) - - def test_add_view_with_route_name_exception(self): - from pyramid.renderers import null_renderer - from zope.interface import implementedBy - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view(view=view, route_name='foo', context=RuntimeError, - renderer=null_renderer) - request_iface = self._getRouteRequestIface(config, 'foo') - wrapper_exc_view = self._getViewCallable( - config, exc_iface=implementedBy(RuntimeError), - request_iface=request_iface) - self.assertNotEqual(wrapper_exc_view, None) - wrapper = self._getViewCallable( - config, ctx_iface=implementedBy(RuntimeError), - request_iface=request_iface) - self.assertEqual(wrapper_exc_view, wrapper) - self.assertEqual(wrapper_exc_view(None, None), 'OK') - - def test_add_view_with_request_method_true(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method='POST', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'POST' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_method_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method='POST') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_request_method_sequence_true(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method=('POST', 'GET'), - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'POST' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_method_sequence_conflict(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view=view, request_method=('POST', 'GET'), - renderer=null_renderer) - config.add_view(view=view, request_method=('GET', 'POST'), - renderer=null_renderer) - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_view_with_request_method_sequence_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method=('POST', 'HEAD')) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_request_method_get_implies_head(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method='GET', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'HEAD' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_param_noval_true(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_param='abc', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':''} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_param_noval_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_param='abc') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_request_param_val_true(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_param='abc=123', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':'123'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_request_param_val_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_param='abc=123') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.params = {'abc':''} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_xhr_true(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, xhr=True, renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_xhr_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, xhr=True) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.is_xhr = False - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_badregex(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view, header='Host:a\\') - self.assertRaises(ConfigurationError, config.commit) - - def test_add_view_with_header_noval_match(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, header='Host', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'whatever'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_header_noval_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, header='Host') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'NotHost':'whatever'} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_val_match(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, header=r'Host:\d', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'1'} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_header_val_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, header=r'Host:\d') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'Host':'abc'} - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_header_val_missing(self): - from pyramid.httpexceptions import HTTPNotFound - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, header=r'Host:\d') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.headers = {'NoHost':'1'} - self.assertRaises(HTTPNotFound, wrapper, None, request) - - def test_add_view_with_accept_match(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/xml', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('text/xml') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_accept_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/xml') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('text/html') - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_range_accept_match(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/*', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('text/html', contains=True) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_range_accept_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, accept='text/*') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.accept = DummyAccept('application/json', contains=False) - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_containment_true(self): - from pyramid.renderers import null_renderer - from zope.interface import directlyProvides - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, containment=IDummy, renderer=null_renderer) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - self.assertEqual(wrapper(context, None), 'OK') - - def test_add_view_with_containment_false(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, containment=IDummy) - wrapper = self._getViewCallable(config) - context = DummyContext() - self._assertNotFound(wrapper, context, None) - - def test_add_view_with_containment_dottedname(self): - from pyramid.renderers import null_renderer - from zope.interface import directlyProvides - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view( - view=view, - containment='pyramid.tests.test_config.IDummy', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - self.assertEqual(wrapper(context, None), 'OK') - - def test_add_view_with_path_info_badregex(self): - view = lambda *arg: 'OK' - config = self._makeOne() - config.add_view(view, path_info='\\') - self.assertRaises(ConfigurationError, config.commit) - - def test_add_view_with_path_info_match(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, path_info='/foo', renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.upath_info = text_(b'/foo') - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_path_info_nomatch(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, path_info='/foo') - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.upath_info = text_('/') - self._assertNotFound(wrapper, None, request) - - def test_add_view_with_check_csrf_predicates_match(self): - import warnings - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - config.add_view(view=view, check_csrf=True, renderer=null_renderer) - self.assertEqual(len(w), 1) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = "POST" - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'csrf_token': 'foo'} - request.headers = {} - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_custom_predicates_match(self): - import warnings - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - def pred1(context, request): - return True - def pred2(context, request): - return True - predicates = (pred1, pred2) - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - config.add_view(view=view, custom_predicates=predicates, - renderer=null_renderer) - self.assertEqual(len(w), 1) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_with_custom_predicates_nomatch(self): - import warnings - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - def pred1(context, request): - return True - def pred2(context, request): - return False - predicates = (pred1, pred2) - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - config.add_view(view=view, custom_predicates=predicates) - self.assertEqual(len(w), 1) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - self._assertNotFound(wrapper, None, request) - - def test_add_view_custom_predicate_bests_standard_predicate(self): - import warnings - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - view2 = lambda *arg: 'NOT OK' - config = self._makeOne(autocommit=True) - def pred1(context, request): - return True - with warnings.catch_warnings(record=True) as w: - warnings.filterwarnings('always') - config.add_view(view=view, custom_predicates=(pred1,), - renderer=null_renderer) - config.add_view(view=view2, request_method='GET', - renderer=null_renderer) - self.assertEqual(len(w), 1) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self): - from pyramid.renderers import null_renderer - view = lambda *arg: 'OK' - view2 = lambda *arg: 'NOT OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view, request_method='GET', xhr=True, - renderer=null_renderer) - config.add_view(view=view2, request_method='GET', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - request = self._makeRequest(config) - request.method = 'GET' - request.is_xhr = True - self.assertEqual(wrapper(None, request), 'OK') - - def test_add_view_same_predicates(self): - view2 = lambda *arg: 'second' - view1 = lambda *arg: 'first' - config = self._makeOne() - config.add_view(view=view1) - config.add_view(view=view2) - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_view_with_csrf_param(self): - from pyramid.renderers import null_renderer - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view, require_csrf='st', renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - request.scheme = "http" - request.method = 'POST' - request.POST = {'st': 'foo'} - request.headers = {} - request.session = DummySession({'csrf_token': 'foo'}) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_csrf_header(self): - from pyramid.renderers import null_renderer - def view(request): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view, require_csrf=True, renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - request.scheme = "http" - request.method = 'POST' - request.POST = {} - request.headers = {'X-CSRF-Token': 'foo'} - request.session = DummySession({'csrf_token': 'foo'}) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_missing_csrf_header(self): - from pyramid.exceptions import BadCSRFToken - from pyramid.renderers import null_renderer - def view(request): return 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view, require_csrf=True, renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - request.scheme = "http" - request.method = 'POST' - request.POST = {} - request.headers = {} - request.session = DummySession({'csrf_token': 'foo'}) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_add_view_with_permission(self): - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - outerself = self - class DummyPolicy(object): - def effective_principals(self, r): - outerself.assertEqual(r, request) - return ['abc'] - def permits(self, context, principals, permission): - outerself.assertEqual(context, None) - outerself.assertEqual(principals, ['abc']) - outerself.assertEqual(permission, 'view') - return True - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy, - autocommit=True) - config.add_view(view=view1, permission='view', renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_default_permission_no_explicit_permission(self): - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - outerself = self - class DummyPolicy(object): - def effective_principals(self, r): - outerself.assertEqual(r, request) - return ['abc'] - def permits(self, context, principals, permission): - outerself.assertEqual(context, None) - outerself.assertEqual(principals, ['abc']) - outerself.assertEqual(permission, 'view') - return True - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy, - default_permission='view', - autocommit=True) - config.add_view(view=view1, renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_no_default_permission_no_explicit_permission(self): - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - class DummyPolicy(object): pass # wont be called - policy = DummyPolicy() - config = self._makeOne(authorization_policy=policy, - authentication_policy=policy, - autocommit=True) - config.add_view(view=view1, renderer=null_renderer) - view = self._getViewCallable(config) - request = self._makeRequest(config) - self.assertEqual(view(None, request), 'OK') - - def test_add_view_with_mapper(self): - from pyramid.renderers import null_renderer - class Mapper(object): - def __init__(self, **kw): - self.__class__.kw = kw - def __call__(self, view): - return view - config = self._makeOne(autocommit=True) - def view(context, request): return 'OK' - config.add_view(view=view, mapper=Mapper, renderer=null_renderer) - view = self._getViewCallable(config) - self.assertEqual(view(None, None), 'OK') - self.assertEqual(Mapper.kw['mapper'], Mapper) - - def test_add_view_with_view_defaults(self): - from pyramid.renderers import null_renderer - from pyramid.exceptions import PredicateMismatch - from zope.interface import directlyProvides - class view(object): - __view_defaults__ = { - 'containment':'pyramid.tests.test_config.IDummy' - } - def __init__(self, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_view( - view=view, - renderer=null_renderer) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - context = DummyContext() - request = self._makeRequest(config) - self.assertRaises(PredicateMismatch, wrapper, context, request) - - def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self): - from pyramid.renderers import null_renderer - from pyramid.exceptions import PredicateMismatch - from zope.interface import directlyProvides - config = self._makeOne(autocommit=True) - config.add_view( - view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - context = DummyContext() - request = self._makeRequest(config) - self.assertRaises(PredicateMismatch, wrapper, context, request) - - def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self): - from pyramid.renderers import null_renderer - from pyramid.exceptions import PredicateMismatch - from zope.interface import directlyProvides - config = self._makeOne(autocommit=True) - config.add_view( - 'pyramid.tests.test_config.test_views.DummyViewDefaultsClass', - renderer=null_renderer) - wrapper = self._getViewCallable(config) - context = DummyContext() - directlyProvides(context, IDummy) - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - context = DummyContext() - request = self._makeRequest(config) - self.assertRaises(PredicateMismatch, wrapper, context, request) - - def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self): - from pyramid.renderers import null_renderer - class view(object): - __view_defaults__ = { - 'containment':'pyramid.tests.test_config.IDummy' - } - class view2(object): - __view_defaults__ = { - 'containment':'pyramid.tests.test_config.IFactory' - } - config = self._makeOne(autocommit=False) - config.add_view( - view=view, - renderer=null_renderer) - config.add_view( - view=view2, - renderer=null_renderer) - config.commit() # does not raise - - def test_add_view_with_view_config_and_view_defaults_conflicts(self): - from pyramid.renderers import null_renderer - class view(object): - __view_defaults__ = { - 'containment':'pyramid.tests.test_config.IDummy' - } - class view2(object): - __view_defaults__ = { - 'containment':'pyramid.tests.test_config.IDummy' - } - config = self._makeOne(autocommit=False) - config.add_view( - view=view, - renderer=null_renderer) - config.add_view( - view=view2, - renderer=null_renderer) - self.assertRaises(ConfigurationConflictError, config.commit) - - def test_add_view_class_method_no_attr(self): - from pyramid.renderers import null_renderer - from zope.interface import directlyProvides - from pyramid.exceptions import ConfigurationError - - config = self._makeOne(autocommit=True) - class DummyViewClass(object): - def run(self): pass - - def configure_view(): - config.add_view(view=DummyViewClass.run, renderer=null_renderer) - - self.assertRaises(ConfigurationError, configure_view) - - def test_add_view_exception_only_no_regular_view(self): - from zope.interface import implementedBy - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view1, context=Exception, exception_only=True, - renderer=null_renderer) - view = self._getViewCallable(config, ctx_iface=implementedBy(Exception)) - self.assertTrue(view is None) - - def test_add_view_exception_only(self): - from zope.interface import implementedBy - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_view(view=view1, context=Exception, exception_only=True, - renderer=null_renderer) - view = self._getViewCallable( - config, exc_iface=implementedBy(Exception)) - self.assertEqual(view1, view) - - def test_add_view_exception_only_misconfiguration(self): - view = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - class NotAnException(object): - pass - self.assertRaises( - ConfigurationError, - config.add_view, view, context=NotAnException, exception_only=True) - - def test_add_exception_view(self): - from zope.interface import implementedBy - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_exception_view(view=view1, renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(Exception)) - context = Exception() - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - - def test_add_exception_view_with_subclass(self): - from zope.interface import implementedBy - from pyramid.renderers import null_renderer - view1 = lambda *arg: 'OK' - config = self._makeOne(autocommit=True) - config.add_exception_view(view=view1, context=ValueError, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(ValueError)) - context = ValueError() - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - - def test_add_exception_view_disallows_name(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, - config.add_exception_view, - context=Exception(), - name='foo') - - def test_add_exception_view_disallows_permission(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, - config.add_exception_view, - context=Exception(), - permission='foo') - - def test_add_exception_view_disallows_require_csrf(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, - config.add_exception_view, - context=Exception(), - require_csrf=True) - - def test_add_exception_view_disallows_for_(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, - config.add_exception_view, - context=Exception(), - for_='foo') - - def test_add_exception_view_disallows_exception_only(self): - config = self._makeOne(autocommit=True) - self.assertRaises(ConfigurationError, - config.add_exception_view, - context=Exception(), - exception_only=True) - - def test_add_exception_view_with_view_defaults(self): - from pyramid.renderers import null_renderer - from pyramid.exceptions import PredicateMismatch - from zope.interface import directlyProvides - from zope.interface import implementedBy - class view(object): - __view_defaults__ = { - 'containment': 'pyramid.tests.test_config.IDummy' - } - def __init__(self, request): - pass - def __call__(self): - return 'OK' - config = self._makeOne(autocommit=True) - config.add_exception_view( - view=view, - context=Exception, - renderer=null_renderer) - wrapper = self._getViewCallable( - config, exc_iface=implementedBy(Exception)) - context = DummyContext() - directlyProvides(context, IDummy) - request = self._makeRequest(config) - self.assertEqual(wrapper(context, request), 'OK') - context = DummyContext() - request = self._makeRequest(config) - self.assertRaises(PredicateMismatch, wrapper, context, request) - - def test_derive_view_function(self): - from pyramid.renderers import null_renderer - def view(request): - return 'OK' - config = self._makeOne() - result = config.derive_view(view, renderer=null_renderer) - self.assertFalse(result is view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_dottedname(self): - from pyramid.renderers import null_renderer - config = self._makeOne() - result = config.derive_view( - 'pyramid.tests.test_config.dummy_view', - renderer=null_renderer) - self.assertFalse(result is dummy_view) - self.assertEqual(result(None, None), 'OK') - - def test_derive_view_with_default_renderer_no_explicit_renderer(self): - config = self._makeOne() - class moo(object): - def __init__(self, view): - pass - def __call__(self, *arg, **kw): - return 'moo' - config.add_renderer(None, moo) - config.commit() - def view(request): - return 'OK' - result = config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(result(None, None).body, b'moo') - - def test_derive_view_with_default_renderer_with_explicit_renderer(self): - class moo(object): pass - class foo(object): - def __init__(self, view): - pass - def __call__(self, *arg, **kw): - return b'foo' - def view(request): - return 'OK' - config = self._makeOne() - config.add_renderer(None, moo) - config.add_renderer('foo', foo) - config.commit() - result = config.derive_view(view, renderer='foo') - self.assertFalse(result is view) - request = self._makeRequest(config) - self.assertEqual(result(None, request).body, b'foo') - - def test_add_static_view_here_no_utility_registered(self): - from pyramid.renderers import null_renderer - from zope.interface import Interface - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - config = self._makeOne(autocommit=True) - config.add_static_view('static', 'files', renderer=null_renderer) - request_type = self._getRouteRequestIface(config, '__static/') - self._assertRoute(config, '__static/', 'static/*subpath') - wrapped = config.registry.adapters.lookup( - (IViewClassifier, request_type, Interface), IView, name='') - from pyramid.request import Request - request = Request.blank('/static/minimal.txt') - request.subpath = ('minimal.txt', ) - result = wrapped(None, request) - self.assertEqual(result.status, '200 OK') - self.assertTrue(result.body.startswith(b'' in body) - - def test__default_app_iter_with_comment_html(self): - cls = self._getTargetSubclass() - exc = cls(comment='comment & comment') - environ = _makeEnviron() - environ['HTTP_ACCEPT'] = 'text/html' - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - self.assertTrue(b'' in body) - - def test__default_app_iter_with_comment_json(self): - cls = self._getTargetSubclass() - exc = cls(comment='comment & comment') - environ = _makeEnviron() - environ['HTTP_ACCEPT'] = 'application/json' - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - import json - retval = json.loads(body.decode('UTF-8')) - self.assertEqual(retval['code'], '200 OK') - self.assertEqual(retval['title'], 'OK') - - def test__default_app_iter_with_custom_json(self): - def json_formatter(status, body, title, environ): - return {'message': body, - 'code': status, - 'title': title, - 'custom': environ['CUSTOM_VARIABLE'] - } - cls = self._getTargetSubclass() - exc = cls(comment='comment', json_formatter=json_formatter) - environ = _makeEnviron() - environ['HTTP_ACCEPT'] = 'application/json' - environ['CUSTOM_VARIABLE'] = 'custom!' - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - import json - retval = json.loads(body.decode('UTF-8')) - self.assertEqual(retval['code'], '200 OK') - self.assertEqual(retval['title'], 'OK') - self.assertEqual(retval['custom'], 'custom!') - - def test_custom_body_template(self): - cls = self._getTargetSubclass() - exc = cls(body_template='${REQUEST_METHOD}') - environ = _makeEnviron() - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - self.assertEqual(body, b'200 OK\n\nGET') - - def test_custom_body_template_with_custom_variable_doesnt_choke(self): - cls = self._getTargetSubclass() - exc = cls(body_template='${REQUEST_METHOD}') - environ = _makeEnviron() - class Choke(object): - def __str__(self): # pragma no cover - raise ValueError - environ['gardentheory.user'] = Choke() - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - self.assertEqual(body, b'200 OK\n\nGET') - - def test_body_template_unicode(self): - cls = self._getTargetSubclass() - la = text_(b'/La Pe\xc3\xb1a', 'utf-8') - environ = _makeEnviron(unicodeval=la) - exc = cls(body_template='${unicodeval}') - start_response = DummyStartResponse() - body = list(exc(environ, start_response))[0] - self.assertEqual(body, b'200 OK\n\n/La Pe\xc3\xb1a') - - def test_allow_detail_non_str(self): - exc = self._makeOne(detail={'error': 'This is a test'}) - self.assertIsInstance(exc.__str__(), string_types) - - -class TestRenderAllExceptionsWithoutArguments(unittest.TestCase): - def _doit(self, content_type): - from pyramid.httpexceptions import status_map - L = [] - self.assertTrue(status_map) - for v in status_map.values(): - environ = _makeEnviron() - start_response = DummyStartResponse() - exc = v() - exc.content_type = content_type - result = list(exc(environ, start_response))[0] - if exc.empty_body: - self.assertEqual(result, b'') - else: - self.assertTrue(bytes_(exc.status) in result) - L.append(result) - self.assertEqual(len(L), len(status_map)) - - def test_it_plain(self): - self._doit('text/plain') - - def test_it_html(self): - self._doit('text/html') - -class Test_HTTPMove(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.httpexceptions import _HTTPMove - return _HTTPMove(*arg, **kw) - - def test_it_location_none_valueerrors(self): - # Constructing a HTTPMove instance with location=None should - # throw a ValueError from __init__ so that a more-confusing - # exception won't be thrown later from .prepare(environ) - self.assertRaises(ValueError, self._makeOne, location=None) - - def test_it_location_not_passed(self): - exc = self._makeOne() - self.assertEqual(exc.location, '') - - def test_it_location_passed(self): - exc = self._makeOne(location='foo') - self.assertEqual(exc.location, 'foo') - - def test_it_location_firstarg(self): - exc = self._makeOne('foo') - self.assertEqual(exc.location, 'foo') - - def test_it_call_with_default_body_tmpl(self): - exc = self._makeOne(location='foo') - environ = _makeEnviron() - start_response = DummyStartResponse() - app_iter = exc(environ, start_response) - self.assertEqual(app_iter[0], - (b'520 Unknown Error\n\nThe resource has been moved to foo; ' - b'you should be redirected automatically.\n\n')) - -class TestHTTPForbidden(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.httpexceptions import HTTPForbidden - return HTTPForbidden(*arg, **kw) - - def test_it_result_not_passed(self): - exc = self._makeOne() - self.assertEqual(exc.result, None) - - def test_it_result_passed(self): - exc = self._makeOne(result='foo') - self.assertEqual(exc.result, 'foo') - -class TestHTTPMethodNotAllowed(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.httpexceptions import HTTPMethodNotAllowed - return HTTPMethodNotAllowed(*arg, **kw) - - def test_it_with_default_body_tmpl(self): - exc = self._makeOne() - environ = _makeEnviron() - start_response = DummyStartResponse() - app_iter = exc(environ, start_response) - self.assertEqual(app_iter[0], - (b'405 Method Not Allowed\n\nThe method GET is not ' - b'allowed for this resource. \n\n\n')) - - -class DummyRequest(object): - exception = None - -class DummyStartResponse(object): - def __call__(self, status, headerlist): - self.status = status - self.headerlist = headerlist - -def _makeEnviron(**kw): - environ = {'REQUEST_METHOD': 'GET', - 'wsgi.url_scheme': 'http', - 'SERVER_NAME': 'localhost', - 'SERVER_PORT': '80'} - environ.update(kw) - return environ diff --git a/src/pyramid/tests/test_i18n.py b/src/pyramid/tests/test_i18n.py deleted file mode 100644 index d72d0d480..000000000 --- a/src/pyramid/tests/test_i18n.py +++ /dev/null @@ -1,508 +0,0 @@ -# -*- coding: utf-8 -*- -# -import os - -here = os.path.dirname(__file__) -localedir = os.path.join(here, 'pkgs', 'localeapp', 'locale') - -import unittest -from pyramid import testing - -class TestTranslationString(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.i18n import TranslationString - return TranslationString(*arg, **kw) - - def test_it(self): - # this is part of the API, we don't actually need to test much more - # than that it's importable - ts = self._makeOne('a') - self.assertEqual(ts, 'a') - -class TestTranslationStringFactory(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.i18n import TranslationStringFactory - return TranslationStringFactory(*arg, **kw) - - def test_it(self): - # this is part of the API, we don't actually need to test much more - # than that it's importable - factory = self._makeOne('a') - self.assertEqual(factory('').domain, 'a') - -class TestLocalizer(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.i18n import Localizer - return Localizer(*arg, **kw) - - def test_ctor(self): - localizer = self._makeOne('en_US', None) - self.assertEqual(localizer.locale_name, 'en_US') - self.assertEqual(localizer.translations, None) - - def test_translate(self): - translations = DummyTranslations() - localizer = self._makeOne(None, translations) - self.assertEqual(localizer.translate('123', domain='1', - mapping={}), '123') - self.assertTrue(localizer.translator) - - def test_pluralize(self): - translations = DummyTranslations() - localizer = self._makeOne(None, translations) - result = localizer.pluralize('singular', 'plural', 1, - domain='1', mapping={}) - self.assertEqual(result, 'singular') - self.assertTrue(localizer.pluralizer) - - def test_pluralize_pluralizer_already_added(self): - translations = DummyTranslations() - localizer = self._makeOne(None, translations) - def pluralizer(*arg, **kw): - return arg, kw - localizer.pluralizer = pluralizer - result = localizer.pluralize('singular', 'plural', 1, domain='1', - mapping={}) - self.assertEqual( - result, - (('singular', 'plural', 1), {'domain': '1', 'mapping': {}}) - ) - self.assertTrue(localizer.pluralizer is pluralizer) - - def test_pluralize_default_translations(self): - # test that even without message ids loaded that - # "localizer.pluralize" "works" instead of raising an inscrutable - # "translations object has no attr 'plural' error; see - # see https://github.com/Pylons/pyramid/issues/235 - from pyramid.i18n import Translations - translations = Translations() - translations._catalog = {} - localizer = self._makeOne(None, translations) - result = localizer.pluralize('singular', 'plural', 2, domain='1', - mapping={}) - self.assertEqual(result, 'plural') - -class Test_negotiate_locale_name(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request): - from pyramid.i18n import negotiate_locale_name - return negotiate_locale_name(request) - - def _registerImpl(self, impl): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - from pyramid.interfaces import ILocaleNegotiator - registry.registerUtility(impl, ILocaleNegotiator) - - def test_no_registry_on_request(self): - self._registerImpl(dummy_negotiator) - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, 'bogus') - - def test_with_registry_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - self._registerImpl(dummy_negotiator) - request = DummyRequest() - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, 'bogus') - - def test_default_from_settings(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - settings = {'default_locale_name':'settings'} - registry.settings = settings - request = DummyRequest() - request.registry = registry - result = self._callFUT(request) - self.assertEqual(result, 'settings') - - def test_use_default_locale_negotiator(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = DummyRequest() - request.registry = registry - request._LOCALE_ = 'locale' - result = self._callFUT(request) - self.assertEqual(result, 'locale') - - def test_default_default(self): - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, 'en') - -class Test_get_locale_name(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request): - from pyramid.i18n import get_locale_name - return get_locale_name(request) - - def test_name_on_request(self): - request = DummyRequest() - request.locale_name = 'ie' - result = self._callFUT(request) - self.assertEqual(result, 'ie') - -class Test_make_localizer(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, locale, tdirs): - from pyramid.i18n import make_localizer - return make_localizer(locale, tdirs) - - def test_locale_from_mo(self): - from pyramid.i18n import Localizer - localedirs = [localedir] - locale_name = 'de' - result = self._callFUT(locale_name, localedirs) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Genehmigen') - self.assertEqual(result.translate('Approve'), 'Approve') - self.assertTrue(hasattr(result, 'pluralize')) - - def test_locale_from_mo_bad_mo(self): - from pyramid.i18n import Localizer - localedirs = [localedir] - locale_name = 'be' - result = self._callFUT(locale_name, localedirs) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Approve') - - def test_locale_from_mo_mo_isdir(self): - from pyramid.i18n import Localizer - localedirs = [localedir] - locale_name = 'gb' - result = self._callFUT(locale_name, localedirs) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Approve') - - def test_territory_fallback(self): - from pyramid.i18n import Localizer - localedirs = [localedir] - locale_name = 'de_DE' - result = self._callFUT(locale_name, localedirs) - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Submit', 'deformsite'), - 'different') # prefer translations from de_DE locale - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Genehmigen') # missing from de_DE locale, but in de - -class Test_get_localizer(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request): - from pyramid.i18n import get_localizer - return get_localizer(request) - - def test_it(self): - request = DummyRequest() - request.localizer = 'localizer' - self.assertEqual(self._callFUT(request), 'localizer') - -class Test_default_locale_negotiator(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request): - from pyramid.i18n import default_locale_negotiator - return default_locale_negotiator(request) - - def test_from_none(self): - request = DummyRequest() - result = self._callFUT(request) - self.assertEqual(result, None) - - def test_from_request_attr(self): - request = DummyRequest() - request._LOCALE_ = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - - def test_from_params(self): - request = DummyRequest() - request.params['_LOCALE_'] = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - - def test_from_cookies(self): - request = DummyRequest() - request.cookies['_LOCALE_'] = 'foo' - result = self._callFUT(request) - self.assertEqual(result, 'foo') - -class TestTranslations(unittest.TestCase): - def _getTargetClass(self): - from pyramid.i18n import Translations - return Translations - - def _makeOne(self): - messages1 = [ - ('foo', 'Voh'), - (('foo1', 1), 'Voh1'), - ] - messages2 = [ - ('foo', 'VohD'), - (('foo1', 1), 'VohD1'), - ] - - klass = self._getTargetClass() - - translations1 = klass(None, domain='messages') - translations1._catalog = dict(messages1) - translations1.plural = lambda *arg: 1 - translations2 = klass(None, domain='messages1') - translations2._catalog = dict(messages2) - translations2.plural = lambda *arg: 1 - translations = translations1.add(translations2, merge=False) - return translations - - def test_load_locales_None(self): - import gettext - klass = self._getTargetClass() - result = klass.load(localedir, None, domain=None) - self.assertEqual(result.__class__, gettext.NullTranslations) - - def test_load_domain_None(self): - import gettext - locales = ['de', 'en'] - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain=None) - self.assertEqual(result.__class__, gettext.NullTranslations) - - def test_load_found_locale_and_domain(self): - locales = ['de', 'en'] - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain='deformsite') - self.assertEqual(result.__class__, klass) - - def test_load_found_locale_and_domain_locale_is_string(self): - locales = 'de' - klass = self._getTargetClass() - result = klass.load(localedir, locales, domain='deformsite') - self.assertEqual(result.__class__, klass) - - def test___repr__(self): - inst = self._makeOne() - result = repr(inst) - self.assertEqual(result, '') - - def test_merge_not_gnutranslations(self): - inst = self._makeOne() - self.assertEqual(inst.merge(None), inst) - - def test_merge_gnutranslations(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2._catalog['a'] = 'b' - inst.merge(inst2) - self.assertEqual(inst._catalog['a'], 'b') - - def test_merge_gnutranslations_not_translations(self): - import gettext - t = gettext.GNUTranslations() - t._catalog = {'a':'b'} - inst = self._makeOne() - inst.merge(t) - self.assertEqual(inst._catalog['a'], 'b') - - def test_add_different_domain_merge_true_notexisting(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2.domain = 'domain2' - inst.add(inst2) - self.assertEqual(inst._domains['domain2'], inst2) - - def test_add_different_domain_merge_true_existing(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst3 = self._makeOne() - inst2.domain = 'domain2' - inst2._catalog['a'] = 'b' - inst3.domain = 'domain2' - inst._domains['domain2'] = inst3 - inst.add(inst2) - self.assertEqual(inst._domains['domain2'], inst3) - self.assertEqual(inst3._catalog['a'], 'b') - - def test_add_same_domain_merge_true(self): - inst = self._makeOne() - inst2 = self._makeOne() - inst2._catalog['a'] = 'b' - inst.add(inst2) - self.assertEqual(inst._catalog['a'], 'b') - - def test_add_default_domain_replaces_plural_first_time(self): - # Create three empty message catalogs in the default domain - inst = self._getTargetClass()(None, domain='messages') - inst2 = self._getTargetClass()(None, domain='messages') - inst3 = self._getTargetClass()(None, domain='messages') - inst._catalog = {} - inst2._catalog = {} - inst3._catalog = {} - - # The default plural scheme is the germanic one - self.assertEqual(inst.plural(0), 1) - self.assertEqual(inst.plural(1), 0) - self.assertEqual(inst.plural(2), 1) - - # inst2 represents a message file that declares french plurals - inst2.plural = lambda n: n > 1 - inst.add(inst2) - # that plural rule should now apply to inst - self.assertEqual(inst.plural(0), 0) - self.assertEqual(inst.plural(1), 0) - self.assertEqual(inst.plural(2), 1) - - # We load a second message file with different plural rules - inst3.plural = lambda n: n > 0 - inst.add(inst3) - # It doesn't override the previously loaded rule - self.assertEqual(inst.plural(0), 0) - self.assertEqual(inst.plural(1), 0) - self.assertEqual(inst.plural(2), 1) - - def test_dgettext(self): - t = self._makeOne() - self.assertEqual(t.dgettext('messages', 'foo'), 'Voh') - self.assertEqual(t.dgettext('messages1', 'foo'), 'VohD') - - def test_ldgettext(self): - t = self._makeOne() - self.assertEqual(t.ldgettext('messages', 'foo'), b'Voh') - self.assertEqual(t.ldgettext('messages1', 'foo'), b'VohD') - - def test_dugettext(self): - t = self._makeOne() - self.assertEqual(t.dugettext('messages', 'foo'), 'Voh') - self.assertEqual(t.dugettext('messages1', 'foo'), 'VohD') - - def test_dngettext(self): - t = self._makeOne() - self.assertEqual(t.dngettext('messages', 'foo1', 'foos1', 1), 'Voh1') - self.assertEqual(t.dngettext('messages1', 'foo1', 'foos1', 1), 'VohD1') - - def test_ldngettext(self): - t = self._makeOne() - self.assertEqual(t.ldngettext('messages', 'foo1', 'foos1', 1), b'Voh1') - self.assertEqual(t.ldngettext('messages1', 'foo1', 'foos1', 1),b'VohD1') - - def test_dungettext(self): - t = self._makeOne() - self.assertEqual(t.dungettext('messages', 'foo1', 'foos1', 1), 'Voh1') - self.assertEqual(t.dungettext('messages1', 'foo1', 'foos1', 1), 'VohD1') - - def test_default_germanic_pluralization(self): - t = self._getTargetClass()() - t._catalog = {} - result = t.dungettext('messages', 'foo1', 'foos1', 2) - self.assertEqual(result, 'foos1') - -class TestLocalizerRequestMixin(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self): - from pyramid.i18n import LocalizerRequestMixin - request = LocalizerRequestMixin() - request.registry = self.config.registry - request.cookies = {} - request.params = {} - return request - - def test_default_localizer(self): - # `localizer` returns a default localizer for `en` - from pyramid.i18n import Localizer - request = self._makeOne() - self.assertEqual(request.localizer.__class__, Localizer) - self.assertEqual(request.locale_name, 'en') - - def test_custom_localizer_for_default_locale(self): - from pyramid.interfaces import ILocalizer - dummy = object() - self.config.registry.registerUtility(dummy, ILocalizer, name='en') - request = self._makeOne() - self.assertEqual(request.localizer, dummy) - - def test_custom_localizer_for_custom_locale(self): - from pyramid.interfaces import ILocalizer - dummy = object() - self.config.registry.registerUtility(dummy, ILocalizer, name='ie') - request = self._makeOne() - request._LOCALE_ = 'ie' - self.assertEqual(request.localizer, dummy) - - def test_localizer_from_mo(self): - from pyramid.interfaces import ITranslationDirectories - from pyramid.i18n import Localizer - localedirs = [localedir] - self.config.registry.registerUtility( - localedirs, ITranslationDirectories) - request = self._makeOne() - request._LOCALE_ = 'de' - result = request.localizer - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Genehmigen') - self.assertEqual(result.translate('Approve'), 'Approve') - self.assertTrue(hasattr(result, 'pluralize')) - - def test_localizer_from_mo_bad_mo(self): - from pyramid.interfaces import ITranslationDirectories - from pyramid.i18n import Localizer - localedirs = [localedir] - self.config.registry.registerUtility( - localedirs, ITranslationDirectories) - request = self._makeOne() - request._LOCALE_ = 'be' - result = request.localizer - self.assertEqual(result.__class__, Localizer) - self.assertEqual(result.translate('Approve', 'deformsite'), - 'Approve') - -class DummyRequest(object): - def __init__(self): - self.params = {} - self.cookies = {} - -def dummy_negotiator(request): - return 'bogus' - -class DummyTranslations(object): - def ugettext(self, text): - return text - - gettext = ugettext - - def ungettext(self, singular, plural, n): - return singular - - ngettext = ungettext diff --git a/src/pyramid/tests/test_integration.py b/src/pyramid/tests/test_integration.py deleted file mode 100644 index eedc145ad..000000000 --- a/src/pyramid/tests/test_integration.py +++ /dev/null @@ -1,848 +0,0 @@ -# -*- coding: utf-8 -*- - -import datetime -import gc -import locale -import os -import unittest - -from pyramid.wsgi import wsgiapp -from pyramid.view import view_config -from pyramid.static import static_view -from pyramid.testing import skip_on -from pyramid.compat import ( - text_, - url_quote, - ) - -from zope.interface import Interface -from webtest import TestApp - -# 5 years from now (more or less) -fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) - -defaultlocale = locale.getdefaultlocale()[1] - -class INothing(Interface): - pass - -@view_config(for_=INothing) -@wsgiapp -def wsgiapptest(environ, start_response): - """ """ - return '123' - -class WGSIAppPlusViewConfigTests(unittest.TestCase): - def test_it(self): - from venusian import ATTACH_ATTR - import types - self.assertTrue(getattr(wsgiapptest, ATTACH_ATTR)) - self.assertTrue(type(wsgiapptest) is types.FunctionType) - context = DummyContext() - request = DummyRequest() - result = wsgiapptest(context, request) - self.assertEqual(result, '123') - - def test_scanned(self): - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - from pyramid.config import Configurator - from pyramid.tests import test_integration - config = Configurator() - config.scan(test_integration) - config.commit() - reg = config.registry - view = reg.adapters.lookup( - (IViewClassifier, IRequest, INothing), IView, name='') - self.assertEqual(view.__original_view__, wsgiapptest) - -class IntegrationBase(object): - root_factory = None - package = None - def setUp(self): - from pyramid.config import Configurator - config = Configurator(root_factory=self.root_factory, - package=self.package) - config.include(self.package) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - self.config = config - - def tearDown(self): - self.config.end() - -here = os.path.dirname(__file__) - -class StaticAppBase(IntegrationBase): - def test_basic(self): - res = self.testapp.get('/minimal.txt', status=200) - _assertBody(res.body, os.path.join(here, 'fixtures/minimal.txt')) - - def test_hidden(self): - res = self.testapp.get('/static/.hiddenfile', status=200) - _assertBody(res.body, os.path.join(here, 'fixtures/static/.hiddenfile')) - - if defaultlocale is not None: # pragma: no cover - # These tests are expected to fail on LANG=C systems due to decode - # errors and on non-Linux systems due to git highchar handling - # vagaries - def test_highchars_in_pathelement(self): - path = os.path.join( - here, - text_('fixtures/static/héhé/index.html', 'utf-8')) - pathdir = os.path.dirname(path) - body = b'hehe\n' - try: - os.makedirs(pathdir) - with open(path, 'wb') as fp: - fp.write(body) - url = url_quote('/static/héhé/index.html') - res = self.testapp.get(url, status=200) - self.assertEqual(res.body, body) - finally: - os.unlink(path) - os.rmdir(pathdir) - - def test_highchars_in_filename(self): - path = os.path.join( - here, - text_('fixtures/static/héhé.html', 'utf-8')) - body = b'hehe file\n' - with open(path, 'wb') as fp: - fp.write(body) - try: - url = url_quote('/static/héhé.html') - res = self.testapp.get(url, status=200) - self.assertEqual(res.body, body) - finally: - os.unlink(path) - - def test_not_modified(self): - self.testapp.extra_environ = { - 'HTTP_IF_MODIFIED_SINCE':httpdate(fiveyrsfuture)} - res = self.testapp.get('/minimal.txt', status=304) - self.assertEqual(res.body, b'') - - def test_file_in_subdir(self): - fn = os.path.join(here, 'fixtures/static/index.html') - res = self.testapp.get('/static/index.html', status=200) - _assertBody(res.body, fn) - - def test_directory_noslash_redir(self): - res = self.testapp.get('/static', status=301) - self.assertEqual(res.headers['Location'], 'http://localhost/static/') - - def test_directory_noslash_redir_preserves_qs(self): - res = self.testapp.get('/static?a=1&b=2', status=301) - self.assertEqual(res.headers['Location'], - 'http://localhost/static/?a=1&b=2') - - def test_directory_noslash_redir_with_scriptname(self): - self.testapp.extra_environ = {'SCRIPT_NAME':'/script_name'} - res = self.testapp.get('/static', status=301) - self.assertEqual(res.headers['Location'], - 'http://localhost/script_name/static/') - - def test_directory_withslash(self): - fn = os.path.join(here, 'fixtures/static/index.html') - res = self.testapp.get('/static/', status=200) - _assertBody(res.body, fn) - - def test_range_inclusive(self): - self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1-2'} - res = self.testapp.get('/static/index.html', status=206) - self.assertEqual(res.body, b'ht') - - def test_range_tilend(self): - self.testapp.extra_environ = {'HTTP_RANGE':'bytes=-5'} - res = self.testapp.get('/static/index.html', status=206) - self.assertEqual(res.body, b'html>') - - def test_range_notbytes(self): - self.testapp.extra_environ = {'HTTP_RANGE':'kHz=-5'} - res = self.testapp.get('/static/index.html', status=200) - _assertBody(res.body, - os.path.join(here, 'fixtures/static/index.html')) - - def test_range_multiple(self): - res = self.testapp.get('/static/index.html', - [('HTTP_RANGE', 'bytes=10-11,11-12')], - status=200) - _assertBody(res.body, - os.path.join(here, 'fixtures/static/index.html')) - - def test_range_oob(self): - self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1000-1002'} - self.testapp.get('/static/index.html', status=416) - - def test_notfound(self): - self.testapp.get('/static/wontbefound.html', status=404) - - def test_oob_dotdotslash(self): - self.testapp.get('/static/../../test_integration.py', status=404) - - def test_oob_dotdotslash_encoded(self): - self.testapp.get('/static/%2E%2E%2F/test_integration.py', status=404) - - def test_oob_slash(self): - self.testapp.get('/%2F/test_integration.py', status=404) - -class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.eventonly' - - def test_sendfoo(self): - res = self.testapp.get('/sendfoo', status=200) - self.assertEqual(sorted(res.body.split()), [b'foo', b'fooyup']) - - def test_sendfoobar(self): - res = self.testapp.get('/sendfoobar', status=200) - self.assertEqual(sorted(res.body.split()), - [b'foobar', b'foobar2', b'foobaryup', b'foobaryup2']) - -class TestStaticAppUsingAbsPath(StaticAppBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.static_abspath' - -class TestStaticAppUsingAssetSpec(StaticAppBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.static_assetspec' - -class TestStaticAppNoSubpath(unittest.TestCase): - staticapp = static_view(os.path.join(here, 'fixtures'), use_subpath=False) - def _makeRequest(self, extra): - from pyramid.request import Request - from io import BytesIO - kw = {'PATH_INFO':'', - 'SCRIPT_NAME':'', - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'80', - 'REQUEST_METHOD':'GET', - 'wsgi.version':(1,0), - 'wsgi.url_scheme':'http', - 'wsgi.input':BytesIO()} - kw.update(extra) - request = Request(kw) - return request - - def test_basic(self): - request = self._makeRequest({'PATH_INFO':'/minimal.txt'}) - context = DummyContext() - result = self.staticapp(context, request) - self.assertEqual(result.status, '200 OK') - _assertBody(result.body, os.path.join(here, 'fixtures/minimal.txt')) - -class TestStaticAppWithRoutePrefix(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.static_routeprefix' - - def test_includelevel1(self): - res = self.testapp.get('/static/minimal.txt', status=200) - _assertBody(res.body, - os.path.join(here, 'fixtures/minimal.txt')) - - def test_includelevel2(self): - res = self.testapp.get('/prefix/static/index.html', status=200) - _assertBody(res.body, - os.path.join(here, 'fixtures/static/index.html')) - - -class TestFixtureApp(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.fixtureapp' - def test_another(self): - res = self.testapp.get('/another.html', status=200) - self.assertEqual(res.body, b'fixture') - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertEqual(res.body, b'fixture') - - def test_dummyskin(self): - self.testapp.get('/dummyskin.html', status=404) - - def test_error(self): - res = self.testapp.get('/error.html', status=200) - self.assertEqual(res.body, b'supressed') - - def test_protected(self): - self.testapp.get('/protected.html', status=403) - -class TestStaticPermApp(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.staticpermapp' - root_factory = 'pyramid.tests.pkgs.staticpermapp:RootFactory' - def test_allowed(self): - result = self.testapp.get('/allowed/index.html', status=200) - _assertBody(result.body, - os.path.join(here, 'fixtures/static/index.html')) - - def test_denied_via_acl_global_root_factory(self): - self.testapp.extra_environ = {'REMOTE_USER':'bob'} - self.testapp.get('/protected/index.html', status=403) - - def test_allowed_via_acl_global_root_factory(self): - self.testapp.extra_environ = {'REMOTE_USER':'fred'} - result = self.testapp.get('/protected/index.html', status=200) - _assertBody(result.body, - os.path.join(here, 'fixtures/static/index.html')) - - def test_denied_via_acl_local_root_factory(self): - self.testapp.extra_environ = {'REMOTE_USER':'fred'} - self.testapp.get('/factory_protected/index.html', status=403) - - def test_allowed_via_acl_local_root_factory(self): - self.testapp.extra_environ = {'REMOTE_USER':'bob'} - result = self.testapp.get('/factory_protected/index.html', status=200) - _assertBody(result.body, - os.path.join(here, 'fixtures/static/index.html')) - -class TestCCBug(IntegrationBase, unittest.TestCase): - # "unordered" as reported in IRC by author of - # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ - package = 'pyramid.tests.pkgs.ccbugapp' - def test_rdf(self): - res = self.testapp.get('/licenses/1/v1/rdf', status=200) - self.assertEqual(res.body, b'rdf') - - def test_juri(self): - res = self.testapp.get('/licenses/1/v1/juri', status=200) - self.assertEqual(res.body, b'juri') - -class TestHybridApp(IntegrationBase, unittest.TestCase): - # make sure views registered for a route "win" over views registered - # without one, even though the context of the non-route view may - # be more specific than the route view. - package = 'pyramid.tests.pkgs.hybridapp' - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertEqual(res.body, b'global') - - def test_abc(self): - res = self.testapp.get('/abc', status=200) - self.assertEqual(res.body, b'route') - - def test_def(self): - res = self.testapp.get('/def', status=200) - self.assertEqual(res.body, b'route2') - - def test_ghi(self): - res = self.testapp.get('/ghi', status=200) - self.assertEqual(res.body, b'global') - - def test_jkl(self): - self.testapp.get('/jkl', status=404) - - def test_mno(self): - self.testapp.get('/mno', status=404) - - def test_pqr_global2(self): - res = self.testapp.get('/pqr/global2', status=200) - self.assertEqual(res.body, b'global2') - - def test_error(self): - res = self.testapp.get('/error', status=200) - self.assertEqual(res.body, b'supressed') - - def test_error2(self): - res = self.testapp.get('/error2', status=200) - self.assertEqual(res.body, b'supressed2') - - def test_error_sub(self): - res = self.testapp.get('/error_sub', status=200) - self.assertEqual(res.body, b'supressed2') - -class TestRestBugApp(IntegrationBase, unittest.TestCase): - # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) - package = 'pyramid.tests.pkgs.restbugapp' - def test_it(self): - res = self.testapp.get('/pet', status=200) - self.assertEqual(res.body, b'gotten') - -class TestForbiddenAppHasResult(IntegrationBase, unittest.TestCase): - # test that forbidden exception has ACLDenied result attached - package = 'pyramid.tests.pkgs.forbiddenapp' - def test_it(self): - res = self.testapp.get('/x', status=403) - message, result = [x.strip() for x in res.body.split(b'\n')] - self.assertTrue(message.endswith(b'failed permission check')) - self.assertTrue( - result.startswith(b"ACLDenied permission 'private' via ACE " - b"'' in ACL " - b"'' on context")) - self.assertTrue( - result.endswith(b"for principals ['system.Everyone']")) - -class TestViewDecoratorApp(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.viewdecoratorapp' - - def test_first(self): - res = self.testapp.get('/first', status=200) - self.assertTrue(b'OK' in res.body) - - def test_second(self): - res = self.testapp.get('/second', status=200) - self.assertTrue(b'OK2' in res.body) - -class TestNotFoundView(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.notfoundview' - - def test_it(self): - res = self.testapp.get('/wontbefound', status=200) - self.assertTrue(b'generic_notfound' in res.body) - res = self.testapp.get('/bar', status=307) - self.assertEqual(res.location, 'http://localhost/bar/') - res = self.testapp.get('/bar/', status=200) - self.assertTrue(b'OK bar' in res.body) - res = self.testapp.get('/foo', status=307) - self.assertEqual(res.location, 'http://localhost/foo/') - res = self.testapp.get('/foo/', status=200) - self.assertTrue(b'OK foo2' in res.body) - res = self.testapp.get('/baz', status=200) - self.assertTrue(b'baz_notfound' in res.body) - -class TestForbiddenView(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.forbiddenview' - - def test_it(self): - res = self.testapp.get('/foo', status=200) - self.assertTrue(b'foo_forbidden' in res.body) - res = self.testapp.get('/bar', status=200) - self.assertTrue(b'generic_forbidden' in res.body) - -class TestViewPermissionBug(IntegrationBase, unittest.TestCase): - # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html - package = 'pyramid.tests.pkgs.permbugapp' - def test_test(self): - res = self.testapp.get('/test', status=200) - self.assertTrue(b'ACLDenied' in res.body) - - def test_x(self): - self.testapp.get('/x', status=403) - -class TestDefaultViewPermissionBug(IntegrationBase, unittest.TestCase): - # default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html - package = 'pyramid.tests.pkgs.defpermbugapp' - def test_x(self): - res = self.testapp.get('/x', status=403) - self.assertTrue(b'failed permission check' in res.body) - - def test_y(self): - res = self.testapp.get('/y', status=403) - self.assertTrue(b'failed permission check' in res.body) - - def test_z(self): - res = self.testapp.get('/z', status=200) - self.assertTrue(b'public' in res.body) - -from pyramid.tests.pkgs.exceptionviewapp.models import \ - AnException, NotAnException -excroot = {'anexception':AnException(), - 'notanexception':NotAnException()} - -class TestExceptionViewsApp(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.exceptionviewapp' - root_factory = lambda *arg: excroot - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue(b'maybe' in res.body) - - def test_notanexception(self): - res = self.testapp.get('/notanexception', status=200) - self.assertTrue(b'no' in res.body) - - def test_anexception(self): - res = self.testapp.get('/anexception', status=200) - self.assertTrue(b'yes' in res.body) - - def test_route_raise_exception(self): - res = self.testapp.get('/route_raise_exception', status=200) - self.assertTrue(b'yes' in res.body) - - def test_route_raise_exception2(self): - res = self.testapp.get('/route_raise_exception2', status=200) - self.assertTrue(b'yes' in res.body) - - def test_route_raise_exception3(self): - res = self.testapp.get('/route_raise_exception3', status=200) - self.assertTrue(b'whoa' in res.body) - - def test_route_raise_exception4(self): - res = self.testapp.get('/route_raise_exception4', status=200) - self.assertTrue(b'whoa' in res.body) - - def test_raise_httpexception(self): - res = self.testapp.get('/route_raise_httpexception', status=200) - self.assertTrue(b'caught' in res.body) - -class TestConflictApp(unittest.TestCase): - package = 'pyramid.tests.pkgs.conflictapp' - def _makeConfig(self): - from pyramid.config import Configurator - config = Configurator() - return config - - def test_autoresolved_view(self): - config = self._makeConfig() - config.include(self.package) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - res = self.testapp.get('/') - self.assertTrue(b'a view' in res.body) - res = self.testapp.get('/route') - self.assertTrue(b'route view' in res.body) - - def test_overridden_autoresolved_view(self): - from pyramid.response import Response - config = self._makeConfig() - config.include(self.package) - def thisview(request): - return Response('this view') - config.add_view(thisview) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - res = self.testapp.get('/') - self.assertTrue(b'this view' in res.body) - - def test_overridden_route_view(self): - from pyramid.response import Response - config = self._makeConfig() - config.include(self.package) - def thisview(request): - return Response('this view') - config.add_view(thisview, route_name='aroute') - app = config.make_wsgi_app() - self.testapp = TestApp(app) - res = self.testapp.get('/route') - self.assertTrue(b'this view' in res.body) - - def test_nonoverridden_authorization_policy(self): - config = self._makeConfig() - config.include(self.package) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - res = self.testapp.get('/protected', status=403) - self.assertTrue(b'403 Forbidden' in res.body) - - def test_overridden_authorization_policy(self): - config = self._makeConfig() - config.include(self.package) - from pyramid.testing import DummySecurityPolicy - config.set_authorization_policy(DummySecurityPolicy('fred')) - config.set_authentication_policy(DummySecurityPolicy(permissive=True)) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - res = self.testapp.get('/protected', status=200) - self.assertTrue('protected view' in res) - -class ImperativeIncludeConfigurationTest(unittest.TestCase): - def setUp(self): - from pyramid.config import Configurator - config = Configurator() - from pyramid.tests.pkgs.includeapp1.root import configure - configure(config) - app = config.make_wsgi_app() - self.testapp = TestApp(app) - self.config = config - - def tearDown(self): - self.config.end() - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue(b'root' in res.body) - - def test_two(self): - res = self.testapp.get('/two', status=200) - self.assertTrue(b'two' in res.body) - - def test_three(self): - res = self.testapp.get('/three', status=200) - self.assertTrue(b'three' in res.body) - -class SelfScanAppTest(unittest.TestCase): - def setUp(self): - from pyramid.tests.test_config.pkgs.selfscan import main - config = main() - app = config.make_wsgi_app() - self.testapp = TestApp(app) - self.config = config - - def tearDown(self): - self.config.end() - - def test_root(self): - res = self.testapp.get('/', status=200) - self.assertTrue(b'root' in res.body) - - def test_two(self): - res = self.testapp.get('/two', status=200) - self.assertTrue(b'two' in res.body) - -class WSGIApp2AppTest(unittest.TestCase): - def setUp(self): - from pyramid.tests.pkgs.wsgiapp2app import main - config = main() - app = config.make_wsgi_app() - self.testapp = TestApp(app) - self.config = config - - def tearDown(self): - self.config.end() - - def test_hello(self): - res = self.testapp.get('/hello', status=200) - self.assertTrue(b'Hello' in res.body) - -class SubrequestAppTest(unittest.TestCase): - def setUp(self): - from pyramid.tests.pkgs.subrequestapp import main - config = main() - app = config.make_wsgi_app() - self.testapp = TestApp(app) - self.config = config - - def tearDown(self): - self.config.end() - - def test_one(self): - res = self.testapp.get('/view_one', status=200) - self.assertTrue(b'This came from view_two, foo=bar' in res.body) - - def test_three(self): - res = self.testapp.get('/view_three', status=500) - self.assertTrue(b'Bad stuff happened' in res.body) - - def test_five(self): - res = self.testapp.get('/view_five', status=200) - self.assertTrue(b'Value error raised' in res.body) - -class RendererScanAppTest(IntegrationBase, unittest.TestCase): - package = 'pyramid.tests.pkgs.rendererscanapp' - def test_root(self): - res = self.testapp.get('/one', status=200) - self.assertTrue(b'One!' in res.body) - - def test_two(self): - res = self.testapp.get('/two', status=200) - self.assertTrue(b'Two!' in res.body) - - def test_rescan(self): - self.config.scan('pyramid.tests.pkgs.rendererscanapp') - app = self.config.make_wsgi_app() - testapp = TestApp(app) - res = testapp.get('/one', status=200) - self.assertTrue(b'One!' in res.body) - res = testapp.get('/two', status=200) - self.assertTrue(b'Two!' in res.body) - -class UnicodeInURLTest(unittest.TestCase): - def _makeConfig(self): - from pyramid.config import Configurator - config = Configurator() - return config - - def _makeTestApp(self, config): - app = config.make_wsgi_app() - return TestApp(app) - - def test_unicode_in_url_404(self): - request_path = '/avalia%C3%A7%C3%A3o_participante' - request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') - - config = self._makeConfig() - testapp = self._makeTestApp(config) - - res = testapp.get(request_path, status=404) - - # Pyramid default 404 handler outputs: - # u'404 Not Found\n\nThe resource could not be found.\n\n\n' - # u'/avalia\xe7\xe3o_participante\n\n' - self.assertTrue(request_path_unicode in res.text) - - def test_unicode_in_url_200(self): - request_path = '/avalia%C3%A7%C3%A3o_participante' - request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') - - def myview(request): - return 'XXX' - - config = self._makeConfig() - config.add_route('myroute', request_path_unicode) - config.add_view(myview, route_name='myroute', renderer='json') - testapp = self._makeTestApp(config) - - res = testapp.get(request_path, status=200) - - self.assertEqual(res.text, '"XXX"') - - -class AcceptContentTypeTest(unittest.TestCase): - def _makeConfig(self): - def hello_view(request): - return {'message': 'Hello!'} - from pyramid.config import Configurator - config = Configurator() - config.add_route('hello', '/hello') - config.add_view(hello_view, route_name='hello', - accept='text/plain', renderer='string') - config.add_view(hello_view, route_name='hello', - accept='application/json', renderer='json') - def hello_fallback_view(request): - request.response.content_type = 'text/x-fallback' - return 'hello fallback' - config.add_view(hello_fallback_view, route_name='hello', - renderer='string') - return config - - def _makeTestApp(self, config): - app = config.make_wsgi_app() - return TestApp(app) - - def tearDown(self): - import pyramid.config - pyramid.config.global_registries.empty() - - def test_client_side_ordering(self): - config = self._makeConfig() - app = self._makeTestApp(config) - res = app.get('/hello', headers={ - 'Accept': 'application/json; q=1.0, text/plain; q=0.9', - }, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={ - 'Accept': 'text/plain; q=0.9, application/json; q=1.0', - }, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={'Accept': 'application/*'}, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={'Accept': 'text/*'}, status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) - self.assertEqual(res.content_type, 'text/x-fallback') - - def test_default_server_side_ordering(self): - config = self._makeConfig() - app = self._makeTestApp(config) - res = app.get('/hello', headers={ - 'Accept': 'application/json, text/plain', - }, status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', headers={ - 'Accept': 'text/plain, application/json', - }, status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', headers={'Accept': '*/*'}, status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) - self.assertEqual(res.content_type, 'text/plain') - res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) - self.assertEqual(res.content_type, 'text/x-fallback') - - def test_custom_server_side_ordering(self): - config = self._makeConfig() - config.add_accept_view_order( - 'application/json', weighs_more_than='text/plain') - app = self._makeTestApp(config) - res = app.get('/hello', headers={ - 'Accept': 'application/json, text/plain', - }, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={ - 'Accept': 'text/plain, application/json', - }, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={'Accept': '*/*'}, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) - self.assertEqual(res.content_type, 'application/json') - res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) - self.assertEqual(res.content_type, 'text/x-fallback') - - def test_deprecated_ranges_in_route_predicate(self): - config = self._makeConfig() - config.add_route('foo', '/foo', accept='text/*') - config.add_view(lambda r: 'OK', route_name='foo', renderer='string') - app = self._makeTestApp(config) - res = app.get('/foo', headers={ - 'Accept': 'application/json; q=1.0, text/plain; q=0.9', - }, status=200) - self.assertEqual(res.content_type, 'text/plain') - self.assertEqual(res.body, b'OK') - res = app.get('/foo', headers={ - 'Accept': 'application/json', - }, status=404) - self.assertEqual(res.content_type, 'application/json') - - def test_deprecated_ranges_in_view_predicate(self): - config = self._makeConfig() - config.add_route('foo', '/foo') - config.add_view(lambda r: 'OK', route_name='foo', - accept='text/*', renderer='string') - app = self._makeTestApp(config) - res = app.get('/foo', headers={ - 'Accept': 'application/json; q=1.0, text/plain; q=0.9', - }, status=200) - self.assertEqual(res.content_type, 'text/plain') - self.assertEqual(res.body, b'OK') - res = app.get('/foo', headers={ - 'Accept': 'application/json', - }, status=404) - self.assertEqual(res.content_type, 'application/json') - - -class DummyContext(object): - pass - -class DummyRequest: - subpath = ('__init__.py',) - traversed = None - environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)} - def get_response(self, application): - return application(None, None) - -def httpdate(ts): - return ts.strftime("%a, %d %b %Y %H:%M:%S GMT") - -def read_(filename): - with open(filename, 'rb') as fp: - val = fp.read() - return val - -def _assertBody(body, filename): - if defaultlocale is None: # pragma: no cover - # If system locale does not have an encoding then default to utf-8 - filename = filename.encode('utf-8') - # strip both \n and \r for windows - body = body.replace(b'\r', b'') - body = body.replace(b'\n', b'') - data = read_(filename) - data = data.replace(b'\r', b'') - data = data.replace(b'\n', b'') - assert(body == data) - - -class MemoryLeaksTest(unittest.TestCase): - - def tearDown(self): - import pyramid.config - pyramid.config.global_registries.empty() - - def get_gc_count(self): - last_collected = 0 - while True: - collected = gc.collect() - if collected == last_collected: - break - last_collected = collected - return len(gc.get_objects()) - - @skip_on('pypy') - def test_memory_leaks(self): - from pyramid.config import Configurator - Configurator().make_wsgi_app() # Initialize all global objects - - initial_count = self.get_gc_count() - Configurator().make_wsgi_app() - current_count = self.get_gc_count() - self.assertEqual(current_count, initial_count) diff --git a/src/pyramid/tests/test_location.py b/src/pyramid/tests/test_location.py deleted file mode 100644 index e1f47f4ab..000000000 --- a/src/pyramid/tests/test_location.py +++ /dev/null @@ -1,40 +0,0 @@ -import unittest - -class TestInside(unittest.TestCase): - def _callFUT(self, one, two): - from pyramid.location import inside - return inside(one, two) - - def test_inside(self): - o1 = Location() - o2 = Location(); o2.__parent__ = o1 - o3 = Location(); o3.__parent__ = o2 - o4 = Location(); o4.__parent__ = o3 - - self.assertEqual(self._callFUT(o1, o1), True) - self.assertEqual(self._callFUT(o2, o1), True) - self.assertEqual(self._callFUT(o3, o1), True) - self.assertEqual(self._callFUT(o4, o1), True) - self.assertEqual(self._callFUT(o1, o4), False) - self.assertEqual(self._callFUT(o1, None), False) - -class TestLineage(unittest.TestCase): - def _callFUT(self, context): - from pyramid.location import lineage - return lineage(context) - - def test_lineage(self): - o1 = Location() - o2 = Location(); o2.__parent__ = o1 - o3 = Location(); o3.__parent__ = o2 - o4 = Location(); o4.__parent__ = o3 - result = list(self._callFUT(o3)) - self.assertEqual(result, [o3, o2, o1]) - result = list(self._callFUT(o1)) - self.assertEqual(result, [o1]) - -from pyramid.interfaces import ILocation -from zope.interface import implementer -@implementer(ILocation) -class Location(object): - __name__ = __parent__ = None diff --git a/src/pyramid/tests/test_paster.py b/src/pyramid/tests/test_paster.py deleted file mode 100644 index 784458647..000000000 --- a/src/pyramid/tests/test_paster.py +++ /dev/null @@ -1,168 +0,0 @@ -import os -import unittest -from pyramid.tests.test_scripts.dummy import DummyLoader - -here = os.path.dirname(__file__) - -class Test_get_app(unittest.TestCase): - def _callFUT(self, config_file, section_name, options=None, _loader=None): - import pyramid.paster - old_loader = pyramid.paster.get_config_loader - try: - if _loader is not None: - pyramid.paster.get_config_loader = _loader - return pyramid.paster.get_app(config_file, section_name, - options=options) - finally: - pyramid.paster.get_config_loader = old_loader - - def test_it(self): - app = DummyApp() - loader = DummyLoader(app=app) - result = self._callFUT( - '/foo/bar/myapp.ini', 'myapp', options={'a': 'b'}, - _loader=loader) - self.assertEqual(loader.uri.path, '/foo/bar/myapp.ini') - self.assertEqual(len(loader.calls), 1) - self.assertEqual(loader.calls[0]['op'], 'app') - self.assertEqual(loader.calls[0]['name'], 'myapp') - self.assertEqual(loader.calls[0]['defaults'], {'a': 'b'}) - self.assertEqual(result, app) - - def test_it_with_dummyapp_requiring_options(self): - options = {'bar': 'baz'} - app = self._callFUT( - os.path.join(here, 'fixtures', 'dummy.ini'), - 'myapp', options=options) - self.assertEqual(app.settings['foo'], 'baz') - -class Test_get_appsettings(unittest.TestCase): - def _callFUT(self, config_file, section_name, options=None, _loader=None): - import pyramid.paster - old_loader = pyramid.paster.get_config_loader - try: - if _loader is not None: - pyramid.paster.get_config_loader = _loader - return pyramid.paster.get_appsettings(config_file, section_name, - options=options) - finally: - pyramid.paster.get_config_loader = old_loader - - def test_it(self): - values = {'a': 1} - loader = DummyLoader(app_settings=values) - result = self._callFUT( - '/foo/bar/myapp.ini', 'myapp', options={'a': 'b'}, - _loader=loader) - self.assertEqual(loader.uri.path, '/foo/bar/myapp.ini') - self.assertEqual(len(loader.calls), 1) - self.assertEqual(loader.calls[0]['op'], 'app_settings') - self.assertEqual(loader.calls[0]['name'], 'myapp') - self.assertEqual(loader.calls[0]['defaults'], {'a': 'b'}) - self.assertEqual(result, values) - - def test_it_with_dummyapp_requiring_options(self): - options = {'bar': 'baz'} - result = self._callFUT( - os.path.join(here, 'fixtures', 'dummy.ini'), - 'myapp', options=options) - self.assertEqual(result['foo'], 'baz') - -class Test_setup_logging(unittest.TestCase): - def _callFUT(self, config_file, global_conf=None, _loader=None): - import pyramid.paster - old_loader = pyramid.paster.get_config_loader - try: - if _loader is not None: - pyramid.paster.get_config_loader = _loader - return pyramid.paster.setup_logging(config_file, global_conf) - finally: - pyramid.paster.get_config_loader = old_loader - - def test_it_no_global_conf(self): - loader = DummyLoader() - self._callFUT('/abc.ini', _loader=loader) - self.assertEqual(loader.uri.path, '/abc.ini') - self.assertEqual(len(loader.calls), 1) - self.assertEqual(loader.calls[0]['op'], 'logging') - self.assertEqual(loader.calls[0]['defaults'], None) - - def test_it_global_conf_empty(self): - loader = DummyLoader() - self._callFUT('/abc.ini', global_conf={}, _loader=loader) - self.assertEqual(loader.uri.path, '/abc.ini') - self.assertEqual(len(loader.calls), 1) - self.assertEqual(loader.calls[0]['op'], 'logging') - self.assertEqual(loader.calls[0]['defaults'], {}) - - def test_it_global_conf_not_empty(self): - loader = DummyLoader() - self._callFUT('/abc.ini', global_conf={'key': 'val'}, _loader=loader) - self.assertEqual(loader.uri.path, '/abc.ini') - self.assertEqual(len(loader.calls), 1) - self.assertEqual(loader.calls[0]['op'], 'logging') - self.assertEqual(loader.calls[0]['defaults'], {'key': 'val'}) - -class Test_bootstrap(unittest.TestCase): - def _callFUT(self, config_uri, request=None): - from pyramid.paster import bootstrap - return bootstrap(config_uri, request) - - def setUp(self): - import pyramid.paster - self.original_get_app = pyramid.paster.get_app - self.original_prepare = pyramid.paster.prepare - self.app = app = DummyApp() - self.root = root = Dummy() - - class DummyGetApp(object): - def __call__(self, *a, **kw): - self.a = a - self.kw = kw - return app - self.get_app = pyramid.paster.get_app = DummyGetApp() - - class DummyPrepare(object): - def __call__(self, *a, **kw): - self.a = a - self.kw = kw - return {'root':root, 'closer':lambda: None} - self.getroot = pyramid.paster.prepare = DummyPrepare() - - def tearDown(self): - import pyramid.paster - pyramid.paster.get_app = self.original_get_app - pyramid.paster.prepare = self.original_prepare - - def test_it_request_with_registry(self): - request = DummyRequest({}) - request.registry = dummy_registry - result = self._callFUT('/foo/bar/myapp.ini', request) - self.assertEqual(result['app'], self.app) - self.assertEqual(result['root'], self.root) - self.assertTrue('closer' in result) - -class Dummy: - pass - -class DummyRegistry(object): - settings = {} - -dummy_registry = DummyRegistry() - -class DummyApp: - def __init__(self): - self.registry = dummy_registry - -def make_dummyapp(global_conf, **settings): - app = DummyApp() - app.settings = settings - app.global_conf = global_conf - return app - -class DummyRequest: - application_url = 'http://example.com:5432' - script_name = '' - def __init__(self, environ): - self.environ = environ - self.matchdict = {} diff --git a/src/pyramid/tests/test_path.py b/src/pyramid/tests/test_path.py deleted file mode 100644 index 563ece6d6..000000000 --- a/src/pyramid/tests/test_path.py +++ /dev/null @@ -1,576 +0,0 @@ -import unittest -import os -from pyramid.compat import PY2 - -here = os.path.abspath(os.path.dirname(__file__)) - -class TestCallerPath(unittest.TestCase): - def tearDown(self): - from pyramid.tests import test_path - if hasattr(test_path, '__abspath__'): - del test_path.__abspath__ - - def _callFUT(self, path, level=2): - from pyramid.path import caller_path - return caller_path(path, level) - - def test_isabs(self): - result = self._callFUT('/a/b/c') - self.assertEqual(result, '/a/b/c') - - def test_pkgrelative(self): - import os - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join(here, 'a/b/c')) - - def test_memoization_has_abspath(self): - import os - from pyramid.tests import test_path - test_path.__abspath__ = '/foo/bar' - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join('/foo/bar', 'a/b/c')) - - def test_memoization_success(self): - import os - from pyramid.tests import test_path - result = self._callFUT('a/b/c') - self.assertEqual(result, os.path.join(here, 'a/b/c')) - self.assertEqual(test_path.__abspath__, here) - -class TestCallerModule(unittest.TestCase): - def _callFUT(self, *arg, **kw): - from pyramid.path import caller_module - return caller_module(*arg, **kw) - - def test_it_level_1(self): - from pyramid.tests import test_path - result = self._callFUT(1) - self.assertEqual(result, test_path) - - def test_it_level_2(self): - from pyramid.tests import test_path - result = self._callFUT(2) - self.assertEqual(result, test_path) - - def test_it_level_3(self): - from pyramid.tests import test_path - result = self._callFUT(3) - self.assertNotEqual(result, test_path) - - def test_it_no___name__(self): - class DummyFrame(object): - f_globals = {} - class DummySys(object): - def _getframe(self, level): - return DummyFrame() - modules = {'__main__':'main'} - dummy_sys = DummySys() - result = self._callFUT(3, sys=dummy_sys) - self.assertEqual(result, 'main') - - -class TestCallerPackage(unittest.TestCase): - def _callFUT(self, *arg, **kw): - from pyramid.path import caller_package - return caller_package(*arg, **kw) - - def test_it_level_1(self): - from pyramid import tests - result = self._callFUT(1) - self.assertEqual(result, tests) - - def test_it_level_2(self): - from pyramid import tests - result = self._callFUT(2) - self.assertEqual(result, tests) - - def test_it_level_3(self): - import unittest - result = self._callFUT(3) - self.assertEqual(result, unittest) - - def test_it_package(self): - import pyramid.tests - def dummy_caller_module(*arg): - return pyramid.tests - result = self._callFUT(1, caller_module=dummy_caller_module) - self.assertEqual(result, pyramid.tests) - -class TestPackagePath(unittest.TestCase): - def _callFUT(self, package): - from pyramid.path import package_path - return package_path(package) - - def test_it_package(self): - from pyramid import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, package.package_path) - - def test_it_module(self): - from pyramid.tests import test_path - module = DummyPackageOrModule(test_path) - result = self._callFUT(module) - self.assertEqual(result, module.package_path) - - def test_memoization_success(self): - from pyramid.tests import test_path - module = DummyPackageOrModule(test_path) - self._callFUT(module) - self.assertEqual(module.__abspath__, module.package_path) - - def test_memoization_fail(self): - from pyramid.tests import test_path - module = DummyPackageOrModule(test_path, raise_exc=TypeError) - result = self._callFUT(module) - self.assertFalse(hasattr(module, '__abspath__')) - self.assertEqual(result, module.package_path) - -class TestPackageOf(unittest.TestCase): - def _callFUT(self, package): - from pyramid.path import package_of - return package_of(package) - - def test_it_package(self): - from pyramid import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, tests) - - def test_it_module(self): - import pyramid.tests.test_path - from pyramid import tests - package = DummyPackageOrModule(pyramid.tests.test_path) - result = self._callFUT(package) - self.assertEqual(result, tests) - -class TestPackageName(unittest.TestCase): - def _callFUT(self, package): - from pyramid.path import package_name - return package_name(package) - - def test_it_package(self): - from pyramid import tests - package = DummyPackageOrModule(tests) - result = self._callFUT(package) - self.assertEqual(result, 'pyramid.tests') - - def test_it_namespace_package(self): - from pyramid import tests - package = DummyNamespacePackage(tests) - result = self._callFUT(package) - self.assertEqual(result, 'pyramid.tests') - - def test_it_module(self): - from pyramid.tests import test_path - module = DummyPackageOrModule(test_path) - result = self._callFUT(module) - self.assertEqual(result, 'pyramid.tests') - - def test_it_None(self): - result = self._callFUT(None) - self.assertEqual(result, '__main__') - - def test_it_main(self): - import __main__ - result = self._callFUT(__main__) - self.assertEqual(result, '__main__') - -class TestResolver(unittest.TestCase): - def _getTargetClass(self): - from pyramid.path import Resolver - return Resolver - - def _makeOne(self, package): - return self._getTargetClass()(package) - - def test_get_package_caller_package(self): - import pyramid.tests - from pyramid.path import CALLER_PACKAGE - self.assertEqual(self._makeOne(CALLER_PACKAGE).get_package(), - pyramid.tests) - - def test_get_package_name_caller_package(self): - from pyramid.path import CALLER_PACKAGE - self.assertEqual(self._makeOne(CALLER_PACKAGE).get_package_name(), - 'pyramid.tests') - - def test_get_package_string(self): - import pyramid.tests - self.assertEqual(self._makeOne('pyramid.tests').get_package(), - pyramid.tests) - - def test_get_package_name_string(self): - self.assertEqual(self._makeOne('pyramid.tests').get_package_name(), - 'pyramid.tests') - -class TestAssetResolver(unittest.TestCase): - def _getTargetClass(self): - from pyramid.path import AssetResolver - return AssetResolver - - def _makeOne(self, package='pyramid.tests'): - return self._getTargetClass()(package) - - def test_ctor_as_package(self): - import sys - tests = sys.modules['pyramid.tests'] - inst = self._makeOne(tests) - self.assertEqual(inst.package, tests) - - def test_ctor_as_str(self): - import sys - tests = sys.modules['pyramid.tests'] - inst = self._makeOne('pyramid.tests') - self.assertEqual(inst.package, tests) - - def test_resolve_abspath(self): - from pyramid.path import FSAssetDescriptor - inst = self._makeOne(None) - r = inst.resolve(os.path.join(here, 'test_asset.py')) - self.assertEqual(r.__class__, FSAssetDescriptor) - self.assertTrue(r.exists()) - - def test_resolve_absspec(self): - from pyramid.path import PkgResourcesAssetDescriptor - inst = self._makeOne(None) - r = inst.resolve('pyramid.tests:test_asset.py') - self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) - self.assertTrue(r.exists()) - - def test_resolve_relspec_with_pkg(self): - from pyramid.path import PkgResourcesAssetDescriptor - inst = self._makeOne('pyramid.tests') - r = inst.resolve('test_asset.py') - self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) - self.assertTrue(r.exists()) - - def test_resolve_relspec_no_package(self): - inst = self._makeOne(None) - self.assertRaises(ValueError, inst.resolve, 'test_asset.py') - - def test_resolve_relspec_caller_package(self): - from pyramid.path import PkgResourcesAssetDescriptor - from pyramid.path import CALLER_PACKAGE - inst = self._makeOne(CALLER_PACKAGE) - r = inst.resolve('test_asset.py') - self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) - self.assertTrue(r.exists()) - -class TestPkgResourcesAssetDescriptor(unittest.TestCase): - def _getTargetClass(self): - from pyramid.path import PkgResourcesAssetDescriptor - return PkgResourcesAssetDescriptor - - def _makeOne(self, pkg='pyramid.tests', path='test_asset.py'): - return self._getTargetClass()(pkg, path) - - def test_class_conforms_to_IAssetDescriptor(self): - from pyramid.interfaces import IAssetDescriptor - from zope.interface.verify import verifyClass - verifyClass(IAssetDescriptor, self._getTargetClass()) - - def test_instance_conforms_to_IAssetDescriptor(self): - from pyramid.interfaces import IAssetDescriptor - from zope.interface.verify import verifyObject - verifyObject(IAssetDescriptor, self._makeOne()) - - def test_absspec(self): - inst = self._makeOne() - self.assertEqual(inst.absspec(), 'pyramid.tests:test_asset.py') - - def test_abspath(self): - inst = self._makeOne() - self.assertEqual(inst.abspath(), os.path.join(here, 'test_asset.py')) - - def test_stream(self): - inst = self._makeOne() - inst.pkg_resources = DummyPkgResource() - inst.pkg_resources.resource_stream = lambda x, y: '%s:%s' % (x, y) - s = inst.stream() - self.assertEqual(s, - '%s:%s' % ('pyramid.tests', 'test_asset.py')) - - def test_isdir(self): - inst = self._makeOne() - inst.pkg_resources = DummyPkgResource() - inst.pkg_resources.resource_isdir = lambda x, y: '%s:%s' % (x, y) - self.assertEqual(inst.isdir(), - '%s:%s' % ('pyramid.tests', 'test_asset.py')) - - def test_listdir(self): - inst = self._makeOne() - inst.pkg_resources = DummyPkgResource() - inst.pkg_resources.resource_listdir = lambda x, y: '%s:%s' % (x, y) - self.assertEqual(inst.listdir(), - '%s:%s' % ('pyramid.tests', 'test_asset.py')) - - def test_exists(self): - inst = self._makeOne() - inst.pkg_resources = DummyPkgResource() - inst.pkg_resources.resource_exists = lambda x, y: '%s:%s' % (x, y) - self.assertEqual(inst.exists(), - '%s:%s' % ('pyramid.tests', 'test_asset.py')) - -class TestFSAssetDescriptor(unittest.TestCase): - def _getTargetClass(self): - from pyramid.path import FSAssetDescriptor - return FSAssetDescriptor - - def _makeOne(self, path=os.path.join(here, 'test_asset.py')): - return self._getTargetClass()(path) - - def test_class_conforms_to_IAssetDescriptor(self): - from pyramid.interfaces import IAssetDescriptor - from zope.interface.verify import verifyClass - verifyClass(IAssetDescriptor, self._getTargetClass()) - - def test_instance_conforms_to_IAssetDescriptor(self): - from pyramid.interfaces import IAssetDescriptor - from zope.interface.verify import verifyObject - verifyObject(IAssetDescriptor, self._makeOne()) - - def test_absspec(self): - inst = self._makeOne() - self.assertRaises(NotImplementedError, inst.absspec) - - def test_abspath(self): - inst = self._makeOne() - self.assertEqual(inst.abspath(), os.path.join(here, 'test_asset.py')) - - def test_stream(self): - inst = self._makeOne() - s = inst.stream() - val = s.read() - s.close() - self.assertTrue(b'asset' in val) - - def test_isdir_False(self): - inst = self._makeOne() - self.assertFalse(inst.isdir()) - - def test_isdir_True(self): - inst = self._makeOne(here) - self.assertTrue(inst.isdir()) - - def test_listdir(self): - inst = self._makeOne(here) - self.assertTrue(inst.listdir()) - - def test_exists(self): - inst = self._makeOne() - self.assertTrue(inst.exists()) - -class TestDottedNameResolver(unittest.TestCase): - def _makeOne(self, package=None): - from pyramid.path import DottedNameResolver - return DottedNameResolver(package) - - def config_exc(self, func, *arg, **kw): - try: - func(*arg, **kw) - except ValueError as e: - return e - else: - raise AssertionError('Invalid not raised') # pragma: no cover - - def test_zope_dottedname_style_resolve_builtin(self): - typ = self._makeOne() - if PY2: - result = typ._zope_dottedname_style('__builtin__.str', None) - else: - result = typ._zope_dottedname_style('builtins.str', None) - self.assertEqual(result, str) - - def test_zope_dottedname_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'pyramid.tests.test_path.TestDottedNameResolver', None) - self.assertEqual(result, self.__class__) - - def test_zope_dottedname_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._zope_dottedname_style, - 'pyramid.test_path.nonexisting_name', None) - - def test__zope_dottedname_style_resolve_relative(self): - import pyramid.tests - typ = self._makeOne() - result = typ._zope_dottedname_style( - '.test_path.TestDottedNameResolver', pyramid.tests) - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_leading_dots(self): - import pyramid.tests.test_path - typ = self._makeOne() - result = typ._zope_dottedname_style( - '..tests.test_path.TestDottedNameResolver', pyramid.tests) - self.assertEqual(result, self.__class__) - - def test__zope_dottedname_style_resolve_relative_is_dot(self): - import pyramid.tests - typ = self._makeOne() - result = typ._zope_dottedname_style('.', pyramid.tests) - self.assertEqual(result, pyramid.tests) - - def test__zope_dottedname_style_irresolveable_relative_is_dot(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.', None) - self.assertEqual( - e.args[0], - "relative name '.' irresolveable without package") - - def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - e = self.config_exc(typ._zope_dottedname_style, '.whatever', None) - self.assertEqual( - e.args[0], - "relative name '.whatever' irresolveable without package") - - def test_zope_dottedname_style_irrresolveable_relative(self): - import pyramid.tests - typ = self._makeOne() - self.assertRaises(ImportError, typ._zope_dottedname_style, - '.notexisting', pyramid.tests) - - def test__zope_dottedname_style_resolveable_relative(self): - import pyramid - typ = self._makeOne() - result = typ._zope_dottedname_style('.tests', pyramid) - from pyramid import tests - self.assertEqual(result, tests) - - def test__zope_dottedname_style_irresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises( - ImportError, - typ._zope_dottedname_style, 'pyramid.fudge.bar', None) - - def test__zope_dottedname_style_resolveable_absolute(self): - typ = self._makeOne() - result = typ._zope_dottedname_style( - 'pyramid.tests.test_path.TestDottedNameResolver', None) - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_absolute(self): - typ = self._makeOne() - result = typ._pkg_resources_style( - 'pyramid.tests.test_path:TestDottedNameResolver', None) - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_irrresolveable_absolute(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ._pkg_resources_style, - 'pyramid.tests:nonexisting', None) - - def test__pkg_resources_style_resolve_relative(self): - import pyramid.tests - typ = self._makeOne() - result = typ._pkg_resources_style( - '.test_path:TestDottedNameResolver', pyramid.tests) - self.assertEqual(result, self.__class__) - - def test__pkg_resources_style_resolve_relative_is_dot(self): - import pyramid.tests - typ = self._makeOne() - result = typ._pkg_resources_style('.', pyramid.tests) - self.assertEqual(result, pyramid.tests) - - def test__pkg_resources_style_resolve_relative_nocurrentpackage(self): - typ = self._makeOne() - self.assertRaises(ValueError, typ._pkg_resources_style, - '.whatever', None) - - def test__pkg_resources_style_irrresolveable_relative(self): - import pyramid - typ = self._makeOne() - self.assertRaises(ImportError, typ._pkg_resources_style, - ':notexisting', pyramid) - - def test_resolve_not_a_string(self): - typ = self._makeOne() - e = self.config_exc(typ.resolve, None) - self.assertEqual(e.args[0], 'None is not a string') - - def test_resolve_using_pkgresources_style(self): - typ = self._makeOne() - result = typ.resolve( - 'pyramid.tests.test_path:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_using_zope_dottedname_style(self): - typ = self._makeOne() - result = typ.resolve( - 'pyramid.tests.test_path:TestDottedNameResolver') - self.assertEqual(result, self.__class__) - - def test_resolve_missing_raises(self): - typ = self._makeOne() - self.assertRaises(ImportError, typ.resolve, 'cant.be.found') - - def test_resolve_caller_package(self): - from pyramid.path import CALLER_PACKAGE - typ = self._makeOne(CALLER_PACKAGE) - self.assertEqual(typ.resolve('.test_path.TestDottedNameResolver'), - self.__class__) - - def test_maybe_resolve_caller_package(self): - from pyramid.path import CALLER_PACKAGE - typ = self._makeOne(CALLER_PACKAGE) - self.assertEqual(typ.maybe_resolve('.test_path.TestDottedNameResolver'), - self.__class__) - - def test_ctor_string_module_resolveable(self): - import pyramid.tests - typ = self._makeOne('pyramid.tests.test_path') - self.assertEqual(typ.package, pyramid.tests) - - def test_ctor_string_package_resolveable(self): - import pyramid.tests - typ = self._makeOne('pyramid.tests') - self.assertEqual(typ.package, pyramid.tests) - - def test_ctor_string_irresolveable(self): - self.assertRaises(ValueError, self._makeOne, 'cant.be.found') - - def test_ctor_module(self): - import pyramid.tests - import pyramid.tests.test_path - typ = self._makeOne(pyramid.tests.test_path) - self.assertEqual(typ.package, pyramid.tests) - - def test_ctor_package(self): - import pyramid.tests - typ = self._makeOne(pyramid.tests) - self.assertEqual(typ.package, pyramid.tests) - - def test_ctor_None(self): - typ = self._makeOne(None) - self.assertEqual(typ.package, None) - -class DummyPkgResource(object): - pass - -class DummyPackageOrModule: - def __init__(self, real_package_or_module, raise_exc=None): - self.__dict__['raise_exc'] = raise_exc - self.__dict__['__name__'] = real_package_or_module.__name__ - import os - self.__dict__['package_path'] = os.path.dirname( - os.path.abspath(real_package_or_module.__file__)) - self.__dict__['__file__'] = real_package_or_module.__file__ - - def __setattr__(self, key, val): - if self.raise_exc is not None: - raise self.raise_exc - self.__dict__[key] = val - -class DummyNamespacePackage: - """Has no __file__ attribute. - """ - - def __init__(self, real_package_or_module): - self.__name__ = real_package_or_module.__name__ - import os - self.package_path = os.path.dirname( - os.path.abspath(real_package_or_module.__file__)) diff --git a/src/pyramid/tests/test_predicates.py b/src/pyramid/tests/test_predicates.py deleted file mode 100644 index da0b44708..000000000 --- a/src/pyramid/tests/test_predicates.py +++ /dev/null @@ -1,556 +0,0 @@ -import unittest - -from pyramid import testing - -from pyramid.compat import text_ - -class TestXHRPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import XHRPredicate - return XHRPredicate(val, None) - - def test___call___true(self): - inst = self._makeOne(True) - request = Dummy() - request.is_xhr = True - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(True) - request = Dummy() - request.is_xhr = False - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(True) - self.assertEqual(inst.text(), 'xhr = True') - - def test_phash(self): - inst = self._makeOne(True) - self.assertEqual(inst.phash(), 'xhr = True') - -class TestRequestMethodPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import RequestMethodPredicate - return RequestMethodPredicate(val, None) - - def test_ctor_get_but_no_head(self): - inst = self._makeOne('GET') - self.assertEqual(inst.val, ('GET', 'HEAD')) - - def test___call___true_single(self): - inst = self._makeOne('GET') - request = Dummy() - request.method = 'GET' - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_multi(self): - inst = self._makeOne(('GET','HEAD')) - request = Dummy() - request.method = 'GET' - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(('GET','HEAD')) - request = Dummy() - request.method = 'POST' - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(('HEAD','GET')) - self.assertEqual(inst.text(), 'request_method = GET,HEAD') - - def test_phash(self): - inst = self._makeOne(('HEAD','GET')) - self.assertEqual(inst.phash(), 'request_method = GET,HEAD') - -class TestPathInfoPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import PathInfoPredicate - return PathInfoPredicate(val, None) - - def test_ctor_compilefail(self): - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, self._makeOne, '\\') - - def test___call___true(self): - inst = self._makeOne(r'/\d{2}') - request = Dummy() - request.upath_info = text_('/12') - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne(r'/\d{2}') - request = Dummy() - request.upath_info = text_('/n12') - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne('/') - self.assertEqual(inst.text(), 'path_info = /') - - def test_phash(self): - inst = self._makeOne('/') - self.assertEqual(inst.phash(), 'path_info = /') - -class TestRequestParamPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import RequestParamPredicate - return RequestParamPredicate(val, None) - - def test___call___true_exists(self): - inst = self._makeOne('abc') - request = Dummy() - request.params = {'abc':1} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withval(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.params = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_multi(self): - inst = self._makeOne(('abc', '=def =2= ')) - request = Dummy() - request.params = {'abc':'1', '=def': '2='} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false_multi(self): - inst = self._makeOne(('abc=3', 'def =2 ')) - request = Dummy() - request.params = {'abc':'3', 'def': '1'} - result = inst(None, request) - self.assertFalse(result) - - def test___call___false(self): - inst = self._makeOne('abc') - request = Dummy() - request.params = {} - result = inst(None, request) - self.assertFalse(result) - - def test_text_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.text(), 'request_param abc') - - def test_text_exists_equal_sign(self): - inst = self._makeOne('=abc') - self.assertEqual(inst.text(), 'request_param =abc') - - def test_text_withval(self): - inst = self._makeOne('abc= 1') - self.assertEqual(inst.text(), 'request_param abc=1') - - def test_text_multi(self): - inst = self._makeOne(('abc= 1', 'def')) - self.assertEqual(inst.text(), 'request_param abc=1,def') - - def test_text_multi_equal_sign(self): - inst = self._makeOne(('abc= 1', '=def= 2')) - self.assertEqual(inst.text(), 'request_param =def=2,abc=1') - - def test_phash_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.phash(), 'request_param abc') - - def test_phash_exists_equal_sign(self): - inst = self._makeOne('=abc') - self.assertEqual(inst.phash(), 'request_param =abc') - - def test_phash_withval(self): - inst = self._makeOne('abc= 1') - self.assertEqual(inst.phash(), "request_param abc=1") - -class TestMatchParamPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import MatchParamPredicate - return MatchParamPredicate(val, None) - - def test___call___true_single(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - - def test___call___true_multi(self): - inst = self._makeOne(('abc=1', 'def=2')) - request = Dummy() - request.matchdict = {'abc':'1', 'def':'2'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = {} - result = inst(None, request) - self.assertFalse(result) - - def test___call___matchdict_is_None(self): - inst = self._makeOne('abc=1') - request = Dummy() - request.matchdict = None - result = inst(None, request) - self.assertFalse(result) - - def test_text(self): - inst = self._makeOne(('def= 1', 'abc =2')) - self.assertEqual(inst.text(), 'match_param abc=2,def=1') - - def test_phash(self): - inst = self._makeOne(('def= 1', 'abc =2')) - self.assertEqual(inst.phash(), 'match_param abc=2,def=1') - -class TestCustomPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import CustomPredicate - return CustomPredicate(val, None) - - def test___call___true(self): - def func(context, request): - self.assertEqual(context, None) - self.assertEqual(request, None) - return True - inst = self._makeOne(func) - result = inst(None, None) - self.assertTrue(result) - - def test___call___false(self): - def func(context, request): - self.assertEqual(context, None) - self.assertEqual(request, None) - return False - inst = self._makeOne(func) - result = inst(None, None) - self.assertFalse(result) - - def test_text_func_has___text__(self): - pred = predicate() - pred.__text__ = 'text' - inst = self._makeOne(pred) - self.assertEqual(inst.text(), 'text') - - def test_text_func_repr(self): - pred = predicate() - inst = self._makeOne(pred) - self.assertEqual(inst.text(), 'custom predicate: object predicate') - - def test_phash(self): - pred = predicate() - inst = self._makeOne(pred) - self.assertEqual(inst.phash(), 'custom:1') - -class TestTraversePredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import TraversePredicate - return TraversePredicate(val, None) - - def test___call__traverse_has_remainder_already(self): - inst = self._makeOne('/1/:a/:b') - info = {'traverse':'abc'} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'traverse':'abc'}) - - def test___call__traverse_matches(self): - inst = self._makeOne('/1/:a/:b') - info = {'match':{'a':'a', 'b':'b'}} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual(info, {'match': - {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) - - def test___call__traverse_matches_with_highorder_chars(self): - inst = self._makeOne(text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) - info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} - request = Dummy() - result = inst(info, request) - self.assertEqual(result, True) - self.assertEqual( - info['match']['traverse'], - (text_(b'La Pe\xc3\xb1a', 'utf-8'), - text_(b'Qu\xc3\xa9bec', 'utf-8')) - ) - - def test_text(self): - inst = self._makeOne('/abc') - self.assertEqual(inst.text(), 'traverse matchdict pseudo-predicate') - - def test_phash(self): - inst = self._makeOne('/abc') - self.assertEqual(inst.phash(), '') - -class Test_CheckCSRFTokenPredicate(unittest.TestCase): - def _makeOne(self, val, config): - from pyramid.predicates import CheckCSRFTokenPredicate - return CheckCSRFTokenPredicate(val, config) - - def test_text(self): - inst = self._makeOne(True, None) - self.assertEqual(inst.text(), 'check_csrf = True') - - def test_phash(self): - inst = self._makeOne(True, None) - self.assertEqual(inst.phash(), 'check_csrf = True') - - def test_it_call_val_True(self): - inst = self._makeOne(True, None) - request = Dummy() - def check_csrf_token(req, val, raises=True): - self.assertEqual(req, request) - self.assertEqual(val, 'csrf_token') - self.assertEqual(raises, False) - return True - inst.check_csrf_token = check_csrf_token - result = inst(None, request) - self.assertEqual(result, True) - - def test_it_call_val_str(self): - inst = self._makeOne('abc', None) - request = Dummy() - def check_csrf_token(req, val, raises=True): - self.assertEqual(req, request) - self.assertEqual(val, 'abc') - self.assertEqual(raises, False) - return True - inst.check_csrf_token = check_csrf_token - result = inst(None, request) - self.assertEqual(result, True) - - def test_it_call_val_False(self): - inst = self._makeOne(False, None) - request = Dummy() - result = inst(None, request) - self.assertEqual(result, True) - -class TestHeaderPredicate(unittest.TestCase): - def _makeOne(self, val): - from pyramid.predicates import HeaderPredicate - return HeaderPredicate(val, None) - - def test___call___true_exists(self): - inst = self._makeOne('abc') - request = Dummy() - request.headers = {'abc':1} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withval(self): - inst = self._makeOne('abc:1') - request = Dummy() - request.headers = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___true_withregex(self): - inst = self._makeOne(r'abc:\d+') - request = Dummy() - request.headers = {'abc':'1'} - result = inst(None, request) - self.assertTrue(result) - - def test___call___false_withregex(self): - inst = self._makeOne(r'abc:\d+') - request = Dummy() - request.headers = {'abc':'a'} - result = inst(None, request) - self.assertFalse(result) - - def test___call___false(self): - inst = self._makeOne('abc') - request = Dummy() - request.headers = {} - result = inst(None, request) - self.assertFalse(result) - - def test_text_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.text(), 'header abc') - - def test_text_withval(self): - inst = self._makeOne('abc:1') - self.assertEqual(inst.text(), 'header abc=1') - - def test_text_withregex(self): - inst = self._makeOne(r'abc:\d+') - self.assertEqual(inst.text(), r'header abc=\d+') - - def test_phash_exists(self): - inst = self._makeOne('abc') - self.assertEqual(inst.phash(), 'header abc') - - def test_phash_withval(self): - inst = self._makeOne('abc:1') - self.assertEqual(inst.phash(), "header abc=1") - - def test_phash_withregex(self): - inst = self._makeOne(r'abc:\d+') - self.assertEqual(inst.phash(), r'header abc=\d+') - -class Test_PhysicalPathPredicate(unittest.TestCase): - def _makeOne(self, val, config): - from pyramid.predicates import PhysicalPathPredicate - return PhysicalPathPredicate(val, config) - - def test_text(self): - inst = self._makeOne('/', None) - self.assertEqual(inst.text(), "physical_path = ('',)") - - def test_phash(self): - inst = self._makeOne('/', None) - self.assertEqual(inst.phash(), "physical_path = ('',)") - - def test_it_call_val_tuple_True(self): - inst = self._makeOne(('', 'abc'), None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_val_list_True(self): - inst = self._makeOne(['', 'abc'], None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_val_str_True(self): - inst = self._makeOne('/abc', None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertTrue(inst(context, None)) - - def test_it_call_False(self): - inst = self._makeOne('/', None) - root = Dummy() - root.__name__ = '' - root.__parent__ = None - context = Dummy() - context.__name__ = 'abc' - context.__parent__ = root - self.assertFalse(inst(context, None)) - - def test_it_call_context_has_no_name(self): - inst = self._makeOne('/', None) - context = Dummy() - self.assertFalse(inst(context, None)) - -class Test_EffectivePrincipalsPredicate(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, val, config): - from pyramid.predicates import EffectivePrincipalsPredicate - return EffectivePrincipalsPredicate(val, config) - - def test_text(self): - inst = self._makeOne(('verna', 'fred'), None) - self.assertEqual(inst.text(), - "effective_principals = ['fred', 'verna']") - - def test_text_noniter(self): - inst = self._makeOne('verna', None) - self.assertEqual(inst.text(), - "effective_principals = ['verna']") - - def test_phash(self): - inst = self._makeOne(('verna', 'fred'), None) - self.assertEqual(inst.phash(), - "effective_principals = ['fred', 'verna']") - - def test_it_call_no_authentication_policy(self): - request = testing.DummyRequest() - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertFalse(inst(context, request)) - - def test_it_call_authentication_policy_provides_superset(self): - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertTrue(inst(context, request)) - - def test_it_call_authentication_policy_provides_superset_implicit(self): - from pyramid.security import Authenticated - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) - inst = self._makeOne(Authenticated, None) - context = Dummy() - self.assertTrue(inst(context, request)) - - def test_it_call_authentication_policy_doesnt_provide_superset(self): - request = testing.DummyRequest() - self.config.testing_securitypolicy('fred') - inst = self._makeOne(('verna', 'fred'), None) - context = Dummy() - self.assertFalse(inst(context, request)) - - -class TestNotted(unittest.TestCase): - def _makeOne(self, predicate): - from pyramid.predicates import Notted - return Notted(predicate) - - def test_it_with_phash_val(self): - pred = DummyPredicate('val') - inst = self._makeOne(pred) - self.assertEqual(inst.text(), '!val') - self.assertEqual(inst.phash(), '!val') - self.assertEqual(inst(None, None), False) - - def test_it_without_phash_val(self): - pred = DummyPredicate('') - inst = self._makeOne(pred) - self.assertEqual(inst.text(), '') - self.assertEqual(inst.phash(), '') - self.assertEqual(inst(None, None), True) - -class predicate(object): - def __repr__(self): - return 'predicate' - def __hash__(self): - return 1 - -class Dummy(object): - pass - -class DummyPredicate(object): - def __init__(self, result): - self.result = result - - def text(self): - return self.result - - phash = text - - def __call__(self, context, request): - return True diff --git a/src/pyramid/tests/test_registry.py b/src/pyramid/tests/test_registry.py deleted file mode 100644 index aa44b5408..000000000 --- a/src/pyramid/tests/test_registry.py +++ /dev/null @@ -1,401 +0,0 @@ -import unittest - -class TestRegistry(unittest.TestCase): - def _getTargetClass(self): - from pyramid.registry import Registry - return Registry - - def _makeOne(self, *args, **kw): - return self._getTargetClass()(*args, **kw) - - def test___nonzero__(self): - registry = self._makeOne() - self.assertEqual(registry.__nonzero__(), True) - - def test__lock(self): - registry = self._makeOne() - self.assertTrue(registry._lock) - - def test_clear_view_cache_lookup(self): - registry = self._makeOne() - registry._view_lookup_cache[1] = 2 - registry._clear_view_lookup_cache() - self.assertEqual(registry._view_lookup_cache, {}) - - def test_package_name(self): - package_name = 'testing' - registry = self._makeOne(package_name) - self.assertEqual(registry.package_name, package_name) - - def test_default_package_name(self): - registry = self._makeOne() - self.assertEqual(registry.package_name, 'pyramid.tests') - - def test_registerHandler_and_notify(self): - registry = self._makeOne() - self.assertEqual(registry.has_listeners, False) - L = [] - def f(event): - L.append(event) - registry.registerHandler(f, [IDummyEvent]) - self.assertEqual(registry.has_listeners, True) - event = DummyEvent() - registry.notify(event) - self.assertEqual(L, [event]) - - def test_registerSubscriptionAdapter(self): - registry = self._makeOne() - self.assertEqual(registry.has_listeners, False) - from zope.interface import Interface - registry.registerSubscriptionAdapter(DummyEvent, - [IDummyEvent], Interface) - self.assertEqual(registry.has_listeners, True) - - def test__get_settings(self): - registry = self._makeOne() - registry._settings = 'foo' - self.assertEqual(registry.settings, 'foo') - - def test__set_settings(self): - registry = self._makeOne() - registry.settings = 'foo' - self.assertEqual(registry._settings, 'foo') - - def test_init_forwards_args(self): - from zope.interface import Interface - from zope.interface.registry import Components - dummy = object() - c = Components() - c.registerUtility(dummy, Interface) - registry = self._makeOne('foo', (c,)) - self.assertEqual(registry.__name__, 'foo') - self.assertEqual(registry.getUtility(Interface), dummy) - - def test_init_forwards_kw(self): - from zope.interface import Interface - from zope.interface.registry import Components - dummy = object() - c = Components() - c.registerUtility(dummy, Interface) - registry = self._makeOne(bases=(c,)) - self.assertEqual(registry.getUtility(Interface), dummy) - -class TestIntrospector(unittest.TestCase): - def _getTargetClass(slf): - from pyramid.registry import Introspector - return Introspector - - def _makeOne(self): - return self._getTargetClass()() - - def test_conformance(self): - from zope.interface.verify import verifyClass - from zope.interface.verify import verifyObject - from pyramid.interfaces import IIntrospector - verifyClass(IIntrospector, self._getTargetClass()) - verifyObject(IIntrospector, self._makeOne()) - - def test_add(self): - inst = self._makeOne() - intr = DummyIntrospectable() - inst.add(intr) - self.assertEqual(intr.order, 0) - category = {'discriminator':intr, 'discriminator_hash':intr} - self.assertEqual(inst._categories, {'category':category}) - - def test_get_success(self): - inst = self._makeOne() - intr = DummyIntrospectable() - inst.add(intr) - self.assertEqual(inst.get('category', 'discriminator'), intr) - - def test_get_success_byhash(self): - inst = self._makeOne() - intr = DummyIntrospectable() - inst.add(intr) - self.assertEqual(inst.get('category', 'discriminator_hash'), intr) - - def test_get_fail(self): - inst = self._makeOne() - intr = DummyIntrospectable() - inst.add(intr) - self.assertEqual(inst.get('category', 'wontexist', 'foo'), 'foo') - - def test_get_category(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr2) - inst.add(intr) - expected = [ - {'introspectable':intr2, 'related':[]}, - {'introspectable':intr, 'related':[]}, - ] - self.assertEqual(inst.get_category('category'), expected) - - def test_get_category_returns_default_on_miss(self): - inst = self._makeOne() - self.assertEqual(inst.get_category('category', '123'), '123') - - def test_get_category_with_sortkey(self): - import operator - inst = self._makeOne() - intr = DummyIntrospectable() - intr.foo = 2 - intr2 = DummyIntrospectable() - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - intr2.foo = 1 - inst.add(intr) - inst.add(intr2) - expected = [ - {'introspectable':intr2, 'related':[]}, - {'introspectable':intr, 'related':[]}, - ] - self.assertEqual( - inst.get_category('category', sort_key=operator.attrgetter('foo')), - expected) - - def test_categorized(self): - import operator - inst = self._makeOne() - intr = DummyIntrospectable() - intr.foo = 2 - intr2 = DummyIntrospectable() - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - intr2.foo = 1 - inst.add(intr) - inst.add(intr2) - expected = [('category', [ - {'introspectable':intr2, 'related':[]}, - {'introspectable':intr, 'related':[]}, - ])] - self.assertEqual( - inst.categorized(sort_key=operator.attrgetter('foo')), expected) - - def test_categories(self): - inst = self._makeOne() - inst._categories['a'] = 1 - inst._categories['b'] = 2 - self.assertEqual(list(inst.categories()), ['a', 'b']) - - def test_remove(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.category_name = 'category2' - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr) - inst.add(intr2) - inst.relate(('category', 'discriminator'), - ('category2', 'discriminator2')) - inst.remove('category', 'discriminator') - self.assertEqual(inst._categories, - {'category': - {}, - 'category2': - {'discriminator2': intr2, - 'discriminator2_hash': intr2} - }) - self.assertEqual(inst._refs.get(intr), None) - self.assertEqual(inst._refs[intr2], []) - - def test_remove_fail(self): - inst = self._makeOne() - self.assertEqual(inst.remove('a', 'b'), None) - - def test_relate(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.category_name = 'category2' - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr) - inst.add(intr2) - inst.relate(('category', 'discriminator'), - ('category2', 'discriminator2')) - self.assertEqual(inst._categories, - {'category': - {'discriminator':intr, - 'discriminator_hash':intr}, - 'category2': - {'discriminator2': intr2, - 'discriminator2_hash': intr2} - }) - self.assertEqual(inst._refs[intr], [intr2]) - self.assertEqual(inst._refs[intr2], [intr]) - - def test_relate_fail(self): - inst = self._makeOne() - intr = DummyIntrospectable() - inst.add(intr) - self.assertRaises( - KeyError, - inst.relate, - ('category', 'discriminator'), - ('category2', 'discriminator2') - ) - - def test_unrelate(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.category_name = 'category2' - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr) - inst.add(intr2) - inst.relate(('category', 'discriminator'), - ('category2', 'discriminator2')) - inst.unrelate(('category', 'discriminator'), - ('category2', 'discriminator2')) - self.assertEqual(inst._categories, - {'category': - {'discriminator':intr, - 'discriminator_hash':intr}, - 'category2': - {'discriminator2': intr2, - 'discriminator2_hash': intr2} - }) - self.assertEqual(inst._refs[intr], []) - self.assertEqual(inst._refs[intr2], []) - - def test_related(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.category_name = 'category2' - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr) - inst.add(intr2) - inst.relate(('category', 'discriminator'), - ('category2', 'discriminator2')) - self.assertEqual(inst.related(intr), [intr2]) - - def test_related_fail(self): - inst = self._makeOne() - intr = DummyIntrospectable() - intr2 = DummyIntrospectable() - intr2.category_name = 'category2' - intr2.discriminator = 'discriminator2' - intr2.discriminator_hash = 'discriminator2_hash' - inst.add(intr) - inst.add(intr2) - inst.relate(('category', 'discriminator'), - ('category2', 'discriminator2')) - del inst._categories['category'] - self.assertRaises(KeyError, inst.related, intr) - -class TestIntrospectable(unittest.TestCase): - def _getTargetClass(slf): - from pyramid.registry import Introspectable - return Introspectable - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def _makeOnePopulated(self): - return self._makeOne('category', 'discrim', 'title', 'type') - - def test_conformance(self): - from zope.interface.verify import verifyClass - from zope.interface.verify import verifyObject - from pyramid.interfaces import IIntrospectable - verifyClass(IIntrospectable, self._getTargetClass()) - verifyObject(IIntrospectable, self._makeOnePopulated()) - - def test_relate(self): - inst = self._makeOnePopulated() - inst.relate('a', 'b') - self.assertEqual(inst._relations, [(True, 'a', 'b')]) - - def test_unrelate(self): - inst = self._makeOnePopulated() - inst.unrelate('a', 'b') - self.assertEqual(inst._relations, [(False, 'a', 'b')]) - - def test_discriminator_hash(self): - inst = self._makeOnePopulated() - self.assertEqual(inst.discriminator_hash, hash(inst.discriminator)) - - def test___hash__(self): - inst = self._makeOnePopulated() - self.assertEqual(hash(inst), - hash((inst.category_name,) + (inst.discriminator,))) - - def test___repr__(self): - inst = self._makeOnePopulated() - self.assertEqual( - repr(inst), - "") - - def test___nonzero__(self): - inst = self._makeOnePopulated() - self.assertEqual(inst.__nonzero__(), True) - - def test___bool__(self): - inst = self._makeOnePopulated() - self.assertEqual(inst.__bool__(), True) - - def test_register(self): - introspector = DummyIntrospector() - action_info = object() - inst = self._makeOnePopulated() - inst._relations.append((True, 'category1', 'discrim1')) - inst._relations.append((False, 'category2', 'discrim2')) - inst.register(introspector, action_info) - self.assertEqual(inst.action_info, action_info) - self.assertEqual(introspector.intrs, [inst]) - self.assertEqual(introspector.relations, - [(('category', 'discrim'), ('category1', 'discrim1'))]) - self.assertEqual(introspector.unrelations, - [(('category', 'discrim'), ('category2', 'discrim2'))]) - -class DummyIntrospector(object): - def __init__(self): - self.intrs = [] - self.relations = [] - self.unrelations = [] - - def add(self, intr): - self.intrs.append(intr) - - def relate(self, *pairs): - self.relations.append(pairs) - - def unrelate(self, *pairs): - self.unrelations.append(pairs) - -class DummyModule: - __path__ = "foo" - __name__ = "dummy" - __file__ = '' - -class DummyIntrospectable(object): - category_name = 'category' - discriminator = 'discriminator' - title = 'title' - type_name = 'type' - order = None - action_info = None - discriminator_hash = 'discriminator_hash' - - def __hash__(self): - return hash((self.category_name,) + (self.discriminator,)) - - -from zope.interface import Interface -from zope.interface import implementer -class IDummyEvent(Interface): - pass - -@implementer(IDummyEvent) -class DummyEvent(object): - pass - diff --git a/src/pyramid/tests/test_renderers.py b/src/pyramid/tests/test_renderers.py deleted file mode 100644 index a2f7bf8c2..000000000 --- a/src/pyramid/tests/test_renderers.py +++ /dev/null @@ -1,705 +0,0 @@ -import unittest - -from pyramid.testing import cleanUp -from pyramid import testing -from pyramid.compat import text_ - -class TestJSON(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, **kw): - from pyramid.renderers import JSON - return JSON(**kw) - - def test_it(self): - renderer = self._makeOne()(None) - result = renderer({'a':1}, {}) - self.assertEqual(result, '{"a": 1}') - - def test_with_request_content_type_notset(self): - request = testing.DummyRequest() - renderer = self._makeOne()(None) - renderer({'a':1}, {'request':request}) - self.assertEqual(request.response.content_type, 'application/json') - - def test_with_request_content_type_set(self): - request = testing.DummyRequest() - request.response.content_type = 'text/mishmash' - renderer = self._makeOne()(None) - renderer({'a':1}, {'request':request}) - self.assertEqual(request.response.content_type, 'text/mishmash') - - def test_with_custom_adapter(self): - request = testing.DummyRequest() - from datetime import datetime - def adapter(obj, req): - self.assertEqual(req, request) - return obj.isoformat() - now = datetime.utcnow() - renderer = self._makeOne() - renderer.add_adapter(datetime, adapter) - result = renderer(None)({'a':now}, {'request':request}) - self.assertEqual(result, '{"a": "%s"}' % now.isoformat()) - - def test_with_custom_adapter2(self): - request = testing.DummyRequest() - from datetime import datetime - def adapter(obj, req): - self.assertEqual(req, request) - return obj.isoformat() - now = datetime.utcnow() - renderer = self._makeOne(adapters=((datetime, adapter),)) - result = renderer(None)({'a':now}, {'request':request}) - self.assertEqual(result, '{"a": "%s"}' % now.isoformat()) - - def test_with_custom_serializer(self): - class Serializer(object): - def __call__(self, obj, **kw): - self.obj = obj - self.kw = kw - return 'foo' - serializer = Serializer() - renderer = self._makeOne(serializer=serializer, baz=5) - obj = {'a':'b'} - result = renderer(None)(obj, {}) - self.assertEqual(result, 'foo') - self.assertEqual(serializer.obj, obj) - self.assertEqual(serializer.kw['baz'], 5) - self.assertTrue('default' in serializer.kw) - - def test_with_object_adapter(self): - request = testing.DummyRequest() - outerself = self - class MyObject(object): - def __init__(self, x): - self.x = x - def __json__(self, req): - outerself.assertEqual(req, request) - return {'x': self.x} - - objects = [MyObject(1), MyObject(2)] - renderer = self._makeOne()(None) - result = renderer(objects, {'request':request}) - self.assertEqual(result, '[{"x": 1}, {"x": 2}]') - - def test_with_object_adapter_no___json__(self): - class MyObject(object): - def __init__(self, x): - self.x = x - objects = [MyObject(1), MyObject(2)] - renderer = self._makeOne()(None) - self.assertRaises(TypeError, renderer, objects, {}) - -class Test_string_renderer_factory(unittest.TestCase): - def _callFUT(self, name): - from pyramid.renderers import string_renderer_factory - return string_renderer_factory(name) - - def test_it_unicode(self): - renderer = self._callFUT(None) - value = text_('La Pe\xc3\xb1a', 'utf-8') - result = renderer(value, {}) - self.assertEqual(result, value) - - def test_it_str(self): - renderer = self._callFUT(None) - value = 'La Pe\xc3\xb1a' - result = renderer(value, {}) - self.assertEqual(result, value) - - def test_it_other(self): - renderer = self._callFUT(None) - value = None - result = renderer(value, {}) - self.assertEqual(result, 'None') - - def test_with_request_content_type_notset(self): - request = testing.DummyRequest() - renderer = self._callFUT(None) - renderer('', {'request':request}) - self.assertEqual(request.response.content_type, 'text/plain') - - def test_with_request_content_type_set(self): - request = testing.DummyRequest() - request.response.content_type = 'text/mishmash' - renderer = self._callFUT(None) - renderer('', {'request':request}) - self.assertEqual(request.response.content_type, 'text/mishmash') - - -class TestRendererHelper(unittest.TestCase): - def setUp(self): - self.config = cleanUp() - - def tearDown(self): - cleanUp() - - def _makeOne(self, *arg, **kw): - from pyramid.renderers import RendererHelper - return RendererHelper(*arg, **kw) - - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IRendererInfo - helper = self._makeOne() - verifyObject(IRendererInfo, helper) - - def test_settings_registry_settings_is_None(self): - class Dummy(object): - settings = None - helper = self._makeOne(registry=Dummy) - self.assertEqual(helper.settings, {}) - - def test_settings_registry_name_is_None(self): - class Dummy(object): - settings = None - helper = self._makeOne(registry=Dummy) - self.assertEqual(helper.name, None) - self.assertEqual(helper.type, '') - - def test_settings_registry_settings_is_not_None(self): - class Dummy(object): - settings = {'a':1} - helper = self._makeOne(registry=Dummy) - self.assertEqual(helper.settings, {'a':1}) - - def _registerRendererFactory(self): - from pyramid.interfaces import IRendererFactory - def renderer(*arg): - def respond(*arg): - return arg - renderer.respond = respond - return respond - self.config.registry.registerUtility(renderer, IRendererFactory, - name='.foo') - return renderer - - def _registerResponseFactory(self): - from pyramid.interfaces import IResponseFactory - class ResponseFactory(object): - pass - - self.config.registry.registerUtility( - lambda r: ResponseFactory(), IResponseFactory - ) - - def test_render_to_response(self): - self._registerRendererFactory() - self._registerResponseFactory() - request = Dummy() - helper = self._makeOne('loo.foo') - response = helper.render_to_response('values', {}, - request=request) - self.assertEqual(response.app_iter[0], 'values') - self.assertEqual(response.app_iter[1], {}) - - def test_get_renderer(self): - factory = self._registerRendererFactory() - helper = self._makeOne('loo.foo') - self.assertEqual(helper.get_renderer(), factory.respond) - - def test_render_view(self): - import pyramid.csrf - self._registerRendererFactory() - self._registerResponseFactory() - request = Dummy() - helper = self._makeOne('loo.foo') - view = 'view' - context = 'context' - request = testing.DummyRequest() - response = 'response' - response = helper.render_view(request, response, view, context) - get_csrf = response.app_iter[1].pop('get_csrf_token') - self.assertEqual(get_csrf.args, (request, )) - self.assertEqual(get_csrf.func, pyramid.csrf.get_csrf_token) - self.assertEqual(response.app_iter[0], 'response') - self.assertEqual(response.app_iter[1], - {'renderer_info': helper, - 'renderer_name': 'loo.foo', - 'request': request, - 'context': 'context', - 'view': 'view', - 'req': request,} - ) - - def test_render_explicit_registry(self): - factory = self._registerRendererFactory() - class DummyRegistry(object): - def __init__(self): - self.responses = [factory, lambda *arg: {}, None] - def queryUtility(self, iface, name=None): - self.queried = True - return self.responses.pop(0) - def notify(self, event): - self.event = event - reg = DummyRegistry() - helper = self._makeOne('loo.foo', registry=reg) - result = helper.render('value', {}) - self.assertEqual(result[0], 'value') - self.assertEqual(result[1], {}) - self.assertTrue(reg.queried) - self.assertEqual(reg.event, {}) - self.assertEqual(reg.event.__class__.__name__, 'BeforeRender') - - def test_render_system_values_is_None(self): - import pyramid.csrf - self._registerRendererFactory() - request = Dummy() - context = Dummy() - request.context = context - helper = self._makeOne('loo.foo') - result = helper.render('values', None, request=request) - get_csrf = result[1].pop('get_csrf_token') - self.assertEqual(get_csrf.args, (request, )) - self.assertEqual(get_csrf.func, pyramid.csrf.get_csrf_token) - system = {'request':request, - 'context':context, - 'renderer_name':'loo.foo', - 'view':None, - 'renderer_info':helper, - 'req':request, - } - self.assertEqual(result[0], 'values') - self.assertEqual(result[1], system) - - def test__make_response_request_is_None(self): - request = None - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.body, b'abc') - - def test__make_response_request_is_None_response_factory_exists(self): - self._registerResponseFactory() - request = None - helper = self._makeOne('loo.foo') - response = helper._make_response(b'abc', request) - self.assertEqual(response.__class__.__name__, 'ResponseFactory') - self.assertEqual(response.body, b'abc') - - def test__make_response_result_is_unicode(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - helper = self._makeOne('loo.foo') - la = text_('/La Pe\xc3\xb1a', 'utf-8') - response = helper._make_response(la, request) - self.assertEqual(response.body, la.encode('utf-8')) - - def test__make_response_result_is_str(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - helper = self._makeOne('loo.foo') - la = text_('/La Pe\xc3\xb1a', 'utf-8') - response = helper._make_response(la.encode('utf-8'), request) - self.assertEqual(response.body, la.encode('utf-8')) - - def test__make_response_result_is_iterable(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - helper = self._makeOne('loo.foo') - la = text_('/La Pe\xc3\xb1a', 'utf-8') - response = helper._make_response([la.encode('utf-8')], request) - self.assertEqual(response.body, la.encode('utf-8')) - - def test__make_response_result_is_other(self): - self._registerResponseFactory() - request = None - helper = self._makeOne('loo.foo') - result = object() - response = helper._make_response(result, request) - self.assertEqual(response.body, result) - - def test__make_response_result_is_None_no_body(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.response = Response() - helper = self._makeOne('loo.foo') - response = helper._make_response(None, request) - self.assertEqual(response.body, b'') - - def test__make_response_result_is_None_existing_body_not_molested(self): - from pyramid.response import Response - request = testing.DummyRequest() - response = Response() - response.body = b'abc' - request.response = response - helper = self._makeOne('loo.foo') - response = helper._make_response(None, request) - self.assertEqual(response.body, b'abc') - - def test_with_alternate_response_factory(self): - from pyramid.interfaces import IResponseFactory - class ResponseFactory(object): - def __init__(self): - pass - self.config.registry.registerUtility( - lambda r: ResponseFactory(), IResponseFactory - ) - request = testing.DummyRequest() - helper = self._makeOne('loo.foo') - response = helper._make_response(b'abc', request) - self.assertEqual(response.__class__, ResponseFactory) - self.assertEqual(response.body, b'abc') - - def test__make_response_with_real_request(self): - # functional - from pyramid.request import Request - request = Request({}) - request.registry = self.config.registry - request.response.status = '406 You Lose' - helper = self._makeOne('loo.foo') - response = helper._make_response('abc', request) - self.assertEqual(response.status, '406 You Lose') - self.assertEqual(response.body, b'abc') - - def test_clone_noargs(self): - helper = self._makeOne('name', 'package', 'registry') - cloned_helper = helper.clone() - self.assertEqual(cloned_helper.name, 'name') - self.assertEqual(cloned_helper.package, 'package') - self.assertEqual(cloned_helper.registry, 'registry') - self.assertFalse(helper is cloned_helper) - - def test_clone_allargs(self): - helper = self._makeOne('name', 'package', 'registry') - cloned_helper = helper.clone(name='name2', package='package2', - registry='registry2') - self.assertEqual(cloned_helper.name, 'name2') - self.assertEqual(cloned_helper.package, 'package2') - self.assertEqual(cloned_helper.registry, 'registry2') - self.assertFalse(helper is cloned_helper) - - def test_renderer_absolute_file(self): - registry = self.config.registry - settings = {} - registry.settings = settings - from pyramid.interfaces import IRendererFactory - import os - here = os.path.dirname(os.path.abspath(__file__)) - fixture = os.path.join(here, 'fixtures/minimal.pt') - def factory(info, **kw): - return info - self.config.registry.registerUtility( - factory, IRendererFactory, name='.pt') - result = self._makeOne(fixture).renderer - self.assertEqual(result.registry, registry) - self.assertEqual(result.type, '.pt') - self.assertEqual(result.package, None) - self.assertEqual(result.name, fixture) - self.assertEqual(result.settings, settings) - - def test_renderer_with_package(self): - import pyramid - registry = self.config.registry - settings = {} - registry.settings = settings - from pyramid.interfaces import IRendererFactory - import os - here = os.path.dirname(os.path.abspath(__file__)) - fixture = os.path.join(here, 'fixtures/minimal.pt') - def factory(info, **kw): - return info - self.config.registry.registerUtility( - factory, IRendererFactory, name='.pt') - result = self._makeOne(fixture, pyramid).renderer - self.assertEqual(result.registry, registry) - self.assertEqual(result.type, '.pt') - self.assertEqual(result.package, pyramid) - self.assertEqual(result.name, fixture) - self.assertEqual(result.settings, settings) - - def test_renderer_missing(self): - inst = self._makeOne('foo') - self.assertRaises(ValueError, getattr, inst, 'renderer') - -class TestNullRendererHelper(unittest.TestCase): - def setUp(self): - self.config = cleanUp() - - def tearDown(self): - cleanUp() - - def _makeOne(self, *arg, **kw): - from pyramid.renderers import NullRendererHelper - return NullRendererHelper(*arg, **kw) - - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IRendererInfo - helper = self._makeOne() - verifyObject(IRendererInfo, helper) - - def test_render_view(self): - helper = self._makeOne() - self.assertEqual(helper.render_view(None, True, None, None), True) - - def test_render(self): - helper = self._makeOne() - self.assertEqual(helper.render(True, None, None), True) - - def test_render_to_response(self): - helper = self._makeOne() - self.assertEqual(helper.render_to_response(True, None, None), True) - - def test_clone(self): - helper = self._makeOne() - self.assertTrue(helper.clone() is helper) - -class Test_render(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, value, request=None, package=None): - from pyramid.renderers import render - return render(renderer_name, value, request=request, package=package) - - def _registerRenderer(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' - return renderer - - def test_it_no_request(self): - renderer = self._registerRenderer() - result = self._callFUT('abc/def.pt', dict(a=1)) - self.assertEqual(result, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=None) - - def test_it_with_request(self): - renderer = self._registerRenderer() - request = testing.DummyRequest() - result = self._callFUT('abc/def.pt', - dict(a=1), request=request) - self.assertEqual(result, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - - def test_it_with_package(self): - import pyramid.tests - renderer = self._registerRenderer() - request = testing.DummyRequest() - result = self._callFUT('abc/def.pt', dict(a=1), request=request, - package=pyramid.tests) - self.assertEqual(result, 'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - - def test_response_preserved(self): - request = testing.DummyRequest() - response = object() # should error if mutated - request.response = response - # use a json renderer, which will mutate the response - result = self._callFUT('json', dict(a=1), request=request) - self.assertEqual(result, '{"a": 1}') - self.assertEqual(request.response, response) - - def test_no_response_to_preserve(self): - from pyramid.decorator import reify - class DummyRequestWithClassResponse(object): - _response = DummyResponse() - _response.content_type = None - _response.default_content_type = None - @reify - def response(self): - return self._response - request = DummyRequestWithClassResponse() - # use a json renderer, which will mutate the response - result = self._callFUT('json', dict(a=1), request=request) - self.assertEqual(result, '{"a": 1}') - self.assertFalse('response' in request.__dict__) - -class Test_render_to_response(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, value, request=None, package=None, - response=None): - from pyramid.renderers import render_to_response - return render_to_response(renderer_name, value, request=request, - package=package, response=response) - - def test_it_no_request(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' - response = self._callFUT('abc/def.pt', dict(a=1)) - self.assertEqual(response.body, b'abc') - renderer.assert_(a=1) - renderer.assert_(request=None) - - def test_it_with_request(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' - request = testing.DummyRequest() - response = self._callFUT('abc/def.pt', - dict(a=1), request=request) - self.assertEqual(response.body, b'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - - def test_it_with_package(self): - import pyramid.tests - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - renderer.string_response = 'abc' - request = testing.DummyRequest() - response = self._callFUT('abc/def.pt', dict(a=1), request=request, - package=pyramid.tests) - self.assertEqual(response.body, b'abc') - renderer.assert_(a=1) - renderer.assert_(request=request) - - def test_response_preserved(self): - request = testing.DummyRequest() - response = object() # should error if mutated - request.response = response - # use a json renderer, which will mutate the response - result = self._callFUT('json', dict(a=1), request=request) - self.assertEqual(result.body, b'{"a": 1}') - self.assertNotEqual(request.response, result) - self.assertEqual(request.response, response) - - def test_no_response_to_preserve(self): - from pyramid.decorator import reify - class DummyRequestWithClassResponse(object): - _response = DummyResponse() - _response.content_type = None - _response.default_content_type = None - @reify - def response(self): - return self._response - request = DummyRequestWithClassResponse() - # use a json renderer, which will mutate the response - result = self._callFUT('json', dict(a=1), request=request) - self.assertEqual(result.body, b'{"a": 1}') - self.assertFalse('response' in request.__dict__) - - def test_custom_response_object(self): - class DummyRequestWithClassResponse(object): - pass - request = DummyRequestWithClassResponse() - response = DummyResponse() - # use a json renderer, which will mutate the response - result = self._callFUT('json', dict(a=1), request=request, - response=response) - self.assertTrue(result is response) - self.assertEqual(result.body, b'{"a": 1}') - self.assertFalse('response' in request.__dict__) - -class Test_get_renderer(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, renderer_name, **kw): - from pyramid.renderers import get_renderer - return get_renderer(renderer_name, **kw) - - def test_it_no_package(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - result = self._callFUT('abc/def.pt') - self.assertEqual(result, renderer) - - def test_it_with_package(self): - import pyramid.tests - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - result = self._callFUT('abc/def.pt', package=pyramid.tests) - self.assertEqual(result, renderer) - - def test_it_with_registry(self): - renderer = self.config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - result = self._callFUT('abc/def.pt', registry=self.config.registry) - self.assertEqual(result, renderer) - - def test_it_with_isolated_registry(self): - from pyramid.config import Configurator - isolated_config = Configurator() - renderer = isolated_config.testing_add_renderer( - 'pyramid.tests:abc/def.pt') - result = self._callFUT('abc/def.pt', registry=isolated_config.registry) - self.assertEqual(result, renderer) - -class TestJSONP(unittest.TestCase): - def _makeOne(self, param_name='callback'): - from pyramid.renderers import JSONP - return JSONP(param_name) - - def test_render_to_jsonp(self): - renderer_factory = self._makeOne() - renderer = renderer_factory(None) - request = testing.DummyRequest() - request.GET['callback'] = 'callback' - result = renderer({'a':'1'}, {'request':request}) - self.assertEqual(result, '/**/callback({"a": "1"});') - self.assertEqual(request.response.content_type, - 'application/javascript') - - def test_render_to_jsonp_with_dot(self): - renderer_factory = self._makeOne() - renderer = renderer_factory(None) - request = testing.DummyRequest() - request.GET['callback'] = 'angular.callbacks._0' - result = renderer({'a':'1'}, {'request':request}) - self.assertEqual(result, '/**/angular.callbacks._0({"a": "1"});') - self.assertEqual(request.response.content_type, - 'application/javascript') - - def test_render_to_json(self): - renderer_factory = self._makeOne() - renderer = renderer_factory(None) - request = testing.DummyRequest() - result = renderer({'a':'1'}, {'request':request}) - self.assertEqual(result, '{"a": "1"}') - self.assertEqual(request.response.content_type, - 'application/json') - - def test_render_without_request(self): - renderer_factory = self._makeOne() - renderer = renderer_factory(None) - result = renderer({'a':'1'}, {}) - self.assertEqual(result, '{"a": "1"}') - - def test_render_to_jsonp_invalid_callback(self): - from pyramid.httpexceptions import HTTPBadRequest - renderer_factory = self._makeOne() - renderer = renderer_factory(None) - request = testing.DummyRequest() - request.GET['callback'] = '78mycallback' - self.assertRaises(HTTPBadRequest, renderer, {'a':'1'}, {'request':request}) - - -class Dummy: - pass - -class DummyResponse: - status = '200 OK' - default_content_type = 'text/html' - content_type = default_content_type - headerlist = () - app_iter = () - body = b'' - - # compat for renderer that will set unicode on py3 - def _set_text(self, val): # pragma: no cover - self.body = val.encode('utf8') - text = property(fset=_set_text) - diff --git a/src/pyramid/tests/test_request.py b/src/pyramid/tests/test_request.py deleted file mode 100644 index c79c84d63..000000000 --- a/src/pyramid/tests/test_request.py +++ /dev/null @@ -1,588 +0,0 @@ -from collections import deque -import unittest -from pyramid import testing - -from pyramid.compat import ( - PY2, - text_, - bytes_, - native_, - ) -from pyramid.security import ( - AuthenticationAPIMixin, - AuthorizationAPIMixin, - ) - -class TestRequest(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTargetClass(self): - from pyramid.request import Request - return Request - - def _makeOne(self, environ=None): - if environ is None: - environ = {} - return self._getTargetClass()(environ) - - def _registerResourceURL(self): - from pyramid.interfaces import IResourceURL - from zope.interface import Interface - class DummyResourceURL(object): - def __init__(self, context, request): - self.physical_path = '/context/' - self.virtual_path = '/context/' - self.config.registry.registerAdapter( - DummyResourceURL, (Interface, Interface), - IResourceURL) - - def test_class_conforms_to_IRequest(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import IRequest - verifyClass(IRequest, self._getTargetClass()) - - def test_instance_conforms_to_IRequest(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import IRequest - verifyObject(IRequest, self._makeOne()) - - def test_ResponseClass_is_pyramid_Response(self): - from pyramid.response import Response - cls = self._getTargetClass() - self.assertEqual(cls.ResponseClass, Response) - - def test_implements_security_apis(self): - apis = (AuthenticationAPIMixin, AuthorizationAPIMixin) - r = self._makeOne() - self.assertTrue(isinstance(r, apis)) - - def test_charset_defaults_to_utf8(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.charset, 'UTF-8') - - def test_exception_defaults_to_None(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.exception, None) - - def test_matchdict_defaults_to_None(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.matchdict, None) - - def test_matched_route_defaults_to_None(self): - r = self._makeOne({'PATH_INFO':'/'}) - self.assertEqual(r.matched_route, None) - - def test_params_decoded_from_utf_8_by_default(self): - environ = { - 'PATH_INFO':'/', - 'QUERY_STRING':'la=La%20Pe%C3%B1a' - } - request = self._makeOne(environ) - request.charset = None - self.assertEqual(request.GET['la'], text_(b'La Pe\xf1a')) - - def test_tmpl_context(self): - from pyramid.request import TemplateContext - inst = self._makeOne() - result = inst.tmpl_context - self.assertEqual(result.__class__, TemplateContext) - - def test_session_configured(self): - from pyramid.interfaces import ISessionFactory - inst = self._makeOne() - def factory(request): - return 'orangejuice' - self.config.registry.registerUtility(factory, ISessionFactory) - inst.registry = self.config.registry - self.assertEqual(inst.session, 'orangejuice') - self.assertEqual(inst.__dict__['session'], 'orangejuice') - - def test_session_not_configured(self): - inst = self._makeOne() - inst.registry = self.config.registry - self.assertRaises(AttributeError, getattr, inst, 'session') - - def test_setattr_and_getattr_dotnotation(self): - inst = self._makeOne() - inst.foo = 1 - self.assertEqual(inst.foo, 1) - - def test_setattr_and_getattr(self): - environ = {} - inst = self._makeOne(environ) - setattr(inst, 'bar', 1) - self.assertEqual(getattr(inst, 'bar'), 1) - self.assertEqual(environ, {}) # make sure we're not using adhoc attrs - - def test_add_response_callback(self): - inst = self._makeOne() - self.assertEqual(len(inst.response_callbacks), 0) - def callback(request, response): - """ """ - inst.add_response_callback(callback) - self.assertEqual(list(inst.response_callbacks), [callback]) - inst.add_response_callback(callback) - self.assertEqual(list(inst.response_callbacks), [callback, callback]) - - def test__process_response_callbacks(self): - inst = self._makeOne() - def callback1(request, response): - request.called1 = True - response.called1 = True - def callback2(request, response): - request.called2 = True - response.called2 = True - inst.add_response_callback(callback1) - inst.add_response_callback(callback2) - response = DummyResponse() - inst._process_response_callbacks(response) - self.assertEqual(inst.called1, True) - self.assertEqual(inst.called2, True) - self.assertEqual(response.called1, True) - self.assertEqual(response.called2, True) - self.assertEqual(len(inst.response_callbacks), 0) - - def test__process_response_callback_adding_response_callback(self): - """ - When a response callback adds another callback, that new callback should still be called. - - See https://github.com/Pylons/pyramid/pull/1373 - """ - inst = self._makeOne() - def callback1(request, response): - request.called1 = True - response.called1 = True - request.add_response_callback(callback2) - def callback2(request, response): - request.called2 = True - response.called2 = True - inst.add_response_callback(callback1) - response = DummyResponse() - inst._process_response_callbacks(response) - self.assertEqual(inst.called1, True) - self.assertEqual(inst.called2, True) - self.assertEqual(response.called1, True) - self.assertEqual(response.called2, True) - self.assertEqual(len(inst.response_callbacks), 0) - - def test_add_finished_callback(self): - inst = self._makeOne() - self.assertEqual(len(inst.finished_callbacks), 0) - def callback(request): - """ """ - inst.add_finished_callback(callback) - self.assertEqual(list(inst.finished_callbacks), [callback]) - inst.add_finished_callback(callback) - self.assertEqual(list(inst.finished_callbacks), [callback, callback]) - - def test__process_finished_callbacks(self): - inst = self._makeOne() - def callback1(request): - request.called1 = True - def callback2(request): - request.called2 = True - inst.add_finished_callback(callback1) - inst.add_finished_callback(callback2) - inst._process_finished_callbacks() - self.assertEqual(inst.called1, True) - self.assertEqual(inst.called2, True) - self.assertEqual(len(inst.finished_callbacks), 0) - - def test_resource_url(self): - self._registerResourceURL() - environ = { - 'PATH_INFO':'/', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - 'wsgi.url_scheme':'http', - } - inst = self._makeOne(environ) - root = DummyContext() - result = inst.resource_url(root) - self.assertEqual(result, 'http://example.com/context/') - - def test_route_url(self): - environ = { - 'PATH_INFO':'/', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'5432', - 'QUERY_STRING':'la=La%20Pe%C3%B1a', - 'wsgi.url_scheme':'http', - } - from pyramid.interfaces import IRoutesMapper - inst = self._makeOne(environ) - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - self.config.registry.registerUtility(mapper, IRoutesMapper) - result = inst.route_url('flub', 'extra1', 'extra2', - a=1, b=2, c=3, _query={'a':1}, - _anchor=text_("foo")) - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') - - def test_route_path(self): - environ = { - 'PATH_INFO':'/', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'5432', - 'QUERY_STRING':'la=La%20Pe%C3%B1a', - 'wsgi.url_scheme':'http', - } - from pyramid.interfaces import IRoutesMapper - inst = self._makeOne(environ) - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - self.config.registry.registerUtility(mapper, IRoutesMapper) - result = inst.route_path('flub', 'extra1', 'extra2', - a=1, b=2, c=3, _query={'a':1}, - _anchor=text_("foo")) - self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') - - def test_static_url(self): - from pyramid.interfaces import IStaticURLInfo - environ = { - 'PATH_INFO':'/', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'5432', - 'QUERY_STRING':'', - 'wsgi.url_scheme':'http', - } - request = self._makeOne(environ) - info = DummyStaticURLInfo('abc') - self.config.registry.registerUtility(info, IStaticURLInfo) - result = request.static_url('pyramid.tests:static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, {}) ) - - def test_is_response_false(self): - request = self._makeOne() - request.registry = self.config.registry - self.assertEqual(request.is_response('abc'), False) - - def test_is_response_true_ob_is_pyramid_response(self): - from pyramid.response import Response - r = Response('hello') - request = self._makeOne() - request.registry = self.config.registry - self.assertEqual(request.is_response(r), True) - - def test_is_response_false_adapter_is_not_self(self): - from pyramid.interfaces import IResponse - request = self._makeOne() - request.registry = self.config.registry - def adapter(ob): - return object() - class Foo(object): - pass - foo = Foo() - request.registry.registerAdapter(adapter, (Foo,), IResponse) - self.assertEqual(request.is_response(foo), False) - - def test_is_response_adapter_true(self): - from pyramid.interfaces import IResponse - request = self._makeOne() - request.registry = self.config.registry - class Foo(object): - pass - foo = Foo() - def adapter(ob): - return ob - request.registry.registerAdapter(adapter, (Foo,), IResponse) - self.assertEqual(request.is_response(foo), True) - - def test_json_body_invalid_json(self): - request = self._makeOne({'REQUEST_METHOD':'POST'}) - request.body = b'{' - self.assertRaises(ValueError, getattr, request, 'json_body') - - def test_json_body_valid_json(self): - request = self._makeOne({'REQUEST_METHOD':'POST'}) - request.body = b'{"a":1}' - self.assertEqual(request.json_body, {'a':1}) - - def test_json_body_alternate_charset(self): - import json - request = self._makeOne({'REQUEST_METHOD':'POST'}) - inp = text_( - b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', - 'utf-8' - ) - if PY2: - body = json.dumps({'a':inp}).decode('utf-8').encode('utf-16') - else: - body = bytes(json.dumps({'a':inp}), 'utf-16') - request.body = body - request.content_type = 'application/json; charset=utf-16' - self.assertEqual(request.json_body, {'a':inp}) - - def test_json_body_GET_request(self): - request = self._makeOne({'REQUEST_METHOD':'GET'}) - self.assertRaises(ValueError, getattr, request, 'json_body') - - def test_set_property(self): - request = self._makeOne() - opts = [2, 1] - def connect(obj): - return opts.pop() - request.set_property(connect, name='db') - self.assertEqual(1, request.db) - self.assertEqual(2, request.db) - - def test_set_property_reify(self): - request = self._makeOne() - opts = [2, 1] - def connect(obj): - return opts.pop() - request.set_property(connect, name='db', reify=True) - self.assertEqual(1, request.db) - self.assertEqual(1, request.db) - -class Test_route_request_iface(unittest.TestCase): - def _callFUT(self, name): - from pyramid.request import route_request_iface - return route_request_iface(name) - - def test_it(self): - iface = self._callFUT('routename') - self.assertEqual(iface.__name__, 'routename_IRequest') - self.assertTrue(hasattr(iface, 'combined')) - self.assertEqual(iface.combined.__name__, 'routename_combined_IRequest') - - def test_it_routename_with_spaces(self): - # see https://github.com/Pylons/pyramid/issues/232 - iface = self._callFUT('routename with spaces') - self.assertEqual(iface.__name__, 'routename with spaces_IRequest') - self.assertTrue(hasattr(iface, 'combined')) - self.assertEqual(iface.combined.__name__, - 'routename with spaces_combined_IRequest') - - -class Test_add_global_response_headers(unittest.TestCase): - def _callFUT(self, request, headerlist): - from pyramid.request import add_global_response_headers - return add_global_response_headers(request, headerlist) - - def test_it(self): - request = DummyRequest() - response = DummyResponse() - self._callFUT(request, [('c', 1)]) - self.assertEqual(len(request.response_callbacks), 1) - request.response_callbacks[0](None, response) - self.assertEqual(response.headerlist, [('c', 1)] ) - -class Test_call_app_with_subpath_as_path_info(unittest.TestCase): - def _callFUT(self, request, app): - from pyramid.request import call_app_with_subpath_as_path_info - return call_app_with_subpath_as_path_info(request, app) - - def test_it_all_request_and_environment_data_missing(self): - request = DummyRequest({}) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '') - self.assertEqual(request.environ['PATH_INFO'], '/') - - def test_it_with_subpath_and_path_info(self): - request = DummyRequest({'PATH_INFO':'/hello'}) - request.subpath = ('hello',) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '') - self.assertEqual(request.environ['PATH_INFO'], '/hello') - - def test_it_with_subpath_and_path_info_path_info_endswith_slash(self): - request = DummyRequest({'PATH_INFO':'/hello/'}) - request.subpath = ('hello',) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '') - self.assertEqual(request.environ['PATH_INFO'], '/hello/') - - def test_it_with_subpath_and_path_info_extra_script_name(self): - request = DummyRequest({'PATH_INFO':'/hello', 'SCRIPT_NAME':'/script'}) - request.subpath = ('hello',) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '/script') - self.assertEqual(request.environ['PATH_INFO'], '/hello') - - def test_it_with_extra_slashes_in_path_info(self): - request = DummyRequest({'PATH_INFO':'//hello/', - 'SCRIPT_NAME':'/script'}) - request.subpath = ('hello',) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '/script') - self.assertEqual(request.environ['PATH_INFO'], '/hello/') - - def test_subpath_path_info_and_script_name_have_utf8(self): - encoded = native_(text_(b'La Pe\xc3\xb1a')) - decoded = text_(bytes_(encoded), 'utf-8') - request = DummyRequest({'PATH_INFO':'/' + encoded, - 'SCRIPT_NAME':'/' + encoded}) - request.subpath = (decoded, ) - response = self._callFUT(request, 'app') - self.assertTrue(request.copied) - self.assertEqual(response, 'app') - self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) - self.assertEqual(request.environ['PATH_INFO'], '/' + encoded) - -class Test_apply_request_extensions(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, request, extensions=None): - from pyramid.request import apply_request_extensions - return apply_request_extensions(request, extensions=extensions) - - def test_it_with_registry(self): - from pyramid.interfaces import IRequestExtensions - extensions = Dummy() - extensions.methods = {'foo': lambda x, y: y} - extensions.descriptors = {'bar': property(lambda x: 'bar')} - self.config.registry.registerUtility(extensions, IRequestExtensions) - request = DummyRequest() - request.registry = self.config.registry - self._callFUT(request) - self.assertEqual(request.bar, 'bar') - self.assertEqual(request.foo('abc'), 'abc') - - def test_it_override_extensions(self): - from pyramid.interfaces import IRequestExtensions - ignore = Dummy() - ignore.methods = {'x': lambda x, y, z: 'asdf'} - ignore.descriptors = {'bar': property(lambda x: 'asdf')} - self.config.registry.registerUtility(ignore, IRequestExtensions) - request = DummyRequest() - request.registry = self.config.registry - - extensions = Dummy() - extensions.methods = {'foo': lambda x, y: y} - extensions.descriptors = {'bar': property(lambda x: 'bar')} - self._callFUT(request, extensions=extensions) - self.assertRaises(AttributeError, lambda: request.x) - self.assertEqual(request.bar, 'bar') - self.assertEqual(request.foo('abc'), 'abc') - -class Dummy(object): - pass - -class Test_subclassing_Request(unittest.TestCase): - def test_subclass(self): - from pyramid.interfaces import IRequest - from pyramid.request import Request - - class RequestSub(Request): - pass - - self.assertTrue(hasattr(Request, '__provides__')) - self.assertTrue(hasattr(Request, '__implemented__')) - self.assertTrue(hasattr(Request, '__providedBy__')) - self.assertFalse(hasattr(RequestSub, '__provides__')) - self.assertTrue(hasattr(RequestSub, '__providedBy__')) - self.assertTrue(hasattr(RequestSub, '__implemented__')) - - self.assertTrue(IRequest.implementedBy(RequestSub)) - # The call to implementedBy will add __provides__ to the class - self.assertTrue(hasattr(RequestSub, '__provides__')) - - - def test_subclass_with_implementer(self): - from pyramid.interfaces import IRequest - from pyramid.request import Request - from pyramid.util import InstancePropertyHelper - from zope.interface import implementer - - @implementer(IRequest) - class RequestSub(Request): - pass - - self.assertTrue(hasattr(Request, '__provides__')) - self.assertTrue(hasattr(Request, '__implemented__')) - self.assertTrue(hasattr(Request, '__providedBy__')) - self.assertTrue(hasattr(RequestSub, '__provides__')) - self.assertTrue(hasattr(RequestSub, '__providedBy__')) - self.assertTrue(hasattr(RequestSub, '__implemented__')) - - req = RequestSub({}) - helper = InstancePropertyHelper() - helper.apply_properties(req, {'b': 'b'}) - - self.assertTrue(IRequest.providedBy(req)) - self.assertTrue(IRequest.implementedBy(RequestSub)) - - def test_subclass_mutate_before_providedBy(self): - from pyramid.interfaces import IRequest - from pyramid.request import Request - from pyramid.util import InstancePropertyHelper - - class RequestSub(Request): - pass - - req = RequestSub({}) - helper = InstancePropertyHelper() - helper.apply_properties(req, {'b': 'b'}) - - self.assertTrue(IRequest.providedBy(req)) - self.assertTrue(IRequest.implementedBy(RequestSub)) - - -class DummyRequest(object): - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - - def add_response_callback(self, callback): - self.response_callbacks = [callback] - - def get_response(self, app): - return app - - def copy(self): - self.copied = True - return self - -class DummyResponse: - def __init__(self): - self.headerlist = [] - - -class DummyContext: - pass - -class DummyRoutesMapper: - raise_exc = None - def __init__(self, route=None, raise_exc=False): - self.route = route - - def get_route(self, route_name): - return self.route - -class DummyRoute: - pregenerator = None - def __init__(self, result='/1/2/3'): - self.result = result - - def generate(self, kw): - self.kw = kw - return self.result - -class DummyStaticURLInfo: - def __init__(self, result): - self.result = result - - def generate(self, path, request, **kw): - self.args = path, request, kw - return self.result diff --git a/src/pyramid/tests/test_response.py b/src/pyramid/tests/test_response.py deleted file mode 100644 index 53e3ce17a..000000000 --- a/src/pyramid/tests/test_response.py +++ /dev/null @@ -1,214 +0,0 @@ -import io -import mimetypes -import os -import unittest -from pyramid import testing - -class TestResponse(unittest.TestCase): - def _getTargetClass(self): - from pyramid.response import Response - return Response - - def test_implements_IResponse(self): - from pyramid.interfaces import IResponse - cls = self._getTargetClass() - self.assertTrue(IResponse.implementedBy(cls)) - - def test_provides_IResponse(self): - from pyramid.interfaces import IResponse - inst = self._getTargetClass()() - self.assertTrue(IResponse.providedBy(inst)) - -class TestFileResponse(unittest.TestCase): - def _makeOne(self, file, **kw): - from pyramid.response import FileResponse - return FileResponse(file, **kw) - - def _getPath(self, suffix='txt'): - here = os.path.dirname(__file__) - return os.path.join(here, 'fixtures', 'minimal.%s' % (suffix,)) - - def test_with_image_content_type(self): - path = self._getPath('jpg') - r = self._makeOne(path, content_type='image/jpeg') - self.assertEqual(r.content_type, 'image/jpeg') - self.assertEqual(r.headers['content-type'], 'image/jpeg') - path = self._getPath() - r.app_iter.close() - - def test_with_xml_content_type(self): - path = self._getPath('xml') - r = self._makeOne(path, content_type='application/xml') - self.assertEqual(r.content_type, 'application/xml') - self.assertEqual(r.headers['content-type'], - 'application/xml; charset=UTF-8') - r.app_iter.close() - - def test_with_pdf_content_type(self): - path = self._getPath('xml') - r = self._makeOne(path, content_type='application/pdf') - self.assertEqual(r.content_type, 'application/pdf') - self.assertEqual(r.headers['content-type'], 'application/pdf') - r.app_iter.close() - - def test_without_content_type(self): - for suffix in ('txt', 'xml', 'pdf'): - path = self._getPath(suffix) - r = self._makeOne(path) - self.assertEqual(r.headers['content-type'].split(';')[0], - mimetypes.guess_type(path, strict=False)[0]) - r.app_iter.close() - - def test_python_277_bug_15207(self): - # python 2.7.7 on windows has a bug where its mimetypes.guess_type - # function returns Unicode for the content_type, unlike any previous - # version of Python. See https://github.com/Pylons/pyramid/issues/1360 - # for more information. - from pyramid.compat import text_ - import mimetypes as old_mimetypes - from pyramid import response - class FakeMimetypesModule(object): - def guess_type(self, *arg, **kw): - return text_('foo/bar'), None - fake_mimetypes = FakeMimetypesModule() - try: - response.mimetypes = fake_mimetypes - path = self._getPath('xml') - r = self._makeOne(path) - self.assertEqual(r.content_type, 'foo/bar') - self.assertEqual(type(r.content_type), str) - finally: - response.mimetypes = old_mimetypes - -class TestFileIter(unittest.TestCase): - def _makeOne(self, file, block_size): - from pyramid.response import FileIter - return FileIter(file, block_size) - - def test___iter__(self): - f = io.BytesIO(b'abc') - inst = self._makeOne(f, 1) - self.assertEqual(inst.__iter__(), inst) - - def test_iteration(self): - data = b'abcdef' - f = io.BytesIO(b'abcdef') - inst = self._makeOne(f, 1) - r = b'' - for x in inst: - self.assertEqual(len(x), 1) - r+=x - self.assertEqual(r, data) - - def test_close(self): - f = io.BytesIO(b'abc') - inst = self._makeOne(f, 1) - inst.close() - self.assertTrue(f.closed) - -class Test_patch_mimetypes(unittest.TestCase): - def _callFUT(self, module): - from pyramid.response import init_mimetypes - return init_mimetypes(module) - - def test_has_init(self): - class DummyMimetypes(object): - def init(self): - self.initted = True - module = DummyMimetypes() - result = self._callFUT(module) - self.assertEqual(result, True) - self.assertEqual(module.initted, True) - - def test_missing_init(self): - class DummyMimetypes(object): - pass - module = DummyMimetypes() - result = self._callFUT(module) - self.assertEqual(result, False) - - -class TestResponseAdapter(unittest.TestCase): - def setUp(self): - registry = Dummy() - self.config = testing.setUp(registry=registry) - - def tearDown(self): - self.config.end() - - def _makeOne(self, *types_or_ifaces, **kw): - from pyramid.response import response_adapter - return response_adapter(*types_or_ifaces, **kw) - - def test_register_single(self): - from zope.interface import Interface - class IFoo(Interface): pass - dec = self._makeOne(IFoo) - def foo(): pass - config = DummyConfigurator() - scanner = Dummy() - scanner.config = config - dec.register(scanner, None, foo) - self.assertEqual(config.adapters, [(foo, IFoo)]) - - def test_register_multi(self): - from zope.interface import Interface - class IFoo(Interface): pass - class IBar(Interface): pass - dec = self._makeOne(IFoo, IBar) - def foo(): pass - config = DummyConfigurator() - scanner = Dummy() - scanner.config = config - dec.register(scanner, None, foo) - self.assertEqual(config.adapters, [(foo, IFoo), (foo, IBar)]) - - def test___call__(self): - from zope.interface import Interface - class IFoo(Interface): pass - dec = self._makeOne(IFoo) - dummy_venusian = DummyVenusian() - dec.venusian = dummy_venusian - def foo(): pass - dec(foo) - self.assertEqual(dummy_venusian.attached, - [(foo, dec.register, 'pyramid', 1)]) - - def test___call___with_venusian_args(self): - from zope.interface import Interface - class IFoo(Interface): pass - dec = self._makeOne(IFoo, _category='foo', _depth=1) - dummy_venusian = DummyVenusian() - dec.venusian = dummy_venusian - def foo(): pass - dec(foo) - self.assertEqual(dummy_venusian.attached, - [(foo, dec.register, 'foo', 2)]) - - -class TestGetResponseFactory(unittest.TestCase): - def test_get_factory(self): - from pyramid.registry import Registry - from pyramid.response import Response, _get_response_factory - - registry = Registry() - response = _get_response_factory(registry)(None) - self.assertTrue(isinstance(response, Response)) - - -class Dummy(object): - pass - -class DummyConfigurator(object): - def __init__(self): - self.adapters = [] - - def add_response_adapter(self, wrapped, type_or_iface): - self.adapters.append((wrapped, type_or_iface)) - -class DummyVenusian(object): - def __init__(self): - self.attached = [] - - def attach(self, wrapped, fn, category=None, depth=None): - self.attached.append((wrapped, fn, category, depth)) diff --git a/src/pyramid/tests/test_router.py b/src/pyramid/tests/test_router.py deleted file mode 100644 index 6097018f0..000000000 --- a/src/pyramid/tests/test_router.py +++ /dev/null @@ -1,1410 +0,0 @@ -import unittest - -from pyramid import testing - -class TestRouter(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - self.registry = self.config.registry - - def tearDown(self): - testing.tearDown() - - def _registerRouteRequest(self, name): - from pyramid.interfaces import IRouteRequest - from pyramid.request import route_request_iface - iface = route_request_iface(name) - self.registry.registerUtility(iface, IRouteRequest, name=name) - return iface - - def _connectRoute(self, name, path, factory=None): - from pyramid.interfaces import IRoutesMapper - from pyramid.urldispatch import RoutesMapper - mapper = self.registry.queryUtility(IRoutesMapper) - if mapper is None: - mapper = RoutesMapper() - self.registry.registerUtility(mapper, IRoutesMapper) - return mapper.connect(name, path, factory) - - def _registerLogger(self): - from pyramid.interfaces import IDebugLogger - logger = DummyLogger() - self.registry.registerUtility(logger, IDebugLogger) - return logger - - def _registerSettings(self, **kw): - settings = {'debug_authorization':False, - 'debug_notfound':False, - 'debug_routematch':False} - settings.update(kw) - self.registry.settings = settings - - def _registerTraverserFactory(self, context, view_name='', subpath=None, - traversed=None, virtual_root=None, - virtual_root_path=None, raise_error=None, - **kw): - from pyramid.interfaces import ITraverser - - if virtual_root is None: - virtual_root = context - if subpath is None: - subpath = [] - if traversed is None: - traversed = [] - if virtual_root_path is None: - virtual_root_path = [] - - class DummyTraverserFactory: - def __init__(self, root): - self.root = root - - def __call__(self, request): - if raise_error: - raise raise_error - values = {'root':self.root, - 'context':context, - 'view_name':view_name, - 'subpath':subpath, - 'traversed':traversed, - 'virtual_root':virtual_root, - 'virtual_root_path':virtual_root_path} - kw.update(values) - return kw - - self.registry.registerAdapter(DummyTraverserFactory, (None,), - ITraverser, name='') - - def _registerView(self, app, name, classifier, req_iface, ctx_iface): - from pyramid.interfaces import IView - self.registry.registerAdapter( - app, (classifier, req_iface, ctx_iface), IView, name) - - def _registerEventListener(self, iface): - L = [] - def listener(event): - L.append(event) - self.registry.registerHandler(listener, (iface,)) - return L - - def _registerRootFactory(self, val): - rootfactory = DummyRootFactory(val) - from pyramid.interfaces import IRootFactory - self.registry.registerUtility(rootfactory, IRootFactory) - return rootfactory - - def _getTargetClass(self): - from pyramid.router import Router - return Router - - def _makeOne(self): - klass = self._getTargetClass() - return klass(self.registry) - - def _makeEnviron(self, **extras): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'8080', - 'REQUEST_METHOD':'GET', - 'PATH_INFO':'/', - } - environ.update(extras) - return environ - - def test_ctor_registry_has_no_settings(self): - self.registry.settings = None - router = self._makeOne() - self.assertEqual(router.debug_notfound, False) - self.assertEqual(router.debug_routematch, False) - self.assertFalse('debug_notfound' in router.__dict__) - self.assertFalse('debug_routematch' in router.__dict__) - - def test_root_policy(self): - context = DummyContext() - self._registerTraverserFactory(context) - rootfactory = self._registerRootFactory('abc') - router = self._makeOne() - self.assertEqual(router.root_policy, rootfactory) - - def test_request_factory(self): - from pyramid.interfaces import IRequestFactory - class DummyRequestFactory(object): - pass - self.registry.registerUtility(DummyRequestFactory, IRequestFactory) - router = self._makeOne() - self.assertEqual(router.request_factory, DummyRequestFactory) - - def test_tween_factories(self): - from pyramid.interfaces import ITweens - from pyramid.config.tweens import Tweens - from pyramid.response import Response - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IResponse - tweens = Tweens() - self.registry.registerUtility(tweens, ITweens) - L = [] - def tween_factory1(handler, registry): - L.append((handler, registry)) - def wrapper(request): - request.environ['handled'].append('one') - return handler(request) - wrapper.name = 'one' - wrapper.child = handler - return wrapper - def tween_factory2(handler, registry): - L.append((handler, registry)) - def wrapper(request): - request.environ['handled'] = ['two'] - return handler(request) - wrapper.name = 'two' - wrapper.child = handler - return wrapper - tweens.add_implicit('one', tween_factory1) - tweens.add_implicit('two', tween_factory2) - router = self._makeOne() - self.assertEqual(router.handle_request.name, 'two') - self.assertEqual(router.handle_request.child.name, 'one') - self.assertEqual(router.handle_request.child.child.__name__, - 'handle_request') - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron() - view = DummyView('abc') - self._registerView(self.config.derive_view(view), '', - IViewClassifier, None, None) - start_response = DummyStartResponse() - def make_response(s): - return Response(s) - router.registry.registerAdapter(make_response, (str,), IResponse) - app_iter = router(environ, start_response) - self.assertEqual(app_iter, [b'abc']) - self.assertEqual(start_response.status, '200 OK') - self.assertEqual(environ['handled'], ['two', 'one']) - - def test_call_traverser_default(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue('/' in why.args[0], why) - self.assertFalse('debug_notfound' in why.args[0]) - self.assertEqual(len(logger.messages), 0) - - def test_traverser_raises_notfound_class(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=HTTPNotFound) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(HTTPNotFound, router, environ, start_response) - - def test_traverser_raises_notfound_instance(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=HTTPNotFound('foo')) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue('foo' in why.args[0], why) - - def test_traverser_raises_forbidden_class(self): - from pyramid.httpexceptions import HTTPForbidden - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=HTTPForbidden) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(HTTPForbidden, router, environ, start_response) - - def test_traverser_raises_forbidden_instance(self): - from pyramid.httpexceptions import HTTPForbidden - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, - raise_error=HTTPForbidden('foo')) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPForbidden, router, environ, start_response) - self.assertTrue('foo' in why.args[0], why) - - def test_call_no_view_registered_no_isettings(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue('/' in why.args[0], why) - self.assertFalse('debug_notfound' in why.args[0]) - self.assertEqual(len(logger.messages), 0) - - def test_call_no_view_registered_debug_notfound_false(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - logger = self._registerLogger() - self._registerSettings(debug_notfound=False) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue('/' in why.args[0], why) - self.assertFalse('debug_notfound' in why.args[0]) - self.assertEqual(len(logger.messages), 0) - - def test_call_no_view_registered_debug_notfound_true(self): - from pyramid.httpexceptions import HTTPNotFound - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context) - self._registerSettings(debug_notfound=True) - logger = self._registerLogger() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue( - "debug_notfound of url http://localhost:8080/; " in why.args[0]) - self.assertTrue("view_name: '', subpath: []" in why.args[0]) - self.assertTrue('http://localhost:8080' in why.args[0], why) - - self.assertEqual(len(logger.messages), 1) - message = logger.messages[0] - self.assertTrue('of url http://localhost:8080' in message) - self.assertTrue("path_info: " in message) - self.assertTrue('DummyContext' in message) - self.assertTrue("view_name: ''" in message) - self.assertTrue("subpath: []" in message) - - def test_call_view_returns_non_iresponse(self): - from pyramid.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron() - view = DummyView('abc') - self._registerView(self.config.derive_view(view), '', IViewClassifier, - None, None) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(ValueError, router, environ, start_response) - - def test_call_view_returns_adapted_response(self): - from pyramid.response import Response - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IResponse - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron() - view = DummyView('abc') - self._registerView(self.config.derive_view(view), '', - IViewClassifier, None, None) - router = self._makeOne() - start_response = DummyStartResponse() - def make_response(s): - return Response(s) - router.registry.registerAdapter(make_response, (str,), IResponse) - app_iter = router(environ, start_response) - self.assertEqual(app_iter, [b'abc']) - self.assertEqual(start_response.status, '200 OK') - - def test_call_with_request_extensions(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequestExtensions - from pyramid.interfaces import IRequest - from pyramid.request import Request - from pyramid.util import InstancePropertyHelper - context = DummyContext() - self._registerTraverserFactory(context) - class Extensions(object): - def __init__(self): - self.methods = {} - self.descriptors = {} - extensions = Extensions() - ext_method = lambda r: 'bar' - name, fn = InstancePropertyHelper.make_property(ext_method, name='foo') - extensions.descriptors[name] = fn - request = Request.blank('/') - request.request_iface = IRequest - request.registry = self.registry - def request_factory(environ): - return request - self.registry.registerUtility(extensions, IRequestExtensions) - environ = self._makeEnviron() - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - self._registerView(self.config.derive_view(view), '', - IViewClassifier, None, None) - router = self._makeOne() - router.request_factory = request_factory - start_response = DummyStartResponse() - router(environ, start_response) - self.assertEqual(view.request.foo, 'bar') - - def test_call_view_registered_nonspecific_default_path(self): - from pyramid.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(self.config.derive_view(view), '', - IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self): - from pyramid.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context, view_name='foo', - subpath=['bar'], - traversed=['context']) - self._registerRootFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, 'foo', IViewClassifier, None, None) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, 'foo') - self.assertEqual(request.subpath, ['bar']) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_specific_success(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context) - self._registerRootFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, context) - - def test_call_view_registered_specific_fail(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from pyramid.httpexceptions import HTTPNotFound - from pyramid.interfaces import IViewClassifier - class IContext(Interface): - pass - class INotContext(Interface): - pass - from pyramid.interfaces import IRequest - context = DummyContext() - directlyProvides(context, INotContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(HTTPNotFound, router, environ, start_response) - - def test_call_view_raises_forbidden(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from pyramid.httpexceptions import HTTPForbidden - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response, - raise_exception=HTTPForbidden("unauthorized")) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPForbidden, router, environ, start_response) - self.assertEqual(why.args[0], 'unauthorized') - - def test_call_view_raises_notfound(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.httpexceptions import HTTPNotFound - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - view = DummyView(response, raise_exception=HTTPNotFound("notfound")) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertEqual(why.args[0], 'notfound') - - def test_call_view_raises_response_cleared(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from pyramid.interfaces import IExceptionViewClassifier - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - def view(context, request): - request.response.a = 1 - raise KeyError - def exc_view(context, request): - self.assertFalse(hasattr(request.response, 'a')) - request.response.body = b'OK' - return request.response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - self._registerView(exc_view, '', IExceptionViewClassifier, - IRequest, KeyError) - router = self._makeOne() - start_response = DummyStartResponse() - itera = router(environ, start_response) - self.assertEqual(itera, [b'OK']) - - def test_call_request_has_response_callbacks(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse('200 OK') - def view(context, request): - def callback(request, response): - response.called_back = True - request.add_response_callback(callback) - return response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - router(environ, start_response) - self.assertEqual(response.called_back, True) - - def test_call_request_has_finished_callbacks_when_view_succeeds(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse('200 OK') - def view(context, request): - def callback(request): - request.environ['called_back'] = True - request.add_finished_callback(callback) - return response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - router(environ, start_response) - self.assertEqual(environ['called_back'], True) - - def test_call_request_has_finished_callbacks_when_view_raises(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - def view(context, request): - def callback(request): - request.environ['called_back'] = True - request.add_finished_callback(callback) - raise NotImplementedError - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, IContext) - router = self._makeOne() - start_response = DummyStartResponse() - exc_raised(NotImplementedError, router, environ, start_response) - self.assertEqual(environ['called_back'], True) - - def test_call_request_factory_raises(self): - # making sure finally doesnt barf when a request cannot be created - environ = self._makeEnviron() - router = self._makeOne() - def dummy_request_factory(environ): - raise NotImplementedError - router.request_factory = dummy_request_factory - start_response = DummyStartResponse() - exc_raised(NotImplementedError, router, environ, start_response) - - def test_call_eventsends(self): - from pyramid.interfaces import INewRequest - from pyramid.interfaces import INewResponse - from pyramid.interfaces import IBeforeTraversal - from pyramid.interfaces import IContextFound - from pyramid.interfaces import IViewClassifier - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, None, None) - request_events = self._registerEventListener(INewRequest) - beforetraversal_events = self._registerEventListener(IBeforeTraversal) - context_found_events = self._registerEventListener(IContextFound) - response_events = self._registerEventListener(INewResponse) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(len(request_events), 1) - self.assertEqual(request_events[0].request.environ, environ) - self.assertEqual(len(beforetraversal_events), 1) - self.assertEqual(beforetraversal_events[0].request.environ, environ) - self.assertEqual(len(context_found_events), 1) - self.assertEqual(context_found_events[0].request.environ, environ) - self.assertEqual(context_found_events[0].request.context, context) - self.assertEqual(len(response_events), 1) - self.assertEqual(response_events[0].response, response) - self.assertEqual(response_events[0].request.context, context) - self.assertEqual(result, response.app_iter) - - def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self): - from pyramid.interfaces import INewRequest - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron() - def listener(event): - raise KeyError - self.registry.registerHandler(listener, (INewRequest,)) - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, KeyError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, exception_response.app_iter) - - def test_call_route_matches_and_has_factory(self): - from pyramid.interfaces import IViewClassifier - logger = self._registerLogger() - self._registerSettings(debug_routematch=True) - self._registerRouteRequest('foo') - root = object() - def factory(request): - return root - route = self._connectRoute('foo', 'archives/:action/:article', factory) - route.predicates = [DummyPredicate()] - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - self._registerView(view, '', IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, root) - matchdict = {'action':'action1', 'article':'article1'} - self.assertEqual(request.matchdict, matchdict) - self.assertEqual(request.matched_route.name, 'foo') - self.assertEqual(len(logger.messages), 1) - self.assertTrue( - logger.messages[0].startswith( - "route matched for url http://localhost:8080" - "/archives/action1/article1; " - "route_name: 'foo', " - "path_info: ") - ) - self.assertTrue( - "predicates: 'predicate'" in logger.messages[0] - ) - - def test_call_route_match_miss_debug_routematch(self): - from pyramid.httpexceptions import HTTPNotFound - logger = self._registerLogger() - self._registerSettings(debug_routematch=True) - self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article') - context = DummyContext() - self._registerTraverserFactory(context) - environ = self._makeEnviron(PATH_INFO='/wontmatch') - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(HTTPNotFound, router, environ, start_response) - - self.assertEqual(len(logger.messages), 1) - self.assertEqual( - logger.messages[0], - 'no route matched for url http://localhost:8080/wontmatch') - - def test_call_route_matches_doesnt_overwrite_subscriber_iface(self): - from pyramid.interfaces import INewRequest - from pyramid.interfaces import IViewClassifier - from zope.interface import alsoProvides - from zope.interface import Interface - self._registerRouteRequest('foo') - class IFoo(Interface): - pass - def listener(event): - alsoProvides(event.request, IFoo) - self.registry.registerHandler(listener, (INewRequest,)) - root = object() - def factory(request): - return root - self._connectRoute('foo', 'archives/:action/:article', factory) - context = DummyContext() - self._registerTraverserFactory(context) - response = DummyResponse() - response.app_iter = ['Hello world'] - view = DummyView(response) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - self._registerView(view, '', IViewClassifier, None, None) - self._registerRootFactory(context) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['Hello world']) - self.assertEqual(start_response.headers, ()) - self.assertEqual(start_response.status, '200 OK') - request = view.request - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, []) - self.assertEqual(request.context, context) - self.assertEqual(request.root, root) - matchdict = {'action':'action1', 'article':'article1'} - self.assertEqual(request.matchdict, matchdict) - self.assertEqual(request.matched_route.name, 'foo') - self.assertTrue(IFoo.providedBy(request)) - - def test_root_factory_raises_notfound(self): - from pyramid.interfaces import IRootFactory - from pyramid.httpexceptions import HTTPNotFound - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise HTTPNotFound('from root factory') - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPNotFound, router, environ, start_response) - self.assertTrue('from root factory' in why.args[0]) - - def test_root_factory_raises_forbidden(self): - from pyramid.interfaces import IRootFactory - from pyramid.httpexceptions import HTTPForbidden - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise HTTPForbidden('from root factory') - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - why = exc_raised(HTTPForbidden, router, environ, start_response) - self.assertTrue('from root factory' in why.args[0]) - - def test_root_factory_exception_propagating(self): - from pyramid.interfaces import IRootFactory - from zope.interface import Interface - from zope.interface import directlyProvides - def rootfactory(request): - raise RuntimeError() - self.registry.registerUtility(rootfactory, IRootFactory) - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_traverser_exception_propagating(self): - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=RuntimeError()) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_view_exception_propagating(self): - from zope.interface import Interface - from zope.interface import directlyProvides - class IContext(Interface): - pass - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequestFactory - from pyramid.interfaces import IExceptionViewClassifier - def rfactory(environ): - return request - self.registry.registerUtility(rfactory, IRequestFactory) - from pyramid.request import Request - request = Request.blank('/') - context = DummyContext() - directlyProvides(context, IContext) - self._registerTraverserFactory(context, subpath=['']) - response = DummyResponse() - response.app_iter = ['OK'] - error = RuntimeError() - view = DummyView(response, raise_exception=error) - environ = self._makeEnviron() - def exception_view(context, request): - self.assertEqual(request.exc_info[0], RuntimeError) - return response - self._registerView(view, '', IViewClassifier, IRequest, IContext) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ['OK']) - # exc_info and exception should still be around on the request after - # the excview tween has run (see - # https://github.com/Pylons/pyramid/issues/1223) - self.assertEqual(request.exception, error) - self.assertEqual(request.exc_info[:2], (RuntimeError, error,)) - - def test_call_view_raises_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=RuntimeError) - def exception_view(context, request): - self.assertEqual(request.exception.__class__, RuntimeError) - return exception_response - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_view_raises_super_exception_sub_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=SuperException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SubException) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(SuperException, router, environ, start_response) - - def test_call_view_raises_sub_exception_super_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=SubException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SuperException) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_view_raises_exception_another_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class MyException(Exception): - pass - class AnotherException(Exception): - pass - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=MyException) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, AnotherException) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(MyException, router, environ, start_response) - - def test_root_factory_raises_exception_view(self): - from pyramid.interfaces import IRootFactory - from pyramid.interfaces import IRequest - from pyramid.interfaces import IExceptionViewClassifier - def rootfactory(request): - raise RuntimeError() - self.registry.registerUtility(rootfactory, IRootFactory) - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - exception_view = DummyView(exception_response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - app_iter = router(environ, start_response) - self.assertEqual(app_iter, ["Hello, world"]) - - def test_traverser_raises_exception_view(self): - from pyramid.interfaces import IRequest - from pyramid.interfaces import IExceptionViewClassifier - environ = self._makeEnviron() - context = DummyContext() - self._registerTraverserFactory(context, raise_error=RuntimeError()) - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - exception_view = DummyView(exception_response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_exception_view_returns_non_iresponse(self): - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - environ = self._makeEnviron() - response = DummyResponse() - view = DummyView(response, raise_exception=RuntimeError) - - self._registerView(self.config.derive_view(view), '', - IViewClassifier, IRequest, None) - exception_view = DummyView(None) - self._registerView(self.config.derive_view(exception_view), '', - IExceptionViewClassifier, - IRequest, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(ValueError, router, environ, start_response) - - def test_call_route_raises_route_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_view_raises_exception_route_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, IRequest, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron() - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_route_raises_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_route_raises_super_exception_sub_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=SuperException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SubException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(SuperException, router, environ, start_response) - - def test_call_route_raises_sub_exception_super_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class SuperException(Exception): - pass - class SubException(SuperException): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=SubException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, SuperException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_call_route_raises_exception_another_exception_view(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class MyException(Exception): - pass - class AnotherException(Exception): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=MyException) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, AnotherException) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(MyException, router, environ, start_response) - - def test_call_route_raises_exception_view_specializing(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - IRequest, RuntimeError) - response_spec = DummyResponse() - response_spec.app_iter = ["Hello, special world"] - exception_view_spec = DummyView(response_spec) - self._registerView(exception_view_spec, '', IExceptionViewClassifier, - req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, special world"]) - - def test_call_route_raises_exception_view_another_route(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - another_req_iface = self._registerRouteRequest('bar') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=RuntimeError) - self._registerView(view, '', IViewClassifier, req_iface, None) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view = DummyView(response) - self._registerView(exception_view, '', IExceptionViewClassifier, - another_req_iface, RuntimeError) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_view_raises_exception_view_route(self): - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - req_iface = self._registerRouteRequest('foo') - response = DummyResponse() - exception_response = DummyResponse() - exception_response.app_iter = ["Hello, world"] - view = DummyView(response, raise_exception=RuntimeError) - exception_view = DummyView(exception_response) - environ = self._makeEnviron() - self._registerView(view, '', IViewClassifier, IRequest, None) - self._registerView(exception_view, '', IExceptionViewClassifier, - req_iface, RuntimeError) - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(RuntimeError, router, environ, start_response) - - def test_call_view_raises_predicate_mismatch(self): - from pyramid.exceptions import PredicateMismatch - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequest - view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) - self._registerView(view, '', IViewClassifier, IRequest, None) - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(PredicateMismatch, router, environ, start_response) - - def test_call_view_predicate_mismatch_doesnt_hide_views(self): - from pyramid.exceptions import PredicateMismatch - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequest, IResponse - from pyramid.response import Response - class BaseContext: - pass - class DummyContext(BaseContext): - pass - context = DummyContext() - self._registerTraverserFactory(context) - view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) - self._registerView(view, '', IViewClassifier, IRequest, - DummyContext) - good_view = DummyView('abc') - self._registerView(self.config.derive_view(good_view), - '', IViewClassifier, IRequest, BaseContext) - router = self._makeOne() - def make_response(s): - return Response(s) - router.registry.registerAdapter(make_response, (str,), IResponse) - environ = self._makeEnviron() - start_response = DummyStartResponse() - app_iter = router(environ, start_response) - self.assertEqual(app_iter, [b'abc']) - - def test_call_view_multiple_predicate_mismatches_dont_hide_views(self): - from pyramid.exceptions import PredicateMismatch - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequest, IResponse - from pyramid.response import Response - from zope.interface import Interface, implementer - class IBaseContext(Interface): - pass - class IContext(IBaseContext): - pass - @implementer(IContext) - class DummyContext: - pass - context = DummyContext() - self._registerTraverserFactory(context) - view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch) - self._registerView(view1, '', IViewClassifier, IRequest, - DummyContext) - view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch) - self._registerView(view2, '', IViewClassifier, IRequest, - IContext) - good_view = DummyView('abc') - self._registerView(self.config.derive_view(good_view), - '', IViewClassifier, IRequest, IBaseContext) - router = self._makeOne() - def make_response(s): - return Response(s) - router.registry.registerAdapter(make_response, (str,), IResponse) - environ = self._makeEnviron() - start_response = DummyStartResponse() - app_iter = router(environ, start_response) - self.assertEqual(app_iter, [b'abc']) - - def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self): - from pyramid.exceptions import PredicateMismatch - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IRequest - from zope.interface import Interface, implementer - class IContext(Interface): - pass - class IOtherContext(Interface): - pass - @implementer(IContext) - class DummyContext: - pass - context = DummyContext() - self._registerTraverserFactory(context) - view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) - self._registerView(view, '', IViewClassifier, IRequest, - DummyContext) - please_dont_call_me_view = DummyView('abc') - self._registerView(self.config.derive_view(please_dont_call_me_view), - '', IViewClassifier, IRequest, IOtherContext) - router = self._makeOne() - environ = self._makeEnviron() - router = self._makeOne() - start_response = DummyStartResponse() - self.assertRaises(PredicateMismatch, router, environ, start_response) - - def test_custom_execution_policy(self): - from pyramid.interfaces import IExecutionPolicy - from pyramid.request import Request - from pyramid.response import Response - registry = self.config.registry - def dummy_policy(environ, router): - return Response(status=200, body=b'foo') - registry.registerUtility(dummy_policy, IExecutionPolicy) - router = self._makeOne() - resp = Request.blank('/').get_response(router) - self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.body, b'foo') - - def test_execution_policy_handles_exception(self): - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IExceptionViewClassifier - from pyramid.interfaces import IRequest - class Exception1(Exception): - pass - class Exception2(Exception): - pass - req_iface = self._registerRouteRequest('foo') - self._connectRoute('foo', 'archives/:action/:article', None) - view = DummyView(DummyResponse(), raise_exception=Exception1) - self._registerView(view, '', IViewClassifier, req_iface, None) - exception_view1 = DummyView(DummyResponse(), - raise_exception=Exception2) - self._registerView(exception_view1, '', IExceptionViewClassifier, - IRequest, Exception1) - response = DummyResponse() - response.app_iter = ["Hello, world"] - exception_view2 = DummyView(response) - self._registerView(exception_view2, '', IExceptionViewClassifier, - IRequest, Exception2) - environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') - start_response = DummyStartResponse() - router = self._makeOne() - result = router(environ, start_response) - self.assertEqual(result, ["Hello, world"]) - - def test_request_context_with_statement(self): - from pyramid.threadlocal import get_current_request - from pyramid.interfaces import IExecutionPolicy - from pyramid.request import Request - from pyramid.response import Response - registry = self.config.registry - result = [] - def dummy_policy(environ, router): - with router.request_context(environ): - result.append(get_current_request()) - result.append(get_current_request()) - return Response(status=200, body=b'foo') - registry.registerUtility(dummy_policy, IExecutionPolicy) - router = self._makeOne() - resp = Request.blank('/test_path').get_response(router) - self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.body, b'foo') - self.assertEqual(result[0].path_info, '/test_path') - self.assertEqual(result[1], None) - - def test_request_context_manually(self): - from pyramid.threadlocal import get_current_request - from pyramid.interfaces import IExecutionPolicy - from pyramid.request import Request - from pyramid.response import Response - registry = self.config.registry - result = [] - def dummy_policy(environ, router): - ctx = router.request_context(environ) - ctx.begin() - result.append(get_current_request()) - ctx.end() - result.append(get_current_request()) - return Response(status=200, body=b'foo') - registry.registerUtility(dummy_policy, IExecutionPolicy) - router = self._makeOne() - resp = Request.blank('/test_path').get_response(router) - self.assertEqual(resp.status_code, 200) - self.assertEqual(resp.body, b'foo') - self.assertEqual(result[0].path_info, '/test_path') - self.assertEqual(result[1], None) - -class DummyPredicate(object): - def __call__(self, info, request): - return True - def text(self): - return 'predicate' - -class DummyContext: - pass - -class DummyView: - def __init__(self, response, raise_exception=None): - self.response = response - self.raise_exception = raise_exception - - def __call__(self, context, request): - self.context = context - self.request = request - if self.raise_exception is not None: - raise self.raise_exception - return self.response - -class DummyRootFactory: - def __init__(self, root): - self.root = root - - def __call__(self, environ): - return self.root - -class DummyStartResponse: - status = () - headers = () - def __call__(self, status, headers): - self.status = status - self.headers = headers - -from pyramid.interfaces import IResponse -from zope.interface import implementer - -@implementer(IResponse) -class DummyResponse(object): - headerlist = () - app_iter = () - environ = None - def __init__(self, status='200 OK'): - self.status = status - - def __call__(self, environ, start_response): - self.environ = environ - start_response(self.status, self.headerlist) - return self.app_iter - -class DummyAuthenticationPolicy: - pass - -class DummyLogger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - -def exc_raised(exc, func, *arg, **kw): - try: - func(*arg, **kw) - except exc as e: - return e - else: - raise AssertionError('%s not raised' % exc) # pragma: no cover - - diff --git a/src/pyramid/tests/test_scaffolds/__init__.py b/src/pyramid/tests/test_scaffolds/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/src/pyramid/tests/test_scaffolds/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/.badfile b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/.badfile deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl deleted file mode 100644 index d763b2435..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl +++ /dev/null @@ -1,12 +0,0 @@ -from pyramid.config import Configurator -from {{package}}.resources import Root - -def main(global_config, **settings): - """ This function returns a Pyramid WSGI application. - """ - config = Configurator(root_factory=Root, settings=settings) - config.add_view('{{package}}.views.my_view', - context='{{package}}:resources.Root', - renderer='{{package}}:templates/mytemplate.pt') - config.add_static_view('static', '{{package}}:static', cache_max_age=3600) - return config.make_wsgi_app() diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/resources.py b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/resources.py deleted file mode 100644 index 3d811895c..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/resources.py +++ /dev/null @@ -1,3 +0,0 @@ -class Root(object): - def __init__(self, request): - self.request = request diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico deleted file mode 100644 index 71f837c9e..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png deleted file mode 100644 index 1fbc873da..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png deleted file mode 100644 index 0596f2020..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css deleted file mode 100644 index b7c8493d8..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css +++ /dev/null @@ -1,8 +0,0 @@ -* html img, -* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", -this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), -this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", -this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) -);} -#wrap{display:table;height:100%} diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png deleted file mode 100644 index 2369cfb7d..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css deleted file mode 100644 index c54499ddd..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css +++ /dev/null @@ -1,65 +0,0 @@ -html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ -vertical-align:baseline;background:transparent;} -body{line-height:1;} -ol,ul{list-style:none;} -blockquote,q{quotes:none;} -blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} -:focus{outline:0;} -ins{text-decoration:none;} -del{text-decoration:line-through;} -table{border-collapse:collapse;border-spacing:0;} -sub{vertical-align:sub;font-size:smaller;line-height:normal;} -sup{vertical-align:super;font-size:smaller;line-height:normal;} -ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} -ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} -li{display:list-item;} -ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} -ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} -ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} -.hidden{display:none;} -p{line-height:1.5em;} -h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} -h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} -h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} -h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} -html,body{width:100%;height:100%;} -body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} -a{color:#1b61d6;text-decoration:none;} -a:hover{color:#e88f00;text-decoration:underline;} -body h1, -body h2, -body h3, -body h4, -body h5, -body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} -#wrap{min-height:100%;} -#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} -#header{background:#000000;top:0;font-size:14px;} -#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} -.header,.footer{width:750px;margin-right:auto;margin-left:auto;} -.wrapper{width:100%} -#top,#top-small,#bottom{width:100%;} -#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} -#bottom{color:#222;background-color:#ffffff;} -.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} -.top{padding-top:40px;} -.top-small{padding-top:10px;} -#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} -.app-welcome{margin-top:25px;} -.app-name{color:#000000;font-weight:bold;} -.bottom{padding-top:50px;} -#left{width:350px;float:left;padding-right:25px;} -#right{width:350px;float:right;padding-left:25px;} -.align-left{text-align:left;} -.align-right{text-align:right;} -.align-center{text-align:center;} -ul.links{margin:0;padding:0;} -ul.links li{list-style-type:none;font-size:14px;} -form{border-style:none;} -fieldset{border-style:none;} -input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} -input[type=text],input[type=password]{width:205px;} -input[type=submit]{background-color:#ddd;font-weight:bold;} -/*Opera Fix*/ -body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png deleted file mode 100644 index a5bc0ade7..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png deleted file mode 100644 index 347e05549..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif deleted file mode 100644 index 0341802e5..000000000 Binary files a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif and /dev/null differ diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl deleted file mode 100644 index f4d98ec29..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl +++ /dev/null @@ -1,76 +0,0 @@ - - - - The Pyramid Web Framework - - - - - - - - - - -
-
-
-
pyramid
-
-
-
-
-

- Welcome to ${project}, an application generated by
- the Pyramid Web Framework. -

-
-
-
-
-
-

Search documentation

-
- - -
-
- -
-
-
- - - diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl deleted file mode 100644 index 1627bf015..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl +++ /dev/null @@ -1,16 +0,0 @@ -import unittest - -from pyramid import testing - -class ViewTests(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_my_view(self): - from {{package}}.views import my_view - request = testing.DummyRequest() - info = my_view(request) - self.assertEqual(info['project'], '{{project}}') diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl deleted file mode 100644 index 12ed8832d..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl +++ /dev/null @@ -1,2 +0,0 @@ -def my_view(request): - return {'project':'{{project}}'} diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl deleted file mode 100644 index 35a34f332..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl +++ /dev/null @@ -1,4 +0,0 @@ -0.0 ---- - -- Initial version diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl deleted file mode 100644 index 0ff6eb7a0..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl +++ /dev/null @@ -1,2 +0,0 @@ -include *.txt *.ini *.cfg *.rst -recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl deleted file mode 100644 index 40f98d14a..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl +++ /dev/null @@ -1 +0,0 @@ -{{project}} README diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl deleted file mode 100644 index 01c504f99..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl +++ /dev/null @@ -1,45 +0,0 @@ -[app:main] -use = egg:{{project}} - -pyramid.reload_templates = true -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.debug_templates = true -pyramid.default_locale_name = en -pyramid.includes = pyramid_debugtoolbar - -[server:main] -use = egg:pyramid#wsgiref -listen = *:6543 - -# Begin logging configuration - -[loggers] -keys = root, {{package_logger}} - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = INFO -handlers = console - -[logger_{{package_logger}}] -level = DEBUG -handlers = -qualname = {{package}} - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl deleted file mode 100644 index becd3aa76..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl +++ /dev/null @@ -1,44 +0,0 @@ -[app:main] -use = egg:{{project}} - -pyramid.reload_templates = false -pyramid.debug_authorization = false -pyramid.debug_notfound = false -pyramid.debug_routematch = false -pyramid.debug_templates = false -pyramid.default_locale_name = en - -[server:main] -use = egg:pyramid#wsgiref -listen = *:6543 - -# Begin logging configuration - -[loggers] -keys = root, {{package_logger}} - -[handlers] -keys = console - -[formatters] -keys = generic - -[logger_root] -level = WARN -handlers = console - -[logger_{{package_logger}}] -level = WARN -handlers = -qualname = {{package}} - -[handler_console] -class = StreamHandler -args = (sys.stderr,) -level = NOTSET -formatter = generic - -[formatter_generic] -format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s - -# End logging configuration diff --git a/src/pyramid/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl b/src/pyramid/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl deleted file mode 100644 index ee9fd5fda..000000000 --- a/src/pyramid/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl +++ /dev/null @@ -1,38 +0,0 @@ -import os - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(here, 'README.txt')) as f: - README = f.read() -with open(os.path.join(here, 'CHANGES.txt')) as f: - CHANGES = f.read() - -requires = ['pyramid', 'pyramid_debugtoolbar'] - -setup(name='{{project}}', - version='0.0', - description='{{project}}', - long_description=README + '\n\n' + CHANGES, - classifiers=[ - "Programming Language :: Python", - "Framework :: Pylons", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", - ], - author='', - author_email='', - url='', - keywords='web pyramid pylons', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - install_requires=requires, - tests_require=requires, - test_suite="{{package}}", - entry_points = """\ - [paste.app_factory] - main = {{package}}:main - """, - ) - diff --git a/src/pyramid/tests/test_scaffolds/test_copydir.py b/src/pyramid/tests/test_scaffolds/test_copydir.py deleted file mode 100644 index 1e92b3c36..000000000 --- a/src/pyramid/tests/test_scaffolds/test_copydir.py +++ /dev/null @@ -1,455 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest -import os -import pkg_resources - -class Test_copy_dir(unittest.TestCase): - def setUp(self): - import tempfile - from pyramid.compat import NativeIO - self.dirname = tempfile.mkdtemp() - self.out = NativeIO() - self.fixturetuple = ('pyramid.tests.test_scaffolds', - 'fixture_scaffold') - - def tearDown(self): - import shutil - shutil.rmtree(self.dirname, ignore_errors=True) - self.out.close() - - def _callFUT(self, *arg, **kw): - kw['out_'] = self.out - from pyramid.scaffolds.copydir import copy_dir - return copy_dir(*arg, **kw) - - def test_copy_source_as_pkg_resource(self): - vars = {'package':'mypackage'} - self._callFUT(self.fixturetuple, - self.dirname, - vars, - 1, False, - template_renderer=dummy_template_renderer) - result = self.out.getvalue() - self.assertTrue('Creating' in result) - self.assertTrue( - 'Copying fixture_scaffold/+package+/__init__.py_tmpl to' in result) - source = pkg_resources.resource_filename( - 'pyramid.tests.test_scaffolds', - 'fixture_scaffold/+package+/__init__.py_tmpl') - target = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(target, 'r') as f: - tcontent = f.read() - with open(source, 'r') as f: - scontent = f.read() - self.assertEqual(scontent, tcontent) - - def test_copy_source_as_dirname(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - self._callFUT(source, - self.dirname, - vars, - 1, False, - template_renderer=dummy_template_renderer) - result = self.out.getvalue() - self.assertTrue('Creating' in result) - self.assertTrue('Copying __init__.py_tmpl to' in result) - source = pkg_resources.resource_filename( - 'pyramid.tests.test_scaffolds', - 'fixture_scaffold/+package+/__init__.py_tmpl') - target = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(target, 'r') as f: - tcontent = f.read() - with open(source, 'r') as f: - scontent = f.read() - self.assertEqual(scontent, tcontent) - - def test_content_is_same_message(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - self._callFUT(source, - self.dirname, - vars, - 2, False, - template_renderer=dummy_template_renderer) - self._callFUT(source, - self.dirname, - vars, - 2, False, - template_renderer=dummy_template_renderer) - result = self.out.getvalue() - self.assertTrue('%s already exists (same content)' % \ - os.path.join(self.dirname, 'mypackage', '__init__.py') in result) - - def test_direxists_message(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - # if not os.path.exists(self.dirname): - # os.mkdir(self.dirname) - self._callFUT(source, - self.dirname, - vars, - 2, False, - template_renderer=dummy_template_renderer) - result = self.out.getvalue() - self.assertTrue('Directory %s exists' % self.dirname in result, result) - - def test_overwrite_false(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - self._callFUT(source, - self.dirname, - vars, - 1, False, - overwrite=False, - template_renderer=dummy_template_renderer) - # toplevel file - toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(toplevel, 'w') as f: - f.write('These are the words you are looking for.') - # sub directory file - sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') - with open(sub, 'w') as f: - f.write('These are the words you are looking for.') - self._callFUT(source, - self.dirname, - vars, - 1, False, - overwrite=False, - template_renderer=dummy_template_renderer) - with open(toplevel, 'r') as f: - tcontent = f.read() - self.assertEqual('These are the words you are looking for.', tcontent) - with open(sub, 'r') as f: - tcontent = f.read() - self.assertEqual('These are the words you are looking for.', tcontent) - - def test_overwrite_true(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - self._callFUT(source, - self.dirname, - vars, - 1, False, - overwrite=True, - template_renderer=dummy_template_renderer) - # toplevel file - toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(toplevel, 'w') as f: - f.write('These are not the words you are looking for.') - # sub directory file - sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') - with open(sub, 'w') as f: - f.write('These are not the words you are looking for.') - self._callFUT(source, - self.dirname, - vars, - 1, False, - overwrite=True, - template_renderer=dummy_template_renderer) - with open(toplevel, 'r') as f: - tcontent = f.read() - self.assertNotEqual('These are not the words you are looking for.', tcontent) - with open(sub, 'r') as f: - tcontent = f.read() - self.assertNotEqual('These are not the words you are looking for.', tcontent) - - def test_detect_SkipTemplate(self): - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - def dummy_template_renderer(*args, **kwargs): - from pyramid.scaffolds.copydir import SkipTemplate - raise SkipTemplate - self._callFUT(source, - self.dirname, - vars, - 1, False, - template_renderer=dummy_template_renderer) - - def test_query_interactive(self): - from pyramid.scaffolds import copydir - vars = {'package':'mypackage'} - source = pkg_resources.resource_filename(*self.fixturetuple) - self._callFUT(source, - self.dirname, - vars, - 1, False, - overwrite=False, - template_renderer=dummy_template_renderer) - target = os.path.join(self.dirname, 'mypackage', '__init__.py') - with open(target, 'w') as f: - f.write('These are not the words you are looking for.') - # We need query_interactive to return False in order to force - # execution of a branch - original_code_object = copydir.query_interactive - copydir.query_interactive = lambda *args, **kwargs: False - self._callFUT(source, - self.dirname, - vars, - 1, False, - interactive=True, - overwrite=False, - template_renderer=dummy_template_renderer) - copydir.query_interactive = original_code_object - -class Test_raise_SkipTemplate(unittest.TestCase): - - def _callFUT(self, *arg, **kw): - from pyramid.scaffolds.copydir import skip_template - return skip_template(*arg, **kw) - - def test_raise_SkipTemplate(self): - from pyramid.scaffolds.copydir import SkipTemplate - self.assertRaises(SkipTemplate, - self._callFUT, True, "exc-message") - -class Test_makedirs(unittest.TestCase): - - def _callFUT(self, *arg, **kw): - from pyramid.scaffolds.copydir import makedirs - return makedirs(*arg, **kw) - - def test_makedirs_parent_dir(self): - import shutil - import tempfile - tmpdir = tempfile.mkdtemp() - target = os.path.join(tmpdir, 'nonexistent_subdir') - self._callFUT(target, 2, None) - shutil.rmtree(tmpdir) - - def test_makedirs_no_parent_dir(self): - import shutil - import tempfile - tmpdir = tempfile.mkdtemp() - target = os.path.join(tmpdir, 'nonexistent_subdir', 'non2') - self._callFUT(target, 2, None) - shutil.rmtree(tmpdir) - -class Test_support_functions(unittest.TestCase): - - def _call_html_quote(self, *arg, **kw): - from pyramid.scaffolds.copydir import html_quote - return html_quote(*arg, **kw) - - def _call_url_quote(self, *arg, **kw): - from pyramid.scaffolds.copydir import url_quote - return url_quote(*arg, **kw) - - def _call_test(self, *arg, **kw): - from pyramid.scaffolds.copydir import test - return test(*arg, **kw) - - def test_html_quote(self): - import string - s = None - self.assertEqual(self._call_html_quote(s), '') - s = string.ascii_letters - self.assertEqual(self._call_html_quote(s), s) - s = "Λεμεσός" - self.assertEqual(self._call_url_quote(s), - "%CE%9B%CE%B5%CE%BC%CE%B5%CF%83%CF%8C%CF%82") - - def test_url_quote(self): - import string - s = None - self.assertEqual(self._call_url_quote(s), '') - s = string.ascii_letters - self.assertEqual(self._call_url_quote(s), s) - s = "Λεμεσός" - self.assertEqual(self._call_url_quote(s), - "%CE%9B%CE%B5%CE%BC%CE%B5%CF%83%CF%8C%CF%82") - - def test_test(self): - conf = True - true_cond = "faked" - self.assertEqual(self._call_test( - conf, true_cond, false_cond=None), "faked") - conf = False - self.assertEqual(self._call_test( - conf, true_cond, false_cond="alsofaked"), "alsofaked") - - -class Test_should_skip_file(unittest.TestCase): - - def _callFUT(self, *arg, **kw): - from pyramid.scaffolds.copydir import should_skip_file - return should_skip_file(*arg, **kw) - - def test_should_skip_dot_hidden_file(self): - self.assertEqual( - self._callFUT('.a_filename'), - 'Skipping hidden file %(filename)s') - - def test_should_skip_backup_file(self): - for name in ('a_filename~', 'a_filename.bak'): - self.assertEqual( - self._callFUT(name), - 'Skipping backup file %(filename)s') - - def test_should_skip_bytecompiled_file(self): - for name in ('afilename.pyc', 'afilename.pyo'): - extension = os.path.splitext(name)[1] - self.assertEqual( - self._callFUT(name), - 'Skipping %s file ' % extension + '%(filename)s') - - def test_should_skip_jython_class_file(self): - self.assertEqual( - self._callFUT('afilename$py.class'), - 'Skipping $py.class file %(filename)s') - - def test_should_skip_version_control_directory(self): - for name in ('CVS', '_darcs'): - self.assertEqual( - self._callFUT(name), - 'Skipping version control directory %(filename)s') - - def test_valid_file_is_not_skipped(self): - self.assertEqual( - self._callFUT('a_filename'), None) - -class RawInputMockObject( object ): - count = 0 - def __init__( self, fake_input ): - self.input= fake_input - self.count = 0 - def __call__( self, prompt ): - # Don't cycle endlessly. - self.count += 1 - if self.count > 1: - return 'y' - else: - return self.input - -class Test_query_interactive(unittest.TestCase): - - def setUp(self): - import tempfile - from pyramid.compat import NativeIO - self.dirname = tempfile.mkdtemp() - self.out = NativeIO() - self.fixturetuple = ('pyramid.tests.test_scaffolds', - 'fixture_scaffold') - self.src_content = """\ -These are not the droids -that you are looking for.""" - self.dest_content = """\ -These are the droids for -whom you are looking; -now you have found them.""" - self.src_fn = os.path.join(self.dirname, 'mypackage', '__init__.py') - self.dest_fn = os.path.join(self.dirname, 'mypackage', '__init__.py') - # query_interactive is only normally executed when the destination - # is discovered to be already occupied by existing files, so ... - # create the required occupancy. - from pyramid.scaffolds.copydir import copy_dir - copy_dir(self.fixturetuple, - self.dirname, - {'package':'mypackage'}, - 0, False, - template_renderer=dummy_template_renderer) - - def tearDown(self): - import shutil - shutil.rmtree(self.dirname, ignore_errors=True) - self.out.close() - - def _callFUT(self, *arg, **kw): - from pyramid.scaffolds.copydir import query_interactive - return query_interactive(*arg, **kw) - - def test_query_interactive_0y(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("y") - self._callFUT(self.src_fn, self.dest_fn, - self.src_content, self.dest_content, - simulate=False, - out_=self.out) - self.assertTrue("Replace" in self.out.getvalue()) - - def test_query_interactive_1n(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("n") - self._callFUT(self.src_fn, self.dest_fn, - self.src_content, - '\n'.join(self.dest_content.split('\n')[:-1]), - simulate=False, - out_=self.out) - self.assertTrue("Replace" in self.out.getvalue()) - - def test_query_interactive_2b(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("b") - with open(os.path.join( - self.dirname, 'mypackage', '__init__.py.bak'), 'w') as fp: - fp.write("") - fp.close() - self._callFUT(self.src_fn, self.dest_fn, - self.dest_content, self.src_content, - simulate=False, - out_=self.out) - self.assertTrue("Backing up" in self.out.getvalue()) - - def test_query_interactive_3d(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("d") - self._callFUT(self.src_fn, self.dest_fn, - self.dest_content, self.src_content, - simulate=False, - out_=self.out) - output = self.out.getvalue() - # The useful text in self.out gets wiped out on the second - # call to raw_input, otherwise the test could be made - # more usefully precise... - # print("3d", output) - # self.assertTrue("@@" in output, output) - self.assertTrue("Replace" in output) - - def test_query_interactive_4dc(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("dc") - self._callFUT(self.src_fn, self.dest_fn, - self.dest_content, self.src_content, - simulate=False, - out_=self.out) - output = self.out.getvalue() - # The useful text in self.out gets wiped out on the second - # call to raw_input, otherwise, the test could be made - # more usefully precise... - # print("4dc", output) - # self.assertTrue("***" in output, output) - self.assertTrue("Replace" in output) - - def test_query_interactive_5allbad(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("all z") - self._callFUT(self.src_fn, self.dest_fn, - self.src_content, self.dest_content, - simulate=False, - out_=self.out) - output = self.out.getvalue() - # The useful text in self.out gets wiped out on the second - # call to raw_input, otherwise the test could be made - # more usefully precise... - # print("5allbad", output) - # self.assertTrue("Responses" in output, output) - self.assertTrue("Replace" in output) - - def test_query_interactive_6all(self): - from pyramid.scaffolds import copydir - copydir.input_ = RawInputMockObject("all b") - self._callFUT(self.src_fn, self.dest_fn, - self.src_content, self.dest_content, - simulate=False, - out_=self.out) - output = self.out.getvalue() - # The useful text in self.out gets wiped out on the second - # call to raw_input, otherwise the test could be made - # more usefully precise... - # print("6all", output) - # self.assertTrue("Responses" in output, output) - self.assertTrue("Replace" in output) - -def dummy_template_renderer(content, v, filename=None): - return content - diff --git a/src/pyramid/tests/test_scaffolds/test_init.py b/src/pyramid/tests/test_scaffolds/test_init.py deleted file mode 100644 index f4d1b287a..000000000 --- a/src/pyramid/tests/test_scaffolds/test_init.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest - -class TestPyramidTemplate(unittest.TestCase): - def _makeOne(self): - from pyramid.scaffolds import PyramidTemplate - return PyramidTemplate('name') - - def test_pre(self): - inst = self._makeOne() - vars = {'package':'one'} - inst.pre('command', 'output dir', vars) - self.assertTrue(vars['random_string']) - self.assertEqual(vars['package_logger'], 'one') - - def test_pre_root(self): - inst = self._makeOne() - vars = {'package':'root'} - inst.pre('command', 'output dir', vars) - self.assertTrue(vars['random_string']) - self.assertEqual(vars['package_logger'], 'app') - diff --git a/src/pyramid/tests/test_scaffolds/test_template.py b/src/pyramid/tests/test_scaffolds/test_template.py deleted file mode 100644 index 98f2daf73..000000000 --- a/src/pyramid/tests/test_scaffolds/test_template.py +++ /dev/null @@ -1,155 +0,0 @@ -import unittest - -from pyramid.compat import bytes_ - -class TestTemplate(unittest.TestCase): - def _makeOne(self, name='whatever'): - from pyramid.scaffolds.template import Template - return Template(name) - - def test_render_template_success(self): - inst = self._makeOne() - result = inst.render_template('{{a}} {{b}}', {'a':'1', 'b':'2'}) - self.assertEqual(result, bytes_('1 2')) - - def test_render_template_expr_failure(self): - inst = self._makeOne() - self.assertRaises(AttributeError, inst.render_template, - '{{a.foo}}', {'a':'1', 'b':'2'}) - - def test_render_template_expr_success(self): - inst = self._makeOne() - result = inst.render_template('{{a.lower()}}', {'a':'A'}) - self.assertEqual(result, b'a') - - def test_render_template_expr_success_via_pipe(self): - inst = self._makeOne() - result = inst.render_template('{{b|c|a.lower()}}', {'a':'A'}) - self.assertEqual(result, b'a') - - def test_render_template_expr_success_via_pipe2(self): - inst = self._makeOne() - result = inst.render_template('{{b|a.lower()|c}}', {'a':'A'}) - self.assertEqual(result, b'a') - - def test_render_template_expr_value_is_None(self): - inst = self._makeOne() - result = inst.render_template('{{a}}', {'a':None}) - self.assertEqual(result, b'') - - def test_render_template_with_escaped_double_braces(self): - inst = self._makeOne() - result = inst.render_template('{{a}} {{b}} \{\{a\}\} \{\{c\}\}', {'a':'1', 'b':'2'}) - self.assertEqual(result, bytes_('1 2 {{a}} {{c}}')) - - def test_render_template_with_breaking_escaped_braces(self): - inst = self._makeOne() - result = inst.render_template('{{a}} {{b}} \{\{a\} \{b\}\}', {'a':'1', 'b':'2'}) - self.assertEqual(result, bytes_('1 2 \{\{a\} \{b\}\}')) - - def test_render_template_with_escaped_single_braces(self): - inst = self._makeOne() - result = inst.render_template('{{a}} {{b}} \{a\} \{b', {'a':'1', 'b':'2'}) - self.assertEqual(result, bytes_('1 2 \{a\} \{b')) - - def test_module_dir(self): - import sys - import pkg_resources - package = sys.modules['pyramid.scaffolds.template'] - path = pkg_resources.resource_filename(package.__name__, '') - inst = self._makeOne() - result = inst.module_dir() - self.assertEqual(result, path) - - def test_template_dir__template_dir_is_None(self): - inst = self._makeOne() - self.assertRaises(AssertionError, inst.template_dir) - - def test_template_dir__template_dir_is_tuple(self): - inst = self._makeOne() - inst._template_dir = ('a', 'b') - self.assertEqual(inst.template_dir(), ('a', 'b')) - - def test_template_dir__template_dir_is_not_None(self): - import os - import sys - import pkg_resources - package = sys.modules['pyramid.scaffolds.template'] - path = pkg_resources.resource_filename(package.__name__, '') - inst = self._makeOne() - inst._template_dir ='foo' - result = inst.template_dir() - self.assertEqual(result, os.path.join(path, 'foo')) - - def test_write_files_path_exists(self): - import os - import sys - import pkg_resources - package = sys.modules['pyramid.scaffolds.template'] - path = pkg_resources.resource_filename(package.__name__, '') - inst = self._makeOne() - inst._template_dir = 'foo' - inst.exists = lambda *arg: True - copydir = DummyCopydir() - inst.copydir = copydir - command = DummyCommand() - inst.write_files(command, 'output dir', {'a':1}) - self.assertEqual(copydir.template_dir, os.path.join(path, 'foo')) - self.assertEqual(copydir.output_dir, 'output dir') - self.assertEqual(copydir.vars, {'a':1}) - self.assertEqual(copydir.kw, - {'template_renderer':inst.render_template, - 'indent':1, - 'verbosity':1, - 'simulate':False, - 'overwrite':False, - 'interactive':False, - }) - - def test_write_files_path_missing(self): - L = [] - inst = self._makeOne() - inst._template_dir = 'foo' - inst.exists = lambda *arg: False - inst.out = lambda *arg: None - inst.makedirs = lambda dir: L.append(dir) - copydir = DummyCopydir() - inst.copydir = copydir - command = DummyCommand() - inst.write_files(command, 'output dir', {'a':1}) - self.assertEqual(L, ['output dir']) - - def test_run(self): - L = [] - inst = self._makeOne() - inst._template_dir = 'foo' - inst.exists = lambda *arg: False - inst.out = lambda *arg: None - inst.makedirs = lambda dir: L.append(dir) - copydir = DummyCopydir() - inst.copydir = copydir - command = DummyCommand() - inst.run(command, 'output dir', {'a':1}) - self.assertEqual(L, ['output dir']) - - def test_check_vars(self): - inst = self._makeOne() - self.assertRaises(RuntimeError, inst.check_vars, 'one', 'two') - -class DummyCopydir(object): - def copy_dir(self, template_dir, output_dir, vars, **kw): - self.template_dir = template_dir - self.output_dir = output_dir - self.vars = vars - self.kw = kw - -class DummyArgs(object): - simulate = False - overwrite = False - interactive = False - -class DummyCommand(object): - args = DummyArgs() - verbosity = 1 - - diff --git a/src/pyramid/tests/test_scripting.py b/src/pyramid/tests/test_scripting.py deleted file mode 100644 index ed88bb470..000000000 --- a/src/pyramid/tests/test_scripting.py +++ /dev/null @@ -1,221 +0,0 @@ -import unittest - -class Test_get_root(unittest.TestCase): - def _callFUT(self, app, request=None): - from pyramid.scripting import get_root - return get_root(app, request) - - def _makeRegistry(self): - return DummyRegistry([DummyFactory]) - - def setUp(self): - from pyramid.threadlocal import manager - self.manager = manager - self.default = manager.get() - - def test_it_norequest(self): - registry = self._makeRegistry() - app = DummyApp(registry=registry) - root, closer = self._callFUT(app) - self.assertEqual(dummy_root, root) - pushed = self.manager.get() - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'].registry, registry) - self.assertEqual(pushed['request'].environ['path'], '/') - closer() - self.assertEqual(self.default, self.manager.get()) - - def test_it_withrequest(self): - registry = self._makeRegistry() - app = DummyApp(registry=registry) - request = DummyRequest({}) - root, closer = self._callFUT(app, request) - self.assertEqual(dummy_root, root) - pushed = self.manager.get() - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'], request) - self.assertEqual(pushed['request'].registry, registry) - closer() - self.assertEqual(self.default, self.manager.get()) - -class Test_prepare(unittest.TestCase): - def _callFUT(self, request=None, registry=None): - from pyramid.scripting import prepare - return prepare(request, registry) - - def _makeRegistry(self, L=None): - if L is None: - L = [None, DummyFactory] - return DummyRegistry(L) - - def setUp(self): - from pyramid.threadlocal import manager - self.manager = manager - self.default = manager.get() - - def test_it_no_valid_apps(self): - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, self._callFUT) - - def test_it_norequest(self): - registry = self._makeRegistry([DummyFactory, None, DummyFactory]) - info = self._callFUT(registry=registry) - root, closer, request = info['root'], info['closer'], info['request'] - pushed = self.manager.get() - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'].registry, registry) - self.assertEqual(root.a, (pushed['request'],)) - closer() - self.assertEqual(self.default, self.manager.get()) - self.assertEqual(request.context, root) - - def test_it_withrequest_hasregistry(self): - request = DummyRequest({}) - registry = request.registry = self._makeRegistry() - info = self._callFUT(request=request) - root, closer, request = info['root'], info['closer'], info['request'] - pushed = self.manager.get() - self.assertEqual(pushed['request'], request) - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'].registry, registry) - self.assertEqual(root.a, (request,)) - closer() - self.assertEqual(self.default, self.manager.get()) - self.assertEqual(request.context, root) - self.assertEqual(request.registry, registry) - - def test_it_withrequest_noregistry(self): - request = DummyRequest({}) - registry = self._makeRegistry() - info = self._callFUT(request=request, registry=registry) - root, closer, request = info['root'], info['closer'], info['request'] - closer() - self.assertEqual(request.context, root) - # should be set by prepare - self.assertEqual(request.registry, registry) - - def test_it_with_request_and_registry(self): - request = DummyRequest({}) - registry = request.registry = self._makeRegistry() - info = self._callFUT(request=request, registry=registry) - root, closer, root = info['root'], info['closer'], info['root'] - pushed = self.manager.get() - self.assertEqual(pushed['request'], request) - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'].registry, registry) - self.assertEqual(root.a, (request,)) - closer() - self.assertEqual(self.default, self.manager.get()) - self.assertEqual(request.context, root) - - def test_it_with_request_context_already_set(self): - request = DummyRequest({}) - context = Dummy() - request.context = context - registry = request.registry = self._makeRegistry() - info = self._callFUT(request=request, registry=registry) - root, closer, root = info['root'], info['closer'], info['root'] - closer() - self.assertEqual(request.context, context) - - def test_it_with_extensions(self): - from pyramid.util import InstancePropertyHelper - exts = DummyExtensions() - ext_method = lambda r: 'bar' - name, fn = InstancePropertyHelper.make_property(ext_method, 'foo') - exts.descriptors[name] = fn - request = DummyRequest({}) - registry = request.registry = self._makeRegistry([exts, DummyFactory]) - info = self._callFUT(request=request, registry=registry) - self.assertEqual(request.foo, 'bar') - root, closer = info['root'], info['closer'] - closer() - - def test_it_is_a_context_manager(self): - request = DummyRequest({}) - registry = request.registry = self._makeRegistry() - closer_called = [False] - with self._callFUT(request=request) as info: - root, request = info['root'], info['request'] - pushed = self.manager.get() - self.assertEqual(pushed['request'], request) - self.assertEqual(pushed['registry'], registry) - self.assertEqual(pushed['request'].registry, registry) - self.assertEqual(root.a, (request,)) - orig_closer = info['closer'] - def closer(): - orig_closer() - closer_called[0] = True - info['closer'] = closer - self.assertTrue(closer_called[0]) - self.assertEqual(self.default, self.manager.get()) - self.assertEqual(request.context, root) - self.assertEqual(request.registry, registry) - -class Test__make_request(unittest.TestCase): - def _callFUT(self, path='/', registry=None): - from pyramid.scripting import _make_request - return _make_request(path, registry) - - def _makeRegistry(self): - return DummyRegistry([DummyFactory]) - - def test_it_with_registry(self): - registry = self._makeRegistry() - request = self._callFUT('/', registry) - self.assertEqual(request.environ['path'], '/') - self.assertEqual(request.registry, registry) - - def test_it_with_no_registry(self): - from pyramid.config import global_registries - registry = self._makeRegistry() - global_registries.add(registry) - try: - request = self._callFUT('/hello') - self.assertEqual(request.environ['path'], '/hello') - self.assertEqual(request.registry, registry) - finally: - global_registries.empty() - -class Dummy: - pass - -dummy_root = Dummy() - -class DummyFactory(object): - @classmethod - def blank(cls, path): - req = DummyRequest({'path': path}) - return req - - def __init__(self, *a, **kw): - self.a = a - self.kw = kw - -class DummyRegistry(object): - def __init__(self, utilities): - self.utilities = utilities - - def queryUtility(self, iface, default=None): # pragma: no cover - if self.utilities: - return self.utilities.pop(0) - return default - -class DummyApp: - def __init__(self, registry=None): - if registry: - self.registry = registry - - def root_factory(self, environ): - return dummy_root - -class DummyRequest(object): - matchdict = None - matched_route = None - def __init__(self, environ): - self.environ = environ - -class DummyExtensions: - def __init__(self): - self.descriptors = {} - self.methods = {} diff --git a/src/pyramid/tests/test_scripts/__init__.py b/src/pyramid/tests/test_scripts/__init__.py deleted file mode 100644 index 5bb534f79..000000000 --- a/src/pyramid/tests/test_scripts/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# package diff --git a/src/pyramid/tests/test_scripts/dummy.py b/src/pyramid/tests/test_scripts/dummy.py deleted file mode 100644 index f1ef403f8..000000000 --- a/src/pyramid/tests/test_scripts/dummy.py +++ /dev/null @@ -1,190 +0,0 @@ -class DummyTweens(object): - def __init__(self, implicit, explicit): - self._implicit = implicit - self.explicit = explicit - self.name_to_alias = {} - def implicit(self): - return self._implicit - -class Dummy: - pass - -dummy_root = Dummy() - -class DummyRegistry(object): - settings = {} - def queryUtility(self, iface, default=None, name=''): - return default - -dummy_registry = DummyRegistry() - -class DummyShell(object): - env = {} - help = '' - called = False - dummy_attr = 1 - - def __call__(self, env, help): - self.env = env - self.help = help - self.called = True - self.env['request'].dummy_attr = self.dummy_attr - -class DummyInteractor: - def __call__(self, banner, local): - self.banner = banner - self.local = local - -class DummyApp: - def __init__(self): - self.registry = dummy_registry - -class DummyMapper(object): - def __init__(self, *routes): - self.routes = routes - - def get_routes(self, include_static=False): - return self.routes - -class DummyRoute(object): - def __init__(self, name, pattern, factory=None, - matchdict=None, predicate=None): - self.name = name - self.path = pattern - self.pattern = pattern - self.factory = factory - self.matchdict = matchdict - self.predicates = [] - if predicate is not None: - self.predicates = [predicate] - - def match(self, route): - return self.matchdict - -class DummyRequest: - application_url = 'http://example.com:5432' - script_name = '' - def __init__(self, environ): - self.environ = environ - self.matchdict = {} - -class DummyView(object): - def __init__(self, **attrs): - self.__request_attrs__ = attrs - - def view(context, request): pass - -from zope.interface import implementer -from pyramid.interfaces import IMultiView -@implementer(IMultiView) -class DummyMultiView(object): - - def __init__(self, *views, **attrs): - self.views = [(None, view, None) for view in views] - self.__request_attrs__ = attrs - -class DummyCloser(object): - def __call__(self): - self.called = True - -class DummyBootstrap(object): - def __init__(self, app=None, registry=None, request=None, root=None, - root_factory=None, closer=None): - self.app = app or DummyApp() - if registry is None: - registry = DummyRegistry() - self.registry = registry - if request is None: - request = DummyRequest({}) - self.request = request - if root is None: - root = Dummy() - self.root = root - if root_factory is None: - root_factory = Dummy() - self.root_factory = root_factory - if closer is None: - closer = DummyCloser() - self.closer = closer - - def __call__(self, *a, **kw): - self.a = a - self.kw = kw - registry = kw.get('registry', self.registry) - request = kw.get('request', self.request) - request.registry = registry - return { - 'app': self.app, - 'registry': registry, - 'request': request, - 'root': self.root, - 'root_factory': self.root_factory, - 'closer': self.closer, - } - - -class DummyEntryPoint(object): - def __init__(self, name, module): - self.name = name - self.module = module - - def load(self): - return self.module - - -class DummyPkgResources(object): - def __init__(self, entry_point_values): - self.entry_points = [] - - for name, module in entry_point_values.items(): - self.entry_points.append(DummyEntryPoint(name, module)) - - def iter_entry_points(self, name): - return self.entry_points - - -class dummy_setup_logging(object): - def __call__(self, config_uri, global_conf): - self.config_uri = config_uri - self.defaults = global_conf - - -class DummyLoader(object): - def __init__(self, settings=None, app_settings=None, app=None, server=None): - if not settings: - settings = {} - if not app_settings: - app_settings = {} - self.settings = settings - self.app_settings = app_settings - self.app = app - self.server = server - self.calls = [] - - def __call__(self, uri): - import plaster - self.uri = plaster.parse_uri(uri) - return self - - def add_call(self, op, name, defaults): - self.calls.append({'op': op, 'name': name, 'defaults': defaults}) - - def get_settings(self, name=None, defaults=None): - self.add_call('settings', name, defaults) - return self.settings.get(name, {}) - - def get_wsgi_app(self, name=None, defaults=None): - self.add_call('app', name, defaults) - return self.app - - def get_wsgi_app_settings(self, name=None, defaults=None): - self.add_call('app_settings', name, defaults) - return self.app_settings - - def get_wsgi_server(self, name=None, defaults=None): - self.add_call('server', name, defaults) - return self.server - - def setup_logging(self, defaults): - self.add_call('logging', None, defaults) - self.defaults = defaults diff --git a/src/pyramid/tests/test_scripts/pystartup.txt b/src/pyramid/tests/test_scripts/pystartup.txt deleted file mode 100644 index c62c4ca74..000000000 --- a/src/pyramid/tests/test_scripts/pystartup.txt +++ /dev/null @@ -1,3 +0,0 @@ -# this file has a .txt extension to avoid coverage reports -# since it is not imported but rather the contents are read and exec'd -foo = 1 diff --git a/src/pyramid/tests/test_scripts/test_common.py b/src/pyramid/tests/test_scripts/test_common.py deleted file mode 100644 index 60741db92..000000000 --- a/src/pyramid/tests/test_scripts/test_common.py +++ /dev/null @@ -1,13 +0,0 @@ -import unittest - -class TestParseVars(unittest.TestCase): - def test_parse_vars_good(self): - from pyramid.scripts.common import parse_vars - vars = ['a=1', 'b=2'] - result = parse_vars(vars) - self.assertEqual(result, {'a': '1', 'b': '2'}) - - def test_parse_vars_bad(self): - from pyramid.scripts.common import parse_vars - vars = ['a'] - self.assertRaises(ValueError, parse_vars, vars) diff --git a/src/pyramid/tests/test_scripts/test_pcreate.py b/src/pyramid/tests/test_scripts/test_pcreate.py deleted file mode 100644 index 0286614ce..000000000 --- a/src/pyramid/tests/test_scripts/test_pcreate.py +++ /dev/null @@ -1,309 +0,0 @@ -import unittest - - -class TestPCreateCommand(unittest.TestCase): - def setUp(self): - from pyramid.compat import NativeIO - self.out_ = NativeIO() - - def out(self, msg): - self.out_.write(msg) - - def _getTargetClass(self): - from pyramid.scripts.pcreate import PCreateCommand - return PCreateCommand - - def _makeOne(self, *args, **kw): - effargs = ['pcreate'] - effargs.extend(args) - tgt_class = kw.pop('target_class', self._getTargetClass()) - cmd = tgt_class(effargs, **kw) - cmd.out = self.out - return cmd - - def test_run_show_scaffolds_exist(self): - cmd = self._makeOne('-l') - result = cmd.run() - self.assertEqual(result, 0) - out = self.out_.getvalue() - self.assertTrue(out.count('Available scaffolds')) - - def test_run_show_scaffolds_none_exist(self): - cmd = self._makeOne('-l') - cmd.scaffolds = [] - result = cmd.run() - self.assertEqual(result, 0) - out = self.out_.getvalue() - self.assertTrue(out.count('No scaffolds available')) - - def test_run_no_scaffold_no_args(self): - cmd = self._makeOne(quiet=True) - result = cmd.run() - self.assertEqual(result, 2) - - def test_run_no_scaffold_name(self): - cmd = self._makeOne('dummy') - result = cmd.run() - self.assertEqual(result, 2) - out = self.out_.getvalue() - self.assertTrue(out.count( - 'You must provide at least one scaffold name')) - - def test_no_project_name(self): - cmd = self._makeOne('-s', 'dummy') - result = cmd.run() - self.assertEqual(result, 2) - out = self.out_.getvalue() - self.assertTrue(out.count('You must provide a project name')) - - def test_unknown_scaffold_name(self): - cmd = self._makeOne('-s', 'dummyXX', 'distro') - result = cmd.run() - self.assertEqual(result, 2) - out = self.out_.getvalue() - self.assertTrue(out.count('Unavailable scaffolds')) - - def test_known_scaffold_single_rendered(self): - import os - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - - def test_scaffold_with_package_name(self): - import os - cmd = self._makeOne('-s', 'dummy', '--package-name', 'dummy_package', - 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - - self.assertEqual(result, 0) - self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'dummy_package', - 'package': 'dummy_package', 'pyramid_version': '0.1', - 'pyramid_docs_branch':'0.1-branch'}) - - - def test_scaffold_with_hyphen_in_project_name(self): - import os - cmd = self._makeOne('-s', 'dummy', 'Distro-') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro-')) - ) - self.assertEqual( - scaffold.vars, - {'project': 'Distro-', 'egg': 'Distro_', 'package': 'distro_', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - - def test_known_scaffold_absolute_path(self): - import os - path = os.path.abspath('Distro') - cmd = self._makeOne('-s', 'dummy', path) - cmd.pyramid_dist = DummyDist("0.1") - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - - def test_known_scaffold_multiple_rendered(self): - import os - cmd = self._makeOne('-s', 'dummy1', '-s', 'dummy2', 'Distro') - scaffold1 = DummyScaffold('dummy1') - scaffold2 = DummyScaffold('dummy2') - cmd.scaffolds = [scaffold1, scaffold2] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold1.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) - self.assertEqual( - scaffold1.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - self.assertEqual( - scaffold2.output_dir, - os.path.normpath(os.path.join(os.getcwd(), 'Distro')) - ) - self.assertEqual( - scaffold2.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - - def test_known_scaffold_with_path_as_project_target_rendered(self): - import os - cmd = self._makeOne('-s', 'dummy', '/tmp/foo/Distro/') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.output_dir, - os.path.normpath(os.path.join(os.getcwd(), '/tmp/foo/Distro')) - ) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) - - - def test_scaffold_with_prod_pyramid_version(self): - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.2") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2', 'pyramid_docs_branch':'0.2-branch'}) - - def test_scaffold_with_prod_pyramid_long_version(self): - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.2.1") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.2.1', 'pyramid_docs_branch':'0.2-branch'}) - - def test_scaffold_with_prod_pyramid_unparsable_version(self): - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("abc") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': 'abc', 'pyramid_docs_branch':'latest'}) - - def test_scaffold_with_dev_pyramid_version(self): - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.12dev") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.12dev', - 'pyramid_docs_branch': 'master'}) - - def test_scaffold_with_dev_pyramid_long_version(self): - cmd = self._makeOne('-s', 'dummy', 'Distro') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.10.1dev") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', - 'pyramid_version': '0.10.1dev', - 'pyramid_docs_branch': 'master'}) - - def test_confirm_override_conflicting_name(self): - from pyramid.scripts.pcreate import PCreateCommand - class YahInputPCreateCommand(PCreateCommand): - def confirm_bad_name(self, pkg_name): - return True - cmd = self._makeOne('-s', 'dummy', 'Unittest', target_class=YahInputPCreateCommand) - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.10.1dev") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Unittest', 'egg': 'Unittest', 'package': 'unittest', - 'pyramid_version': '0.10.1dev', - 'pyramid_docs_branch': 'master'}) - - def test_force_override_conflicting_name(self): - cmd = self._makeOne('-s', 'dummy', 'Unittest', '--ignore-conflicting-name') - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.10.1dev") - result = cmd.run() - self.assertEqual(result, 0) - self.assertEqual( - scaffold.vars, - {'project': 'Unittest', 'egg': 'Unittest', 'package': 'unittest', - 'pyramid_version': '0.10.1dev', - 'pyramid_docs_branch': 'master'}) - - def test_force_override_site_name(self): - from pyramid.scripts.pcreate import PCreateCommand - class NayInputPCreateCommand(PCreateCommand): - def confirm_bad_name(self, pkg_name): - return False - cmd = self._makeOne('-s', 'dummy', 'Site', target_class=NayInputPCreateCommand) - scaffold = DummyScaffold('dummy') - cmd.scaffolds = [scaffold] - cmd.pyramid_dist = DummyDist("0.10.1dev") - result = cmd.run() - self.assertEqual(result, 2) - - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.pcreate import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['pcreate']) - self.assertEqual(result, 2) - -class DummyScaffold(object): - def __init__(self, name): - self.name = name - - def run(self, command, output_dir, vars): - self.command = command - self.output_dir = output_dir - self.vars = vars - -class DummyDist(object): - def __init__(self, version): - self.version = version diff --git a/src/pyramid/tests/test_scripts/test_pdistreport.py b/src/pyramid/tests/test_scripts/test_pdistreport.py deleted file mode 100644 index e229667c5..000000000 --- a/src/pyramid/tests/test_scripts/test_pdistreport.py +++ /dev/null @@ -1,73 +0,0 @@ -import unittest - -class TestPDistReportCommand(unittest.TestCase): - def _callFUT(self, **kw): - argv = [] - from pyramid.scripts.pdistreport import main - return main(argv, **kw) - - def test_no_dists(self): - def platform(): - return 'myplatform' - pkg_resources = DummyPkgResources() - L = [] - def out(*args): - L.extend(args) - result = self._callFUT(pkg_resources=pkg_resources, platform=platform, - out=out) - self.assertEqual(result, None) - self.assertEqual( - L, - ['Pyramid version:', '1', - 'Platform:', 'myplatform', - 'Packages:'] - ) - - def test_with_dists(self): - def platform(): - return 'myplatform' - working_set = (DummyDistribution('abc'), DummyDistribution('def')) - pkg_resources = DummyPkgResources(working_set) - L = [] - def out(*args): - L.extend(args) - result = self._callFUT(pkg_resources=pkg_resources, platform=platform, - out=out) - self.assertEqual(result, None) - self.assertEqual( - L, - ['Pyramid version:', - '1', - 'Platform:', - 'myplatform', - 'Packages:', - ' ', - 'abc', - '1', - ' ', - '/projects/abc', - ' ', - 'def', - '1', - ' ', - '/projects/def'] - ) - -class DummyPkgResources(object): - def __init__(self, working_set=()): - self.working_set = working_set - - def get_distribution(self, name): - return Version('1') - -class Version(object): - def __init__(self, version): - self.version = version - -class DummyDistribution(object): - def __init__(self, name): - self.project_name = name - self.version = '1' - self.location = '/projects/%s' % name - - diff --git a/src/pyramid/tests/test_scripts/test_prequest.py b/src/pyramid/tests/test_scripts/test_prequest.py deleted file mode 100644 index 75d5cc198..000000000 --- a/src/pyramid/tests/test_scripts/test_prequest.py +++ /dev/null @@ -1,214 +0,0 @@ -import unittest -from pyramid.tests.test_scripts import dummy - -class TestPRequestCommand(unittest.TestCase): - def _getTargetClass(self): - from pyramid.scripts.prequest import PRequestCommand - return PRequestCommand - - def _makeOne(self, argv, headers=None): - cmd = self._getTargetClass()(argv) - - def helloworld(environ, start_request): - self._environ = environ - self._path_info = environ['PATH_INFO'] - start_request('200 OK', headers or []) - return [b'abc'] - self.loader = dummy.DummyLoader(app=helloworld) - self._out = [] - cmd._get_config_loader = self.loader - cmd.out = self.out - return cmd - - def out(self, msg): - self._out.append(msg) - - def test_command_not_enough_args(self): - command = self._makeOne([]) - command.run() - self.assertEqual(self._out, ['You must provide at least two arguments']) - - def test_command_two_args(self): - command = self._makeOne(['', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._path_info, '/') - self.assertEqual(self.loader.uri.path, 'development.ini') - self.assertEqual(self.loader.calls[0]['op'], 'logging') - self.assertEqual(self.loader.calls[1]['op'], 'app') - self.assertEqual(self.loader.calls[1]['name'], None) - self.assertEqual(self._out, ['abc']) - - def test_command_path_doesnt_start_with_slash(self): - command = self._makeOne(['', 'development.ini', 'abc'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._path_info, '/abc') - self.assertEqual(self.loader.uri.path, 'development.ini') - self.assertEqual(self._out, ['abc']) - - def test_command_has_bad_config_header(self): - command = self._makeOne( - ['', '--header=name','development.ini', '/']) - command.run() - self.assertEqual( - self._out[0], - ("Bad --header=name option, value must be in the form " - "'name:value'")) - - def test_command_has_good_header_var(self): - command = self._makeOne( - ['', '--header=name:value','development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._environ['HTTP_NAME'], 'value') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_w_basic_auth(self): - command = self._makeOne( - ['', '--login=user:password', - '--header=name:value','development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._environ['HTTP_NAME'], 'value') - self.assertEqual(self._environ['HTTP_AUTHORIZATION'], - 'Basic dXNlcjpwYXNzd29yZA==') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_has_content_type_header_var(self): - command = self._makeOne( - ['', '--header=content-type:app/foo','development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._environ['CONTENT_TYPE'], 'app/foo') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_has_multiple_header_vars(self): - command = self._makeOne( - ['', - '--header=name:value', - '--header=name2:value2', - 'development.ini', - '/'], - [('Content-Type', 'text/html; charset=UTF-8')] - ) - command.run() - self.assertEqual(self._environ['HTTP_NAME'], 'value') - self.assertEqual(self._environ['HTTP_NAME2'], 'value2') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_get(self): - command = self._makeOne(['', '--method=GET', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'GET') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_post(self): - from pyramid.compat import NativeIO - command = self._makeOne(['', '--method=POST', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - stdin = NativeIO() - command.stdin = stdin - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'POST') - self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') - self.assertEqual(self._environ['wsgi.input'], stdin) - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_put(self): - from pyramid.compat import NativeIO - command = self._makeOne(['', '--method=PUT', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - stdin = NativeIO() - command.stdin = stdin - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'PUT') - self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') - self.assertEqual(self._environ['wsgi.input'], stdin) - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_patch(self): - from pyramid.compat import NativeIO - command = self._makeOne(['', '--method=PATCH', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - stdin = NativeIO() - command.stdin = stdin - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'PATCH') - self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') - self.assertEqual(self._environ['wsgi.input'], stdin) - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_propfind(self): - from pyramid.compat import NativeIO - command = self._makeOne(['', '--method=PROPFIND', 'development.ini', - '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - stdin = NativeIO() - command.stdin = stdin - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'PROPFIND') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_method_options(self): - from pyramid.compat import NativeIO - command = self._makeOne(['', '--method=OPTIONS', 'development.ini', - '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - stdin = NativeIO() - command.stdin = stdin - command.run() - self.assertEqual(self._environ['REQUEST_METHOD'], 'OPTIONS') - self.assertEqual(self._path_info, '/') - self.assertEqual(self._out, ['abc']) - - def test_command_with_query_string(self): - command = self._makeOne(['', 'development.ini', '/abc?a=1&b=2&c'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._environ['QUERY_STRING'], 'a=1&b=2&c') - self.assertEqual(self._path_info, '/abc') - self.assertEqual(self._out, ['abc']) - - def test_command_display_headers(self): - command = self._makeOne( - ['', '--display-headers', 'development.ini', '/'], - [('Content-Type', 'text/html; charset=UTF-8')]) - command.run() - self.assertEqual(self._path_info, '/') - self.assertEqual( - self._out, - ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']) - - def test_command_response_has_no_charset(self): - command = self._makeOne(['', '--method=GET', 'development.ini', '/'], - headers=[('Content-Type', 'image/jpeg')]) - command.run() - self.assertEqual(self._path_info, '/') - - self.assertEqual(self._out, [b'abc']) - - def test_command_method_configures_logging(self): - command = self._makeOne(['', 'development.ini', '/']) - command.run() - self.assertEqual(self.loader.calls[0]['op'], 'logging') - - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.prequest import main - return main(argv, True) - - def test_it(self): - result = self._callFUT(['prequest']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_scripts/test_proutes.py b/src/pyramid/tests/test_scripts/test_proutes.py deleted file mode 100644 index fab5e163e..000000000 --- a/src/pyramid/tests/test_scripts/test_proutes.py +++ /dev/null @@ -1,792 +0,0 @@ -import os -import unittest -from pyramid.tests.test_scripts import dummy - - -class DummyIntrospector(object): - def __init__(self): - self.relations = {} - self.introspectables = {} - - def get(self, name, discrim): - pass - - -class TestPRoutesCommand(unittest.TestCase): - def _getTargetClass(self): - from pyramid.scripts.proutes import PRoutesCommand - return PRoutesCommand - - def _makeOne(self): - cmd = self._getTargetClass()([]) - cmd.bootstrap = dummy.DummyBootstrap() - cmd.get_config_loader = dummy.DummyLoader() - cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' - - return cmd - - def _makeRegistry(self): - from pyramid.registry import Registry - registry = Registry() - registry.introspector = DummyIntrospector() - return registry - - def _makeConfig(self, *arg, **kw): - from pyramid.config import Configurator - config = Configurator(*arg, **kw) - return config - - def test_good_args(self): - cmd = self._getTargetClass()([]) - cmd.bootstrap = dummy.DummyBootstrap() - cmd.get_config_loader = dummy.DummyLoader() - cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' - cmd.args.config_args = ('a=1',) - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - cmd._get_mapper = lambda *arg: mapper - registry = self._makeRegistry() - cmd.bootstrap = dummy.DummyBootstrap(registry=registry) - L = [] - cmd.out = lambda msg: L.append(msg) - cmd.run() - self.assertTrue('' in ''.join(L)) - - def test_bad_args(self): - cmd = self._getTargetClass()([]) - cmd.bootstrap = dummy.DummyBootstrap() - cmd.get_config_loader = dummy.DummyLoader() - cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' - cmd.args.config_vars = ('a',) - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - cmd._get_mapper = lambda *arg: mapper - - self.assertRaises(ValueError, cmd.run) - - def test_no_routes(self): - command = self._makeOne() - mapper = dummy.DummyMapper() - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L, []) - - def test_no_mapper(self): - command = self._makeOne() - command._get_mapper = lambda *arg:None - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L, []) - - def test_single_route_no_route_registered(self): - command = self._makeOne() - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - registry = self._makeRegistry() - command.bootstrap = dummy.DummyBootstrap(registry=registry) - - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - self.assertEqual(L[-1].split(), ['a', '/a', '', '*']) - - def test_route_with_no_slash_prefix(self): - command = self._makeOne() - route = dummy.DummyRoute('a', 'a') - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - registry = self._makeRegistry() - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - self.assertEqual(L[-1].split(), ['a', '/a', '', '*']) - - def test_single_route_no_views_registered(self): - from zope.interface import Interface - from pyramid.interfaces import IRouteRequest - registry = self._makeRegistry() - - def view():pass - class IMyRoute(Interface): - pass - registry.registerUtility(IMyRoute, IRouteRequest, name='a') - command = self._makeOne() - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - self.assertEqual(L[-1].split()[:3], ['a', '/a', '']) - - def test_single_route_one_view_registered(self): - from zope.interface import Interface - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - registry = self._makeRegistry() - - def view():pass - class IMyRoute(Interface): - pass - registry.registerAdapter(view, - (IViewClassifier, IMyRoute, Interface), - IView, '') - registry.registerUtility(IMyRoute, IRouteRequest, name='a') - command = self._makeOne() - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split()[:3] - self.assertEqual( - compare_to, - ['a', '/a', 'pyramid.tests.test_scripts.test_proutes.view'] - ) - - def test_one_route_with_long_name_one_view_registered(self): - from zope.interface import Interface - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - registry = self._makeRegistry() - - def view():pass - - class IMyRoute(Interface): - pass - - registry.registerAdapter( - view, - (IViewClassifier, IMyRoute, Interface), - IView, '' - ) - - registry.registerUtility(IMyRoute, IRouteRequest, - name='very_long_name_123') - - command = self._makeOne() - route = dummy.DummyRoute( - 'very_long_name_123', - '/and_very_long_pattern_as_well' - ) - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split()[:3] - self.assertEqual( - compare_to, - ['very_long_name_123', - '/and_very_long_pattern_as_well', - 'pyramid.tests.test_scripts.test_proutes.view'] - ) - - def test_class_view(self): - from pyramid.renderers import null_renderer as nr - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=dummy.DummyView, - attr='view', - renderer=nr, - request_method='POST' - ) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - 'pyramid.tests.test_scripts.dummy.DummyView.view', 'POST' - ] - self.assertEqual(compare_to, expected) - - def test_single_route_one_view_registered_with_factory(self): - from zope.interface import Interface - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - registry = self._makeRegistry() - - def view():pass - class IMyRoot(Interface): - pass - class IMyRoute(Interface): - pass - registry.registerAdapter(view, - (IViewClassifier, IMyRoute, IMyRoot), - IView, '') - registry.registerUtility(IMyRoute, IRouteRequest, name='a') - command = self._makeOne() - def factory(request): pass - route = dummy.DummyRoute('a', '/a', factory=factory) - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - self.assertEqual(L[-1].split()[:3], ['a', '/a', '']) - - def test_single_route_multiview_registered(self): - from zope.interface import Interface - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - - registry = self._makeRegistry() - - def view(): pass - - class IMyRoute(Interface): - pass - - multiview1 = dummy.DummyMultiView( - view, context='context', - view_name='a1' - ) - - registry.registerAdapter( - multiview1, - (IViewClassifier, IMyRoute, Interface), - IMultiView, '' - ) - registry.registerUtility(IMyRoute, IRouteRequest, name='a') - command = self._makeOne() - route = dummy.DummyRoute('a', '/a') - mapper = dummy.DummyMapper(route) - command._get_mapper = lambda *arg: mapper - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split()[:3] - view_module = 'pyramid.tests.test_scripts.dummy' - view_str = '' - ] - self.assertEqual(compare_to, expected) - - def test_route_static_views(self): - from pyramid.renderers import null_renderer as nr - config = self._makeConfig(autocommit=True) - config.add_static_view('static', 'static', cache_max_age=3600) - path2 = os.path.normpath('/var/www/static') - config.add_static_view(name='static2', path=path2) - config.add_static_view( - name='pyramid_scaffold', - path='pyramid:scaffolds/starter/+package+/static' - ) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 5) - - expected = [ - ['__static/', '/static/*subpath', - 'pyramid.tests.test_scripts:static/', '*'], - ['__static2/', '/static2/*subpath', path2 + os.sep, '*'], - ['__pyramid_scaffold/', '/pyramid_scaffold/*subpath', - 'pyramid:scaffolds/starter/+package+/static/', '*'], - ] - - for index, line in enumerate(L[2:]): - data = line.split() - self.assertEqual(data, expected[index]) - - def test_route_no_view(self): - from pyramid.renderers import null_renderer as nr - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b', request_method='POST') - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - '', - 'POST', - ] - self.assertEqual(compare_to, expected) - - def test_route_as_wsgiapp(self): - from pyramid.wsgi import wsgiapp2 - - config1 = self._makeConfig(autocommit=True) - def view1(context, request): return 'view1' - config1.add_route('foo', '/a/b', request_method='POST') - config1.add_view(view=view1, route_name='foo') - - config2 = self._makeConfig(autocommit=True) - config2.add_route('foo', '/a/b', request_method='POST') - config2.add_view( - wsgiapp2(config1.make_wsgi_app()), - route_name='foo', - ) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config2.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - '', - 'POST', - ] - self.assertEqual(compare_to, expected) - - def test_route_is_get_view_request_method_not_post(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b', request_method='GET') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - 'pyramid.tests.test_scripts.test_proutes.view1', - 'GET' - ] - self.assertEqual(compare_to, expected) - - def test_view_request_method_not_post(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - 'pyramid.tests.test_scripts.test_proutes.view1', - '!POST,*' - ] - self.assertEqual(compare_to, expected) - - def test_view_glob(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - def view2(context, request): return 'view2' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - config.add_route('bar', '/b/a') - config.add_view( - route_name='bar', - view=view2, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - command.args.glob = '*foo*' - - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', '/a/b', - 'pyramid.tests.test_scripts.test_proutes.view1', - '!POST,*' - ] - self.assertEqual(compare_to, expected) - - def test_good_format(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - command.args.glob = '*foo*' - command.args.format = 'method,name' - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = ['!POST,*', 'foo'] - - self.assertEqual(compare_to, expected) - self.assertEqual(L[0].split(), ['Method', 'Name']) - - def test_bad_format(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - command.args.glob = '*foo*' - command.args.format = 'predicates,name,pattern' - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - expected = ( - "You provided invalid formats ['predicates'], " - "Available formats are ['name', 'pattern', 'view', 'method']" - ) - result = command.run() - self.assertEqual(result, 2) - self.assertEqual(L[0], expected) - - def test_config_format_ini_newlines(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - command.get_config_loader = dummy.DummyLoader( - {'proutes': {'format': 'method\nname'}}) - - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = ['!POST,*', 'foo'] - - self.assertEqual(compare_to, expected) - self.assertEqual(L[0].split(), ['Method', 'Name']) - - def test_config_format_ini_spaces(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - command.get_config_loader = dummy.DummyLoader( - {'proutes': {'format': 'method name'}}) - - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = ['!POST,*', 'foo'] - - self.assertEqual(compare_to, expected) - self.assertEqual(L[0].split(), ['Method', 'Name']) - - def test_config_format_ini_commas(self): - from pyramid.renderers import null_renderer as nr - from pyramid.config import not_ - - def view1(context, request): return 'view1' - - config = self._makeConfig(autocommit=True) - config.add_route('foo', '/a/b') - config.add_view( - route_name='foo', - view=view1, - renderer=nr, - request_method=not_('POST') - ) - - command = self._makeOne() - - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - command.get_config_loader = dummy.DummyLoader( - {'proutes': {'format': 'method,name'}}) - - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = ['!POST,*', 'foo'] - - self.assertEqual(compare_to, expected) - self.assertEqual(L[0].split(), ['Method', 'Name']) - - def test_static_routes_included_in_list(self): - from pyramid.renderers import null_renderer as nr - - config = self._makeConfig(autocommit=True) - config.add_route('foo', 'http://example.com/bar.aspx', static=True) - - command = self._makeOne() - L = [] - command.out = L.append - command.bootstrap = dummy.DummyBootstrap(registry=config.registry) - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(len(L), 3) - compare_to = L[-1].split() - expected = [ - 'foo', 'http://example.com/bar.aspx', - '', '*', - ] - self.assertEqual(compare_to, expected) - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.proutes import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['proutes']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_scripts/test_pserve.py b/src/pyramid/tests/test_scripts/test_pserve.py deleted file mode 100644 index 485cf38cb..000000000 --- a/src/pyramid/tests/test_scripts/test_pserve.py +++ /dev/null @@ -1,131 +0,0 @@ -import os -import unittest -from pyramid.tests.test_scripts import dummy - - -here = os.path.abspath(os.path.dirname(__file__)) - - -class TestPServeCommand(unittest.TestCase): - def setUp(self): - from pyramid.compat import NativeIO - self.out_ = NativeIO() - - def out(self, msg): - self.out_.write(msg) - - def _getTargetClass(self): - from pyramid.scripts.pserve import PServeCommand - return PServeCommand - - def _makeOne(self, *args): - effargs = ['pserve'] - effargs.extend(args) - cmd = self._getTargetClass()(effargs) - cmd.out = self.out - self.loader = dummy.DummyLoader() - cmd._get_config_loader = self.loader - return cmd - - def test_run_no_args(self): - inst = self._makeOne() - result = inst.run() - self.assertEqual(result, 2) - self.assertEqual(self.out_.getvalue(), 'You must give a config file') - - def test_parse_vars_good(self): - inst = self._makeOne('development.ini', 'a=1', 'b=2') - app = dummy.DummyApp() - - def get_app(name, global_conf): - app.name = name - app.global_conf = global_conf - return app - self.loader.get_wsgi_app = get_app - self.loader.server = lambda x: x - - inst.run() - self.assertEqual(app.global_conf, {'a': '1', 'b': '2'}) - - def test_parse_vars_bad(self): - inst = self._makeOne('development.ini', 'a') - self.assertRaises(ValueError, inst.run) - - def test_config_file_finds_watch_files(self): - inst = self._makeOne('development.ini') - loader = self.loader('/base/path.ini') - loader.settings = {'pserve': { - 'watch_files': 'foo\n/baz\npyramid.tests.test_scripts:*.py', - }} - inst.pserve_file_config(loader, global_conf={'a': '1'}) - self.assertEqual(loader.calls[0]['defaults'], { - 'a': '1', - }) - self.assertEqual(inst.watch_files, set([ - os.path.abspath('/base/foo'), - os.path.abspath('/baz'), - os.path.abspath(os.path.join(here, '*.py')), - ])) - - def test_config_file_finds_open_url(self): - inst = self._makeOne('development.ini') - loader = self.loader('/base/path.ini') - loader.settings = {'pserve': { - 'open_url': 'http://127.0.0.1:8080/', - }} - inst.pserve_file_config(loader, global_conf={'a': '1'}) - self.assertEqual(loader.calls[0]['defaults'], { - 'a': '1', - }) - self.assertEqual(inst.open_url, 'http://127.0.0.1:8080/') - - def test_guess_server_url(self): - inst = self._makeOne('development.ini') - loader = self.loader('/base/path.ini') - loader.settings = {'server:foo': { - 'port': '8080', - }} - url = inst.guess_server_url(loader, 'foo', global_conf={'a': '1'}) - self.assertEqual(loader.calls[0]['defaults'], { - 'a': '1', - }) - self.assertEqual(url, 'http://127.0.0.1:8080') - - def test_reload_call_hupper_with_correct_args(self): - from pyramid.scripts import pserve - - class AttrDict(dict): - def __init__(self, *args, **kwargs): - super(AttrDict, self).__init__(*args, **kwargs) - self.__dict__ = self - - def dummy_start_reloader(*args, **kwargs): - dummy_start_reloader.args = args - dummy_start_reloader.kwargs = kwargs - - orig_hupper = pserve.hupper - try: - pserve.hupper = AttrDict(is_active=lambda: False, - start_reloader=dummy_start_reloader) - - inst = self._makeOne('--reload', 'development.ini') - inst.run() - finally: - pserve.hupper = orig_hupper - - self.assertEquals(dummy_start_reloader.args, ('pyramid.scripts.pserve.main',)) - self.assertEquals(dummy_start_reloader.kwargs, { - 'reload_interval': 1, - 'verbose': 1, - 'worker_kwargs': {'argv': ['pserve', '--reload', 'development.ini'], - 'quiet': False}}) - - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.pserve import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['pserve']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_scripts/test_pshell.py b/src/pyramid/tests/test_scripts/test_pshell.py deleted file mode 100644 index df664bea9..000000000 --- a/src/pyramid/tests/test_scripts/test_pshell.py +++ /dev/null @@ -1,398 +0,0 @@ -import os -import unittest -from pyramid.tests.test_scripts import dummy - - -class TestPShellCommand(unittest.TestCase): - def _getTargetClass(self): - from pyramid.scripts.pshell import PShellCommand - return PShellCommand - - def _makeOne(self, patch_bootstrap=True, patch_loader=True, - patch_args=True, patch_options=True): - cmd = self._getTargetClass()([]) - - if patch_bootstrap: - self.bootstrap = dummy.DummyBootstrap() - cmd.bootstrap = self.bootstrap - if patch_loader: - self.loader = dummy.DummyLoader() - cmd.get_config_loader = self.loader - if patch_args: - class Args(object): pass - self.args = Args() - self.args.config_uri = '/foo/bar/myapp.ini#myapp' - cmd.args.config_uri = self.args.config_uri - if patch_options: - class Options(object): pass - self.options = Options() - self.options.python_shell = '' - self.options.setup = None - self.options.list = None - cmd.options = self.options - - # default to None to prevent side-effects from running tests in - # unknown environments - cmd.pystartup = None - return cmd - - def _makeEntryPoints(self, command, shells): - command.pkg_resources = dummy.DummyPkgResources(shells) - - def test_command_loads_default_shell(self): - command = self._makeOne() - shell = dummy.DummyShell() - self._makeEntryPoints(command, {}) - - command.default_runner = shell - command.run() - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':self.bootstrap.root, - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_errors_with_unknown_shell(self): - command = self._makeOne() - out_calls = [] - - def out(msg): - out_calls.append(msg) - - command.out = out - - shell = dummy.DummyShell() - - self._makeEntryPoints(command, {}) - - command.default_runner = shell - command.args.python_shell = 'unknown_python_shell' - result = command.run() - self.assertEqual(result, 1) - self.assertEqual( - out_calls, ['could not find a shell named "unknown_python_shell"'] - ) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertTrue(self.bootstrap.closer.called) - - def test_command_loads_ipython(self): - command = self._makeOne() - shell = dummy.DummyShell() - bad_shell = dummy.DummyShell() - self._makeEntryPoints( - command, - { - 'ipython': shell, - 'bpython': bad_shell, - } - ) - - command.args.python_shell = 'ipython' - - command.run() - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':self.bootstrap.root, - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_shell_entry_points(self): - command = self._makeOne() - dshell = dummy.DummyShell() - - self._makeEntryPoints( - command, - { - 'ipython': dshell, - 'bpython': dshell, - } - ) - - command.default_runner = None - shell = command.make_shell() - self.assertEqual(shell, dshell) - - def test_shell_override(self): - command = self._makeOne() - ipshell = dummy.DummyShell() - bpshell = dummy.DummyShell() - dshell = dummy.DummyShell() - - self._makeEntryPoints(command, {}) - - command.default_runner = dshell - - shell = command.make_shell() - self.assertEqual(shell, dshell) - - command.args.python_shell = 'ipython' - self.assertRaises(ValueError, command.make_shell) - - self._makeEntryPoints( - command, - { - 'ipython': ipshell, - 'bpython': bpshell, - 'python': dshell, - } - ) - - command.args.python_shell = 'ipython' - shell = command.make_shell() - self.assertEqual(shell, ipshell) - - command.args.python_shell = 'bpython' - shell = command.make_shell() - self.assertEqual(shell, bpshell) - - command.args.python_shell = 'python' - shell = command.make_shell() - self.assertEqual(shell, dshell) - - def test_shell_ordering(self): - command = self._makeOne() - ipshell = dummy.DummyShell() - bpshell = dummy.DummyShell() - dshell = dummy.DummyShell() - - self._makeEntryPoints( - command, - { - 'ipython': ipshell, - 'bpython': bpshell, - 'python': dshell, - } - ) - - command.default_runner = dshell - - command.preferred_shells = ['ipython', 'bpython'] - shell = command.make_shell() - self.assertEqual(shell, ipshell) - - command.preferred_shells = ['bpython', 'python'] - shell = command.make_shell() - self.assertEqual(shell, bpshell) - - command.preferred_shells = ['python', 'ipython'] - shell = command.make_shell() - self.assertEqual(shell, dshell) - - def test_command_loads_custom_items(self): - command = self._makeOne() - model = dummy.Dummy() - user = dummy.Dummy() - self.loader.settings = {'pshell': {'m': model, 'User': user}} - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':self.bootstrap.root, - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'm':model, - 'User': user, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_setup(self): - command = self._makeOne() - def setup(env): - env['a'] = 1 - env['root'] = 'root override' - env['none'] = None - self.loader.settings = {'pshell': {'setup': setup}} - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':'root override', - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'a':1, - 'none': None, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_setup_generator(self): - command = self._makeOne() - did_resume_after_yield = {} - def setup(env): - env['a'] = 1 - env['root'] = 'root override' - env['none'] = None - request = env['request'] - yield - did_resume_after_yield['result'] = True - self.assertEqual(request.dummy_attr, 1) - self.loader.settings = {'pshell': {'setup': setup}} - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':'root override', - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'a':1, - 'none': None, - }) - self.assertTrue(did_resume_after_yield['result']) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_default_shell_option(self): - command = self._makeOne() - ipshell = dummy.DummyShell() - dshell = dummy.DummyShell() - self._makeEntryPoints( - command, - { - 'ipython': ipshell, - 'python': dshell, - } - ) - self.loader.settings = {'pshell': { - 'default_shell': 'bpython python\nipython'}} - command.run() - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertTrue(dshell.called) - - def test_command_loads_check_variable_override_order(self): - command = self._makeOne() - model = dummy.Dummy() - def setup(env): - env['a'] = 1 - env['m'] = 'model override' - env['root'] = 'root override' - self.loader.settings = {'pshell': {'setup': setup, 'm': model}} - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':'root override', - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'a':1, 'm':'model override', - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_loads_setup_from_options(self): - command = self._makeOne() - def setup(env): - env['a'] = 1 - env['root'] = 'root override' - model = dummy.Dummy() - self.loader.settings = {'pshell': {'setup': 'abc', 'm': model}} - command.args.setup = setup - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':'root override', - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'a':1, 'm':model, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_custom_section_override(self): - command = self._makeOne() - dummy_ = dummy.Dummy() - self.loader.settings = {'pshell': { - 'app': dummy_, 'root': dummy_, 'registry': dummy_, - 'request': dummy_}} - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':dummy_, 'root':dummy_, 'registry':dummy_, 'request':dummy_, - 'root_factory':self.bootstrap.root_factory, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_command_loads_pythonstartup(self): - command = self._makeOne() - command.pystartup = ( - os.path.abspath( - os.path.join( - os.path.dirname(__file__), - 'pystartup.txt'))) - shell = dummy.DummyShell() - command.run(shell) - self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') - self.assertEqual(shell.env, { - 'app':self.bootstrap.app, 'root':self.bootstrap.root, - 'registry':self.bootstrap.registry, - 'request':self.bootstrap.request, - 'root_factory':self.bootstrap.root_factory, - 'foo':1, - }) - self.assertTrue(self.bootstrap.closer.called) - self.assertTrue(shell.help) - - def test_list_shells(self): - command = self._makeOne() - - dshell = dummy.DummyShell() - out_calls = [] - - def out(msg): - out_calls.append(msg) - - command.out = out - - self._makeEntryPoints( - command, - { - 'ipython': dshell, - 'python': dshell, - } - ) - - command.args.list = True - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(out_calls, [ - 'Available shells:', - ' ipython', - ' python', - ]) - - -class Test_python_shell_runner(unittest.TestCase): - def _callFUT(self, env, help, interact): - from pyramid.scripts.pshell import python_shell_runner - return python_shell_runner(env, help, interact=interact) - - def test_it(self): - interact = dummy.DummyInteractor() - self._callFUT({'foo': 'bar'}, 'a help message', interact) - self.assertEqual(interact.local, {'foo': 'bar'}) - self.assertTrue('a help message' in interact.banner) - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.pshell import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['pshell']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_scripts/test_ptweens.py b/src/pyramid/tests/test_scripts/test_ptweens.py deleted file mode 100644 index 6907b858d..000000000 --- a/src/pyramid/tests/test_scripts/test_ptweens.py +++ /dev/null @@ -1,62 +0,0 @@ -import unittest -from pyramid.tests.test_scripts import dummy - -class TestPTweensCommand(unittest.TestCase): - def _getTargetClass(self): - from pyramid.scripts.ptweens import PTweensCommand - return PTweensCommand - - def _makeOne(self): - cmd = self._getTargetClass()([]) - cmd.bootstrap = dummy.DummyBootstrap() - cmd.setup_logging = dummy.dummy_setup_logging() - cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' - return cmd - - def test_command_no_tweens(self): - command = self._makeOne() - command._get_tweens = lambda *arg: None - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L, []) - - def test_command_implicit_tweens_only(self): - command = self._makeOne() - tweens = dummy.DummyTweens([('name', 'item')], None) - command._get_tweens = lambda *arg: tweens - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual( - L[0], - '"pyramid.tweens" config value NOT set (implicitly ordered tweens ' - 'used)') - - def test_command_implicit_and_explicit_tweens(self): - command = self._makeOne() - tweens = dummy.DummyTweens([('name', 'item')], [('name2', 'item2')]) - command._get_tweens = lambda *arg: tweens - L = [] - command.out = L.append - result = command.run() - self.assertEqual(result, 0) - self.assertEqual( - L[0], - '"pyramid.tweens" config value set (explicitly ordered tweens used)') - - def test__get_tweens(self): - command = self._makeOne() - registry = dummy.DummyRegistry() - self.assertEqual(command._get_tweens(registry), None) - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.ptweens import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['ptweens']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_scripts/test_pviews.py b/src/pyramid/tests/test_scripts/test_pviews.py deleted file mode 100644 index 6ec9defbd..000000000 --- a/src/pyramid/tests/test_scripts/test_pviews.py +++ /dev/null @@ -1,501 +0,0 @@ -import unittest -from pyramid.tests.test_scripts import dummy - -class TestPViewsCommand(unittest.TestCase): - def _getTargetClass(self): - from pyramid.scripts.pviews import PViewsCommand - return PViewsCommand - - def _makeOne(self, registry=None): - cmd = self._getTargetClass()([]) - cmd.bootstrap = dummy.DummyBootstrap(registry=registry) - cmd.setup_logging = dummy.dummy_setup_logging() - cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' - return cmd - - def _makeRequest(self, url, registry): - from pyramid.request import Request - request = Request.blank('/a') - request.registry = registry - return request - - def _register_mapper(self, registry, routes): - from pyramid.interfaces import IRoutesMapper - mapper = dummy.DummyMapper(*routes) - registry.registerUtility(mapper, IRoutesMapper) - - def test__find_view_no_match(self): - from pyramid.registry import Registry - registry = Registry() - self._register_mapper(registry, []) - command = self._makeOne(registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertEqual(result, None) - - def test__find_view_no_match_multiview_registered(self): - from zope.interface import implementer - from zope.interface import providedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - from pyramid.traversal import DefaultRootFactory - from pyramid.registry import Registry - registry = Registry() - @implementer(IMultiView) - class View1(object): - pass - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - root = DefaultRootFactory(request) - root_iface = providedBy(root) - registry.registerAdapter(View1(), - (IViewClassifier, IRequest, root_iface), - IMultiView) - self._register_mapper(registry, []) - command = self._makeOne(registry=registry) - request = self._makeRequest('/x', registry) - result = command._find_view(request) - self.assertEqual(result, None) - - def test__find_view_traversal(self): - from zope.interface import providedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - from pyramid.traversal import DefaultRootFactory - from pyramid.registry import Registry - registry = Registry() - def view1(): pass - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - root = DefaultRootFactory(request) - root_iface = providedBy(root) - registry.registerAdapter(view1, - (IViewClassifier, IRequest, root_iface), - IView, name='a') - self._register_mapper(registry, []) - command = self._makeOne(registry=registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertEqual(result, view1) - - def test__find_view_traversal_multiview(self): - from zope.interface import implementer - from zope.interface import providedBy - from pyramid.interfaces import IRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IMultiView - from pyramid.traversal import DefaultRootFactory - from pyramid.registry import Registry - registry = Registry() - @implementer(IMultiView) - class View1(object): - pass - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - root = DefaultRootFactory(request) - root_iface = providedBy(root) - view = View1() - registry.registerAdapter(view, - (IViewClassifier, IRequest, root_iface), - IMultiView, name='a') - self._register_mapper(registry, []) - command = self._makeOne(registry=registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertEqual(result, view) - - def test__find_view_route_no_multiview(self): - from zope.interface import Interface - from zope.interface import implementer - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - from pyramid.registry import Registry - registry = Registry() - def view():pass - class IMyRoot(Interface): - pass - class IMyRoute(Interface): - pass - registry.registerAdapter(view, - (IViewClassifier, IMyRoute, IMyRoot), - IView, '') - registry.registerUtility(IMyRoute, IRouteRequest, name='a') - @implementer(IMyRoot) - class Factory(object): - def __init__(self, request): - pass - routes = [dummy.DummyRoute('a', '/a', factory=Factory, matchdict={}), - dummy.DummyRoute('b', '/b', factory=Factory)] - self._register_mapper(registry, routes) - command = self._makeOne(registry=registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertEqual(result, view) - - def test__find_view_route_multiview_no_view_registered(self): - from zope.interface import Interface - from zope.interface import implementer - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IRootFactory - from pyramid.registry import Registry - registry = Registry() - def view1():pass - def view2():pass - class IMyRoot(Interface): - pass - class IMyRoute1(Interface): - pass - class IMyRoute2(Interface): - pass - registry.registerUtility(IMyRoute1, IRouteRequest, name='a') - registry.registerUtility(IMyRoute2, IRouteRequest, name='b') - @implementer(IMyRoot) - class Factory(object): - def __init__(self, request): - pass - registry.registerUtility(Factory, IRootFactory) - routes = [dummy.DummyRoute('a', '/a', matchdict={}), - dummy.DummyRoute('b', '/a', matchdict={})] - self._register_mapper(registry, routes) - command = self._makeOne(registry=registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertTrue(IMultiView.providedBy(result)) - - def test__find_view_route_multiview(self): - from zope.interface import Interface - from zope.interface import implementer - from pyramid.interfaces import IRouteRequest - from pyramid.interfaces import IViewClassifier - from pyramid.interfaces import IView - from pyramid.interfaces import IMultiView - from pyramid.interfaces import IRootFactory - from pyramid.registry import Registry - registry = Registry() - def view1():pass - def view2():pass - class IMyRoot(Interface): - pass - class IMyRoute1(Interface): - pass - class IMyRoute2(Interface): - pass - registry.registerAdapter(view1, - (IViewClassifier, IMyRoute1, IMyRoot), - IView, '') - registry.registerAdapter(view2, - (IViewClassifier, IMyRoute2, IMyRoot), - IView, '') - registry.registerUtility(IMyRoute1, IRouteRequest, name='a') - registry.registerUtility(IMyRoute2, IRouteRequest, name='b') - @implementer(IMyRoot) - class Factory(object): - def __init__(self, request): - pass - registry.registerUtility(Factory, IRootFactory) - routes = [dummy.DummyRoute('a', '/a', matchdict={}), - dummy.DummyRoute('b', '/a', matchdict={})] - self._register_mapper(registry, routes) - command = self._makeOne(registry=registry) - request = self._makeRequest('/a', registry) - result = command._find_view(request) - self.assertTrue(IMultiView.providedBy(result)) - self.assertEqual(len(result.views), 2) - self.assertTrue((None, view1, None) in result.views) - self.assertTrue((None, view2, None) in result.views) - - def test__find_multi_routes_all_match(self): - command = self._makeOne() - def factory(request): pass - routes = [dummy.DummyRoute('a', '/a', factory=factory, matchdict={}), - dummy.DummyRoute('b', '/a', factory=factory, matchdict={})] - mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - result = command._find_multi_routes(mapper, request) - self.assertEqual(result, [{'match':{}, 'route':routes[0]}, - {'match':{}, 'route':routes[1]}]) - - def test__find_multi_routes_some_match(self): - command = self._makeOne() - def factory(request): pass - routes = [dummy.DummyRoute('a', '/a', factory=factory), - dummy.DummyRoute('b', '/a', factory=factory, matchdict={})] - mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - result = command._find_multi_routes(mapper, request) - self.assertEqual(result, [{'match':{}, 'route':routes[1]}]) - - def test__find_multi_routes_none_match(self): - command = self._makeOne() - def factory(request): pass - routes = [dummy.DummyRoute('a', '/a', factory=factory), - dummy.DummyRoute('b', '/a', factory=factory)] - mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO':'/a'}) - result = command._find_multi_routes(mapper, request) - self.assertEqual(result, []) - - def test_views_command_not_found(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - command._find_view = lambda arg1: None - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' Not found.') - - def test_views_command_not_found_url_starts_without_slash(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - command._find_view = lambda arg1: None - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = 'a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' Not found.') - - def test_views_command_single_view_traversal(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - view = dummy.DummyView(context='context', view_name='a') - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.DummyView') - - def test_views_command_single_view_function_traversal(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - def view(): pass - view.__request_attrs__ = {'context': 'context', 'view_name': 'a'} - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.test_pviews.view') - - def test_views_command_single_view_traversal_with_permission(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - view = dummy.DummyView(context='context', view_name='a') - view.__permission__ = 'test' - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.DummyView') - self.assertEqual(L[9], ' required permission = test') - - def test_views_command_single_view_traversal_with_predicates(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - def predicate(): pass - predicate.text = lambda *arg: "predicate = x" - view = dummy.DummyView(context='context', view_name='a') - view.__predicates__ = [predicate] - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.DummyView') - self.assertEqual(L[9], ' view predicates (predicate = x)') - - def test_views_command_single_view_route(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - route = dummy.DummyRoute('a', '/a', matchdict={}) - view = dummy.DummyView(context='context', view_name='a', - matched_route=route, subpath='') - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[6], ' Route:') - self.assertEqual(L[8], ' route name: a') - self.assertEqual(L[9], ' route pattern: /a') - self.assertEqual(L[10], ' route path: /a') - self.assertEqual(L[11], ' subpath: ') - self.assertEqual(L[15], - ' pyramid.tests.test_scripts.dummy.DummyView') - - def test_views_command_multi_view_nested(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - view1 = dummy.DummyView(context='context', view_name='a1') - view1.__name__ = 'view1' - view1.__view_attr__ = 'call' - multiview1 = dummy.DummyMultiView(view1, context='context', - view_name='a1') - multiview2 = dummy.DummyMultiView(multiview1, context='context', - view_name='a') - command._find_view = lambda arg1: multiview2 - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.DummyMultiView') - self.assertEqual(L[12], - ' pyramid.tests.test_scripts.dummy.view1.call') - - def test_views_command_single_view_route_with_route_predicates(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - def predicate(): pass - predicate.text = lambda *arg: "predicate = x" - route = dummy.DummyRoute('a', '/a', matchdict={}, predicate=predicate) - view = dummy.DummyView(context='context', view_name='a', - matched_route=route, subpath='') - command._find_view = lambda arg1: view - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[6], ' Route:') - self.assertEqual(L[8], ' route name: a') - self.assertEqual(L[9], ' route pattern: /a') - self.assertEqual(L[10], ' route path: /a') - self.assertEqual(L[11], ' subpath: ') - self.assertEqual(L[12], ' route predicates (predicate = x)') - self.assertEqual(L[16], - ' pyramid.tests.test_scripts.dummy.DummyView') - - def test_views_command_multiview(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - view = dummy.DummyView(context='context') - view.__name__ = 'view' - view.__view_attr__ = 'call' - multiview = dummy.DummyMultiView(view, context='context', view_name='a') - command._find_view = lambda arg1: multiview - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.view.call') - - def test_views_command_multiview_with_permission(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - view = dummy.DummyView(context='context') - view.__name__ = 'view' - view.__view_attr__ = 'call' - view.__permission__ = 'test' - multiview = dummy.DummyMultiView(view, context='context', view_name='a') - command._find_view = lambda arg1: multiview - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.view.call') - self.assertEqual(L[9], ' required permission = test') - - def test_views_command_multiview_with_predicates(self): - from pyramid.registry import Registry - registry = Registry() - command = self._makeOne(registry=registry) - L = [] - command.out = L.append - def predicate(): pass - predicate.text = lambda *arg: "predicate = x" - view = dummy.DummyView(context='context') - view.__name__ = 'view' - view.__view_attr__ = 'call' - view.__predicates__ = [predicate] - multiview = dummy.DummyMultiView(view, context='context', view_name='a') - command._find_view = lambda arg1: multiview - command.args.config_uri = '/foo/bar/myapp.ini#myapp' - command.args.url = '/a' - result = command.run() - self.assertEqual(result, 0) - self.assertEqual(L[1], 'URL = /a') - self.assertEqual(L[3], ' context: context') - self.assertEqual(L[4], ' view name: a') - self.assertEqual(L[8], - ' pyramid.tests.test_scripts.dummy.view.call') - self.assertEqual(L[9], ' view predicates (predicate = x)') - -class Test_main(unittest.TestCase): - def _callFUT(self, argv): - from pyramid.scripts.pviews import main - return main(argv, quiet=True) - - def test_it(self): - result = self._callFUT(['pviews']) - self.assertEqual(result, 2) diff --git a/src/pyramid/tests/test_security.py b/src/pyramid/tests/test_security.py deleted file mode 100644 index e5399ecdf..000000000 --- a/src/pyramid/tests/test_security.py +++ /dev/null @@ -1,549 +0,0 @@ -import unittest - -from pyramid import testing - -class TestAllPermissionsList(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTargetClass(self): - from pyramid.security import AllPermissionsList - return AllPermissionsList - - def _makeOne(self): - return self._getTargetClass()() - - def test_equality_w_self(self): - thing = self._makeOne() - self.assertTrue(thing.__eq__(thing)) - - def test_equality_w_other_instances_of_class(self): - thing = self._makeOne() - other = self._makeOne() - self.assertTrue(thing.__eq__(other)) - - def test_equality_miss(self): - thing = self._makeOne() - other = object() - self.assertFalse(thing.__eq__(other)) - - def test_contains_w_string(self): - thing = self._makeOne() - self.assertTrue('anything' in thing) - - def test_contains_w_object(self): - thing = self._makeOne() - self.assertTrue(object() in thing) - - def test_iterable(self): - thing = self._makeOne() - self.assertEqual(list(thing), []) - - def test_singleton(self): - from pyramid.security import ALL_PERMISSIONS - self.assertEqual(ALL_PERMISSIONS.__class__, self._getTargetClass()) - -class TestAllowed(unittest.TestCase): - def _getTargetClass(self): - from pyramid.security import Allowed - return Allowed - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - allowed = self._makeOne('hello') - self.assertEqual(allowed.msg, 'hello') - self.assertEqual(allowed, True) - self.assertTrue(allowed) - self.assertEqual(str(allowed), 'hello') - self.assertTrue('" in repr(allowed)) - -class TestDenied(unittest.TestCase): - def _getTargetClass(self): - from pyramid.security import Denied - return Denied - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - denied = self._makeOne('hello') - self.assertEqual(denied.msg, 'hello') - self.assertEqual(denied, False) - self.assertFalse(denied) - self.assertEqual(str(denied), 'hello') - self.assertTrue('" in repr(denied)) - -class TestACLAllowed(unittest.TestCase): - def _getTargetClass(self): - from pyramid.security import ACLAllowed - return ACLAllowed - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - from pyramid.security import Allowed - msg = ("ACLAllowed permission 'permission' via ACE 'ace' in ACL 'acl' " - "on context 'ctx' for principals 'principals'") - allowed = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') - self.assertIsInstance(allowed, Allowed) - self.assertTrue(msg in allowed.msg) - self.assertEqual(allowed, True) - self.assertTrue(allowed) - self.assertEqual(str(allowed), msg) - self.assertTrue('" % msg in repr(allowed)) - -class TestACLDenied(unittest.TestCase): - def _getTargetClass(self): - from pyramid.security import ACLDenied - return ACLDenied - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def test_it(self): - from pyramid.security import Denied - msg = ("ACLDenied permission 'permission' via ACE 'ace' in ACL 'acl' " - "on context 'ctx' for principals 'principals'") - denied = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') - self.assertIsInstance(denied, Denied) - self.assertTrue(msg in denied.msg) - self.assertEqual(denied, False) - self.assertFalse(denied) - self.assertEqual(str(denied), msg) - self.assertTrue('" % msg in repr(denied)) - -class TestPrincipalsAllowedByPermission(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg): - from pyramid.security import principals_allowed_by_permission - return principals_allowed_by_permission(*arg) - - def test_no_authorization_policy(self): - from pyramid.security import Everyone - context = DummyContext() - result = self._callFUT(context, 'view') - self.assertEqual(result, [Everyone]) - - def test_with_authorization_policy(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - _registerAuthorizationPolicy(registry, 'yo') - context = DummyContext() - result = self._callFUT(context, 'view') - self.assertEqual(result, 'yo') - -class TestRemember(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kwarg): - from pyramid.security import remember - return remember(*arg, **kwarg) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request, 'me') - self.assertEqual(result, []) - - def test_with_authentication_policy(self): - request = _makeRequest() - registry = request.registry - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request, 'me') - self.assertEqual(result, [('X-Pyramid-Test', 'me')]) - - def test_with_authentication_policy_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = _makeRequest() - del request.registry - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request, 'me') - self.assertEqual(result, [('X-Pyramid-Test', 'me')]) - - def test_with_missing_arg(self): - request = _makeRequest() - registry = request.registry - _registerAuthenticationPolicy(registry, 'yo') - self.assertRaises(TypeError, lambda: self._callFUT(request)) - -class TestForget(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg): - from pyramid.security import forget - return forget(*arg) - - def test_no_authentication_policy(self): - request = _makeRequest() - result = self._callFUT(request) - self.assertEqual(result, []) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, [('X-Pyramid-Test', 'logout')]) - - def test_with_authentication_policy_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = _makeRequest() - del request.registry - _registerAuthenticationPolicy(registry, 'yo') - result = self._callFUT(request) - self.assertEqual(result, [('X-Pyramid-Test', 'logout')]) - -class TestViewExecutionPermitted(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self, *arg, **kw): - from pyramid.security import view_execution_permitted - return view_execution_permitted(*arg, **kw) - - def _registerSecuredView(self, view_name, allow=True): - from pyramid.threadlocal import get_current_registry - from zope.interface import Interface - from pyramid.interfaces import ISecuredView - from pyramid.interfaces import IViewClassifier - class Checker(object): - def __permitted__(self, context, request): - self.context = context - self.request = request - return allow - checker = Checker() - reg = get_current_registry() - reg.registerAdapter(checker, (IViewClassifier, Interface, Interface), - ISecuredView, view_name) - return checker - - def test_no_permission(self): - from zope.interface import Interface - from pyramid.threadlocal import get_current_registry - from pyramid.interfaces import ISettings - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - settings = dict(debug_authorization=True) - reg = get_current_registry() - reg.registerUtility(settings, ISettings) - context = DummyContext() - request = testing.DummyRequest({}) - class DummyView(object): - pass - view = DummyView() - reg.registerAdapter(view, (IViewClassifier, Interface, Interface), - IView, '') - result = self._callFUT(context, request, '') - msg = result.msg - self.assertTrue("Allowed: view name '' in context" in msg) - self.assertTrue('(no permission defined)' in msg) - self.assertEqual(result, True) - - def test_no_view_registered(self): - from pyramid.threadlocal import get_current_registry - from pyramid.interfaces import ISettings - settings = dict(debug_authorization=True) - reg = get_current_registry() - reg.registerUtility(settings, ISettings) - context = DummyContext() - request = testing.DummyRequest({}) - self.assertRaises(TypeError, self._callFUT, context, request, '') - - def test_with_permission(self): - from zope.interface import Interface - from zope.interface import directlyProvides - from pyramid.interfaces import IRequest - class IContext(Interface): - pass - context = DummyContext() - directlyProvides(context, IContext) - self._registerSecuredView('', True) - request = testing.DummyRequest({}) - directlyProvides(request, IRequest) - result = self._callFUT(context, request, '') - self.assertTrue(result) - -class TestAuthenticatedUserId(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_backward_compat_delegates_to_mixin(self): - from zope.deprecation import __show__ - try: - __show__.off() - request = _makeFakeRequest() - from pyramid.security import authenticated_userid - self.assertEqual( - authenticated_userid(request), - 'authenticated_userid' - ) - finally: - __show__.on() - - def test_no_authentication_policy(self): - request = _makeRequest() - self.assertEqual(request.authenticated_userid, None) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - self.assertEqual(request.authenticated_userid, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = _makeRequest() - del request.registry - _registerAuthenticationPolicy(registry, 'yo') - self.assertEqual(request.authenticated_userid, 'yo') - -class TestUnAuthenticatedUserId(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_backward_compat_delegates_to_mixin(self): - from zope.deprecation import __show__ - try: - __show__.off() - request = _makeFakeRequest() - from pyramid.security import unauthenticated_userid - self.assertEqual( - unauthenticated_userid(request), - 'unauthenticated_userid', - ) - finally: - __show__.on() - - def test_no_authentication_policy(self): - request = _makeRequest() - self.assertEqual(request.unauthenticated_userid, None) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - self.assertEqual(request.unauthenticated_userid, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = _makeRequest() - del request.registry - _registerAuthenticationPolicy(registry, 'yo') - self.assertEqual(request.unauthenticated_userid, 'yo') - -class TestEffectivePrincipals(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def test_backward_compat_delegates_to_mixin(self): - request = _makeFakeRequest() - from zope.deprecation import __show__ - try: - __show__.off() - from pyramid.security import effective_principals - self.assertEqual( - effective_principals(request), - 'effective_principals' - ) - finally: - __show__.on() - - def test_no_authentication_policy(self): - from pyramid.security import Everyone - request = _makeRequest() - self.assertEqual(request.effective_principals, [Everyone]) - - def test_with_authentication_policy(self): - request = _makeRequest() - _registerAuthenticationPolicy(request.registry, 'yo') - self.assertEqual(request.effective_principals, 'yo') - - def test_with_authentication_policy_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = _makeRequest() - del request.registry - _registerAuthenticationPolicy(registry, 'yo') - self.assertEqual(request.effective_principals, 'yo') - -class TestHasPermission(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self): - from pyramid.security import AuthorizationAPIMixin - from pyramid.registry import Registry - mixin = AuthorizationAPIMixin() - mixin.registry = Registry() - mixin.context = object() - return mixin - - def test_delegates_to_mixin(self): - from zope.deprecation import __show__ - try: - __show__.off() - mixin = self._makeOne() - from pyramid.security import has_permission - self.called_has_permission = False - - def mocked_has_permission(*args, **kw): - self.called_has_permission = True - - mixin.has_permission = mocked_has_permission - has_permission('view', object(), mixin) - self.assertTrue(self.called_has_permission) - finally: - __show__.on() - - def test_no_authentication_policy(self): - request = self._makeOne() - result = request.has_permission('view') - self.assertTrue(result) - self.assertEqual(result.msg, 'No authentication policy in use.') - - def test_with_no_authorization_policy(self): - request = self._makeOne() - _registerAuthenticationPolicy(request.registry, None) - self.assertRaises(ValueError, - request.has_permission, 'view', context=None) - - def test_with_authn_and_authz_policies_registered(self): - request = self._makeOne() - _registerAuthenticationPolicy(request.registry, None) - _registerAuthorizationPolicy(request.registry, 'yo') - self.assertEqual(request.has_permission('view', context=None), 'yo') - - def test_with_no_reg_on_request(self): - from pyramid.threadlocal import get_current_registry - registry = get_current_registry() - request = self._makeOne() - del request.registry - _registerAuthenticationPolicy(registry, None) - _registerAuthorizationPolicy(registry, 'yo') - self.assertEqual(request.has_permission('view'), 'yo') - - def test_with_no_context_passed(self): - request = self._makeOne() - self.assertTrue(request.has_permission('view')) - - def test_with_no_context_passed_or_on_request(self): - request = self._makeOne() - del request.context - self.assertRaises(AttributeError, request.has_permission, 'view') - -_TEST_HEADER = 'X-Pyramid-Test' - -class DummyContext: - def __init__(self, *arg, **kw): - self.__dict__.update(kw) - -class DummyAuthenticationPolicy: - def __init__(self, result): - self.result = result - - def effective_principals(self, request): - return self.result - - def unauthenticated_userid(self, request): - return self.result - - def authenticated_userid(self, request): - return self.result - - def remember(self, request, userid, **kw): - headers = [(_TEST_HEADER, userid)] - self._header_remembered = headers[0] - return headers - - def forget(self, request): - headers = [(_TEST_HEADER, 'logout')] - self._header_forgotten = headers[0] - return headers - -class DummyAuthorizationPolicy: - def __init__(self, result): - self.result = result - - def permits(self, context, principals, permission): - return self.result - - def principals_allowed_by_permission(self, context, permission): - return self.result - -def _registerAuthenticationPolicy(reg, result): - from pyramid.interfaces import IAuthenticationPolicy - policy = DummyAuthenticationPolicy(result) - reg.registerUtility(policy, IAuthenticationPolicy) - return policy - -def _registerAuthorizationPolicy(reg, result): - from pyramid.interfaces import IAuthorizationPolicy - policy = DummyAuthorizationPolicy(result) - reg.registerUtility(policy, IAuthorizationPolicy) - return policy - -def _makeRequest(): - from pyramid.registry import Registry - request = testing.DummyRequest(environ={}) - request.registry = Registry() - request.context = object() - return request - -def _makeFakeRequest(): - class FakeRequest(testing.DummyRequest): - @property - def authenticated_userid(req): - return 'authenticated_userid' - - @property - def unauthenticated_userid(req): - return 'unauthenticated_userid' - - @property - def effective_principals(req): - return 'effective_principals' - - return FakeRequest({}) - diff --git a/src/pyramid/tests/test_session.py b/src/pyramid/tests/test_session.py deleted file mode 100644 index 3585ed635..000000000 --- a/src/pyramid/tests/test_session.py +++ /dev/null @@ -1,754 +0,0 @@ -import base64 -import json -import unittest -from pyramid import testing -from pyramid.compat import pickle - -class SharedCookieSessionTests(object): - - def test_ctor_no_cookie(self): - request = testing.DummyRequest() - session = self._makeOne(request) - self.assertEqual(dict(session), {}) - - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ISession - request = testing.DummyRequest() - session = self._makeOne(request) - verifyObject(ISession, session) - - def test_ctor_with_cookie_still_valid(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request) - self.assertEqual(dict(session), {'state':1}) - - def test_ctor_with_cookie_expired(self): - request = testing.DummyRequest() - cookieval = self._serialize((0, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request) - self.assertEqual(dict(session), {}) - - def test_ctor_with_bad_cookie_cannot_deserialize(self): - request = testing.DummyRequest() - request.cookies['session'] = 'abc' - session = self._makeOne(request) - self.assertEqual(dict(session), {}) - - def test_ctor_with_bad_cookie_not_tuple(self): - request = testing.DummyRequest() - cookieval = self._serialize('abc') - request.cookies['session'] = cookieval - session = self._makeOne(request) - self.assertEqual(dict(session), {}) - - def test_timeout(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time() - 5, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, timeout=1) - self.assertEqual(dict(session), {}) - - def test_timeout_never(self): - import time - request = testing.DummyRequest() - LONG_TIME = 31536000 - cookieval = self._serialize((time.time() + LONG_TIME, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, timeout=None) - self.assertEqual(dict(session), {'state': 1}) - - def test_timeout_str(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time() - 5, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, timeout='1') - self.assertEqual(dict(session), {}) - - def test_timeout_invalid(self): - request = testing.DummyRequest() - self.assertRaises(ValueError, self._makeOne, request, timeout='Invalid value') - - def test_changed(self): - request = testing.DummyRequest() - session = self._makeOne(request) - self.assertEqual(session.changed(), None) - self.assertTrue(session._dirty) - - def test_invalidate(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session['a'] = 1 - self.assertEqual(session.invalidate(), None) - self.assertFalse('a' in session) - - def test_reissue_triggered(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request) - self.assertEqual(session['state'], 1) - self.assertTrue(session._dirty) - - def test__set_cookie_on_exception(self): - request = testing.DummyRequest() - request.exception = True - session = self._makeOne(request) - session._cookie_on_exception = False - response = DummyResponse() - self.assertEqual(session._set_cookie(response), False) - - def test__set_cookie_on_exception_no_request_exception(self): - import webob - request = testing.DummyRequest() - request.exception = None - session = self._makeOne(request) - session._cookie_on_exception = False - response = webob.Response() - self.assertEqual(session._set_cookie(response), True) - self.assertEqual(response.headerlist[-1][0], 'Set-Cookie') - - def test__set_cookie_cookieval_too_long(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session['abc'] = 'x'*100000 - response = DummyResponse() - self.assertRaises(ValueError, session._set_cookie, response) - - def test__set_cookie_real_webob_response(self): - import webob - request = testing.DummyRequest() - session = self._makeOne(request) - session['abc'] = 'x' - response = webob.Response() - self.assertEqual(session._set_cookie(response), True) - self.assertEqual(response.headerlist[-1][0], 'Set-Cookie') - - def test__set_cookie_options(self): - from pyramid.response import Response - request = testing.DummyRequest() - request.exception = None - session = self._makeOne(request, - cookie_name='abc', - path='/foo', - domain='localhost', - secure=True, - httponly=True, - ) - session['abc'] = 'x' - response = Response() - self.assertEqual(session._set_cookie(response), True) - cookieval = response.headerlist[-1][1] - val, domain, path, secure, httponly, samesite = [x.strip() for x in - cookieval.split(';')] - self.assertTrue(val.startswith('abc=')) - self.assertEqual(domain, 'Domain=localhost') - self.assertEqual(path, 'Path=/foo') - self.assertEqual(secure, 'secure') - self.assertEqual(httponly, 'HttpOnly') - self.assertEqual(samesite, 'SameSite=Lax') - - def test_flash_default(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session.flash('msg1') - session.flash('msg2') - self.assertEqual(session['_f_'], ['msg1', 'msg2']) - - def test_flash_allow_duplicate_false(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session.flash('msg1') - session.flash('msg1', allow_duplicate=False) - self.assertEqual(session['_f_'], ['msg1']) - - def test_flash_allow_duplicate_true_and_msg_not_in_storage(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session.flash('msg1', allow_duplicate=True) - self.assertEqual(session['_f_'], ['msg1']) - - def test_flash_allow_duplicate_false_and_msg_not_in_storage(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session.flash('msg1', allow_duplicate=False) - self.assertEqual(session['_f_'], ['msg1']) - - def test_flash_mixed(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session.flash('warn1', 'warn') - session.flash('warn2', 'warn') - session.flash('err1', 'error') - session.flash('err2', 'error') - self.assertEqual(session['_f_warn'], ['warn1', 'warn2']) - - def test_pop_flash_default_queue(self): - request = testing.DummyRequest() - session = self._makeOne(request) - queue = ['one', 'two'] - session['_f_'] = queue - result = session.pop_flash() - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_'), None) - - def test_pop_flash_nodefault_queue(self): - request = testing.DummyRequest() - session = self._makeOne(request) - queue = ['one', 'two'] - session['_f_error'] = queue - result = session.pop_flash('error') - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_error'), None) - - def test_peek_flash_default_queue(self): - request = testing.DummyRequest() - session = self._makeOne(request) - queue = ['one', 'two'] - session['_f_'] = queue - result = session.peek_flash() - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_'), queue) - - def test_peek_flash_nodefault_queue(self): - request = testing.DummyRequest() - session = self._makeOne(request) - queue = ['one', 'two'] - session['_f_error'] = queue - result = session.peek_flash('error') - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_error'), queue) - - def test_new_csrf_token(self): - request = testing.DummyRequest() - session = self._makeOne(request) - token = session.new_csrf_token() - self.assertEqual(token, session['_csrft_']) - - def test_get_csrf_token(self): - request = testing.DummyRequest() - session = self._makeOne(request) - session['_csrft_'] = 'token' - token = session.get_csrf_token() - self.assertEqual(token, 'token') - self.assertTrue('_csrft_' in session) - - def test_get_csrf_token_new(self): - request = testing.DummyRequest() - session = self._makeOne(request) - token = session.get_csrf_token() - self.assertTrue(token) - self.assertTrue('_csrft_' in session) - - def test_no_set_cookie_with_exception(self): - import webob - request = testing.DummyRequest() - request.exception = True - session = self._makeOne(request, set_on_exception=False) - session['a'] = 1 - callbacks = request.response_callbacks - self.assertEqual(len(callbacks), 1) - response = webob.Response() - result = callbacks[0](request, response) - self.assertEqual(result, None) - self.assertFalse('Set-Cookie' in dict(response.headerlist)) - - def test_set_cookie_with_exception(self): - import webob - request = testing.DummyRequest() - request.exception = True - session = self._makeOne(request) - session['a'] = 1 - callbacks = request.response_callbacks - self.assertEqual(len(callbacks), 1) - response = webob.Response() - result = callbacks[0](request, response) - self.assertEqual(result, None) - self.assertTrue('Set-Cookie' in dict(response.headerlist)) - - def test_cookie_is_set(self): - import webob - request = testing.DummyRequest() - session = self._makeOne(request) - session['a'] = 1 - callbacks = request.response_callbacks - self.assertEqual(len(callbacks), 1) - response = webob.Response() - result = callbacks[0](request, response) - self.assertEqual(result, None) - self.assertTrue('Set-Cookie' in dict(response.headerlist)) - -class TestBaseCookieSession(SharedCookieSessionTests, unittest.TestCase): - def _makeOne(self, request, **kw): - from pyramid.session import BaseCookieSessionFactory - serializer = DummySerializer() - return BaseCookieSessionFactory(serializer, **kw)(request) - - def _serialize(self, value): - return base64.b64encode(json.dumps(value).encode('utf-8')) - - def test_reissue_not_triggered(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time=1) - self.assertEqual(session['state'], 1) - self.assertFalse(session._dirty) - - def test_reissue_never(self): - request = testing.DummyRequest() - cookieval = self._serialize((0, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time=None, timeout=None) - self.assertEqual(session['state'], 1) - self.assertFalse(session._dirty) - - def test_reissue_str_triggered(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time='0') - self.assertEqual(session['state'], 1) - self.assertTrue(session._dirty) - - def test_reissue_invalid(self): - request = testing.DummyRequest() - self.assertRaises(ValueError, self._makeOne, request, reissue_time='invalid value') - - def test_cookie_max_age_invalid(self): - request = testing.DummyRequest() - self.assertRaises(ValueError, self._makeOne, request, max_age='invalid value') - -class TestSignedCookieSession(SharedCookieSessionTests, unittest.TestCase): - def _makeOne(self, request, **kw): - from pyramid.session import SignedCookieSessionFactory - kw.setdefault('secret', 'secret') - return SignedCookieSessionFactory(**kw)(request) - - def _serialize(self, value, salt=b'pyramid.session.', hashalg='sha512'): - import base64 - import hashlib - import hmac - import pickle - - digestmod = lambda: hashlib.new(hashalg) - cstruct = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) - sig = hmac.new(salt + b'secret', cstruct, digestmod).digest() - return base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') - - def test_reissue_not_triggered(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time=1) - self.assertEqual(session['state'], 1) - self.assertFalse(session._dirty) - - def test_reissue_never(self): - request = testing.DummyRequest() - cookieval = self._serialize((0, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time=None, timeout=None) - self.assertEqual(session['state'], 1) - self.assertFalse(session._dirty) - - def test_reissue_str_triggered(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, reissue_time='0') - self.assertEqual(session['state'], 1) - self.assertTrue(session._dirty) - - def test_reissue_invalid(self): - request = testing.DummyRequest() - self.assertRaises(ValueError, self._makeOne, request, reissue_time='invalid value') - - def test_cookie_max_age_invalid(self): - request = testing.DummyRequest() - self.assertRaises(ValueError, self._makeOne, request, max_age='invalid value') - - def test_custom_salt(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1}), salt=b'f.') - request.cookies['session'] = cookieval - session = self._makeOne(request, salt=b'f.') - self.assertEqual(session['state'], 1) - - def test_salt_mismatch(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1}), salt=b'f.') - request.cookies['session'] = cookieval - session = self._makeOne(request, salt=b'g.') - self.assertEqual(session, {}) - - def test_custom_hashalg(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1}), - hashalg='sha1') - request.cookies['session'] = cookieval - session = self._makeOne(request, hashalg='sha1') - self.assertEqual(session['state'], 1) - - def test_hashalg_mismatch(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1}), - hashalg='sha1') - request.cookies['session'] = cookieval - session = self._makeOne(request, hashalg='sha256') - self.assertEqual(session, {}) - - def test_secret_mismatch(self): - import time - request = testing.DummyRequest() - cookieval = self._serialize((time.time(), 0, {'state': 1})) - request.cookies['session'] = cookieval - session = self._makeOne(request, secret='evilsecret') - self.assertEqual(session, {}) - - def test_custom_serializer(self): - import base64 - from hashlib import sha512 - import hmac - import time - request = testing.DummyRequest() - serializer = DummySerializer() - cstruct = serializer.dumps((time.time(), 0, {'state': 1})) - sig = hmac.new(b'pyramid.session.secret', cstruct, sha512).digest() - cookieval = base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') - request.cookies['session'] = cookieval - session = self._makeOne(request, serializer=serializer) - self.assertEqual(session['state'], 1) - - def test_invalid_data_size(self): - from hashlib import sha512 - import base64 - request = testing.DummyRequest() - num_bytes = sha512().digest_size - 1 - cookieval = base64.b64encode(b' ' * num_bytes) - request.cookies['session'] = cookieval - session = self._makeOne(request) - self.assertEqual(session, {}) - - def test_very_long_key(self): - verylongkey = b'a' * 1024 - import webob - request = testing.DummyRequest() - session = self._makeOne(request, secret=verylongkey) - session['a'] = 1 - callbacks = request.response_callbacks - self.assertEqual(len(callbacks), 1) - response = webob.Response() - - try: - result = callbacks[0](request, response) - except TypeError: # pragma: no cover - self.fail('HMAC failed to initialize due to key length.') - - self.assertEqual(result, None) - self.assertTrue('Set-Cookie' in dict(response.headerlist)) - - def test_bad_pickle(self): - import base64 - import hashlib - import hmac - - digestmod = lambda: hashlib.new('sha512') - # generated from dumping an object that cannot be found anymore, eg: - # class Foo: pass - # print(pickle.dumps(Foo())) - cstruct = b'(i__main__\nFoo\np0\n(dp1\nb.' - sig = hmac.new(b'pyramid.session.secret', cstruct, digestmod).digest() - cookieval = base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') - - request = testing.DummyRequest() - request.cookies['session'] = cookieval - session = self._makeOne(request, secret='secret') - self.assertEqual(session, {}) - -class TestUnencryptedCookieSession(SharedCookieSessionTests, unittest.TestCase): - def setUp(self): - super(TestUnencryptedCookieSession, self).setUp() - from zope.deprecation import __show__ - __show__.off() - - def tearDown(self): - super(TestUnencryptedCookieSession, self).tearDown() - from zope.deprecation import __show__ - __show__.on() - - def _makeOne(self, request, **kw): - from pyramid.session import UnencryptedCookieSessionFactoryConfig - self._rename_cookie_var(kw, 'path', 'cookie_path') - self._rename_cookie_var(kw, 'domain', 'cookie_domain') - self._rename_cookie_var(kw, 'secure', 'cookie_secure') - self._rename_cookie_var(kw, 'httponly', 'cookie_httponly') - self._rename_cookie_var(kw, 'set_on_exception', 'cookie_on_exception') - return UnencryptedCookieSessionFactoryConfig('secret', **kw)(request) - - def _rename_cookie_var(self, kw, src, dest): - if src in kw: - kw.setdefault(dest, kw.pop(src)) - - def _serialize(self, value): - from pyramid.compat import bytes_ - from pyramid.session import signed_serialize - return bytes_(signed_serialize(value, 'secret')) - - def test_serialize_option(self): - from pyramid.response import Response - secret = 'secret' - request = testing.DummyRequest() - session = self._makeOne(request, - signed_serialize=dummy_signed_serialize) - session['key'] = 'value' - response = Response() - self.assertEqual(session._set_cookie(response), True) - cookie = response.headerlist[-1][1] - expected_cookieval = dummy_signed_serialize( - (session.accessed, session.created, {'key': 'value'}), secret) - response = Response() - response.set_cookie('session', expected_cookieval, samesite='Lax') - expected_cookie = response.headerlist[-1][1] - self.assertEqual(cookie, expected_cookie) - - def test_deserialize_option(self): - import time - secret = 'secret' - request = testing.DummyRequest() - accessed = time.time() - state = {'key': 'value'} - cookieval = dummy_signed_serialize((accessed, accessed, state), secret) - request.cookies['session'] = cookieval - session = self._makeOne(request, - signed_deserialize=dummy_signed_deserialize) - self.assertEqual(dict(session), state) - -def dummy_signed_serialize(data, secret): - import base64 - from pyramid.compat import pickle, bytes_ - pickled = pickle.dumps(data) - return base64.b64encode(bytes_(secret)) + base64.b64encode(pickled) - -def dummy_signed_deserialize(serialized, secret): - import base64 - from pyramid.compat import pickle, bytes_ - serialized_data = base64.b64decode( - serialized[len(base64.b64encode(bytes_(secret))):]) - return pickle.loads(serialized_data) - -class Test_manage_accessed(unittest.TestCase): - def _makeOne(self, wrapped): - from pyramid.session import manage_accessed - return manage_accessed(wrapped) - - def test_accessed_set(self): - request = testing.DummyRequest() - session = DummySessionFactory(request) - session.renewed = 0 - wrapper = self._makeOne(session.__class__.get) - wrapper(session, 'a') - self.assertNotEqual(session.accessed, None) - self.assertTrue(session._dirty) - - def test_accessed_without_renew(self): - import time - request = testing.DummyRequest() - session = DummySessionFactory(request) - session._reissue_time = 5 - session.renewed = time.time() - wrapper = self._makeOne(session.__class__.get) - wrapper(session, 'a') - self.assertNotEqual(session.accessed, None) - self.assertFalse(session._dirty) - - def test_already_dirty(self): - request = testing.DummyRequest() - session = DummySessionFactory(request) - session.renewed = 0 - session._dirty = True - session['a'] = 1 - wrapper = self._makeOne(session.__class__.get) - self.assertEqual(wrapper.__doc__, session.get.__doc__) - result = wrapper(session, 'a') - self.assertEqual(result, 1) - callbacks = request.response_callbacks - if callbacks is not None: self.assertEqual(len(callbacks), 0) - -class Test_manage_changed(unittest.TestCase): - def _makeOne(self, wrapped): - from pyramid.session import manage_changed - return manage_changed(wrapped) - - def test_it(self): - request = testing.DummyRequest() - session = DummySessionFactory(request) - wrapper = self._makeOne(session.__class__.__setitem__) - wrapper(session, 'a', 1) - self.assertNotEqual(session.accessed, None) - self.assertTrue(session._dirty) - -def serialize(data, secret): - import hmac - import base64 - from hashlib import sha1 - from pyramid.compat import bytes_ - from pyramid.compat import native_ - from pyramid.compat import pickle - pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) - sig = hmac.new(bytes_(secret, 'utf-8'), pickled, sha1).hexdigest() - return sig + native_(base64.b64encode(pickled)) - -class Test_signed_serialize(unittest.TestCase): - def _callFUT(self, data, secret): - from pyramid.session import signed_serialize - return signed_serialize(data, secret) - - def test_it(self): - expected = serialize('123', 'secret') - result = self._callFUT('123', 'secret') - self.assertEqual(result, expected) - - def test_it_with_highorder_secret(self): - secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') - expected = serialize('123', secret) - result = self._callFUT('123', secret) - self.assertEqual(result, expected) - - def test_it_with_latin1_secret(self): - secret = b'La Pe\xc3\xb1a' - expected = serialize('123', secret) - result = self._callFUT('123', secret.decode('latin-1')) - self.assertEqual(result, expected) - -class Test_signed_deserialize(unittest.TestCase): - def _callFUT(self, serialized, secret, hmac=None): - if hmac is None: - import hmac - from pyramid.session import signed_deserialize - return signed_deserialize(serialized, secret, hmac=hmac) - - def test_it(self): - serialized = serialize('123', 'secret') - result = self._callFUT(serialized, 'secret') - self.assertEqual(result, '123') - - def test_invalid_bits(self): - serialized = serialize('123', 'secret') - self.assertRaises(ValueError, self._callFUT, serialized, 'seekrit') - - def test_invalid_len(self): - class hmac(object): - def new(self, *arg): - return self - def hexdigest(self): - return '1234' - serialized = serialize('123', 'secret123') - self.assertRaises(ValueError, self._callFUT, serialized, 'secret', - hmac=hmac()) - - def test_it_bad_encoding(self): - serialized = 'bad' + serialize('123', 'secret') - self.assertRaises(ValueError, self._callFUT, serialized, 'secret') - - def test_it_with_highorder_secret(self): - secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') - serialized = serialize('123', secret) - result = self._callFUT(serialized, secret) - self.assertEqual(result, '123') - - # bwcompat with pyramid <= 1.5b1 where latin1 is the default - def test_it_with_latin1_secret(self): - secret = b'La Pe\xc3\xb1a' - serialized = serialize('123', secret) - result = self._callFUT(serialized, secret.decode('latin-1')) - self.assertEqual(result, '123') - - -class TestPickleSerializer(unittest.TestCase): - def _makeOne(self): - from pyramid.session import PickleSerializer - return PickleSerializer() - - def test_loads(self): - # generated from dumping Dummy() using protocol=2 - cstruct = b'\x80\x02cpyramid.tests.test_session\nDummy\nq\x00)\x81q\x01.' - serializer = self._makeOne() - result = serializer.loads(cstruct) - self.assertIsInstance(result, Dummy) - - def test_loads_raises_ValueError_on_invalid_data(self): - cstruct = b'not pickled' - serializer = self._makeOne() - self.assertRaises(ValueError, serializer.loads, cstruct) - - def test_loads_raises_ValueError_on_bad_import(self): - # generated from dumping an object that cannot be found anymore, eg: - # class Foo: pass - # print(pickle.dumps(Foo())) - cstruct = b'(i__main__\nFoo\np0\n(dp1\nb.' - serializer = self._makeOne() - self.assertRaises(ValueError, serializer.loads, cstruct) - - def test_dumps(self): - obj = Dummy() - serializer = self._makeOne() - result = serializer.dumps(obj) - expected_result = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL) - self.assertEqual(result, expected_result) - self.assertIsInstance(result, bytes) - - -class Dummy(object): - pass - - -class DummySerializer(object): - def dumps(self, value): - return base64.b64encode(json.dumps(value).encode('utf-8')) - - def loads(self, value): - try: - return json.loads(base64.b64decode(value).decode('utf-8')) - - # base64.b64decode raises a TypeError on py2 instead of a ValueError - # and a ValueError is required for the session to handle it properly - except TypeError: - raise ValueError - -class DummySessionFactory(dict): - _dirty = False - _cookie_name = 'session' - _cookie_max_age = None - _cookie_path = '/' - _cookie_domain = None - _cookie_secure = False - _cookie_httponly = False - _timeout = 1200 - _reissue_time = 0 - - def __init__(self, request): - self.request = request - dict.__init__(self, {}) - - def changed(self): - self._dirty = True - -class DummyResponse(object): - def __init__(self): - self.headerlist = [] diff --git a/src/pyramid/tests/test_settings.py b/src/pyramid/tests/test_settings.py deleted file mode 100644 index a586cb6fd..000000000 --- a/src/pyramid/tests/test_settings.py +++ /dev/null @@ -1,80 +0,0 @@ -import unittest - -class Test_asbool(unittest.TestCase): - def _callFUT(self, s): - from pyramid.settings import asbool - return asbool(s) - - def test_s_is_None(self): - result = self._callFUT(None) - self.assertEqual(result, False) - - def test_s_is_True(self): - result = self._callFUT(True) - self.assertEqual(result, True) - - def test_s_is_False(self): - result = self._callFUT(False) - self.assertEqual(result, False) - - def test_s_is_true(self): - result = self._callFUT('True') - self.assertEqual(result, True) - - def test_s_is_false(self): - result = self._callFUT('False') - self.assertEqual(result, False) - - def test_s_is_yes(self): - result = self._callFUT('yes') - self.assertEqual(result, True) - - def test_s_is_on(self): - result = self._callFUT('on') - self.assertEqual(result, True) - - def test_s_is_1(self): - result = self._callFUT(1) - self.assertEqual(result, True) - -class Test_aslist_cronly(unittest.TestCase): - def _callFUT(self, val): - from pyramid.settings import aslist_cronly - return aslist_cronly(val) - - def test_with_list(self): - result = self._callFUT(['abc', 'def']) - self.assertEqual(result, ['abc', 'def']) - - def test_with_string(self): - result = self._callFUT('abc def') - self.assertEqual(result, ['abc def']) - - def test_with_string_crsep(self): - result = self._callFUT(' abc\n def') - self.assertEqual(result, ['abc', 'def']) - -class Test_aslist(unittest.TestCase): - def _callFUT(self, val, **kw): - from pyramid.settings import aslist - return aslist(val, **kw) - - def test_with_list(self): - result = self._callFUT(['abc', 'def']) - self.assertEqual(list(result), ['abc', 'def']) - - def test_with_string(self): - result = self._callFUT('abc def') - self.assertEqual(result, ['abc', 'def']) - - def test_with_string_crsep(self): - result = self._callFUT(' abc\n def') - self.assertEqual(result, ['abc', 'def']) - - def test_with_string_crsep_spacesep(self): - result = self._callFUT(' abc\n def ghi') - self.assertEqual(result, ['abc', 'def', 'ghi']) - - def test_with_string_crsep_spacesep_no_flatten(self): - result = self._callFUT(' abc\n def ghi ', flatten=False) - self.assertEqual(result, ['abc', 'def ghi']) diff --git a/src/pyramid/tests/test_static.py b/src/pyramid/tests/test_static.py deleted file mode 100644 index f76cc5067..000000000 --- a/src/pyramid/tests/test_static.py +++ /dev/null @@ -1,477 +0,0 @@ -import datetime -import os.path -import unittest - -here = os.path.dirname(__file__) - -# 5 years from now (more or less) -fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) - -class Test_static_view_use_subpath_False(unittest.TestCase): - def _getTargetClass(self): - from pyramid.static import static_view - return static_view - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def _makeRequest(self, kw=None): - from pyramid.request import Request - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'6543', - 'PATH_INFO':'/', - 'SCRIPT_NAME':'', - 'REQUEST_METHOD':'GET', - } - if kw is not None: - environ.update(kw) - return Request(environ=environ) - - def test_ctor_defaultargs(self): - inst = self._makeOne('package:resource_name') - self.assertEqual(inst.package_name, 'package') - self.assertEqual(inst.docroot, 'resource_name') - self.assertEqual(inst.cache_max_age, 3600) - self.assertEqual(inst.index, 'index.html') - - def test_call_adds_slash_path_info_empty(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':''}) - context = DummyContext() - from pyramid.httpexceptions import HTTPMovedPermanently - self.assertRaises(HTTPMovedPermanently, inst, context, request) - - def test_path_info_slash_means_index_html(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - - def test_oob_singledot(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/./index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertEqual(response.status, '200 OK') - self.assertTrue(b'static' in response.body) - - def test_oob_emptyelement(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'//index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertEqual(response.status, '200 OK') - self.assertTrue(b'static' in response.body) - - def test_oob_dotdotslash(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/subdir/../../minimal.pt'}) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_dotdotslash_encoded(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest( - {'PATH_INFO':'/subdir/%2E%2E%2F%2E%2E/minimal.pt'}) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_os_sep(self): - import os - inst = self._makeOne('pyramid.tests:fixtures/static') - dds = '..' + os.sep - request = self._makeRequest({'PATH_INFO':'/subdir/%s%sminimal.pt' % - (dds, dds)}) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_resource_doesnt_exist(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/notthere'}) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_resource_isdir(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/subdir/'}) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'subdir' in response.body) - - def test_resource_is_file(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - - def test_resource_is_file_with_wsgi_file_wrapper(self): - from pyramid.response import _BLOCK_SIZE - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/index.html'}) - class _Wrapper(object): - def __init__(self, file, block_size=None): - self.file = file - self.block_size = block_size - request.environ['wsgi.file_wrapper'] = _Wrapper - context = DummyContext() - response = inst(context, request) - app_iter = response.app_iter - self.assertTrue(isinstance(app_iter, _Wrapper)) - self.assertTrue(b'static' in app_iter.file.read()) - self.assertEqual(app_iter.block_size, _BLOCK_SIZE) - app_iter.file.close() - - def test_resource_is_file_with_cache_max_age(self): - inst = self._makeOne('pyramid.tests:fixtures/static', cache_max_age=600) - request = self._makeRequest({'PATH_INFO':'/index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - self.assertEqual(len(response.headerlist), 5) - header_names = [ x[0] for x in response.headerlist ] - header_names.sort() - self.assertEqual(header_names, - ['Cache-Control', 'Content-Length', 'Content-Type', - 'Expires', 'Last-Modified']) - - def test_resource_is_file_with_no_cache_max_age(self): - inst = self._makeOne('pyramid.tests:fixtures/static', - cache_max_age=None) - request = self._makeRequest({'PATH_INFO':'/index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - self.assertEqual(len(response.headerlist), 3) - header_names = [ x[0] for x in response.headerlist ] - header_names.sort() - self.assertEqual( - header_names, - ['Content-Length', 'Content-Type', 'Last-Modified']) - - def test_resource_notmodified(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/index.html'}) - request.if_modified_since = fiveyrsfuture - context = DummyContext() - response = inst(context, request) - start_response = DummyStartResponse() - app_iter = response(request.environ, start_response) - try: - self.assertEqual(start_response.status, '304 Not Modified') - self.assertEqual(list(app_iter), []) - finally: - app_iter.close() - - def test_not_found(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/notthere.html'}) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_gz_resource_no_content_encoding(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/arcs.svg.tgz'}) - context = DummyContext() - response = inst(context, request) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'application/x-tar') - self.assertEqual(response.content_encoding, None) - response.app_iter.close() - - def test_resource_no_content_encoding(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':'/index.html'}) - context = DummyContext() - response = inst(context, request) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.content_type, 'text/html') - self.assertEqual(response.content_encoding, None) - response.app_iter.close() - -class Test_static_view_use_subpath_True(unittest.TestCase): - def _getTargetClass(self): - from pyramid.static import static_view - return static_view - - def _makeOne(self, *arg, **kw): - kw['use_subpath'] = True - return self._getTargetClass()(*arg, **kw) - - def _makeRequest(self, kw=None): - from pyramid.request import Request - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'6543', - 'PATH_INFO':'/', - 'SCRIPT_NAME':'', - 'REQUEST_METHOD':'GET', - } - if kw is not None: - environ.update(kw) - return Request(environ=environ) - - def test_ctor_defaultargs(self): - inst = self._makeOne('package:resource_name') - self.assertEqual(inst.package_name, 'package') - self.assertEqual(inst.docroot, 'resource_name') - self.assertEqual(inst.cache_max_age, 3600) - self.assertEqual(inst.index, 'index.html') - - def test_call_adds_slash_path_info_empty(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest({'PATH_INFO':''}) - request.subpath = () - context = DummyContext() - from pyramid.httpexceptions import HTTPMovedPermanently - self.assertRaises(HTTPMovedPermanently, inst, context, request) - - def test_path_info_slash_means_index_html(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = () - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - - def test_oob_singledot(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('.', 'index.html') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_emptyelement(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('', 'index.html') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_dotdotslash(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('subdir', '..', '..', 'minimal.pt') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_dotdotslash_encoded(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('subdir', '%2E%2E', '%2E%2E', 'minimal.pt') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_oob_os_sep(self): - import os - inst = self._makeOne('pyramid.tests:fixtures/static') - dds = '..' + os.sep - request = self._makeRequest() - request.subpath = ('subdir', dds, dds, 'minimal.pt') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_resource_doesnt_exist(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('notthere,') - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - - def test_resource_isdir(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('subdir',) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'subdir' in response.body) - - def test_resource_is_file(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('index.html',) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - - def test_resource_is_file_with_cache_max_age(self): - inst = self._makeOne('pyramid.tests:fixtures/static', cache_max_age=600) - request = self._makeRequest() - request.subpath = ('index.html',) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - self.assertEqual(len(response.headerlist), 5) - header_names = [ x[0] for x in response.headerlist ] - header_names.sort() - self.assertEqual(header_names, - ['Cache-Control', 'Content-Length', 'Content-Type', - 'Expires', 'Last-Modified']) - - def test_resource_is_file_with_no_cache_max_age(self): - inst = self._makeOne('pyramid.tests:fixtures/static', - cache_max_age=None) - request = self._makeRequest() - request.subpath = ('index.html',) - context = DummyContext() - response = inst(context, request) - self.assertTrue(b'static' in response.body) - self.assertEqual(len(response.headerlist), 3) - header_names = [ x[0] for x in response.headerlist ] - header_names.sort() - self.assertEqual( - header_names, - ['Content-Length', 'Content-Type', 'Last-Modified']) - - def test_resource_notmodified(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.if_modified_since = fiveyrsfuture - request.subpath = ('index.html',) - context = DummyContext() - response = inst(context, request) - start_response = DummyStartResponse() - app_iter = response(request.environ, start_response) - try: - self.assertEqual(start_response.status, '304 Not Modified') - self.assertEqual(list(app_iter), []) - finally: - app_iter.close() - - def test_not_found(self): - inst = self._makeOne('pyramid.tests:fixtures/static') - request = self._makeRequest() - request.subpath = ('notthere.html',) - context = DummyContext() - from pyramid.httpexceptions import HTTPNotFound - self.assertRaises(HTTPNotFound, inst, context, request) - -class TestQueryStringConstantCacheBuster(unittest.TestCase): - - def _makeOne(self, param=None): - from pyramid.static import QueryStringConstantCacheBuster as cls - if param: - inst = cls('foo', param) - else: - inst = cls('foo') - return inst - - def test_token(self): - fut = self._makeOne().tokenize - self.assertEqual(fut(None, 'whatever', None), 'foo') - - def test_it(self): - fut = self._makeOne() - self.assertEqual( - fut('foo', 'bar', {}), - ('bar', {'_query': {'x': 'foo'}})) - - def test_change_param(self): - fut = self._makeOne('y') - self.assertEqual( - fut('foo', 'bar', {}), - ('bar', {'_query': {'y': 'foo'}})) - - def test_query_is_already_tuples(self): - fut = self._makeOne() - self.assertEqual( - fut('foo', 'bar', {'_query': [('a', 'b')]}), - ('bar', {'_query': (('a', 'b'), ('x', 'foo'))})) - - def test_query_is_tuple_of_tuples(self): - fut = self._makeOne() - self.assertEqual( - fut('foo', 'bar', {'_query': (('a', 'b'),)}), - ('bar', {'_query': (('a', 'b'), ('x', 'foo'))})) - -class TestManifestCacheBuster(unittest.TestCase): - - def _makeOne(self, path, **kw): - from pyramid.static import ManifestCacheBuster as cls - return cls(path, **kw) - - def test_it(self): - manifest_path = os.path.join(here, 'fixtures', 'manifest.json') - fut = self._makeOne(manifest_path) - self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-test.css', {})) - - def test_it_with_relspec(self): - fut = self._makeOne('fixtures/manifest.json') - self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-test.css', {})) - - def test_it_with_absspec(self): - fut = self._makeOne('pyramid.tests:fixtures/manifest.json') - self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-test.css', {})) - - def test_reload(self): - manifest_path = os.path.join(here, 'fixtures', 'manifest.json') - new_manifest_path = os.path.join(here, 'fixtures', 'manifest2.json') - inst = self._makeOne('foo', reload=True) - inst.getmtime = lambda *args, **kwargs: 0 - fut = inst - - # test without a valid manifest - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main.css', {})) - - # swap to a real manifest, setting mtime to 0 - inst.manifest_path = manifest_path - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-test.css', {})) - - # ensure switching the path doesn't change the result - inst.manifest_path = new_manifest_path - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-test.css', {})) - - # update mtime, should cause a reload - inst.getmtime = lambda *args, **kwargs: 1 - self.assertEqual( - fut('foo', 'css/main.css', {}), - ('css/main-678b7c80.css', {})) - - def test_invalid_manifest(self): - self.assertRaises(IOError, lambda: self._makeOne('foo')) - - def test_invalid_manifest_with_reload(self): - inst = self._makeOne('foo', reload=True) - self.assertEqual(inst.manifest, {}) - -class DummyContext: - pass - -class DummyStartResponse: - status = () - headers = () - def __call__(self, status, headers): - self.status = status - self.headers = headers diff --git a/src/pyramid/tests/test_testing.py b/src/pyramid/tests/test_testing.py deleted file mode 100644 index 86c219988..000000000 --- a/src/pyramid/tests/test_testing.py +++ /dev/null @@ -1,689 +0,0 @@ -import unittest -from zope.component import getSiteManager -from pyramid import testing - -class TestDummyRootFactory(unittest.TestCase): - def _makeOne(self, environ): - from pyramid.testing import DummyRootFactory - return DummyRootFactory(environ) - - def test_it(self): - environ = {'bfg.routes.matchdict':{'a':1}} - factory = self._makeOne(environ) - self.assertEqual(factory.a, 1) - -class TestDummySecurityPolicy(unittest.TestCase): - def _getTargetClass(self): - from pyramid.testing import DummySecurityPolicy - return DummySecurityPolicy - - def _makeOne(self, userid=None, groupids=(), permissive=True): - klass = self._getTargetClass() - return klass(userid, groupids, permissive) - - def test_authenticated_userid(self): - policy = self._makeOne('user') - self.assertEqual(policy.authenticated_userid(None), 'user') - - def test_unauthenticated_userid(self): - policy = self._makeOne('user') - self.assertEqual(policy.unauthenticated_userid(None), 'user') - - def test_effective_principals_userid(self): - policy = self._makeOne('user', ('group1',)) - from pyramid.security import Everyone - from pyramid.security import Authenticated - self.assertEqual(policy.effective_principals(None), - [Everyone, Authenticated, 'user', 'group1']) - - def test_effective_principals_nouserid(self): - policy = self._makeOne() - from pyramid.security import Everyone - self.assertEqual(policy.effective_principals(None), [Everyone]) - - def test_permits(self): - policy = self._makeOne() - self.assertEqual(policy.permits(None, None, None), True) - - def test_principals_allowed_by_permission(self): - policy = self._makeOne('user', ('group1',)) - from pyramid.security import Everyone - from pyramid.security import Authenticated - result = policy.principals_allowed_by_permission(None, None) - self.assertEqual(result, [Everyone, Authenticated, 'user', 'group1']) - - def test_forget(self): - policy = self._makeOne() - self.assertEqual(policy.forget(None), []) - - def test_remember(self): - policy = self._makeOne() - self.assertEqual(policy.remember(None, None), []) - - - -class TestDummyResource(unittest.TestCase): - def _getTargetClass(self): - from pyramid.testing import DummyResource - return DummyResource - - def _makeOne(self, name=None, parent=None, **kw): - klass = self._getTargetClass() - return klass(name, parent, **kw) - - def test__setitem__and__getitem__and__delitem__and__contains__and_get(self): - class Dummy: - pass - dummy = Dummy() - resource = self._makeOne() - resource['abc'] = dummy - self.assertEqual(dummy.__name__, 'abc') - self.assertEqual(dummy.__parent__, resource) - self.assertEqual(resource['abc'], dummy) - self.assertEqual(resource.get('abc'), dummy) - self.assertRaises(KeyError, resource.__getitem__, 'none') - self.assertTrue('abc' in resource) - del resource['abc'] - self.assertFalse('abc' in resource) - self.assertEqual(resource.get('abc', 'foo'), 'foo') - self.assertEqual(resource.get('abc'), None) - - def test_extra_params(self): - resource = self._makeOne(foo=1) - self.assertEqual(resource.foo, 1) - - def test_clone(self): - resource = self._makeOne('name', 'parent', foo=1, bar=2) - clone = resource.clone('name2', 'parent2', bar=1) - self.assertEqual(clone.bar, 1) - self.assertEqual(clone.__name__, 'name2') - self.assertEqual(clone.__parent__, 'parent2') - self.assertEqual(clone.foo, 1) - - def test_keys_items_values_len(self): - class Dummy: - pass - resource = self._makeOne() - resource['abc'] = Dummy() - resource['def'] = Dummy() - L = list - self.assertEqual(L(resource.values()), L(resource.subs.values())) - self.assertEqual(L(resource.items()), L(resource.subs.items())) - self.assertEqual(L(resource.keys()), L(resource.subs.keys())) - self.assertEqual(len(resource), 2) - - def test_nonzero(self): - resource = self._makeOne() - self.assertEqual(resource.__nonzero__(), True) - - def test_bool(self): - resource = self._makeOne() - self.assertEqual(resource.__bool__(), True) - - def test_ctor_with__provides__(self): - resource = self._makeOne(__provides__=IDummy) - self.assertTrue(IDummy.providedBy(resource)) - -class TestDummyRequest(unittest.TestCase): - def _getTargetClass(self): - from pyramid.testing import DummyRequest - return DummyRequest - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def test_params(self): - request = self._makeOne(params = {'say':'Hello'}, - environ = {'PATH_INFO':'/foo'}, - headers = {'X-Foo':'YUP'}, - ) - self.assertEqual(request.params['say'], 'Hello') - self.assertEqual(request.GET['say'], 'Hello') - self.assertEqual(request.POST['say'], 'Hello') - self.assertEqual(request.headers['X-Foo'], 'YUP') - self.assertEqual(request.environ['PATH_INFO'], '/foo') - - def test_defaults(self): - from pyramid.threadlocal import get_current_registry - from pyramid.testing import DummySession - request = self._makeOne() - self.assertEqual(request.method, 'GET') - self.assertEqual(request.application_url, 'http://example.com') - self.assertEqual(request.host_url, 'http://example.com') - self.assertEqual(request.path_url, 'http://example.com') - self.assertEqual(request.url, 'http://example.com') - self.assertEqual(request.host, 'example.com:80') - self.assertEqual(request.content_length, 0) - self.assertEqual(request.environ.get('PATH_INFO'), None) - self.assertEqual(request.headers.get('X-Foo'), None) - self.assertEqual(request.params.get('foo'), None) - self.assertEqual(request.GET.get('foo'), None) - self.assertEqual(request.POST.get('foo'), None) - self.assertEqual(request.cookies.get('type'), None) - self.assertEqual(request.path, '/') - self.assertEqual(request.path_info, '/') - self.assertEqual(request.script_name, '') - self.assertEqual(request.path_qs, '') - self.assertEqual(request.view_name, '') - self.assertEqual(request.subpath, ()) - self.assertEqual(request.context, None) - self.assertEqual(request.root, None) - self.assertEqual(request.virtual_root, None) - self.assertEqual(request.virtual_root_path, ()) - self.assertEqual(request.registry, get_current_registry()) - self.assertEqual(request.session.__class__, DummySession) - - def test_params_explicit(self): - request = self._makeOne(params = {'foo':'bar'}) - self.assertEqual(request.params['foo'], 'bar') - self.assertEqual(request.GET['foo'], 'bar') - self.assertEqual(request.POST['foo'], 'bar') - - def test_environ_explicit(self): - request = self._makeOne(environ = {'PATH_INFO':'/foo'}) - self.assertEqual(request.environ['PATH_INFO'], '/foo') - - def test_headers_explicit(self): - request = self._makeOne(headers = {'X-Foo':'YUP'}) - self.assertEqual(request.headers['X-Foo'], 'YUP') - - def test_path_explicit(self): - request = self._makeOne(path = '/abc') - self.assertEqual(request.path, '/abc') - - def test_cookies_explicit(self): - request = self._makeOne(cookies = {'type': 'gingersnap'}) - self.assertEqual(request.cookies['type'], 'gingersnap') - - def test_post_explicit(self): - POST = {'foo': 'bar', 'baz': 'qux'} - request = self._makeOne(post=POST) - self.assertEqual(request.method, 'POST') - self.assertEqual(request.POST, POST) - # N.B.: Unlike a normal request, passing 'post' should *not* put - # explict POST data into params: doing so masks a possible - # XSS bug in the app. Tests for apps which don't care about - # the distinction should just use 'params'. - self.assertEqual(request.params, {}) - - def test_post_empty_shadows_params(self): - request = self._makeOne(params={'foo': 'bar'}, post={}) - self.assertEqual(request.method, 'POST') - self.assertEqual(request.params.get('foo'), 'bar') - self.assertEqual(request.POST.get('foo'), None) - - def test_kwargs(self): - request = self._makeOne(water = 1) - self.assertEqual(request.water, 1) - - def test_add_response_callback(self): - request = self._makeOne() - request.add_response_callback(1) - self.assertEqual(list(request.response_callbacks), [1]) - - def test_registry_is_config_registry_when_setup_is_called_after_ctor(self): - # see https://github.com/Pylons/pyramid/issues/165 - from pyramid.registry import Registry - from pyramid.config import Configurator - request = self._makeOne() - try: - registry = Registry('this_test') - config = Configurator(registry=registry) - config.begin() - self.assertTrue(request.registry is registry) - finally: - config.end() - - def test_set_registry(self): - request = self._makeOne() - request.registry = 'abc' - self.assertEqual(request.registry, 'abc') - - def test_del_registry(self): - # see https://github.com/Pylons/pyramid/issues/165 - from pyramid.registry import Registry - from pyramid.config import Configurator - request = self._makeOne() - request.registry = 'abc' - self.assertEqual(request.registry, 'abc') - del request.registry - try: - registry = Registry('this_test') - config = Configurator(registry=registry) - config.begin() - self.assertTrue(request.registry is registry) - finally: - config.end() - - def test_response_with_responsefactory(self): - from pyramid.registry import Registry - from pyramid.interfaces import IResponseFactory - registry = Registry('this_test') - class ResponseFactory(object): - pass - registry.registerUtility( - lambda r: ResponseFactory(), IResponseFactory - ) - request = self._makeOne() - request.registry = registry - resp = request.response - self.assertEqual(resp.__class__, ResponseFactory) - self.assertTrue(request.response is resp) # reified - - def test_response_without_responsefactory(self): - from pyramid.registry import Registry - from pyramid.response import Response - registry = Registry('this_test') - request = self._makeOne() - request.registry = registry - resp = request.response - self.assertEqual(resp.__class__, Response) - self.assertTrue(request.response is resp) # reified - - -class TestDummyTemplateRenderer(unittest.TestCase): - def _getTargetClass(self, ): - from pyramid.testing import DummyTemplateRenderer - return DummyTemplateRenderer - - def _makeOne(self, string_response=''): - return self._getTargetClass()(string_response=string_response) - - def test_implementation(self): - renderer = self._makeOne() - impl = renderer.implementation() - impl(a=1, b=2) - self.assertEqual(renderer._implementation._received['a'], 1) - self.assertEqual(renderer._implementation._received['b'], 2) - - def test_getattr(self): - renderer = self._makeOne() - renderer({'a':1}) - self.assertEqual(renderer.a, 1) - self.assertRaises(AttributeError, renderer.__getattr__, 'b') - - def test_assert_(self): - renderer = self._makeOne() - renderer({'a':1, 'b':2}) - self.assertRaises(AssertionError, renderer.assert_, c=1) - self.assertRaises(AssertionError, renderer.assert_, b=3) - self.assertTrue(renderer.assert_(a=1, b=2)) - - def test_nondefault_string_response(self): - renderer = self._makeOne('abc') - result = renderer({'a':1, 'b':2}) - self.assertEqual(result, 'abc') - -class Test_setUp(unittest.TestCase): - def _callFUT(self, **kw): - from pyramid.testing import setUp - return setUp(**kw) - - def tearDown(self): - from pyramid.threadlocal import manager - manager.clear() - getSiteManager.reset() - - def _assertSMHook(self, hook): - result = getSiteManager.sethook(None) - self.assertEqual(result, hook) - - def test_it_defaults(self): - from pyramid.threadlocal import manager - from pyramid.threadlocal import get_current_registry - from pyramid.registry import Registry - old = True - manager.push(old) - config = self._callFUT() - current = manager.get() - self.assertFalse(current is old) - self.assertEqual(config.registry, current['registry']) - self.assertEqual(current['registry'].__class__, Registry) - self.assertEqual(current['request'], None) - self.assertEqual(config.package.__name__, 'pyramid.tests') - self._assertSMHook(get_current_registry) - - def test_it_with_registry(self): - from pyramid.registry import Registry - from pyramid.threadlocal import manager - registry = Registry() - self._callFUT(registry=registry) - current = manager.get() - self.assertEqual(current['registry'], registry) - - def test_it_with_request(self): - from pyramid.threadlocal import manager - request = object() - self._callFUT(request=request) - current = manager.get() - self.assertEqual(current['request'], request) - - def test_it_with_package(self): - config = self._callFUT(package='pyramid') - self.assertEqual(config.package.__name__, 'pyramid') - - def test_it_with_hook_zca_false(self): - from pyramid.registry import Registry - registry = Registry() - self._callFUT(registry=registry, hook_zca=False) - sm = getSiteManager() - self.assertFalse(sm is registry) - - def test_it_with_settings_passed_explicit_registry(self): - from pyramid.registry import Registry - registry = Registry() - self._callFUT(registry=registry, hook_zca=False, settings=dict(a=1)) - self.assertEqual(registry.settings['a'], 1) - - def test_it_with_settings_passed_implicit_registry(self): - config = self._callFUT(hook_zca=False, settings=dict(a=1)) - self.assertEqual(config.registry.settings['a'], 1) - -class Test_cleanUp(Test_setUp): - def _callFUT(self, *arg, **kw): - from pyramid.testing import cleanUp - return cleanUp(*arg, **kw) - -class Test_tearDown(unittest.TestCase): - def _callFUT(self, **kw): - from pyramid.testing import tearDown - return tearDown(**kw) - - def tearDown(self): - from pyramid.threadlocal import manager - manager.clear() - getSiteManager.reset() - - def _assertSMHook(self, hook): - result = getSiteManager.sethook(None) - self.assertEqual(result, hook) - - def _setSMHook(self, hook): - getSiteManager.sethook(hook) - - def test_defaults(self): - from pyramid.threadlocal import manager - registry = DummyRegistry() - old = {'registry':registry} - hook = lambda *arg: None - try: - self._setSMHook(hook) - manager.push(old) - self._callFUT() - current = manager.get() - self.assertNotEqual(current, old) - self.assertEqual(registry.inited, 2) - finally: - result = getSiteManager.sethook(None) - self.assertNotEqual(result, hook) - - def test_registry_cannot_be_inited(self): - from pyramid.threadlocal import manager - registry = DummyRegistry() - def raiseit(name): - raise TypeError - registry.__init__ = raiseit - old = {'registry':registry} - try: - manager.push(old) - self._callFUT() # doesn't blow up - current = manager.get() - self.assertNotEqual(current, old) - self.assertEqual(registry.inited, 1) - finally: - manager.clear() - - def test_unhook_zc_false(self): - hook = lambda *arg: None - try: - self._setSMHook(hook) - self._callFUT(unhook_zca=False) - finally: - self._assertSMHook(hook) - -class TestDummyRendererFactory(unittest.TestCase): - def _makeOne(self, name, factory): - from pyramid.testing import DummyRendererFactory - return DummyRendererFactory(name, factory) - - def test_add_no_colon(self): - f = self._makeOne('name', None) - f.add('spec', 'renderer') - self.assertEqual(f.renderers['spec'], 'renderer') - - def test_add_with_colon(self): - f = self._makeOne('name', None) - f.add('spec:spec2', 'renderer') - self.assertEqual(f.renderers['spec:spec2'], 'renderer') - self.assertEqual(f.renderers['spec2'], 'renderer') - - def test_call(self): - f = self._makeOne('name', None) - f.renderers['spec'] = 'renderer' - info = DummyRendererInfo({'name':'spec'}) - self.assertEqual(f(info), 'renderer') - - def test_call2(self): - f = self._makeOne('name', None) - f.renderers['spec'] = 'renderer' - info = DummyRendererInfo({'name':'spec:spec'}) - self.assertEqual(f(info), 'renderer') - - def test_call3(self): - def factory(spec): - return 'renderer' - f = self._makeOne('name', factory) - info = DummyRendererInfo({'name':'spec'}) - self.assertEqual(f(info), 'renderer') - - def test_call_miss(self): - f = self._makeOne('name', None) - info = DummyRendererInfo({'name':'spec'}) - self.assertRaises(KeyError, f, info) - -class TestMockTemplate(unittest.TestCase): - def _makeOne(self, response): - from pyramid.testing import MockTemplate - return MockTemplate(response) - - def test_getattr(self): - template = self._makeOne(None) - self.assertEqual(template.foo, template) - - def test_getitem(self): - template = self._makeOne(None) - self.assertEqual(template['foo'], template) - - def test_call(self): - template = self._makeOne('123') - self.assertEqual(template(), '123') - -class Test_skip_on(unittest.TestCase): - def setUp(self): - from pyramid.testing import skip_on - self.os_name = skip_on.os_name - skip_on.os_name = 'wrong' - - def tearDown(self): - from pyramid.testing import skip_on - skip_on.os_name = self.os_name - - def _callFUT(self, *platforms): - from pyramid.testing import skip_on - return skip_on(*platforms) - - def test_wrong_platform(self): - def foo(): return True - decorated = self._callFUT('wrong')(foo) - self.assertEqual(decorated(), None) - - def test_ok_platform(self): - def foo(): return True - decorated = self._callFUT('ok')(foo) - self.assertEqual(decorated(), True) - -class TestDummySession(unittest.TestCase): - def _makeOne(self): - from pyramid.testing import DummySession - return DummySession() - - @testing.skip_on('pypy') # see https://github.com/Pylons/pyramid/issues/3237 - def test_instance_conforms(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ISession - session = self._makeOne() - verifyObject(ISession, session) - - def test_changed(self): - session = self._makeOne() - self.assertEqual(session.changed(), None) - - def test_invalidate(self): - session = self._makeOne() - session['a'] = 1 - self.assertEqual(session.invalidate(), None) - self.assertFalse('a' in session) - - def test_flash_default(self): - session = self._makeOne() - session.flash('msg1') - session.flash('msg2') - self.assertEqual(session['_f_'], ['msg1', 'msg2']) - - def test_flash_mixed(self): - session = self._makeOne() - session.flash('warn1', 'warn') - session.flash('warn2', 'warn') - session.flash('err1', 'error') - session.flash('err2', 'error') - self.assertEqual(session['_f_warn'], ['warn1', 'warn2']) - - def test_pop_flash_default_queue(self): - session = self._makeOne() - queue = ['one', 'two'] - session['_f_'] = queue - result = session.pop_flash() - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_'), None) - - def test_pop_flash_nodefault_queue(self): - session = self._makeOne() - queue = ['one', 'two'] - session['_f_error'] = queue - result = session.pop_flash('error') - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_error'), None) - - def test_peek_flash_default_queue(self): - session = self._makeOne() - queue = ['one', 'two'] - session['_f_'] = queue - result = session.peek_flash() - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_'), queue) - - def test_peek_flash_nodefault_queue(self): - session = self._makeOne() - queue = ['one', 'two'] - session['_f_error'] = queue - result = session.peek_flash('error') - self.assertEqual(result, queue) - self.assertEqual(session.get('_f_error'), queue) - - def test_new_csrf_token(self): - session = self._makeOne() - token = session.new_csrf_token() - self.assertEqual(token, session['_csrft_']) - - def test_get_csrf_token(self): - session = self._makeOne() - session['_csrft_'] = 'token' - token = session.get_csrf_token() - self.assertEqual(token, 'token') - self.assertTrue('_csrft_' in session) - - def test_get_csrf_token_generates_token(self): - session = self._makeOne() - token = session.get_csrf_token() - self.assertNotEqual(token, None) - self.assertTrue(len(token) >= 1) - -from zope.interface import Interface -from zope.interface import implementer - -class IDummy(Interface): - pass - -@implementer(IDummy) -class DummyEvent: - pass - -class DummyFactory: - def __init__(self, environ): - """ """ - -class DummyRegistry(object): - inited = 0 - __name__ = 'name' - def __init__(self, name=''): - self.inited = self.inited + 1 - -class DummyRendererInfo(object): - def __init__(self, kw): - self.__dict__.update(kw) - -class Test_testConfig(unittest.TestCase): - - def _setUp(self, **kw): - self._log.append(('setUp', kw)) - return 'fake config' - - def _tearDown(self, **kw): - self._log.append(('tearDown', kw)) - - def setUp(self): - from pyramid import testing - self._log = [] - self._orig_setUp = testing.setUp - testing.setUp = self._setUp - self._orig_tearDown = testing.tearDown - testing.tearDown = self._tearDown - - def tearDown(self): - from pyramid import testing - testing.setUp = self._orig_setUp - testing.tearDown = self._orig_tearDown - - def _callFUT(self, inner, **kw): - from pyramid.testing import testConfig - with testConfig(**kw) as config: - inner(config) - - def test_ok_calls(self): - self.assertEqual(self._log, []) - def inner(config): - self.assertEqual(self._log, - [('setUp', - {'autocommit': True, - 'hook_zca': True, - 'registry': None, - 'request': None, - 'settings': None})]) - self._log.pop() - self._callFUT(inner) - self.assertEqual(self._log, - [('tearDown', {'unhook_zca': True})]) - - def test_teardown_called_on_exception(self): - class TestException(Exception): - pass - def inner(config): - self._log = [] - raise TestException('oops') - self.assertRaises(TestException, self._callFUT, inner) - self.assertEqual(self._log[0][0], 'tearDown') - - def test_ok_get_config(self): - def inner(config): - self.assertEqual(config, 'fake config') - self._callFUT(inner) diff --git a/src/pyramid/tests/test_threadlocal.py b/src/pyramid/tests/test_threadlocal.py deleted file mode 100644 index 088156507..000000000 --- a/src/pyramid/tests/test_threadlocal.py +++ /dev/null @@ -1,95 +0,0 @@ -from pyramid import testing -import unittest - -class TestThreadLocalManager(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTargetClass(self): - from pyramid.threadlocal import ThreadLocalManager - return ThreadLocalManager - - def _makeOne(self, default=lambda *x: 1): - return self._getTargetClass()(default) - - def test_init(self): - local = self._makeOne() - self.assertEqual(local.stack, []) - self.assertEqual(local.get(), 1) - - def test_default(self): - def thedefault(): - return '123' - local = self._makeOne(thedefault) - self.assertEqual(local.stack, []) - self.assertEqual(local.get(), '123') - - def test_push_and_pop(self): - local = self._makeOne() - local.push(True) - self.assertEqual(local.get(), True) - self.assertEqual(local.pop(), True) - self.assertEqual(local.pop(), None) - self.assertEqual(local.get(), 1) - - def test_set_get_and_clear(self): - local = self._makeOne() - local.set(None) - self.assertEqual(local.stack, [None]) - self.assertEqual(local.get(), None) - local.clear() - self.assertEqual(local.get(), 1) - local.clear() - self.assertEqual(local.get(), 1) - - -class TestGetCurrentRequest(unittest.TestCase): - def _callFUT(self): - from pyramid.threadlocal import get_current_request - return get_current_request() - - def test_it_None(self): - request = self._callFUT() - self.assertEqual(request, None) - - def test_it(self): - from pyramid.threadlocal import manager - request = object() - try: - manager.push({'request':request}) - self.assertEqual(self._callFUT(), request) - finally: - manager.pop() - self.assertEqual(self._callFUT(), None) - -class GetCurrentRegistryTests(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _callFUT(self): - from pyramid.threadlocal import get_current_registry - return get_current_registry() - - def test_it(self): - from pyramid.threadlocal import manager - try: - manager.push({'registry':123}) - self.assertEqual(self._callFUT(), 123) - finally: - manager.pop() - -class GetCurrentRegistryWithoutTestingRegistry(unittest.TestCase): - def _callFUT(self): - from pyramid.threadlocal import get_current_registry - return get_current_registry() - - def test_it(self): - from pyramid.registry import global_registry - self.assertEqual(self._callFUT(), global_registry) - diff --git a/src/pyramid/tests/test_traversal.py b/src/pyramid/tests/test_traversal.py deleted file mode 100644 index 437fe46df..000000000 --- a/src/pyramid/tests/test_traversal.py +++ /dev/null @@ -1,1221 +0,0 @@ -# -*- coding: utf-8 -*- -import unittest - -from pyramid.testing import cleanUp - -from pyramid.compat import ( - text_, - native_, - text_type, - url_quote, - PY2, - ) - -class TraversalPathTests(unittest.TestCase): - def _callFUT(self, path): - from pyramid.traversal import traversal_path - return traversal_path(path) - - def test_utf8(self): - la = b'La Pe\xc3\xb1a' - encoded = url_quote(la) - decoded = text_(la, 'utf-8') - path = '/'.join([encoded, encoded]) - result = self._callFUT(path) - self.assertEqual(result, (decoded, decoded)) - - def test_utf16(self): - from pyramid.exceptions import URLDecodeError - la = text_(b'La Pe\xc3\xb1a', 'utf-8').encode('utf-16') - encoded = url_quote(la) - path = '/'.join([encoded, encoded]) - self.assertRaises(URLDecodeError, self._callFUT, path) - - def test_unicode_highorder_chars(self): - path = text_('/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') - self.assertEqual(self._callFUT(path), - (text_('\u6d41\u884c\u8d8b\u52bf', 'unicode_escape'),)) - - def test_element_urllquoted(self): - self.assertEqual(self._callFUT('/foo/space%20thing/bar'), - (text_('foo'), text_('space thing'), text_('bar'))) - - def test_unicode_undecodeable_to_ascii(self): - path = text_(b'/La Pe\xc3\xb1a', 'utf-8') - self.assertRaises(UnicodeEncodeError, self._callFUT, path) - -class TraversalPathInfoTests(unittest.TestCase): - def _callFUT(self, path): - from pyramid.traversal import traversal_path_info - return traversal_path_info(path) - - def test_path_startswith_endswith(self): - self.assertEqual(self._callFUT('/foo/'), (text_('foo'),)) - - def test_empty_elements(self): - self.assertEqual(self._callFUT('foo///'), (text_('foo'),)) - - def test_onedot(self): - self.assertEqual(self._callFUT('foo/./bar'), - (text_('foo'), text_('bar'))) - - def test_twodots(self): - self.assertEqual(self._callFUT('foo/../bar'), (text_('bar'),)) - - def test_twodots_at_start(self): - self.assertEqual(self._callFUT('../../bar'), (text_('bar'),)) - - def test_segments_are_unicode(self): - result = self._callFUT('/foo/bar') - self.assertEqual(type(result[0]), text_type) - self.assertEqual(type(result[1]), text_type) - - def test_same_value_returned_if_cached(self): - result1 = self._callFUT('/foo/bar') - result2 = self._callFUT('/foo/bar') - self.assertEqual(result1, (text_('foo'), text_('bar'))) - self.assertEqual(result2, (text_('foo'), text_('bar'))) - - def test_unicode_simple(self): - path = text_('/abc') - self.assertEqual(self._callFUT(path), (text_('abc'),)) - - def test_highorder(self): - la = b'La Pe\xc3\xb1a' - latin1 = native_(la) - result = self._callFUT(latin1) - self.assertEqual(result, (text_(la, 'utf-8'),)) - - def test_highorder_undecodeable(self): - from pyramid.exceptions import URLDecodeError - la = text_(b'La Pe\xc3\xb1a', 'utf-8') - notlatin1 = native_(la) - self.assertRaises(URLDecodeError, self._callFUT, notlatin1) - -class ResourceTreeTraverserTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _getTargetClass(self): - from pyramid.traversal import ResourceTreeTraverser - return ResourceTreeTraverser - - def _makeOne(self, *arg, **kw): - klass = self._getTargetClass() - return klass(*arg, **kw) - - def _getEnviron(self, **kw): - environ = {} - environ.update(kw) - return environ - - def test_class_conforms_to_ITraverser(self): - from zope.interface.verify import verifyClass - from pyramid.interfaces import ITraverser - verifyClass(ITraverser, self._getTargetClass()) - - def test_instance_conforms_to_ITraverser(self): - from zope.interface.verify import verifyObject - from pyramid.interfaces import ITraverser - context = DummyContext() - verifyObject(ITraverser, self._makeOne(context)) - - def test_call_with_empty_pathinfo(self): - policy = self._makeOne(None) - environ = self._getEnviron() - request = DummyRequest(environ, path_info='') - result = policy(request) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_pathinfo_KeyError(self): - policy = self._makeOne(None) - environ = self._getEnviron() - request = DummyRequest(environ, toraise=KeyError) - result = policy(request) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_pathinfo_highorder(self): - path = text_(b'/Qu\xc3\xa9bec', 'utf-8') - foo = DummyContext(None, path) - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=path) - result = policy(request) - self.assertEqual(result['context'], foo) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (path[1:],)) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_pathel_with_no_getitem(self): - policy = self._makeOne(None) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=text_('/foo/bar')) - result = policy(request) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_emptypath_nosubpath(self): - root = DummyContext() - policy = self._makeOne(root) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=text_('')) - result = policy(request) - self.assertEqual(result['context'], root) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_withpath_nosubpath(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=text_('/foo/bar')) - result = policy(request) - self.assertEqual(result['context'], foo) - self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], (text_('foo'),)) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_withconn_getitem_withpath_withsubpath(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) - result = policy(request) - self.assertEqual(result['context'], foo) - self.assertEqual(result['view_name'], 'bar') - self.assertEqual(result['subpath'], ('baz', 'buz')) - self.assertEqual(result['traversed'], (text_('foo'),)) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_explicit_viewname(self): - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron() - request = DummyRequest(environ, path_info=text_('/@@foo')) - result = policy(request) - self.assertEqual(result['context'], root) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_vh_root(self): - environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - request = DummyRequest(environ, path_info=text_('/baz')) - result = policy(request) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], - (text_('foo'), text_('bar'), text_('baz'))) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], bar) - self.assertEqual(result['virtual_root_path'], - (text_('foo'), text_('bar'))) - - def test_call_with_vh_root2(self): - environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - request = DummyRequest(environ, path_info=text_('/bar/baz')) - result = policy(request) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], - (text_('foo'), text_('bar'), text_('baz'))) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], foo) - self.assertEqual(result['virtual_root_path'], (text_('foo'),)) - - def test_call_with_vh_root3(self): - environ = self._getEnviron(HTTP_X_VHM_ROOT='/') - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - policy = self._makeOne(root) - request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) - result = policy(request) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], - (text_('foo'), text_('bar'), text_('baz'))) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_vh_root4(self): - environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar/baz') - baz = DummyContext(None, 'baz') - bar = DummyContext(baz, 'bar') - foo = DummyContext(bar, 'foo') - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - request = DummyRequest(environ, path_info=text_('/')) - result = policy(request) - self.assertEqual(result['context'], baz) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], - (text_('foo'), text_('bar'), text_('baz'))) - self.assertEqual(result['root'], root) - self.assertEqual(result['virtual_root'], baz) - self.assertEqual(result['virtual_root_path'], - (text_('foo'), text_('bar'), text_('baz'))) - - def test_call_with_vh_root_path_root(self): - policy = self._makeOne(None) - environ = self._getEnviron(HTTP_X_VHM_ROOT='/') - request = DummyRequest(environ, path_info=text_('/')) - result = policy(request) - self.assertEqual(result['context'], None) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], policy.root) - self.assertEqual(result['virtual_root_path'], ()) - - def test_call_with_vh_root_highorder(self): - path = text_(b'Qu\xc3\xa9bec', 'utf-8') - bar = DummyContext(None, 'bar') - foo = DummyContext(bar, path) - root = DummyContext(foo, 'root') - policy = self._makeOne(root) - if PY2: - vhm_root = b'/Qu\xc3\xa9bec' - else: - vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') - environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) - request = DummyRequest(environ, path_info=text_('/bar')) - result = policy(request) - self.assertEqual(result['context'], bar) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual( - result['traversed'], - (path, text_('bar')) - ) - self.assertEqual(result['root'], policy.root) - self.assertEqual(result['virtual_root'], foo) - self.assertEqual( - result['virtual_root_path'], - (path,) - ) - - def test_path_info_raises_unicodedecodeerror(self): - from pyramid.exceptions import URLDecodeError - foo = DummyContext() - root = DummyContext(foo) - policy = self._makeOne(root) - environ = self._getEnviron() - toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5') - request = DummyRequest(environ, toraise=toraise) - request.matchdict = None - self.assertRaises(URLDecodeError, policy, request) - - def test_withroute_nothingfancy(self): - resource = DummyContext() - traverser = self._makeOne(resource) - request = DummyRequest({}) - request.matchdict = {} - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_with_subpath_string(self): - resource = DummyContext() - traverser = self._makeOne(resource) - matchdict = {'subpath':'/a/b/c'} - request = DummyRequest({}) - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ('a', 'b','c')) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_with_subpath_tuple(self): - resource = DummyContext() - traverser = self._makeOne(resource) - matchdict = {'subpath':('a', 'b', 'c')} - request = DummyRequest({}) - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ('a', 'b','c')) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_string(self): - resource = DummyContext() - traverser = self._makeOne(resource) - matchdict = {'traverse':text_('foo/bar')} - request = DummyRequest({}) - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_tuple(self): - resource = DummyContext() - traverser = self._makeOne(resource) - matchdict = {'traverse':('foo', 'bar')} - request = DummyRequest({}) - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_empty(self): - resource = DummyContext() - traverser = self._makeOne(resource) - matchdict = {'traverse':''} - request = DummyRequest({}) - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], resource) - self.assertEqual(result['view_name'], '') - self.assertEqual(result['subpath'], ()) - self.assertEqual(result['traversed'], ()) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], resource) - self.assertEqual(result['virtual_root_path'], ()) - - def test_withroute_and_traverse_and_vroot(self): - abc = DummyContext() - resource = DummyContext(next=abc) - environ = self._getEnviron(HTTP_X_VHM_ROOT='/abc') - request = DummyRequest(environ) - traverser = self._makeOne(resource) - matchdict = {'traverse':text_('/foo/bar')} - request.matchdict = matchdict - result = traverser(request) - self.assertEqual(result['context'], abc) - self.assertEqual(result['view_name'], 'foo') - self.assertEqual(result['subpath'], ('bar',)) - self.assertEqual(result['traversed'], ('abc', 'foo')) - self.assertEqual(result['root'], resource) - self.assertEqual(result['virtual_root'], abc) - self.assertEqual(result['virtual_root_path'], ('abc',)) - -class FindInterfaceTests(unittest.TestCase): - def _callFUT(self, context, iface): - from pyramid.traversal import find_interface - return find_interface(context, iface) - - def test_it_interface(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = 'root' - foo.__parent__ = root - foo.__name__ = 'foo' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - from zope.interface import directlyProvides - from zope.interface import Interface - class IFoo(Interface): - pass - directlyProvides(root, IFoo) - result = self._callFUT(baz, IFoo) - self.assertEqual(result.__name__, 'root') - - def test_it_class(self): - class DummyRoot(object): - def __init__(self, child): - self.child = child - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyRoot(foo) - root.__parent__ = None - root.__name__ = 'root' - foo.__parent__ = root - foo.__name__ = 'foo' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, DummyRoot) - self.assertEqual(result.__name__, 'root') - -class FindRootTests(unittest.TestCase): - def _callFUT(self, context): - from pyramid.traversal import find_root - return find_root(context) - - def test_it(self): - dummy = DummyContext() - baz = DummyContext() - baz.__parent__ = dummy - baz.__name__ = 'baz' - dummy.__parent__ = None - dummy.__name__ = None - result = self._callFUT(baz) - self.assertEqual(result, dummy) - -class FindResourceTests(unittest.TestCase): - def _callFUT(self, context, name): - from pyramid.traversal import find_resource - return find_resource(context, name) - - def _registerTraverser(self, traverser): - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - from pyramid.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_list(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, ['']) - self.assertEqual(result, resource) - self.assertEqual(resource.request.environ['PATH_INFO'], '/') - - def test_generator(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - def foo(): - yield '' - result = self._callFUT(resource, foo()) - self.assertEqual(result, resource) - self.assertEqual(resource.request.environ['PATH_INFO'], '/') - - def test_self_string_found(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, '') - self.assertEqual(result, resource) - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_self_tuple_found(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, ()) - self.assertEqual(result, resource) - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_relative_string_found(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, 'baz') - self.assertEqual(result, baz) - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_found(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, ('baz',)) - self.assertEqual(result, baz) - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_relative_string_notfound(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':'bar'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, resource, 'baz') - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_notfound(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':'bar'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, resource, ('baz',)) - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_absolute_string_found(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, '/') - self.assertEqual(result, root) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_found(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(resource, ('',)) - self.assertEqual(result, root) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_string_notfound(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':'fuz'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, resource, '/') - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_notfound(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':'fuz'}) - self._registerTraverser(traverser) - self.assertRaises(KeyError, self._callFUT, resource, ('',)) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_unicode_found(self): - # test for bug wiggy found in wild, traceback stack: - # root = u'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF' - # wiggy's code: section=find_resource(page, root) - # find_resource L76: D = traverse(resource, path) - # traverse L291: return traverser(request) - # __call__ line 568: vpath_tuple = traversal_path(vpath) - # lru_cached line 91: f(*arg) - # traversal_path line 443: path.encode('ascii') - # UnicodeEncodeError: 'ascii' codec can't encode characters in - # position 1-12: ordinal not in range(128) - # - # solution: encode string to ascii in pyramid.traversal.traverse - # before passing it along to webob as path_info - from pyramid.traversal import ResourceTreeTraverser - unprintable = DummyContext() - root = DummyContext(unprintable) - unprintable.__parent__ = root - unprintable.__name__ = text_( - b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8') - root.__parent__ = None - root.__name__ = None - traverser = ResourceTreeTraverser - self._registerTraverser(traverser) - result = self._callFUT( - root, - text_(b'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') - ) - self.assertEqual(result, unprintable) - -class ResourcePathTests(unittest.TestCase): - def _callFUT(self, resource, *elements): - from pyramid.traversal import resource_path - return resource_path(resource, *elements) - - def test_it(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, 'this/theotherthing', 'that') - self.assertEqual(result, '/foo%20/bar/baz/this%2Ftheotherthing/that') - - def test_root_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - result = self._callFUT(root) - self.assertEqual(result, '/') - - def test_root_default_emptystring(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = '' - result = self._callFUT(root) - self.assertEqual(result, '/') - - def test_root_object_nonnull_name_direct(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = 'flubadub' - result = self._callFUT(root) - self.assertEqual(result, 'flubadub') # insane case - - def test_root_object_nonnull_name_indirect(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = 'flubadub' - other = DummyContext() - other.__parent__ = root - other.__name__ = 'barker' - result = self._callFUT(other) - self.assertEqual(result, 'flubadub/barker') # insane case - - def test_nonroot_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = 'other' - result = self._callFUT(other) - self.assertEqual(result, '/other') - - def test_path_with_None_itermediate_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = None - other2 = DummyContext() - other2.__parent__ = other - other2.__name__ = 'other2' - result = self._callFUT(other2) - self.assertEqual(result, '//other2') - -class ResourcePathTupleTests(unittest.TestCase): - def _callFUT(self, resource, *elements): - from pyramid.traversal import resource_path_tuple - return resource_path_tuple(resource, *elements) - - def test_it(self): - baz = DummyContext() - bar = DummyContext(baz) - foo = DummyContext(bar) - root = DummyContext(foo) - root.__parent__ = None - root.__name__ = None - foo.__parent__ = root - foo.__name__ = 'foo ' - bar.__parent__ = foo - bar.__name__ = 'bar' - baz.__parent__ = bar - baz.__name__ = 'baz' - result = self._callFUT(baz, 'this/theotherthing', 'that') - self.assertEqual(result, ('','foo ', 'bar', 'baz', 'this/theotherthing', - 'that')) - - def test_root_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - result = self._callFUT(root) - self.assertEqual(result, ('',)) - - def test_root_default_emptystring_name(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = '' - other = DummyContext() - other.__parent__ = root - other.__name__ = 'other' - result = self._callFUT(other) - self.assertEqual(result, ('', 'other',)) - - def test_nonroot_default(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = 'other' - result = self._callFUT(other) - self.assertEqual(result, ('', 'other')) - - def test_path_with_None_itermediate_names(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - other = DummyContext() - other.__parent__ = root - other.__name__ = None - other2 = DummyContext() - other2.__parent__ = other - other2.__name__ = 'other2' - result = self._callFUT(other2) - self.assertEqual(result, ('', '', 'other2')) - -class QuotePathSegmentTests(unittest.TestCase): - def _callFUT(self, s): - from pyramid.traversal import quote_path_segment - return quote_path_segment(s) - - def test_unicode(self): - la = text_(b'/La Pe\xc3\xb1a', 'utf-8') - result = self._callFUT(la) - self.assertEqual(result, '%2FLa%20Pe%C3%B1a') - - def test_string(self): - s = '/ hello!' - result = self._callFUT(s) - self.assertEqual(result, '%2F%20hello!') - - def test_int(self): - s = 12345 - result = self._callFUT(s) - self.assertEqual(result, '12345') - - def test_long(self): - from pyramid.compat import long - import sys - s = long(sys.maxsize + 1) - result = self._callFUT(s) - expected = str(s) - self.assertEqual(result, expected) - - def test_other(self): - class Foo(object): - def __str__(self): - return 'abc' - s = Foo() - result = self._callFUT(s) - self.assertEqual(result, 'abc') - -class ResourceURLTests(unittest.TestCase): - def _makeOne(self, context, url): - return self._getTargetClass()(context, url) - - def _getTargetClass(self): - from pyramid.traversal import ResourceURL - return ResourceURL - - def test_instance_conforms_to_IResourceURL(self): - from pyramid.interfaces import IResourceURL - from zope.interface.verify import verifyObject - context = DummyContext() - request = DummyRequest() - verifyObject(IResourceURL, self._makeOne(context, request)) - - def test_IResourceURL_attributes_with_vroot(self): - from pyramid.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - environ = {VH_ROOT_KEY:'/one'} - request = DummyRequest(environ) - context_url = self._makeOne(two, request) - self.assertEqual(context_url.physical_path, '/one/two/') - self.assertEqual(context_url.virtual_path, '/two/') - self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) - self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) - - def test_IResourceURL_attributes_vroot_ends_with_slash(self): - from pyramid.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - environ = {VH_ROOT_KEY:'/one/'} - request = DummyRequest(environ) - context_url = self._makeOne(two, request) - self.assertEqual(context_url.physical_path, '/one/two/') - self.assertEqual(context_url.virtual_path, '/two/') - self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) - self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) - - def test_IResourceURL_attributes_no_vroot(self): - root = DummyContext() - root.__parent__ = None - root.__name__ = None - one = DummyContext() - one.__parent__ = root - one.__name__ = 'one' - two = DummyContext() - two.__parent__ = one - two.__name__ = 'two' - environ = {} - request = DummyRequest(environ) - context_url = self._makeOne(two, request) - self.assertEqual(context_url.physical_path, '/one/two/') - self.assertEqual(context_url.virtual_path, '/one/two/') - self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) - self.assertEqual(context_url.virtual_path_tuple, ('', 'one', 'two', '')) - -class TestVirtualRoot(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, resource, request): - from pyramid.traversal import virtual_root - return virtual_root(resource, request) - - def _registerTraverser(self, traverser): - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - from pyramid.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_virtual_root_no_virtual_root_path(self): - root = DummyContext() - root.__name__ = None - root.__parent__ = None - one = DummyContext() - one.__name__ = 'one' - one.__parent__ = root - request = DummyRequest() - result = self._callFUT(one, request) - self.assertEqual(result, root) - - def test_virtual_root_no_virtual_root_path_with_root_on_request(self): - context = DummyContext() - context.__parent__ = None - request = DummyRequest() - request.root = DummyContext() - result = self._callFUT(context, request) - self.assertEqual(result, request.root) - - def test_virtual_root_with_virtual_root_path(self): - from pyramid.interfaces import VH_ROOT_KEY - root = DummyContext() - root.__parent__ = None - context = DummyContext() - context.__name__ = 'one' - context.__parent__ = root - traversed_to = DummyContext() - environ = {VH_ROOT_KEY:'/one'} - request = DummyRequest(environ) - traverser = make_traverser({'context':traversed_to, 'view_name':''}) - self._registerTraverser(traverser) - result = self._callFUT(context, request) - self.assertEqual(result, traversed_to) - self.assertEqual(root.request.environ['PATH_INFO'], '/one') - - def test_default(self): - context = DummyContext() - request = _makeRequest() - request.environ['PATH_INFO'] = '/' - result = self._callFUT(context, request) - self.assertEqual(result, context) - - def test_default_no_registry_on_request(self): - context = DummyContext() - request = _makeRequest() - del request.registry - request.environ['PATH_INFO'] = '/' - result = self._callFUT(context, request) - self.assertEqual(result, context) - -class TraverseTests(unittest.TestCase): - def setUp(self): - cleanUp() - - def tearDown(self): - cleanUp() - - def _callFUT(self, context, name): - from pyramid.traversal import traverse - return traverse(context, name) - - def _registerTraverser(self, traverser): - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - from pyramid.interfaces import ITraverser - from zope.interface import Interface - reg.registerAdapter(traverser, (Interface,), ITraverser) - - def test_request_has_registry(self): - from pyramid.threadlocal import get_current_registry - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ['']) - self.assertEqual(resource.request.registry, get_current_registry()) - - def test_list(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ['']) - self.assertEqual(resource.request.environ['PATH_INFO'], '/') - - def test_generator(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - def foo(): - yield '' - self._callFUT(resource, foo()) - self.assertEqual(resource.request.environ['PATH_INFO'], '/') - - def test_self_string_found(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, '') - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_self_unicode_found(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, text_('')) - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_self_tuple_found(self): - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ()) - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_relative_string_found(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, 'baz') - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_relative_tuple_found(self): - resource = DummyContext() - baz = DummyContext() - traverser = make_traverser({'context':baz, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ('baz',)) - self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') - - def test_absolute_string_found(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, '/') - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_absolute_tuple_found(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ('',)) - self.assertEqual(root.wascontext, True) - self.assertEqual(root.request.environ['PATH_INFO'], '/') - - def test_empty_sequence(self): - root = DummyContext() - resource = DummyContext() - resource.__parent__ = root - resource.__name__ = 'baz' - traverser = make_traverser({'context':root, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, []) - self.assertEqual(resource.wascontext, True) - self.assertEqual(resource.request.environ['PATH_INFO'], '') - - def test_default_traverser(self): - resource = DummyContext() - result = self._callFUT(resource, '') - self.assertEqual(result['view_name'], '') - self.assertEqual(result['context'], resource) - - def test_requestfactory_overridden(self): - from pyramid.interfaces import IRequestFactory - from pyramid.request import Request - from pyramid.threadlocal import get_current_registry - reg = get_current_registry() - class MyRequest(Request): - pass - reg.registerUtility(MyRequest, IRequestFactory) - resource = DummyContext() - traverser = make_traverser({'context':resource, 'view_name':''}) - self._registerTraverser(traverser) - self._callFUT(resource, ['']) - self.assertEqual(resource.request.__class__, MyRequest) - -class TestDefaultRootFactory(unittest.TestCase): - def _getTargetClass(self): - from pyramid.traversal import DefaultRootFactory - return DefaultRootFactory - - def _makeOne(self, environ): - return self._getTargetClass()(environ) - - def test_it(self): - class DummyRequest(object): - pass - root = self._makeOne(DummyRequest()) - self.assertEqual(root.__parent__, None) - self.assertEqual(root.__name__, None) - -class Test__join_path_tuple(unittest.TestCase): - def _callFUT(self, tup): - from pyramid.traversal import _join_path_tuple - return _join_path_tuple(tup) - - def test_empty_tuple(self): - # tests "or '/'" case - result = self._callFUT(()) - self.assertEqual(result, '/') - - def test_nonempty_tuple(self): - result = self._callFUT(('x',)) - self.assertEqual(result, 'x') - - def test_segments_with_unsafes(self): - safe_segments = tuple(u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=:@") - result = self._callFUT(safe_segments) - self.assertEqual(result, u'/'.join(safe_segments)) - unsafe_segments = tuple(chr(i) for i in range(0x20, 0x80) if not chr(i) in safe_segments) + (u'あ',) - result = self._callFUT(unsafe_segments) - self.assertEqual(result, u'/'.join(''.join('%%%02X' % (ord(c) if isinstance(c, str) else c) for c in unsafe_segment.encode('utf-8')) for unsafe_segment in unsafe_segments)) - - -def make_traverser(result): - class DummyTraverser(object): - def __init__(self, context): - self.context = context - context.wascontext = True - def __call__(self, request): - self.context.request = request - return result - return DummyTraverser - -class DummyContext(object): - __parent__ = None - def __init__(self, next=None, name=None): - self.next = next - self.__name__ = name - - def __getitem__(self, name): - if self.next is None: - raise KeyError(name) - return self.next - - def __repr__(self): - return ''%(self.__name__, id(self)) - -class DummyRequest: - - application_url = 'http://example.com:5432' # app_url never ends with slash - matchdict = None - matched_route = None - - def __init__(self, environ=None, path_info=text_('/'), toraise=None): - if environ is None: - environ = {} - self.environ = environ - self._set_path_info(path_info) - self.toraise = toraise - - def _get_path_info(self): - if self.toraise: - raise self.toraise - return self._path_info - - def _set_path_info(self, v): - self._path_info = v - - path_info = property(_get_path_info, _set_path_info) - - -def _makeRequest(environ=None): - from pyramid.registry import Registry - request = DummyRequest() - request.registry = Registry() - return request diff --git a/src/pyramid/tests/test_tweens.py b/src/pyramid/tests/test_tweens.py deleted file mode 100644 index 2e74ad7cf..000000000 --- a/src/pyramid/tests/test_tweens.py +++ /dev/null @@ -1,88 +0,0 @@ -import unittest -from pyramid import testing - -class Test_excview_tween_factory(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, handler, registry=None): - from pyramid.tweens import excview_tween_factory - if registry is None: - registry = self.config.registry - return excview_tween_factory(handler, registry) - - def test_it_passthrough_no_exception(self): - dummy_response = DummyResponse() - def handler(request): - return dummy_response - tween = self._makeOne(handler) - request = DummyRequest() - result = tween(request) - self.assertTrue(result is dummy_response) - self.assertIsNone(request.exception) - self.assertIsNone(request.exc_info) - - def test_it_catches_notfound(self): - from pyramid.request import Request - from pyramid.httpexceptions import HTTPNotFound - self.config.add_notfound_view(lambda exc, request: exc) - def handler(request): - raise HTTPNotFound - tween = self._makeOne(handler) - request = Request.blank('/') - request.registry = self.config.registry - result = tween(request) - self.assertEqual(result.status, '404 Not Found') - self.assertIsInstance(request.exception, HTTPNotFound) - self.assertEqual(request.exception, request.exc_info[1]) - - def test_it_catches_with_predicate(self): - from pyramid.request import Request - from pyramid.response import Response - def excview(request): - return Response('foo') - self.config.add_view(excview, context=ValueError, request_method='GET') - def handler(request): - raise ValueError - tween = self._makeOne(handler) - request = Request.blank('/') - request.registry = self.config.registry - result = tween(request) - self.assertTrue(b'foo' in result.body) - self.assertIsInstance(request.exception, ValueError) - self.assertEqual(request.exception, request.exc_info[1]) - - def test_it_reraises_on_mismatch(self): - from pyramid.request import Request - def excview(request): pass - self.config.add_view(excview, context=ValueError, request_method='GET') - def handler(request): - raise ValueError - tween = self._makeOne(handler) - request = Request.blank('/') - request.registry = self.config.registry - request.method = 'POST' - self.assertRaises(ValueError, lambda: tween(request)) - self.assertIsNone(request.exception) - self.assertIsNone(request.exc_info) - - def test_it_reraises_on_no_match(self): - from pyramid.request import Request - def handler(request): - raise ValueError - tween = self._makeOne(handler) - request = Request.blank('/') - request.registry = self.config.registry - self.assertRaises(ValueError, lambda: tween(request)) - self.assertIsNone(request.exception) - self.assertIsNone(request.exc_info) - -class DummyRequest: - exception = None - exc_info = None - -class DummyResponse: - pass diff --git a/src/pyramid/tests/test_url.py b/src/pyramid/tests/test_url.py deleted file mode 100644 index 31b3dd571..000000000 --- a/src/pyramid/tests/test_url.py +++ /dev/null @@ -1,1352 +0,0 @@ -import os -import unittest -import warnings - -from pyramid import testing - -from pyramid.compat import ( - text_, - WIN, - ) - -class TestURLMethodsMixin(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, environ=None): - from pyramid.url import URLMethodsMixin - if environ is None: - environ = {} - class Request(URLMethodsMixin): - application_url = 'http://example.com:5432' - script_name = '' - def __init__(self, environ): - self.environ = environ - request = Request(environ) - request.registry = self.config.registry - return request - - def _registerResourceURL(self, reg): - from pyramid.interfaces import IResourceURL - from zope.interface import Interface - class DummyResourceURL(object): - physical_path = '/context/' - virtual_path = '/context/' - def __init__(self, context, request): pass - reg.registerAdapter(DummyResourceURL, (Interface, Interface), - IResourceURL) - return DummyResourceURL - - def test_resource_url_root_default(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_url(root) - self.assertEqual(result, 'http://example.com:5432/context/') - - def test_resource_url_extra_args(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'this/theotherthing', 'that') - self.assertEqual( - result, - 'http://example.com:5432/context/this%2Ftheotherthing/that') - - def test_resource_url_unicode_in_element_names(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - uc = text_(b'La Pe\xc3\xb1a', 'utf-8') - context = DummyContext() - result = request.resource_url(context, uc) - self.assertEqual(result, - 'http://example.com:5432/context/La%20Pe%C3%B1a') - - def test_resource_url_at_sign_in_element_names(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, '@@myview') - self.assertEqual(result, - 'http://example.com:5432/context/@@myview') - - def test_resource_url_element_names_url_quoted(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a b c') - self.assertEqual(result, 'http://example.com:5432/context/a%20b%20c') - - def test_resource_url_with_query_str(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a', query='(openlayers)') - self.assertEqual(result, - 'http://example.com:5432/context/a?(openlayers)') - - def test_resource_url_with_query_dict(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - uc = text_(b'La Pe\xc3\xb1a', 'utf-8') - result = request.resource_url(context, 'a', query={'a':uc}) - self.assertEqual(result, - 'http://example.com:5432/context/a?a=La+Pe%C3%B1a') - - def test_resource_url_with_query_seq(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - uc = text_(b'La Pe\xc3\xb1a', 'utf-8') - result = request.resource_url(context, 'a', query=[('a', 'hi there'), - ('b', uc)]) - self.assertEqual(result, - 'http://example.com:5432/context/a?a=hi+there&b=La+Pe%C3%B1a') - - def test_resource_url_with_query_empty(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a', query=[]) - self.assertEqual(result, - 'http://example.com:5432/context/a') - - def test_resource_url_with_query_None(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a', query=None) - self.assertEqual(result, - 'http://example.com:5432/context/a') - - def test_resource_url_anchor_is_after_root_when_no_elements(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, anchor='a') - self.assertEqual(result, - 'http://example.com:5432/context/#a') - - def test_resource_url_anchor_is_after_elements_when_no_qs(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a', anchor='b') - self.assertEqual(result, - 'http://example.com:5432/context/a#b') - - def test_resource_url_anchor_is_after_qs_when_qs_is_present(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, 'a', - query={'b':'c'}, anchor='d') - self.assertEqual(result, - 'http://example.com:5432/context/a?b=c#d') - - def test_resource_url_anchor_is_encoded_utf8_if_unicode(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - uc = text_(b'La Pe\xc3\xb1a', 'utf-8') - result = request.resource_url(context, anchor=uc) - self.assertEqual(result, - 'http://example.com:5432/context/#La%20Pe%C3%B1a') - - def test_resource_url_anchor_is_urlencoded_safe(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, anchor=' /#?&+') - self.assertEqual(result, - 'http://example.com:5432/context/#%20/%23?&+') - - def test_resource_url_anchor_is_None(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - context = DummyContext() - result = request.resource_url(context, anchor=None) - self.assertEqual(result, 'http://example.com:5432/context/') - - def test_resource_url_no_IResourceURL_registered(self): - # falls back to ResourceURL - root = DummyContext() - root.__name__ = '' - root.__parent__ = None - request = self._makeOne() - request.environ = {} - result = request.resource_url(root) - self.assertEqual(result, 'http://example.com:5432/') - - def test_resource_url_no_registry_on_request(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - del request.registry - root = DummyContext() - result = request.resource_url(root) - self.assertEqual(result, 'http://example.com:5432/context/') - - def test_resource_url_with_app_url(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_url(root, app_url='http://somewhere.com') - self.assertEqual(result, 'http://somewhere.com/context/') - - def test_resource_url_with_scheme(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_url(root, scheme='https') - self.assertEqual(result, 'https://example.com/context/') - - def test_resource_url_with_host(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_url(root, host='someotherhost.com') - self.assertEqual(result, 'http://someotherhost.com:8080/context/') - - def test_resource_url_with_port(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_url(root, port='8181') - self.assertEqual(result, 'http://example.com:8181/context/') - - def test_resource_url_with_local_url(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - self._registerResourceURL(request.registry) - root = DummyContext() - def resource_url(req, info): - self.assertEqual(req, request) - self.assertEqual(info['virtual_path'], '/context/') - self.assertEqual(info['physical_path'], '/context/') - self.assertEqual(info['app_url'], 'http://example.com:5432') - return 'http://example.com/contextabc/' - root.__resource_url__ = resource_url - result = request.resource_url(root) - self.assertEqual(result, 'http://example.com/contextabc/') - - def test_resource_url_with_route_name_no_remainder_on_adapter(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # no virtual_path_tuple on adapter - adapter.virtual_path = '/a/b/c/' - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, route_name='foo') - self.assertEqual(result, 'http://example.com:5432/1/2/3') - self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) - - def test_resource_url_with_route_name_remainder_on_adapter(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, route_name='foo') - self.assertEqual(result, 'http://example.com:5432/1/2/3') - self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) - - def test_resource_url_with_route_name_and_app_url(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, route_name='foo', app_url='app_url') - self.assertEqual(result, 'app_url/1/2/3') - self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) - - def test_resource_url_with_route_name_and_scheme_host_port_etc(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, route_name='foo', scheme='scheme', - host='host', port='port', query={'a':'1'}, - anchor='anchor') - self.assertEqual(result, 'scheme://host:port/1/2/3?a=1#anchor') - self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) - - def test_resource_url_with_route_name_and_route_kwargs(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url( - root, route_name='foo', route_kw={'a':'1', 'b':'2'}) - self.assertEqual(result, 'http://example.com:5432/1/2/3') - self.assertEqual( - route.kw, - {'traverse': ('', 'a', 'b', 'c', ''), - 'a':'1', - 'b':'2'} - ) - - def test_resource_url_with_route_name_and_elements(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, 'e1', 'e2', route_name='foo') - self.assertEqual(result, 'http://example.com:5432/1/2/3/e1/e2') - self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) - - def test_resource_url_with_route_name_and_remainder_name(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'8080', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - adapter = self._registerResourceURL(request.registry) - # virtual_path_tuple on adapter - adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route) - request.registry.registerUtility(mapper, IRoutesMapper) - root = DummyContext() - result = request.resource_url(root, route_name='foo', - route_remainder_name='fred') - self.assertEqual(result, 'http://example.com:5432/1/2/3') - self.assertEqual(route.kw, {'fred': ('', 'a', 'b', 'c', '')}) - - def test_resource_path(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_path(root) - self.assertEqual(result, '/context/') - - def test_resource_path_kwarg(self): - request = self._makeOne() - self._registerResourceURL(request.registry) - root = DummyContext() - result = request.resource_path(root, anchor='abc') - self.assertEqual(result, '/context/#abc') - - def test_route_url_with_elements(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', 'extra1', 'extra2') - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2') - - def test_route_url_with_elements_path_endswith_slash(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3/')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', 'extra1', 'extra2') - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2') - - def test_route_url_no_elements(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', a=1, b=2, c=3, _query={'a':1}, - _anchor=text_(b"foo")) - self.assertEqual(result, - 'http://example.com:5432/1/2/3?a=1#foo') - - def test_route_url_with_query_None(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', a=1, b=2, c=3, _query=None) - self.assertEqual(result, 'http://example.com:5432/1/2/3') - - def test_route_url_with_anchor_binary(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _anchor=b"La Pe\xc3\xb1a") - - self.assertEqual(result, - 'http://example.com:5432/1/2/3#La%20Pe%C3%B1a') - - def test_route_url_with_anchor_unicode(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - anchor = text_(b'La Pe\xc3\xb1a', 'utf-8') - result = request.route_url('flub', _anchor=anchor) - - self.assertEqual(result, - 'http://example.com:5432/1/2/3#La%20Pe%C3%B1a') - - def test_route_url_with_anchor_None(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _anchor=None) - - self.assertEqual(result, 'http://example.com:5432/1/2/3') - - def test_route_url_with_query(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _query={'q':'1'}) - self.assertEqual(result, - 'http://example.com:5432/1/2/3?q=1') - - def test_route_url_with_query_str(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _query='(openlayers)') - self.assertEqual(result, - 'http://example.com:5432/1/2/3?(openlayers)') - - def test_route_url_with_empty_query(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _query={}) - self.assertEqual(result, - 'http://example.com:5432/1/2/3') - - def test_route_url_with_app_url(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _app_url='http://example2.com') - self.assertEqual(result, - 'http://example2.com/1/2/3') - - def test_route_url_with_host(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'5432', - } - request = self._makeOne(environ) - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _host='someotherhost.com') - self.assertEqual(result, - 'http://someotherhost.com:5432/1/2/3') - - def test_route_url_with_port(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'5432', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _port='8080') - self.assertEqual(result, - 'http://example.com:8080/1/2/3') - - def test_route_url_with_scheme(self): - from pyramid.interfaces import IRoutesMapper - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_PORT':'5432', - 'SERVER_NAME':'example.com', - } - request = self._makeOne(environ) - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _scheme='https') - self.assertEqual(result, - 'https://example.com/1/2/3') - - def test_route_url_generation_error(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(raise_exc=KeyError) - request.registry.registerUtility(mapper, IRoutesMapper) - mapper.raise_exc = KeyError - self.assertRaises(KeyError, request.route_url, 'flub', request, a=1) - - def test_route_url_generate_doesnt_receive_query_or_anchor(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - route = DummyRoute(result='') - mapper = DummyRoutesMapper(route=route) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', _query=dict(name='some_name')) - self.assertEqual(route.kw, {}) # shouldnt have anchor/query - self.assertEqual(result, 'http://example.com:5432?name=some_name') - - def test_route_url_with_pregenerator(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - route = DummyRoute(result='/1/2/3') - def pregenerator(request, elements, kw): - return ('a',), {'_app_url':'http://example2.com'} - route.pregenerator = pregenerator - mapper = DummyRoutesMapper(route=route) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub') - self.assertEqual(result, 'http://example2.com/1/2/3/a') - self.assertEqual(route.kw, {}) # shouldnt have anchor/query - - def test_route_url_with_anchor_app_url_elements_and_query(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute(result='/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', 'element1', - _app_url='http://example2.com', - _anchor='anchor', _query={'q':'1'}) - self.assertEqual(result, - 'http://example2.com/1/2/3/element1?q=1#anchor') - - def test_route_url_integration_with_real_request(self): - # to try to replicate https://github.com/Pylons/pyramid/issues/213 - from pyramid.interfaces import IRoutesMapper - from pyramid.request import Request - request = Request.blank('/') - request.registry = self.config.registry - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_url('flub', 'extra1', 'extra2') - self.assertEqual(result, - 'http://localhost/1/2/3/extra1/extra2') - - - def test_current_route_url_current_request_has_no_route(self): - request = self._makeOne() - self.assertRaises(ValueError, request.current_route_url) - - def test_current_route_url_with_elements_query_and_anchor(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_url('extra1', 'extra2', _query={'a':1}, - _anchor=text_(b"foo")) - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') - - def test_current_route_url_with_route_name(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_url('extra1', 'extra2', _query={'a':1}, - _anchor=text_(b"foo"), - _route_name='bar') - self.assertEqual(result, - 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') - - def test_current_route_url_with_request_query(self): - from pyramid.interfaces import IRoutesMapper - from webob.multidict import GetDict - request = self._makeOne() - request.GET = GetDict([('q', '123')], {}) - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_url() - self.assertEqual(result, - 'http://example.com:5432/1/2/3?q=123') - - def test_current_route_url_with_request_query_duplicate_entries(self): - from pyramid.interfaces import IRoutesMapper - from webob.multidict import GetDict - request = self._makeOne() - request.GET = GetDict( - [('q', '123'), ('b', '2'), ('b', '2'), ('q', '456')], {}) - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_url() - self.assertEqual(result, - 'http://example.com:5432/1/2/3?q=123&b=2&b=2&q=456') - - def test_current_route_url_with_query_override(self): - from pyramid.interfaces import IRoutesMapper - from webob.multidict import GetDict - request = self._makeOne() - request.GET = GetDict([('q', '123')], {}) - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_url(_query={'a':1}) - self.assertEqual(result, - 'http://example.com:5432/1/2/3?a=1') - - def test_current_route_path(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - route = DummyRoute('/1/2/3') - mapper = DummyRoutesMapper(route=route) - request.matched_route = route - request.matchdict = {} - request.script_name = '/script_name' - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.current_route_path('extra1', 'extra2', _query={'a':1}, - _anchor=text_(b"foo")) - self.assertEqual(result, '/script_name/1/2/3/extra1/extra2?a=1#foo') - - def test_route_path_with_elements(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - request.script_name = '' - result = request.route_path('flub', 'extra1', 'extra2', - a=1, b=2, c=3, _query={'a':1}, - _anchor=text_(b"foo")) - self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') - - def test_route_path_with_script_name(self): - from pyramid.interfaces import IRoutesMapper - request = self._makeOne() - request.script_name = '/foo' - mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) - request.registry.registerUtility(mapper, IRoutesMapper) - result = request.route_path('flub', 'extra1', 'extra2', - a=1, b=2, c=3, _query={'a':1}, - _anchor=text_(b"foo")) - self.assertEqual(result, '/foo/1/2/3/extra1/extra2?a=1#foo') - - def test_static_url_staticurlinfo_notfound(self): - request = self._makeOne() - self.assertRaises(ValueError, request.static_url, 'static/foo.css') - - def test_static_url_abspath(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - info = DummyStaticURLInfo('abc') - registry = request.registry - registry.registerUtility(info, IStaticURLInfo) - abspath = makeabs('static', 'foo.css') - result = request.static_url(abspath) - self.assertEqual(result, 'abc') - self.assertEqual(info.args, (makeabs('static', 'foo.css'), request, {})) - request = self._makeOne() - - def test_static_url_found_rel(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = request.static_url('static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, {}) ) - - def test_static_url_abs(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = request.static_url('pyramid.tests:static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, {}) ) - - def test_static_url_found_abs_no_registry_on_request(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - registry = request.registry - info = DummyStaticURLInfo('abc') - registry.registerUtility(info, IStaticURLInfo) - del request.registry - result = request.static_url('pyramid.tests:static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, {}) ) - - def test_static_url_abspath_integration_with_staticurlinfo(self): - from pyramid.interfaces import IStaticURLInfo - from pyramid.config.views import StaticURLInfo - info = StaticURLInfo() - here = os.path.abspath(os.path.dirname(__file__)) - info.add(self.config, 'absstatic', here) - request = self._makeOne() - registry = request.registry - registry.registerUtility(info, IStaticURLInfo) - abspath = os.path.join(here, 'test_url.py') - result = request.static_url(abspath) - self.assertEqual(result, - 'http://example.com:5432/absstatic/test_url.py') - - def test_static_url_noscheme_uses_scheme_from_request(self): - from pyramid.interfaces import IStaticURLInfo - from pyramid.config.views import StaticURLInfo - info = StaticURLInfo() - here = os.path.abspath(os.path.dirname(__file__)) - info.add(self.config, '//subdomain.example.com/static', here) - request = self._makeOne({'wsgi.url_scheme': 'https'}) - registry = request.registry - registry.registerUtility(info, IStaticURLInfo) - abspath = os.path.join(here, 'test_url.py') - result = request.static_url(abspath) - self.assertEqual(result, - 'https://subdomain.example.com/static/test_url.py') - - def test_static_path_abspath(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - request.script_name = '/foo' - info = DummyStaticURLInfo('abc') - registry = request.registry - registry.registerUtility(info, IStaticURLInfo) - abspath = makeabs('static', 'foo.css') - result = request.static_path(abspath) - self.assertEqual(result, 'abc') - self.assertEqual(info.args, (makeabs('static', 'foo.css'), request, - {'_app_url':'/foo'}) - ) - - def test_static_path_found_rel(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - request.script_name = '/foo' - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = request.static_path('static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, - {'_app_url':'/foo'}) - ) - - def test_static_path_abs(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - request.script_name = '/foo' - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = request.static_path('pyramid.tests:static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, - {'_app_url':'/foo'}) - ) - - def test_static_path(self): - from pyramid.interfaces import IStaticURLInfo - request = self._makeOne() - request.script_name = '/foo' - info = DummyStaticURLInfo('abc') - request.registry.registerUtility(info, IStaticURLInfo) - result = request.static_path('static/foo.css') - self.assertEqual(result, 'abc') - self.assertEqual(info.args, - ('pyramid.tests:static/foo.css', request, - {'_app_url':'/foo'}) - ) - - def test_partial_application_url_with_http_host_default_port_http(self): - environ = { - 'wsgi.url_scheme':'http', - 'HTTP_HOST':'example.com:80', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'http://example.com') - - def test_partial_application_url_with_http_host_default_port_https(self): - environ = { - 'wsgi.url_scheme':'https', - 'HTTP_HOST':'example.com:443', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'https://example.com') - - def test_partial_application_url_with_http_host_nondefault_port_http(self): - environ = { - 'wsgi.url_scheme':'http', - 'HTTP_HOST':'example.com:8080', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'http://example.com:8080') - - def test_partial_application_url_with_http_host_nondefault_port_https(self): - environ = { - 'wsgi.url_scheme':'https', - 'HTTP_HOST':'example.com:4443', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'https://example.com:4443') - - def test_partial_application_url_with_http_host_no_colon(self): - environ = { - 'wsgi.url_scheme':'http', - 'HTTP_HOST':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'http://example.com') - - def test_partial_application_url_no_http_host(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url() - self.assertEqual(result, 'http://example.com') - - def test_partial_application_replace_port(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url(port=8080) - self.assertEqual(result, 'http://example.com:8080') - - def test_partial_application_replace_scheme_https_special_case(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url(scheme='https') - self.assertEqual(result, 'https://example.com') - - def test_partial_application_replace_scheme_https_special_case_avoid(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url(scheme='https', port='8080') - self.assertEqual(result, 'https://example.com:8080') - - def test_partial_application_replace_scheme_http_special_case(self): - environ = { - 'wsgi.url_scheme':'https', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'8080', - } - request = self._makeOne(environ) - result = request._partial_application_url(scheme='http') - self.assertEqual(result, 'http://example.com') - - def test_partial_application_replace_scheme_http_special_case_avoid(self): - environ = { - 'wsgi.url_scheme':'https', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'8000', - } - request = self._makeOne(environ) - result = request._partial_application_url(scheme='http', port='8080') - self.assertEqual(result, 'http://example.com:8080') - - def test_partial_application_replace_host_no_port(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url(host='someotherhost.com') - self.assertEqual(result, 'http://someotherhost.com') - - def test_partial_application_replace_host_with_port(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'8000', - } - request = self._makeOne(environ) - result = request._partial_application_url(host='someotherhost.com:8080') - self.assertEqual(result, 'http://someotherhost.com:8080') - - def test_partial_application_replace_host_and_port(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url(host='someotherhost.com:8080', - port='8000') - self.assertEqual(result, 'http://someotherhost.com:8000') - - def test_partial_application_replace_host_port_and_scheme(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'80', - } - request = self._makeOne(environ) - result = request._partial_application_url( - host='someotherhost.com:8080', - port='8000', - scheme='https', - ) - self.assertEqual(result, 'https://someotherhost.com:8000') - - def test_partial_application_url_with_custom_script_name(self): - environ = { - 'wsgi.url_scheme':'http', - 'SERVER_NAME':'example.com', - 'SERVER_PORT':'8000', - } - request = self._makeOne(environ) - request.script_name = '/abc' - result = request._partial_application_url() - self.assertEqual(result, 'http://example.com:8000/abc') - -class Test_route_url(unittest.TestCase): - def _callFUT(self, route_name, request, *elements, **kw): - from pyramid.url import route_url - return route_url(route_name, request, *elements, **kw) - - def _makeRequest(self): - class Request(object): - def route_url(self, route_name, *elements, **kw): - self.route_name = route_name - self.elements = elements - self.kw = kw - return 'route url' - return Request() - - def test_it(self): - request = self._makeRequest() - result = self._callFUT('abc', request, 'a', _app_url='') - self.assertEqual(result, 'route url') - self.assertEqual(request.route_name, 'abc') - self.assertEqual(request.elements, ('a',)) - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_route_path(unittest.TestCase): - def _callFUT(self, route_name, request, *elements, **kw): - from pyramid.url import route_path - return route_path(route_name, request, *elements, **kw) - - def _makeRequest(self): - class Request(object): - def route_path(self, route_name, *elements, **kw): - self.route_name = route_name - self.elements = elements - self.kw = kw - return 'route path' - return Request() - - def test_it(self): - request = self._makeRequest() - result = self._callFUT('abc', request, 'a', _app_url='') - self.assertEqual(result, 'route path') - self.assertEqual(request.route_name, 'abc') - self.assertEqual(request.elements, ('a',)) - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_resource_url(unittest.TestCase): - def _callFUT(self, resource, request, *elements, **kw): - from pyramid.url import resource_url - return resource_url(resource, request, *elements, **kw) - - def _makeRequest(self): - class Request(object): - def resource_url(self, resource, *elements, **kw): - self.resource = resource - self.elements = elements - self.kw = kw - return 'resource url' - return Request() - - def test_it(self): - request = self._makeRequest() - result = self._callFUT('abc', request, 'a', _app_url='') - self.assertEqual(result, 'resource url') - self.assertEqual(request.resource, 'abc') - self.assertEqual(request.elements, ('a',)) - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_static_url(unittest.TestCase): - def _callFUT(self, path, request, **kw): - from pyramid.url import static_url - return static_url(path, request, **kw) - - def _makeRequest(self): - class Request(object): - def static_url(self, path, **kw): - self.path = path - self.kw = kw - return 'static url' - return Request() - - def test_it_abs(self): - request = self._makeRequest() - result = self._callFUT('/foo/bar/abc', request, _app_url='') - self.assertEqual(result, 'static url') - self.assertEqual(request.path, '/foo/bar/abc') - self.assertEqual(request.kw, {'_app_url':''}) - - def test_it_absspec(self): - request = self._makeRequest() - result = self._callFUT('foo:abc', request, _anchor='anchor') - self.assertEqual(result, 'static url') - self.assertEqual(request.path, 'foo:abc') - self.assertEqual(request.kw, {'_anchor':'anchor'}) - - def test_it_rel(self): - request = self._makeRequest() - result = self._callFUT('abc', request, _app_url='') - self.assertEqual(result, 'static url') - self.assertEqual(request.path, 'pyramid.tests:abc') - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_static_path(unittest.TestCase): - def _callFUT(self, path, request, **kw): - from pyramid.url import static_path - return static_path(path, request, **kw) - - def _makeRequest(self): - class Request(object): - def static_path(self, path, **kw): - self.path = path - self.kw = kw - return 'static path' - return Request() - - def test_it_abs(self): - request = self._makeRequest() - result = self._callFUT('/foo/bar/abc', request, _anchor='anchor') - self.assertEqual(result, 'static path') - self.assertEqual(request.path, '/foo/bar/abc') - self.assertEqual(request.kw, {'_anchor':'anchor'}) - - def test_it_absspec(self): - request = self._makeRequest() - result = self._callFUT('foo:abc', request, _anchor='anchor') - self.assertEqual(result, 'static path') - self.assertEqual(request.path, 'foo:abc') - self.assertEqual(request.kw, {'_anchor':'anchor'}) - - def test_it_rel(self): - request = self._makeRequest() - result = self._callFUT('abc', request, _app_url='') - self.assertEqual(result, 'static path') - self.assertEqual(request.path, 'pyramid.tests:abc') - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_current_route_url(unittest.TestCase): - def _callFUT(self, request, *elements, **kw): - from pyramid.url import current_route_url - return current_route_url(request, *elements, **kw) - - def _makeRequest(self): - class Request(object): - def current_route_url(self, *elements, **kw): - self.elements = elements - self.kw = kw - return 'current route url' - return Request() - - def test_it(self): - request = self._makeRequest() - result = self._callFUT(request, 'abc', _app_url='') - self.assertEqual(result, 'current route url') - self.assertEqual(request.elements, ('abc',)) - self.assertEqual(request.kw, {'_app_url':''}) - -class Test_current_route_path(unittest.TestCase): - def _callFUT(self, request, *elements, **kw): - from pyramid.url import current_route_path - return current_route_path(request, *elements, **kw) - - def _makeRequest(self): - class Request(object): - def current_route_path(self, *elements, **kw): - self.elements = elements - self.kw = kw - return 'current route path' - return Request() - - def test_it(self): - request = self._makeRequest() - result = self._callFUT(request, 'abc', _anchor='abc') - self.assertEqual(result, 'current route path') - self.assertEqual(request.elements, ('abc',)) - self.assertEqual(request.kw, {'_anchor':'abc'}) - -class Test_external_static_url_integration(unittest.TestCase): - - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeRequest(self): - from pyramid.request import Request - return Request.blank('/') - - def test_generate_external_url(self): - self.config.add_route('acme', 'https://acme.org/path/{foo}') - request = self._makeRequest() - request.registry = self.config.registry - self.assertEqual( - request.route_url('acme', foo='bar'), - 'https://acme.org/path/bar') - - def test_generate_external_url_without_scheme(self): - self.config.add_route('acme', '//acme.org/path/{foo}') - request = self._makeRequest() - request.registry = self.config.registry - self.assertEqual( - request.route_url('acme', foo='bar'), - 'http://acme.org/path/bar') - - def test_generate_external_url_with_explicit_scheme(self): - self.config.add_route('acme', '//acme.org/path/{foo}') - request = self._makeRequest() - request.registry = self.config.registry - self.assertEqual( - request.route_url('acme', foo='bar', _scheme='https'), - 'https://acme.org/path/bar') - - def test_generate_external_url_with_explicit_app_url(self): - self.config.add_route('acme', 'http://acme.org/path/{foo}') - request = self._makeRequest() - request.registry = self.config.registry - self.assertRaises(ValueError, - request.route_url, 'acme', foo='bar', _app_url='http://fakeme.com') - - def test_generate_external_url_route_path(self): - self.config.add_route('acme', 'https://acme.org/path/{foo}') - request = self._makeRequest() - request.registry = self.config.registry - self.assertRaises(ValueError, request.route_path, 'acme', foo='bar') - - def test_generate_external_url_with_pregenerator(self): - def pregenerator(request, elements, kw): - kw['_query'] = {'q': 'foo'} - return elements, kw - self.config.add_route('acme', 'https://acme.org/path/{foo}', - pregenerator=pregenerator) - request = self._makeRequest() - request.registry = self.config.registry - self.assertEqual( - request.route_url('acme', foo='bar'), - 'https://acme.org/path/bar?q=foo') - - def test_external_url_with_route_prefix(self): - def includeme(config): - config.add_route('acme', '//acme.org/{foo}') - self.config.include(includeme, route_prefix='some_prefix') - request = self._makeRequest() - request.registry = self.config.registry - self.assertEqual( - request.route_url('acme', foo='bar'), - 'http://acme.org/bar') - -class Test_with_route_prefix(unittest.TestCase): - - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeRequest(self, route): - from pyramid.request import Request - return Request.blank(route) - - def test_old_route_is_preserved(self): - self.config.route_prefix = 'old_prefix' - with self.config.route_prefix_context('new_addon'): - assert 'new_addon' in self.config.route_prefix - - assert 'old_prefix' == self.config.route_prefix - - def test_route_prefix_none(self): - self.config.route_prefix = 'old_prefix' - with self.config.route_prefix_context(None): - assert 'old_prefix' == self.config.route_prefix - - assert 'old_prefix' == self.config.route_prefix - - def test_route_prefix_empty(self): - self.config.route_prefix = 'old_prefix' - with self.config.route_prefix_context(''): - assert 'old_prefix' == self.config.route_prefix - - assert 'old_prefix' == self.config.route_prefix - - def test_route_has_prefix(self): - with self.config.route_prefix_context('bar'): - self.config.add_route('acme', '/foo') - request = self._makeRequest('/') - self.assertEqual( - request.route_url('acme'), - 'http://localhost/bar/foo', - ) - - def test_route_does_not_have_prefix(self): - with self.config.route_prefix_context('bar'): - pass - - self.config.add_route('acme', '/foo') - request = self._makeRequest('/') - self.assertEqual( - request.route_url('acme'), - 'http://localhost/foo', - ) - - def test_error_reset_prefix(self): - self.config.route_prefix = 'old_prefix' - - try: - with self.config.route_prefix_context('new_prefix'): - raise RuntimeError - except RuntimeError: - pass - - assert self.config.route_prefix == 'old_prefix' - -class DummyContext(object): - def __init__(self, next=None): - self.next = next - -class DummyRoutesMapper: - raise_exc = None - def __init__(self, route=None, raise_exc=False): - self.route = route - - def get_route(self, route_name): - return self.route - -class DummyRoute: - pregenerator = None - name = 'route' - def __init__(self, result='/1/2/3'): - self.result = result - - def generate(self, kw): - self.kw = kw - return self.result - -class DummyStaticURLInfo: - def __init__(self, result): - self.result = result - - def generate(self, path, request, **kw): - self.args = path, request, kw - return self.result - -def makeabs(*elements): - if WIN: # pragma: no cover - return r'c:\\' + os.path.sep.join(elements) - else: - return os.path.sep + os.path.sep.join(elements) diff --git a/src/pyramid/tests/test_urldispatch.py b/src/pyramid/tests/test_urldispatch.py deleted file mode 100644 index 06f4ad793..000000000 --- a/src/pyramid/tests/test_urldispatch.py +++ /dev/null @@ -1,539 +0,0 @@ -import unittest -from pyramid import testing -from pyramid.compat import ( - text_, - PY2, - ) - -class TestRoute(unittest.TestCase): - def _getTargetClass(self): - from pyramid.urldispatch import Route - return Route - - def _makeOne(self, *arg): - return self._getTargetClass()(*arg) - - def test_provides_IRoute(self): - from pyramid.interfaces import IRoute - from zope.interface.verify import verifyObject - verifyObject(IRoute, self._makeOne('name', 'pattern')) - - def test_ctor(self): - import types - route = self._makeOne('name', ':path', 'factory') - self.assertEqual(route.pattern, ':path') - self.assertEqual(route.path, ':path') - self.assertEqual(route.name, 'name') - self.assertEqual(route.factory, 'factory') - self.assertTrue(route.generate.__class__ is types.FunctionType) - self.assertTrue(route.match.__class__ is types.FunctionType) - - def test_ctor_defaults(self): - import types - route = self._makeOne('name', ':path') - self.assertEqual(route.pattern, ':path') - self.assertEqual(route.path, ':path') - self.assertEqual(route.name, 'name') - self.assertEqual(route.factory, None) - self.assertTrue(route.generate.__class__ is types.FunctionType) - self.assertTrue(route.match.__class__ is types.FunctionType) - - def test_match(self): - route = self._makeOne('name', ':path') - self.assertEqual(route.match('/whatever'), {'path':'whatever'}) - - def test_generate(self): - route = self._makeOne('name', ':path') - self.assertEqual(route.generate({'path':'abc'}), '/abc') - -class RoutesMapperTests(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getRequest(self, **kw): - from pyramid.threadlocal import get_current_registry - environ = {'SERVER_NAME':'localhost', - 'wsgi.url_scheme':'http'} - environ.update(kw) - request = DummyRequest(environ) - reg = get_current_registry() - request.registry = reg - return request - - def _getTargetClass(self): - from pyramid.urldispatch import RoutesMapper - return RoutesMapper - - def _makeOne(self): - klass = self._getTargetClass() - return klass() - - def test_provides_IRoutesMapper(self): - from pyramid.interfaces import IRoutesMapper - from zope.interface.verify import verifyObject - verifyObject(IRoutesMapper, self._makeOne()) - - def test_no_route_matches(self): - mapper = self._makeOne() - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['match'], None) - self.assertEqual(result['route'], None) - - def test_connect_name_exists_removes_old(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article') - mapper.connect('foo', 'archives/:action/:article2') - self.assertEqual(len(mapper.routelist), 1) - self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article2') - self.assertEqual(mapper.routelist[0].pattern, - 'archives/:action/:article2') - - def test_connect_static(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article', static=True) - self.assertEqual(len(mapper.routelist), 0) - self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article') - - def test_connect_static_overridden(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article', static=True) - self.assertEqual(len(mapper.routelist), 0) - self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article') - mapper.connect('foo', 'archives/:action/:article2') - self.assertEqual(len(mapper.routelist), 1) - self.assertEqual(len(mapper.routes), 1) - self.assertEqual(mapper.routes['foo'].pattern, - 'archives/:action/:article2') - self.assertEqual(mapper.routelist[0].pattern, - 'archives/:action/:article2') - - def test___call__pathinfo_cant_be_decoded(self): - from pyramid.exceptions import URLDecodeError - mapper = self._makeOne() - if PY2: - path_info = b'\xff\xfe\xe6\x00' - else: - path_info = b'\xff\xfe\xe6\x00'.decode('latin-1') - request = self._getRequest(PATH_INFO=path_info) - self.assertRaises(URLDecodeError, mapper, request) - - def test___call__route_matches(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['foo']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__route_matches_with_predicates(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/:article', - predicates=[lambda *arg: True]) - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['foo']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__route_fails_to_match_with_predicates(self): - mapper = self._makeOne() - mapper.connect('foo', 'archives/:action/article1', - predicates=[lambda *arg: True, lambda *arg: False]) - mapper.connect('bar', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['bar']) - self.assertEqual(result['match']['action'], 'action1') - self.assertEqual(result['match']['article'], 'article1') - - def test___call__custom_predicate_gets_info(self): - mapper = self._makeOne() - def pred(info, request): - self.assertEqual(info['match'], {'action':'action1'}) - self.assertEqual(info['route'], mapper.routes['foo']) - return True - mapper.connect('foo', 'archives/:action/article1', predicates=[pred]) - request = self._getRequest(PATH_INFO='/archives/action1/article1') - mapper(request) - - def test_cc_bug(self): - # "unordered" as reported in IRC by author of - # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ - mapper = self._makeOne() - mapper.connect('rdf', 'licenses/:license_code/:license_version/rdf') - mapper.connect('juri', - 'licenses/:license_code/:license_version/:jurisdiction') - - request = self._getRequest(PATH_INFO='/licenses/1/v2/rdf') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['rdf']) - self.assertEqual(result['match']['license_code'], '1') - self.assertEqual(result['match']['license_version'], 'v2') - - request = self._getRequest(PATH_INFO='/licenses/1/v2/usa') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['juri']) - self.assertEqual(result['match']['license_code'], '1') - self.assertEqual(result['match']['license_version'], 'v2') - self.assertEqual(result['match']['jurisdiction'], 'usa') - - def test___call__root_route_matches(self): - mapper = self._makeOne() - mapper.connect('root', '') - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__root_route_matches2(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__root_route_when_path_info_empty(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__root_route_when_path_info_notempty(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='/') - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test___call__no_path_info(self): - mapper = self._makeOne() - mapper.connect('root', '/') - request = self._getRequest() - result = mapper(request) - self.assertEqual(result['route'], mapper.routes['root']) - self.assertEqual(result['match'], {}) - - def test_has_routes(self): - mapper = self._makeOne() - self.assertEqual(mapper.has_routes(), False) - mapper.connect('whatever', 'archives/:action/:article') - self.assertEqual(mapper.has_routes(), True) - - def test_get_routes(self): - from pyramid.urldispatch import Route - mapper = self._makeOne() - self.assertEqual(mapper.get_routes(), []) - mapper.connect('whatever', 'archives/:action/:article') - routes = mapper.get_routes() - self.assertEqual(len(routes), 1) - self.assertEqual(routes[0].__class__, Route) - - def test_get_route_matches(self): - mapper = self._makeOne() - mapper.connect('whatever', 'archives/:action/:article') - result = mapper.get_route('whatever') - self.assertEqual(result.pattern, 'archives/:action/:article') - - def test_get_route_misses(self): - mapper = self._makeOne() - result = mapper.get_route('whatever') - self.assertEqual(result, None) - - def test_generate(self): - mapper = self._makeOne() - def generator(kw): - return 123 - route = DummyRoute(generator) - mapper.routes['abc'] = route - self.assertEqual(mapper.generate('abc', {}), 123) - -class TestCompileRoute(unittest.TestCase): - def _callFUT(self, pattern): - from pyramid.urldispatch import _compile_route - return _compile_route(pattern) - - def test_no_star(self): - matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') - - def test_with_star(self): - matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar*traverse') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz', 'traverse':()}) - self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), - {'baz':'baz', 'buz':'buz', - 'traverse':('everything', 'else', 'here')}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator( - {'baz':1, 'buz':2, 'traverse':'/a/b'}), '/foo/1/biz/2/bar/a/b') - - def test_with_bracket_star(self): - matcher, generator = self._callFUT( - '/foo/{baz}/biz/{buz}/bar{remainder:.*}') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz', 'remainder':''}) - self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), - {'baz':'baz', 'buz':'buz', - 'remainder':'/everything/else/here'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator( - {'baz':1, 'buz':2, 'remainder':'/a/b'}), '/foo/1/biz/2/bar/a/b') - - def test_no_beginning_slash(self): - matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar') - self.assertEqual(matcher('/foo/baz/biz/buz/bar'), - {'baz':'baz', 'buz':'buz'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') - - def test_custom_regex(self): - matcher, generator = self._callFUT('foo/{baz}/biz/{buz:[^/\.]+}.{bar}') - self.assertEqual(matcher('/foo/baz/biz/buz.bar'), - {'baz':'baz', 'buz':'buz', 'bar':'bar'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), - '/foo/1/biz/2.html') - - def test_custom_regex_with_colons(self): - matcher, generator = self._callFUT('foo/{baz}/biz/{buz:(?:[^/\.]+)}.{bar}') - self.assertEqual(matcher('/foo/baz/biz/buz.bar'), - {'baz':'baz', 'buz':'buz', 'bar':'bar'}) - self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) - self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), - '/foo/1/biz/2.html') - - def test_mixed_newstyle_oldstyle_pattern_defaults_to_newstyle(self): - # pattern: '\\/foo\\/(?Pabc)\\/biz\\/(?P[^/]+)\\/bar$' - # note presence of :abc in pattern (oldstyle match) - matcher, generator = self._callFUT('foo/{baz:abc}/biz/{buz}/bar') - self.assertEqual(matcher('/foo/abc/biz/buz/bar'), - {'baz':'abc', 'buz':'buz'}) - self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') - - def test_custom_regex_with_embedded_squigglies(self): - matcher, generator = self._callFUT('/{buz:\d{4}}') - self.assertEqual(matcher('/2001'), {'buz':'2001'}) - self.assertEqual(matcher('/200'), None) - self.assertEqual(generator({'buz':2001}), '/2001') - - def test_custom_regex_with_embedded_squigglies2(self): - matcher, generator = self._callFUT('/{buz:\d{3,4}}') - self.assertEqual(matcher('/2001'), {'buz':'2001'}) - self.assertEqual(matcher('/200'), {'buz':'200'}) - self.assertEqual(matcher('/20'), None) - self.assertEqual(generator({'buz':2001}), '/2001') - - def test_custom_regex_with_embedded_squigglies3(self): - matcher, generator = self._callFUT( - '/{buz:(\d{2}|\d{4})-[a-zA-Z]{3,4}-\d{2}}') - self.assertEqual(matcher('/2001-Nov-15'), {'buz':'2001-Nov-15'}) - self.assertEqual(matcher('/99-June-10'), {'buz':'99-June-10'}) - self.assertEqual(matcher('/2-Nov-15'), None) - self.assertEqual(matcher('/200-Nov-15'), None) - self.assertEqual(matcher('/2001-No-15'), None) - self.assertEqual(generator({'buz':'2001-Nov-15'}), '/2001-Nov-15') - self.assertEqual(generator({'buz':'99-June-10'}), '/99-June-10') - - def test_pattern_with_high_order_literal(self): - pattern = text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') - matcher, generator = self._callFUT(pattern) - self.assertEqual(matcher(text_(b'/La Pe\xc3\xb1a/x', 'utf-8')), - {'x':'x'}) - self.assertEqual(generator({'x':'1'}), '/La%20Pe%C3%B1a/1') - - def test_pattern_generate_with_high_order_dynamic(self): - pattern = '/{x}' - _, generator = self._callFUT(pattern) - self.assertEqual( - generator({'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}), - '/La%20Pe%C3%B1a') - - def test_docs_sample_generate(self): - # sample from urldispatch.rst - pattern = text_(b'/La Pe\xc3\xb1a/{city}', 'utf-8') - _, generator = self._callFUT(pattern) - self.assertEqual( - generator({'city':text_(b'Qu\xc3\xa9bec', 'utf-8')}), - '/La%20Pe%C3%B1a/Qu%C3%A9bec') - - def test_generate_with_mixedtype_values(self): - pattern = '/{city}/{state}' - _, generator = self._callFUT(pattern) - result = generator( - {'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), - 'state': b'La Pe\xc3\xb1a'} - ) - self.assertEqual(result, '/Qu%C3%A9bec/La%20Pe%C3%B1a') - # should be a native string - self.assertEqual(type(result), str) - - def test_highorder_pattern_utf8(self): - pattern = b'/La Pe\xc3\xb1a/{city}' - self.assertRaises(ValueError, self._callFUT, pattern) - - def test_generate_with_string_remainder_and_unicode_replacement(self): - pattern = text_(b'/abc*remainder', 'utf-8') - _, generator = self._callFUT(pattern) - result = generator( - {'remainder': text_(b'/Qu\xc3\xa9bec/La Pe\xc3\xb1a', 'utf-8')} - ) - self.assertEqual(result, '/abc/Qu%C3%A9bec/La%20Pe%C3%B1a') - # should be a native string - self.assertEqual(type(result), str) - - def test_generate_with_string_remainder_and_nonstring_replacement(self): - pattern = text_(b'/abc/*remainder', 'utf-8') - _, generator = self._callFUT(pattern) - result = generator( - {'remainder': None} - ) - self.assertEqual(result, '/abc/None') - # should be a native string - self.assertEqual(type(result), str) - -class TestCompileRouteFunctional(unittest.TestCase): - def matches(self, pattern, path, expected): - from pyramid.urldispatch import _compile_route - matcher = _compile_route(pattern)[0] - result = matcher(path) - self.assertEqual(result, expected) - - def generates(self, pattern, dict, result): - from pyramid.urldispatch import _compile_route - self.assertEqual(_compile_route(pattern)[1](dict), result) - - def test_matcher_functional_notdynamic(self): - self.matches('/', '', None) - self.matches('', '', None) - self.matches('/', '/foo', None) - self.matches('/foo/', '/foo', None) - self.matches('', '/', {}) - self.matches('/', '/', {}) - - def test_matcher_functional_newstyle(self): - self.matches('/{x}', '', None) - self.matches('/{x}', '/', None) - self.matches('/abc/{def}', '/abc/', None) - self.matches('/{x}', '/a', {'x':'a'}) - self.matches('zzz/{x}', '/zzz/abc', {'x':'abc'}) - self.matches('zzz/{x}*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) - self.matches('zzz/{x}*traverse', '/zzz/abc/def/g', - {'x':'abc', 'traverse':('def', 'g')}) - self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) - self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) - #'/La%20Pe%C3%B1a' - self.matches('{x}', text_(b'/La Pe\xc3\xb1a', 'utf-8'), - {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) - # '/La%20Pe%C3%B1a/x' - self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x'), - {'traverse':(text_(b'La Pe\xc3\xb1a'), 'x')}) - self.matches('/foo/{id}.html', '/foo/bar.html', {'id':'bar'}) - self.matches('/{num:[0-9]+}/*traverse', '/555/abc/def', - {'num':'555', 'traverse':('abc', 'def')}) - self.matches('/{num:[0-9]*}/*traverse', '/555/abc/def', - {'num':'555', 'traverse':('abc', 'def')}) - self.matches('zzz/{_}', '/zzz/abc', {'_':'abc'}) - self.matches('zzz/{_abc}', '/zzz/abc', {'_abc':'abc'}) - self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def':'abc'}) - - def test_matcher_functional_oldstyle(self): - self.matches('/:x', '', None) - self.matches('/:x', '/', None) - self.matches('/abc/:def', '/abc/', None) - self.matches('/:x', '/a', {'x':'a'}) - self.matches('zzz/:x', '/zzz/abc', {'x':'abc'}) - self.matches('zzz/:x*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) - self.matches('zzz/:x*traverse', '/zzz/abc/def/g', - {'x':'abc', 'traverse':('def', 'g')}) - self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) - self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) - #'/La%20Pe%C3%B1a' - # pattern, path, expected - self.matches(':x', text_(b'/La Pe\xc3\xb1a', 'utf-8'), - {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) - # '/La%20Pe%C3%B1a/x' - self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x', 'utf-8'), - {'traverse':(text_(b'La Pe\xc3\xb1a', 'utf-8'), 'x')}) - self.matches('/foo/:id.html', '/foo/bar.html', {'id':'bar'}) - self.matches('/foo/:id_html', '/foo/bar_html', {'id_html':'bar_html'}) - self.matches('zzz/:_', '/zzz/abc', {'_':'abc'}) - self.matches('zzz/:_abc', '/zzz/abc', {'_abc':'abc'}) - self.matches('zzz/:abc_def', '/zzz/abc', {'abc_def':'abc'}) - - def test_generator_functional_notdynamic(self): - self.generates('', {}, '/') - self.generates('/', {}, '/') - - def test_generator_functional_newstyle(self): - self.generates('/{x}', {'x':''}, '/') - self.generates('/{x}', {'x':'a'}, '/a') - self.generates('/{x}', {'x':'a/b/c'}, '/a/b/c') - self.generates('/{x}', {'x':':@&+$,'}, '/:@&+$,') - self.generates('zzz/{x}', {'x':'abc'}, '/zzz/abc') - self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':''}, - '/zzz/abc') - self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'}, - '/zzz/abc/def/g') - self.generates('zzz/{x}*traverse', {'x':':@&+$,', 'traverse':'/:@&+$,'}, - '/zzz/:@&+$,/:@&+$,') - self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, - '//La%20Pe%C3%B1a') - self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), - 'y':'/rest/of/path'}, - '//La%20Pe%C3%B1a/rest/of/path') - self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, - '/a/La%20Pe%C3%B1a') - self.generates('/foo/{id}.html', {'id':'bar'}, '/foo/bar.html') - self.generates('/foo/{_}', {'_':'20'}, '/foo/20') - self.generates('/foo/{_abc}', {'_abc':'20'}, '/foo/20') - self.generates('/foo/{abc_def}', {'abc_def':'20'}, '/foo/20') - - def test_generator_functional_oldstyle(self): - self.generates('/:x', {'x':''}, '/') - self.generates('/:x', {'x':'a'}, '/a') - self.generates('zzz/:x', {'x':'abc'}, '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':''}, - '/zzz/abc') - self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'}, - '/zzz/abc/def/g') - self.generates('/:x', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, - '//La%20Pe%C3%B1a') - self.generates('/:x*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), - 'y':'/rest/of/path'}, - '//La%20Pe%C3%B1a/rest/of/path') - self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, - '/a/La%20Pe%C3%B1a') - self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html') - self.generates('/foo/:_', {'_':'20'}, '/foo/20') - self.generates('/foo/:_abc', {'_abc':'20'}, '/foo/20') - self.generates('/foo/:abc_def', {'abc_def':'20'}, '/foo/20') - -class DummyContext(object): - """ """ - -class DummyRequest(object): - def __init__(self, environ): - self.environ = environ - -class DummyRoute(object): - def __init__(self, generator): - self.generate = generator - diff --git a/src/pyramid/tests/test_util.py b/src/pyramid/tests/test_util.py deleted file mode 100644 index a76cd2017..000000000 --- a/src/pyramid/tests/test_util.py +++ /dev/null @@ -1,1111 +0,0 @@ -import unittest -from pyramid.compat import ( - PY2, - text_, - bytes_, - ) - - -class Test_InstancePropertyHelper(unittest.TestCase): - def _makeOne(self): - cls = self._getTargetClass() - return cls() - - def _getTargetClass(self): - from pyramid.util import InstancePropertyHelper - return InstancePropertyHelper - - def test_callable(self): - def worker(obj): - return obj.bar - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker) - foo.bar = 1 - self.assertEqual(1, foo.worker) - foo.bar = 2 - self.assertEqual(2, foo.worker) - - def test_callable_with_name(self): - def worker(obj): - return obj.bar - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker, name='x') - foo.bar = 1 - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - - def test_callable_with_reify(self): - def worker(obj): - return obj.bar - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker, reify=True) - foo.bar = 1 - self.assertEqual(1, foo.worker) - foo.bar = 2 - self.assertEqual(1, foo.worker) - - def test_callable_with_name_reify(self): - def worker(obj): - return obj.bar - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker, name='x') - helper.set_property(foo, worker, name='y', reify=True) - foo.bar = 1 - self.assertEqual(1, foo.y) - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - self.assertEqual(1, foo.y) - - def test_property_without_name(self): - def worker(obj): pass - foo = Dummy() - helper = self._getTargetClass() - self.assertRaises(ValueError, helper.set_property, foo, property(worker)) - - def test_property_with_name(self): - def worker(obj): - return obj.bar - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, property(worker), name='x') - foo.bar = 1 - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - - def test_property_with_reify(self): - def worker(obj): pass - foo = Dummy() - helper = self._getTargetClass() - self.assertRaises(ValueError, helper.set_property, - foo, property(worker), name='x', reify=True) - - def test_override_property(self): - def worker(obj): pass - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker, name='x') - def doit(): - foo.x = 1 - self.assertRaises(AttributeError, doit) - - def test_override_reify(self): - def worker(obj): pass - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, worker, name='x', reify=True) - foo.x = 1 - self.assertEqual(1, foo.x) - foo.x = 2 - self.assertEqual(2, foo.x) - - def test_reset_property(self): - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, lambda _: 1, name='x') - self.assertEqual(1, foo.x) - helper.set_property(foo, lambda _: 2, name='x') - self.assertEqual(2, foo.x) - - def test_reset_reify(self): - """ This is questionable behavior, but may as well get notified - if it changes.""" - foo = Dummy() - helper = self._getTargetClass() - helper.set_property(foo, lambda _: 1, name='x', reify=True) - self.assertEqual(1, foo.x) - helper.set_property(foo, lambda _: 2, name='x', reify=True) - self.assertEqual(1, foo.x) - - def test_make_property(self): - from pyramid.decorator import reify - helper = self._getTargetClass() - name, fn = helper.make_property(lambda x: 1, name='x', reify=True) - self.assertEqual(name, 'x') - self.assertTrue(isinstance(fn, reify)) - - def test_apply_properties_with_iterable(self): - foo = Dummy() - helper = self._getTargetClass() - x = helper.make_property(lambda _: 1, name='x', reify=True) - y = helper.make_property(lambda _: 2, name='y') - helper.apply_properties(foo, [x, y]) - self.assertEqual(1, foo.x) - self.assertEqual(2, foo.y) - - def test_apply_properties_with_dict(self): - foo = Dummy() - helper = self._getTargetClass() - x_name, x_fn = helper.make_property(lambda _: 1, name='x', reify=True) - y_name, y_fn = helper.make_property(lambda _: 2, name='y') - helper.apply_properties(foo, {x_name: x_fn, y_name: y_fn}) - self.assertEqual(1, foo.x) - self.assertEqual(2, foo.y) - - def test_make_property_unicode(self): - from pyramid.compat import text_ - from pyramid.exceptions import ConfigurationError - - cls = self._getTargetClass() - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' - - def make_bad_name(): - cls.make_property(lambda x: 1, name=name, reify=True) - - self.assertRaises(ConfigurationError, make_bad_name) - - def test_add_property(self): - helper = self._makeOne() - helper.add_property(lambda obj: obj.bar, name='x', reify=True) - helper.add_property(lambda obj: obj.bar, name='y') - self.assertEqual(len(helper.properties), 2) - foo = Dummy() - helper.apply(foo) - foo.bar = 1 - self.assertEqual(foo.x, 1) - self.assertEqual(foo.y, 1) - foo.bar = 2 - self.assertEqual(foo.x, 1) - self.assertEqual(foo.y, 2) - - def test_apply_multiple_times(self): - helper = self._makeOne() - helper.add_property(lambda obj: 1, name='x') - foo, bar = Dummy(), Dummy() - helper.apply(foo) - self.assertEqual(foo.x, 1) - helper.add_property(lambda obj: 2, name='x') - helper.apply(bar) - self.assertEqual(foo.x, 1) - self.assertEqual(bar.x, 2) - -class Test_InstancePropertyMixin(unittest.TestCase): - def _makeOne(self): - cls = self._getTargetClass() - - class Foo(cls): - pass - return Foo() - - def _getTargetClass(self): - from pyramid.util import InstancePropertyMixin - return InstancePropertyMixin - - def test_callable(self): - def worker(obj): - return obj.bar - foo = self._makeOne() - foo.set_property(worker) - foo.bar = 1 - self.assertEqual(1, foo.worker) - foo.bar = 2 - self.assertEqual(2, foo.worker) - - def test_callable_with_name(self): - def worker(obj): - return obj.bar - foo = self._makeOne() - foo.set_property(worker, name='x') - foo.bar = 1 - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - - def test_callable_with_reify(self): - def worker(obj): - return obj.bar - foo = self._makeOne() - foo.set_property(worker, reify=True) - foo.bar = 1 - self.assertEqual(1, foo.worker) - foo.bar = 2 - self.assertEqual(1, foo.worker) - - def test_callable_with_name_reify(self): - def worker(obj): - return obj.bar - foo = self._makeOne() - foo.set_property(worker, name='x') - foo.set_property(worker, name='y', reify=True) - foo.bar = 1 - self.assertEqual(1, foo.y) - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - self.assertEqual(1, foo.y) - - def test_property_without_name(self): - def worker(obj): pass - foo = self._makeOne() - self.assertRaises(ValueError, foo.set_property, property(worker)) - - def test_property_with_name(self): - def worker(obj): - return obj.bar - foo = self._makeOne() - foo.set_property(property(worker), name='x') - foo.bar = 1 - self.assertEqual(1, foo.x) - foo.bar = 2 - self.assertEqual(2, foo.x) - - def test_property_with_reify(self): - def worker(obj): pass - foo = self._makeOne() - self.assertRaises(ValueError, foo.set_property, - property(worker), name='x', reify=True) - - def test_override_property(self): - def worker(obj): pass - foo = self._makeOne() - foo.set_property(worker, name='x') - def doit(): - foo.x = 1 - self.assertRaises(AttributeError, doit) - - def test_override_reify(self): - def worker(obj): pass - foo = self._makeOne() - foo.set_property(worker, name='x', reify=True) - foo.x = 1 - self.assertEqual(1, foo.x) - foo.x = 2 - self.assertEqual(2, foo.x) - - def test_reset_property(self): - foo = self._makeOne() - foo.set_property(lambda _: 1, name='x') - self.assertEqual(1, foo.x) - foo.set_property(lambda _: 2, name='x') - self.assertEqual(2, foo.x) - - def test_reset_reify(self): - """ This is questionable behavior, but may as well get notified - if it changes.""" - foo = self._makeOne() - foo.set_property(lambda _: 1, name='x', reify=True) - self.assertEqual(1, foo.x) - foo.set_property(lambda _: 2, name='x', reify=True) - self.assertEqual(1, foo.x) - - def test_new_class_keeps_parent_module_name(self): - foo = self._makeOne() - self.assertEqual(foo.__module__, 'pyramid.tests.test_util') - self.assertEqual(foo.__class__.__module__, 'pyramid.tests.test_util') - foo.set_property(lambda _: 1, name='x', reify=True) - self.assertEqual(foo.__module__, 'pyramid.tests.test_util') - self.assertEqual(foo.__class__.__module__, 'pyramid.tests.test_util') - -class Test_WeakOrderedSet(unittest.TestCase): - def _makeOne(self): - from pyramid.config import WeakOrderedSet - return WeakOrderedSet() - - def test_ctor(self): - wos = self._makeOne() - self.assertEqual(len(wos), 0) - self.assertEqual(wos.last, None) - - def test_add_item(self): - wos = self._makeOne() - reg = Dummy() - wos.add(reg) - self.assertEqual(list(wos), [reg]) - self.assertTrue(reg in wos) - self.assertEqual(wos.last, reg) - - def test_add_multiple_items(self): - wos = self._makeOne() - reg1 = Dummy() - reg2 = Dummy() - wos.add(reg1) - wos.add(reg2) - self.assertEqual(len(wos), 2) - self.assertEqual(list(wos), [reg1, reg2]) - self.assertTrue(reg1 in wos) - self.assertTrue(reg2 in wos) - self.assertEqual(wos.last, reg2) - - def test_add_duplicate_items(self): - wos = self._makeOne() - reg = Dummy() - wos.add(reg) - wos.add(reg) - self.assertEqual(len(wos), 1) - self.assertEqual(list(wos), [reg]) - self.assertTrue(reg in wos) - self.assertEqual(wos.last, reg) - - def test_weakref_removal(self): - wos = self._makeOne() - reg = Dummy() - wos.add(reg) - wos.remove(reg) - self.assertEqual(len(wos), 0) - self.assertEqual(list(wos), []) - self.assertEqual(wos.last, None) - - def test_last_updated(self): - wos = self._makeOne() - reg = Dummy() - reg2 = Dummy() - wos.add(reg) - wos.add(reg2) - wos.remove(reg2) - self.assertEqual(len(wos), 1) - self.assertEqual(list(wos), [reg]) - self.assertEqual(wos.last, reg) - - def test_empty(self): - wos = self._makeOne() - reg = Dummy() - reg2 = Dummy() - wos.add(reg) - wos.add(reg2) - wos.empty() - self.assertEqual(len(wos), 0) - self.assertEqual(list(wos), []) - self.assertEqual(wos.last, None) - -class Test_strings_differ(unittest.TestCase): - def _callFUT(self, *args, **kw): - from pyramid.util import strings_differ - return strings_differ(*args, **kw) - - def test_it_bytes(self): - self.assertFalse(self._callFUT(b'foo', b'foo')) - self.assertTrue(self._callFUT(b'123', b'345')) - self.assertTrue(self._callFUT(b'1234', b'123')) - self.assertTrue(self._callFUT(b'123', b'1234')) - - def test_it_native_str(self): - self.assertFalse(self._callFUT('123', '123')) - self.assertTrue(self._callFUT('123', '1234')) - - def test_it_with_internal_comparator(self): - result = self._callFUT(b'foo', b'foo', compare_digest=None) - self.assertFalse(result) - - result = self._callFUT(b'123', b'abc', compare_digest=None) - self.assertTrue(result) - - def test_it_with_external_comparator(self): - class DummyComparator(object): - called = False - def __init__(self, ret_val): - self.ret_val = ret_val - - def __call__(self, a, b): - self.called = True - return self.ret_val - - dummy_compare = DummyComparator(True) - result = self._callFUT(b'foo', b'foo', compare_digest=dummy_compare) - self.assertTrue(dummy_compare.called) - self.assertFalse(result) - - dummy_compare = DummyComparator(False) - result = self._callFUT(b'123', b'345', compare_digest=dummy_compare) - self.assertTrue(dummy_compare.called) - self.assertTrue(result) - - dummy_compare = DummyComparator(False) - result = self._callFUT(b'abc', b'abc', compare_digest=dummy_compare) - self.assertTrue(dummy_compare.called) - self.assertTrue(result) - -class Test_object_description(unittest.TestCase): - def _callFUT(self, object): - from pyramid.util import object_description - return object_description(object) - - def test_string(self): - self.assertEqual(self._callFUT('abc'), 'abc') - - def test_int(self): - self.assertEqual(self._callFUT(1), '1') - - def test_bool(self): - self.assertEqual(self._callFUT(True), 'True') - - def test_None(self): - self.assertEqual(self._callFUT(None), 'None') - - def test_float(self): - self.assertEqual(self._callFUT(1.2), '1.2') - - def test_tuple(self): - self.assertEqual(self._callFUT(('a', 'b')), "('a', 'b')") - - def test_set(self): - if PY2: - self.assertEqual(self._callFUT(set(['a'])), "set(['a'])") - else: - self.assertEqual(self._callFUT(set(['a'])), "{'a'}") - - def test_list(self): - self.assertEqual(self._callFUT(['a']), "['a']") - - def test_dict(self): - self.assertEqual(self._callFUT({'a':1}), "{'a': 1}") - - def test_nomodule(self): - o = object() - self.assertEqual(self._callFUT(o), 'object %s' % str(o)) - - def test_module(self): - import pyramid - self.assertEqual(self._callFUT(pyramid), 'module pyramid') - - def test_method(self): - self.assertEqual( - self._callFUT(self.test_method), - 'method test_method of class pyramid.tests.test_util.' - 'Test_object_description') - - def test_class(self): - self.assertEqual( - self._callFUT(self.__class__), - 'class pyramid.tests.test_util.Test_object_description') - - def test_function(self): - self.assertEqual( - self._callFUT(dummyfunc), - 'function pyramid.tests.test_util.dummyfunc') - - def test_instance(self): - inst = Dummy() - self.assertEqual( - self._callFUT(inst), - "object %s" % str(inst)) - - def test_shortened_repr(self): - inst = ['1'] * 1000 - self.assertEqual( - self._callFUT(inst), - str(inst)[:100] + ' ... ]') - -class TestTopologicalSorter(unittest.TestCase): - def _makeOne(self, *arg, **kw): - from pyramid.util import TopologicalSorter - return TopologicalSorter(*arg, **kw) - - def test_remove(self): - inst = self._makeOne() - inst.names.append('name') - inst.name2val['name'] = 1 - inst.req_after.add('name') - inst.req_before.add('name') - inst.name2after['name'] = ('bob',) - inst.name2before['name'] = ('fred',) - inst.order.append(('bob', 'name')) - inst.order.append(('name', 'fred')) - inst.remove('name') - self.assertFalse(inst.names) - self.assertFalse(inst.req_before) - self.assertFalse(inst.req_after) - self.assertFalse(inst.name2before) - self.assertFalse(inst.name2after) - self.assertFalse(inst.name2val) - self.assertFalse(inst.order) - - def test_add(self): - from pyramid.util import LAST - sorter = self._makeOne() - sorter.add('name', 'factory') - self.assertEqual(sorter.names, ['name']) - self.assertEqual(sorter.name2val, - {'name':'factory'}) - self.assertEqual(sorter.order, [('name', LAST)]) - sorter.add('name2', 'factory2') - self.assertEqual(sorter.names, ['name', 'name2']) - self.assertEqual(sorter.name2val, - {'name':'factory', 'name2':'factory2'}) - self.assertEqual(sorter.order, - [('name', LAST), ('name2', LAST)]) - sorter.add('name3', 'factory3', before='name2') - self.assertEqual(sorter.names, - ['name', 'name2', 'name3']) - self.assertEqual(sorter.name2val, - {'name':'factory', 'name2':'factory2', - 'name3':'factory3'}) - self.assertEqual(sorter.order, - [('name', LAST), ('name2', LAST), - ('name3', 'name2')]) - - def test_sorted_ordering_1(self): - sorter = self._makeOne() - sorter.add('name1', 'factory1') - sorter.add('name2', 'factory2') - self.assertEqual(sorter.sorted(), - [ - ('name1', 'factory1'), - ('name2', 'factory2'), - ]) - - def test_sorted_ordering_2(self): - from pyramid.util import FIRST - sorter = self._makeOne() - sorter.add('name1', 'factory1') - sorter.add('name2', 'factory2', after=FIRST) - self.assertEqual(sorter.sorted(), - [ - ('name2', 'factory2'), - ('name1', 'factory1'), - ]) - - def test_sorted_ordering_3(self): - from pyramid.util import FIRST - sorter = self._makeOne() - add = sorter.add - add('auth', 'auth_factory', after='browserid') - add('dbt', 'dbt_factory') - add('retry', 'retry_factory', before='txnmgr', after='exceptionview') - add('browserid', 'browserid_factory') - add('txnmgr', 'txnmgr_factory', after='exceptionview') - add('exceptionview', 'excview_factory', after=FIRST) - self.assertEqual(sorter.sorted(), - [ - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ('dbt', 'dbt_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ]) - - def test_sorted_ordering_4(self): - from pyramid.util import FIRST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', after=FIRST) - add('auth', 'auth_factory', after='browserid') - add('retry', 'retry_factory', before='txnmgr', after='exceptionview') - add('browserid', 'browserid_factory') - add('txnmgr', 'txnmgr_factory', after='exceptionview') - add('dbt', 'dbt_factory') - self.assertEqual(sorter.sorted(), - [ - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('dbt', 'dbt_factory'), - ]) - - def test_sorted_ordering_5(self): - from pyramid.util import LAST, FIRST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory') - add('auth', 'auth_factory', after=FIRST) - add('retry', 'retry_factory', before='txnmgr', after='exceptionview') - add('browserid', 'browserid_factory', after=FIRST) - add('txnmgr', 'txnmgr_factory', after='exceptionview', before=LAST) - add('dbt', 'dbt_factory') - self.assertEqual(sorter.sorted(), - [ - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('txnmgr', 'txnmgr_factory'), - ('dbt', 'dbt_factory'), - ]) - - def test_sorted_ordering_missing_before_partial(self): - from pyramid.exceptions import ConfigurationError - sorter = self._makeOne() - add = sorter.add - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', after='browserid') - add('retry', 'retry_factory', before='txnmgr', after='exceptionview') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, sorter.sorted) - - def test_sorted_ordering_missing_after_partial(self): - from pyramid.exceptions import ConfigurationError - sorter = self._makeOne() - add = sorter.add - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', after='txnmgr') - add('retry', 'retry_factory', before='dbt', after='exceptionview') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, sorter.sorted) - - def test_sorted_ordering_missing_before_and_after_partials(self): - from pyramid.exceptions import ConfigurationError - sorter = self._makeOne() - add = sorter.add - add('dbt', 'dbt_factory') - add('auth', 'auth_factory', after='browserid') - add('retry', 'retry_factory', before='foo', after='txnmgr') - add('browserid', 'browserid_factory') - self.assertRaises(ConfigurationError, sorter.sorted) - - def test_sorted_ordering_missing_before_partial_with_fallback(self): - from pyramid.util import LAST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', before=LAST) - add('auth', 'auth_factory', after='browserid') - add('retry', 'retry_factory', before=('txnmgr', LAST), - after='exceptionview') - add('browserid', 'browserid_factory') - add('dbt', 'dbt_factory') - self.assertEqual(sorter.sorted(), - [ - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('dbt', 'dbt_factory'), - ]) - - def test_sorted_ordering_missing_after_partial_with_fallback(self): - from pyramid.util import FIRST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', after=FIRST) - add('auth', 'auth_factory', after=('txnmgr','browserid')) - add('retry', 'retry_factory', after='exceptionview') - add('browserid', 'browserid_factory') - add('dbt', 'dbt_factory') - self.assertEqual(sorter.sorted(), - [ - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ('browserid', 'browserid_factory'), - ('auth', 'auth_factory'), - ('dbt', 'dbt_factory'), - ]) - - def test_sorted_ordering_with_partial_fallbacks(self): - from pyramid.util import LAST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', before=('wontbethere', LAST)) - add('retry', 'retry_factory', after='exceptionview') - add('browserid', 'browserid_factory', before=('wont2', 'exceptionview')) - self.assertEqual(sorter.sorted(), - [ - ('browserid', 'browserid_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_sorted_ordering_with_multiple_matching_fallbacks(self): - from pyramid.util import LAST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', before=LAST) - add('retry', 'retry_factory', after='exceptionview') - add('browserid', 'browserid_factory', before=('retry', 'exceptionview')) - self.assertEqual(sorter.sorted(), - [ - ('browserid', 'browserid_factory'), - ('exceptionview', 'excview_factory'), - ('retry', 'retry_factory'), - ]) - - def test_sorted_ordering_with_missing_fallbacks(self): - from pyramid.exceptions import ConfigurationError - from pyramid.util import LAST - sorter = self._makeOne() - add = sorter.add - add('exceptionview', 'excview_factory', before=LAST) - add('retry', 'retry_factory', after='exceptionview') - add('browserid', 'browserid_factory', before=('txnmgr', 'auth')) - self.assertRaises(ConfigurationError, sorter.sorted) - - def test_sorted_ordering_conflict_direct(self): - from pyramid.exceptions import CyclicDependencyError - sorter = self._makeOne() - add = sorter.add - add('browserid', 'browserid_factory') - add('auth', 'auth_factory', before='browserid', after='browserid') - self.assertRaises(CyclicDependencyError, sorter.sorted) - - def test_sorted_ordering_conflict_indirect(self): - from pyramid.exceptions import CyclicDependencyError - sorter = self._makeOne() - add = sorter.add - add('browserid', 'browserid_factory') - add('auth', 'auth_factory', before='browserid') - add('dbt', 'dbt_factory', after='browserid', before='auth') - self.assertRaises(CyclicDependencyError, sorter.sorted) - -class TestSentinel(unittest.TestCase): - def test_repr(self): - from pyramid.util import Sentinel - r = repr(Sentinel('ABC')) - self.assertEqual(r, 'ABC') - - -class TestCallableName(unittest.TestCase): - def test_valid_ascii(self): - from pyramid.util import get_callable_name - from pyramid.compat import text_ - - if PY2: - name = text_(b'hello world', 'utf-8') - else: - name = b'hello world' - - self.assertEqual(get_callable_name(name), 'hello world') - - def test_invalid_ascii(self): - from pyramid.util import get_callable_name - from pyramid.compat import text_ - from pyramid.exceptions import ConfigurationError - - def get_bad_name(): - if PY2: - name = text_(b'La Pe\xc3\xb1a', 'utf-8') - else: - name = b'La Pe\xc3\xb1a' - - get_callable_name(name) - - self.assertRaises(ConfigurationError, get_bad_name) - - -class Test_hide_attrs(unittest.TestCase): - def _callFUT(self, obj, *attrs): - from pyramid.util import hide_attrs - return hide_attrs(obj, *attrs) - - def _makeDummy(self): - from pyramid.decorator import reify - class Dummy(object): - x = 1 - - @reify - def foo(self): - return self.x - return Dummy() - - def test_restores_attrs(self): - obj = self._makeDummy() - obj.bar = 'asdf' - orig_foo = obj.foo - with self._callFUT(obj, 'foo', 'bar'): - obj.foo = object() - obj.bar = 'nope' - self.assertEqual(obj.foo, orig_foo) - self.assertEqual(obj.bar, 'asdf') - - def test_restores_attrs_on_exception(self): - obj = self._makeDummy() - orig_foo = obj.foo - try: - with self._callFUT(obj, 'foo'): - obj.foo = object() - raise RuntimeError() - except RuntimeError: - self.assertEqual(obj.foo, orig_foo) - else: # pragma: no cover - self.fail("RuntimeError not raised") - - def test_restores_attrs_to_none(self): - obj = self._makeDummy() - obj.foo = None - with self._callFUT(obj, 'foo'): - obj.foo = object() - self.assertEqual(obj.foo, None) - - def test_deletes_attrs(self): - obj = self._makeDummy() - with self._callFUT(obj, 'foo'): - obj.foo = object() - self.assertTrue('foo' not in obj.__dict__) - - def test_does_not_delete_attr_if_no_attr_to_delete(self): - obj = self._makeDummy() - with self._callFUT(obj, 'foo'): - pass - self.assertTrue('foo' not in obj.__dict__) - - -def dummyfunc(): pass - - -class Dummy(object): - pass - - -class Test_is_same_domain(unittest.TestCase): - def _callFUT(self, *args, **kw): - from pyramid.util import is_same_domain - return is_same_domain(*args, **kw) - - def test_it(self): - self.assertTrue(self._callFUT("example.com", "example.com")) - self.assertFalse(self._callFUT("evil.com", "example.com")) - self.assertFalse(self._callFUT("evil.example.com", "example.com")) - self.assertFalse(self._callFUT("example.com", "")) - - def test_with_wildcard(self): - self.assertTrue(self._callFUT("example.com", ".example.com")) - self.assertTrue(self._callFUT("good.example.com", ".example.com")) - - def test_with_port(self): - self.assertTrue(self._callFUT("example.com:8080", "example.com:8080")) - self.assertFalse(self._callFUT("example.com:8080", "example.com")) - self.assertFalse(self._callFUT("example.com", "example.com:8080")) - - -class Test_make_contextmanager(unittest.TestCase): - def _callFUT(self, *args, **kw): - from pyramid.util import make_contextmanager - return make_contextmanager(*args, **kw) - - def test_with_None(self): - mgr = self._callFUT(None) - with mgr() as ctx: - self.assertIsNone(ctx) - - def test_with_generator(self): - def mygen(ctx): - yield ctx - mgr = self._callFUT(mygen) - with mgr('a') as ctx: - self.assertEqual(ctx, 'a') - - def test_with_multiple_yield_generator(self): - def mygen(): - yield 'a' - yield 'b' - mgr = self._callFUT(mygen) - try: - with mgr() as ctx: - self.assertEqual(ctx, 'a') - except RuntimeError: - pass - else: # pragma: no cover - raise AssertionError('expected raise from multiple yields') - - def test_with_regular_fn(self): - def mygen(): - return 'a' - mgr = self._callFUT(mygen) - with mgr() as ctx: - self.assertEqual(ctx, 'a') - - -class Test_takes_one_arg(unittest.TestCase): - def _callFUT(self, view, attr=None, argname=None): - from pyramid.util import takes_one_arg - return takes_one_arg(view, attr=attr, argname=argname) - - def test_requestonly_newstyle_class_no_init(self): - class foo(object): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_requestonly_newstyle_class_init_toomanyargs(self): - class foo(object): - def __init__(self, context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_requestonly_newstyle_class_init_onearg_named_request(self): - class foo(object): - def __init__(self, request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_newstyle_class_init_onearg_named_somethingelse(self): - class foo(object): - def __init__(self, req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_newstyle_class_init_defaultargs_firstname_not_request(self): - class foo(object): - def __init__(self, context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_newstyle_class_init_defaultargs_firstname_request(self): - class foo(object): - def __init__(self, request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo, argname='request')) - - def test_newstyle_class_init_firstname_request_with_secondname(self): - class foo(object): - def __init__(self, request, two): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_newstyle_class_init_noargs(self): - class foo(object): - def __init__(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_no_init(self): - class foo: - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_toomanyargs(self): - class foo: - def __init__(self, context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_onearg_named_request(self): - class foo: - def __init__(self, request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_oldstyle_class_init_onearg_named_somethingelse(self): - class foo: - def __init__(self, req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_oldstyle_class_init_defaultargs_firstname_not_request(self): - class foo: - def __init__(self, context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_oldstyle_class_init_defaultargs_firstname_request(self): - class foo: - def __init__(self, request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo, argname='request'), True) - - def test_oldstyle_class_init_noargs(self): - class foo: - def __init__(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_toomanyargs(self): - def foo(context, request): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_with_attr_false(self): - def bar(context, request): - """ """ - def foo(context, request): - """ """ - foo.bar = bar - self.assertFalse(self._callFUT(foo, 'bar')) - - def test_function_with_attr_true(self): - def bar(context, request): - """ """ - def foo(request): - """ """ - foo.bar = bar - self.assertTrue(self._callFUT(foo, 'bar')) - - def test_function_onearg_named_request(self): - def foo(request): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_function_onearg_named_somethingelse(self): - def foo(req): - """ """ - self.assertTrue(self._callFUT(foo)) - - def test_function_defaultargs_firstname_not_request(self): - def foo(context, request=None): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_function_defaultargs_firstname_request(self): - def foo(request, foo=1, bar=2): - """ """ - self.assertTrue(self._callFUT(foo, argname='request')) - - def test_function_noargs(self): - def foo(): - """ """ - self.assertFalse(self._callFUT(foo)) - - def test_instance_toomanyargs(self): - class Foo: - def __call__(self, context, request): - """ """ - foo = Foo() - self.assertFalse(self._callFUT(foo)) - - def test_instance_defaultargs_onearg_named_request(self): - class Foo: - def __call__(self, request): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo)) - - def test_instance_defaultargs_onearg_named_somethingelse(self): - class Foo: - def __call__(self, req): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo)) - - def test_instance_defaultargs_firstname_not_request(self): - class Foo: - def __call__(self, context, request=None): - """ """ - foo = Foo() - self.assertFalse(self._callFUT(foo)) - - def test_instance_defaultargs_firstname_request(self): - class Foo: - def __call__(self, request, foo=1, bar=2): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo, argname='request'), True) - - def test_instance_nocall(self): - class Foo: pass - foo = Foo() - self.assertFalse(self._callFUT(foo)) - - def test_method_onearg_named_request(self): - class Foo: - def method(self, request): - """ """ - foo = Foo() - self.assertTrue(self._callFUT(foo.method)) - - def test_function_annotations(self): - def foo(bar): - """ """ - # avoid SyntaxErrors in python2, this if effectively nop - getattr(foo, '__annotations__', {}).update({'bar': 'baz'}) - self.assertTrue(self._callFUT(foo)) - - -class TestSimpleSerializer(unittest.TestCase): - def _makeOne(self): - from pyramid.util import SimpleSerializer - return SimpleSerializer() - - def test_loads(self): - inst = self._makeOne() - self.assertEqual(inst.loads(b'abc'), text_('abc')) - - def test_dumps(self): - inst = self._makeOne() - self.assertEqual(inst.dumps('abc'), bytes_('abc')) diff --git a/src/pyramid/tests/test_view.py b/src/pyramid/tests/test_view.py deleted file mode 100644 index 3344bd739..000000000 --- a/src/pyramid/tests/test_view.py +++ /dev/null @@ -1,1071 +0,0 @@ -import unittest -import sys - -from zope.interface import implementer - -from pyramid import testing - -from pyramid.interfaces import IRequest - -class BaseTest(object): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _registerView(self, reg, app, name): - from pyramid.interfaces import IViewClassifier - for_ = (IViewClassifier, IRequest, IContext) - from pyramid.interfaces import IView - reg.registerAdapter(app, for_, IView, name) - - def _makeEnviron(self, **extras): - environ = { - 'wsgi.url_scheme':'http', - 'wsgi.version':(1,0), - 'SERVER_NAME':'localhost', - 'SERVER_PORT':'8080', - 'REQUEST_METHOD':'GET', - 'PATH_INFO':'/', - } - environ.update(extras) - return environ - - def _makeRequest(self, **environ): - from pyramid.request import Request - from pyramid.registry import Registry - environ = self._makeEnviron(**environ) - request = Request(environ) - request.registry = Registry() - return request - - def _makeContext(self): - from zope.interface import directlyProvides - context = DummyContext() - directlyProvides(context, IContext) - return context - -class Test_notfound_view_config(BaseTest, unittest.TestCase): - def _makeOne(self, **kw): - from pyramid.view import notfound_view_config - return notfound_view_config(**kw) - - def test_ctor(self): - inst = self._makeOne(attr='attr', path_info='path_info', - append_slash=True) - self.assertEqual(inst.__dict__, - {'attr':'attr', 'path_info':'path_info', - 'append_slash':True}) - - def test_it_function(self): - def view(request): pass - decorator = self._makeOne(attr='attr', renderer='renderer', - append_slash=True) - venusian = DummyVenusian() - decorator.venusian = venusian - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual( - settings, - [{'attr': 'attr', 'venusian': venusian, 'append_slash': True, - 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] - ) - - def test_it_class(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class view(object): pass - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 4) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['attr'], 'view') - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_call_with_venusian_args(self): - decorator = self._makeOne(_depth=1, _category='foo') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - category = attachments[0][2] - depth = attachments[0][3] - self.assertEqual(depth, 2) - self.assertEqual(category, 'foo') - -class Test_forbidden_view_config(BaseTest, unittest.TestCase): - def _makeOne(self, **kw): - from pyramid.view import forbidden_view_config - return forbidden_view_config(**kw) - - def test_ctor(self): - inst = self._makeOne(attr='attr', path_info='path_info') - self.assertEqual(inst.__dict__, - {'attr':'attr', 'path_info':'path_info'}) - - def test_it_function(self): - def view(request): pass - decorator = self._makeOne(attr='attr', renderer='renderer') - venusian = DummyVenusian() - decorator.venusian = venusian - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual( - settings, - [{'attr': 'attr', 'venusian': venusian, - 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] - ) - - def test_it_class(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class view(object): pass - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 4) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['attr'], 'view') - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_call_with_venusian_args(self): - decorator = self._makeOne(_depth=1, _category='foo') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - category = attachments[0][2] - depth = attachments[0][3] - self.assertEqual(depth, 2) - self.assertEqual(category, 'foo') - -class Test_exception_view_config(BaseTest, unittest.TestCase): - def _makeOne(self, *args, **kw): - from pyramid.view import exception_view_config - return exception_view_config(*args, **kw) - - def test_ctor(self): - inst = self._makeOne(context=Exception, path_info='path_info') - self.assertEqual(inst.__dict__, - {'context':Exception, 'path_info':'path_info'}) - - def test_ctor_positional_exception(self): - inst = self._makeOne(Exception, path_info='path_info') - self.assertEqual(inst.__dict__, - {'context':Exception, 'path_info':'path_info'}) - - def test_ctor_positional_extras(self): - from pyramid.exceptions import ConfigurationError - self.assertRaises(ConfigurationError, lambda: self._makeOne(Exception, True)) - - def test_it_function(self): - def view(request): pass - decorator = self._makeOne(context=Exception, renderer='renderer') - venusian = DummyVenusian() - decorator.venusian = venusian - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual( - settings, - [{'venusian': venusian, 'context': Exception, - 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] - ) - - def test_it_class(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class view(object): pass - wrapped = decorator(view) - self.assertTrue(wrapped is view) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 4) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['attr'], 'view') - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_call_with_venusian_args(self): - decorator = self._makeOne(_depth=1, _category='foo') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - category = attachments[0][2] - depth = attachments[0][3] - self.assertEqual(depth, 2) - self.assertEqual(category, 'foo') - -class RenderViewToResponseTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from pyramid.view import render_view_to_response - return render_view_to_response(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_no_registry_on_request(self): - request = self._makeRequest() - del request.registry - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=True) - self.assertEqual(response.status, '200 OK') - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(response.status, '200 OK') - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse('anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - response = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.app_iter, ['anotherview']) - - def test_call_view_with_request_iface_on_request(self): - # See https://github.com/Pylons/pyramid/issues/1643 - from zope.interface import Interface - class IWontBeFound(Interface): pass - context = self._makeContext() - request = self._makeRequest() - request.request_iface = IWontBeFound - response = DummyResponse('aview') - view = make_view(response) - self._registerView(request.registry, view, 'aview') - response = self._callFUT(context, request, name='aview') - self.assertEqual(response.status, '200 OK') - self.assertEqual(response.app_iter, ['aview']) - -class RenderViewToIterableTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from pyramid.view import render_view_to_iterable - return render_view_to_iterable(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=True) - self.assertEqual(iterable, ()) - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(iterable, ()) - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse(b'anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=False) - self.assertEqual(iterable, [b'anotherview']) - - def test_verify_output_bytestring(self): - from pyramid.request import Request - from pyramid.config import Configurator - from pyramid.view import render_view - from webob.compat import text_type - config = Configurator(settings={}) - def view(request): - request.response.text = text_type('') - return request.response - - config.add_view(name='test', view=view) - config.commit() - - r = Request({}) - r.registry = config.registry - self.assertEqual(render_view(object(), r, 'test'), b'') - - def test_call_request_has_no_registry(self): - request = self._makeRequest() - del request.registry - registry = self.config.registry - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(registry, view, 'registered') - iterable = self._callFUT(context, request, name='registered', - secure=True) - self.assertEqual(iterable, ()) - -class RenderViewTests(BaseTest, unittest.TestCase): - def _callFUT(self, *arg, **kw): - from pyramid.view import render_view - return render_view(*arg, **kw) - - def test_call_no_view_registered(self): - request = self._makeRequest() - context = self._makeContext() - result = self._callFUT(context, request, name='notregistered') - self.assertEqual(result, None) - - def test_call_view_registered_secure(self): - request = self._makeRequest() - context = self._makeContext() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=True) - self.assertEqual(s, b'') - - def test_call_view_registered_insecure_no_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, b'') - - def test_call_view_registered_insecure_with_call_permissive(self): - context = self._makeContext() - request = self._makeRequest() - response = DummyResponse() - view = make_view(response) - def anotherview(context, request): - return DummyResponse(b'anotherview') - view.__call_permissive__ = anotherview - self._registerView(request.registry, view, 'registered') - s = self._callFUT(context, request, name='registered', secure=False) - self.assertEqual(s, b'anotherview') - -class TestViewConfigDecorator(unittest.TestCase): - def setUp(self): - testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _getTargetClass(self): - from pyramid.view import view_config - return view_config - - def _makeOne(self, *arg, **kw): - return self._getTargetClass()(*arg, **kw) - - def test_create_defaults(self): - decorator = self._makeOne() - self.assertEqual(decorator.__dict__, {}) - - def test_create_context_trumps_for(self): - decorator = self._makeOne(context='123', for_='456') - self.assertEqual(decorator.context, '123') - - def test_create_for_trumps_context_None(self): - decorator = self._makeOne(context=None, for_='456') - self.assertEqual(decorator.context, '456') - - def test_create_nondefaults(self): - decorator = self._makeOne( - name=None, request_type=None, for_=None, - permission='foo', mapper='mapper', - decorator='decorator', match_param='match_param' - ) - self.assertEqual(decorator.name, None) - self.assertEqual(decorator.request_type, None) - self.assertEqual(decorator.context, None) - self.assertEqual(decorator.permission, 'foo') - self.assertEqual(decorator.mapper, 'mapper') - self.assertEqual(decorator.decorator, 'decorator') - self.assertEqual(decorator.match_param, 'match_param') - - def test_create_with_other_predicates(self): - decorator = self._makeOne(foo=1) - self.assertEqual(decorator.foo, 1) - - def test_create_decorator_tuple(self): - decorator = self._makeOne(decorator=('decorator1', 'decorator2')) - self.assertEqual(decorator.decorator, ('decorator1', 'decorator2')) - - def test_call_function(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 3) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_call_class(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class foo(object): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 4) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['attr'], 'foo') - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_call_class_attr_already_set(self): - decorator = self._makeOne(attr='abc') - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - class foo(object): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(len(settings[0]), 4) - self.assertEqual(settings[0]['venusian'], venusian) - self.assertEqual(settings[0]['view'], None) # comes from call_venusian - self.assertEqual(settings[0]['attr'], 'abc') - self.assertEqual(settings[0]['_info'], 'codeinfo') - - def test_stacking(self): - decorator1 = self._makeOne(name='1') - venusian1 = DummyVenusian() - decorator1.venusian = venusian1 - venusian2 = DummyVenusian() - decorator2 = self._makeOne(name='2') - decorator2.venusian = venusian2 - def foo(): pass - wrapped1 = decorator1(foo) - wrapped2 = decorator2(wrapped1) - self.assertTrue(wrapped1 is foo) - self.assertTrue(wrapped2 is foo) - config1 = call_venusian(venusian1) - self.assertEqual(len(config1.settings), 1) - self.assertEqual(config1.settings[0]['name'], '1') - config2 = call_venusian(venusian2) - self.assertEqual(len(config2.settings), 1) - self.assertEqual(config2.settings[0]['name'], '2') - - def test_call_as_method(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - decorator.venusian.info.scope = 'class' - def foo(self): pass - def bar(self): pass - class foo(object): - foomethod = decorator(foo) - barmethod = decorator(bar) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 2) - self.assertEqual(settings[0]['attr'], 'foo') - self.assertEqual(settings[1]['attr'], 'bar') - - def test_with_custom_predicates(self): - decorator = self._makeOne(custom_predicates=(1,)) - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(context, request): pass - decorated = decorator(foo) - self.assertTrue(decorated is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(settings[0]['custom_predicates'], (1,)) - - def test_call_with_renderer_string(self): - import pyramid.tests - decorator = self._makeOne(renderer='fixtures/minimal.pt') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - renderer = settings[0]['renderer'] - self.assertEqual(renderer, 'fixtures/minimal.pt') - self.assertEqual(config.pkg, pyramid.tests) - - def test_call_with_renderer_dict(self): - import pyramid.tests - decorator = self._makeOne(renderer={'a':1}) - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - config = call_venusian(venusian) - settings = config.settings - self.assertEqual(len(settings), 1) - self.assertEqual(settings[0]['renderer'], {'a':1}) - self.assertEqual(config.pkg, pyramid.tests) - - def test_call_with_renderer_IRendererInfo(self): - import pyramid.tests - from pyramid.interfaces import IRendererInfo - @implementer(IRendererInfo) - class DummyRendererHelper(object): - pass - renderer_helper = DummyRendererHelper() - decorator = self._makeOne(renderer=renderer_helper) - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - wrapped = decorator(foo) - self.assertTrue(wrapped is foo) - context = DummyVenusianContext() - config = call_venusian(venusian, context) - settings = config.settings - self.assertEqual(len(settings), 1) - renderer = settings[0]['renderer'] - self.assertTrue(renderer is renderer_helper) - self.assertEqual(config.pkg, pyramid.tests) - - def test_call_withdepth(self): - decorator = self._makeOne(_depth=1) - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - depth = attachments[0][3] - self.assertEqual(depth, 2) - - def test_call_withoutcategory(self): - decorator = self._makeOne() - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - category = attachments[0][2] - self.assertEqual(category, 'pyramid') - - def test_call_withcategory(self): - decorator = self._makeOne(_category='not_pyramid') - venusian = DummyVenusian() - decorator.venusian = venusian - def foo(): pass - decorator(foo) - attachments = venusian.attachments - category = attachments[0][2] - self.assertEqual(category, 'not_pyramid') - -class Test_append_slash_notfound_view(BaseTest, unittest.TestCase): - def _callFUT(self, context, request): - from pyramid.view import append_slash_notfound_view - return append_slash_notfound_view(context, request) - - def _registerMapper(self, reg, match=True): - from pyramid.interfaces import IRoutesMapper - class DummyRoute(object): - def __init__(self, val): - self.val = val - def match(self, path): - return self.val - class DummyMapper(object): - def __init__(self): - self.routelist = [ DummyRoute(match) ] - def get_routes(self): - return self.routelist - mapper = DummyMapper() - reg.registerUtility(mapper, IRoutesMapper) - return mapper - - def test_context_is_not_exception(self): - request = self._makeRequest(PATH_INFO='/abc') - request.exception = ExceptionResponse() - context = DummyContext() - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - self.assertEqual(response.app_iter, ['Not Found']) - - def test_no_mapper(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_no_path(self): - request = self._makeRequest() - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_mapper_path_already_slash_ending(self): - request = self._makeRequest(PATH_INFO='/abc/') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_no_route_matches(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - mapper = self._registerMapper(request.registry, True) - mapper.routelist[0].val = None - response = self._callFUT(context, request) - self.assertEqual(response.status, '404 Not Found') - - def test_matches(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '307 Temporary Redirect') - self.assertEqual(response.location, '/abc/') - - def test_matches_with_script_name(self): - request = self._makeRequest(PATH_INFO='/abc', SCRIPT_NAME='/foo') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '307 Temporary Redirect') - self.assertEqual(response.location, '/foo/abc/') - - def test_with_query_string(self): - request = self._makeRequest(PATH_INFO='/abc', QUERY_STRING='a=1&b=2') - context = ExceptionResponse() - self._registerMapper(request.registry, True) - response = self._callFUT(context, request) - self.assertEqual(response.status, '307 Temporary Redirect') - self.assertEqual(response.location, '/abc/?a=1&b=2') - -class TestAppendSlashNotFoundViewFactory(BaseTest, unittest.TestCase): - def _makeOne(self, notfound_view): - from pyramid.view import AppendSlashNotFoundViewFactory - return AppendSlashNotFoundViewFactory(notfound_view) - - def test_custom_notfound_view(self): - request = self._makeRequest(PATH_INFO='/abc') - context = ExceptionResponse() - def custom_notfound(context, request): - return 'OK' - view = self._makeOne(custom_notfound) - response = view(context, request) - self.assertEqual(response, 'OK') - -class Test_default_exceptionresponse_view(unittest.TestCase): - def _callFUT(self, context, request): - from pyramid.view import default_exceptionresponse_view - return default_exceptionresponse_view(context, request) - - def test_is_exception(self): - context = Exception() - result = self._callFUT(context, None) - self.assertTrue(result is context) - - def test_is_not_exception_context_is_false_still_chose(self): - request = DummyRequest() - request.exception = 0 - result = self._callFUT(None, request) - self.assertTrue(result is None) - - def test_is_not_exception_no_request_exception(self): - context = object() - request = DummyRequest() - request.exception = None - result = self._callFUT(context, request) - self.assertTrue(result is context) - - def test_is_not_exception_request_exception(self): - context = object() - request = DummyRequest() - request.exception = 'abc' - result = self._callFUT(context, request) - self.assertEqual(result, 'abc') - -class Test_view_defaults(unittest.TestCase): - def test_it(self): - from pyramid.view import view_defaults - @view_defaults(route_name='abc', renderer='def') - class Foo(object): pass - self.assertEqual(Foo.__view_defaults__['route_name'],'abc') - self.assertEqual(Foo.__view_defaults__['renderer'],'def') - - def test_it_inheritance_not_overridden(self): - from pyramid.view import view_defaults - @view_defaults(route_name='abc', renderer='def') - class Foo(object): pass - class Bar(Foo): pass - self.assertEqual(Bar.__view_defaults__['route_name'],'abc') - self.assertEqual(Bar.__view_defaults__['renderer'],'def') - - def test_it_inheritance_overriden(self): - from pyramid.view import view_defaults - @view_defaults(route_name='abc', renderer='def') - class Foo(object): pass - @view_defaults(route_name='ghi') - class Bar(Foo): pass - self.assertEqual(Bar.__view_defaults__['route_name'],'ghi') - self.assertFalse('renderer' in Bar.__view_defaults__) - - def test_it_inheritance_overriden_empty(self): - from pyramid.view import view_defaults - @view_defaults(route_name='abc', renderer='def') - class Foo(object): pass - @view_defaults() - class Bar(Foo): pass - self.assertEqual(Bar.__view_defaults__, {}) - -class TestViewMethodsMixin(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - testing.tearDown() - - def _makeOne(self, environ=None): - from pyramid.decorator import reify - from pyramid.view import ViewMethodsMixin - if environ is None: - environ = {} - class Request(ViewMethodsMixin): - def __init__(self, environ): - self.environ = environ - - @reify - def response(self): - return DummyResponse() - request = Request(environ) - request.registry = self.config.registry - return request - - def test_it(self): - def exc_view(exc, request): - self.assertTrue(exc is dummy_exc) - self.assertTrue(request.exception is dummy_exc) - return DummyResponse(b'foo') - self.config.add_view(exc_view, context=RuntimeError) - request = self._makeOne() - dummy_exc = RuntimeError() - try: - raise dummy_exc - except RuntimeError: - response = request.invoke_exception_view() - self.assertEqual(response.app_iter, [b'foo']) - else: # pragma: no cover - self.fail() - - def test_it_hides_attrs(self): - def exc_view(exc, request): - self.assertTrue(exc is not orig_exc) - self.assertTrue(request.exception is not orig_exc) - self.assertTrue(request.exc_info is not orig_exc_info) - self.assertTrue(request.response is not orig_response) - request.response.app_iter = [b'bar'] - return request.response - self.config.add_view(exc_view, context=RuntimeError) - request = self._makeOne() - orig_exc = request.exception = DummyContext() - orig_exc_info = request.exc_info = DummyContext() - orig_response = request.response = DummyResponse(b'foo') - try: - raise RuntimeError - except RuntimeError as ex: - response = request.invoke_exception_view() - self.assertEqual(response.app_iter, [b'bar']) - self.assertTrue(request.exception is ex) - self.assertTrue(request.exc_info[1] is ex) - self.assertTrue(request.response is orig_response) - else: # pragma: no cover - self.fail() - - def test_it_supports_alternate_requests(self): - def exc_view(exc, request): - self.assertTrue(request is other_req) - from pyramid.threadlocal import get_current_request - self.assertTrue(get_current_request() is other_req) - return DummyResponse(b'foo') - self.config.add_view(exc_view, context=RuntimeError) - request = self._makeOne() - other_req = self._makeOne() - try: - raise RuntimeError - except RuntimeError: - response = request.invoke_exception_view(request=other_req) - self.assertEqual(response.app_iter, [b'foo']) - else: # pragma: no cover - self.fail() - - def test_it_supports_threadlocal_registry(self): - def exc_view(exc, request): - return DummyResponse(b'foo') - self.config.add_view(exc_view, context=RuntimeError) - request = self._makeOne() - del request.registry - try: - raise RuntimeError - except RuntimeError: - response = request.invoke_exception_view() - self.assertEqual(response.app_iter, [b'foo']) - else: # pragma: no cover - self.fail() - - def test_it_raises_if_no_registry(self): - request = self._makeOne() - del request.registry - from pyramid.threadlocal import manager - manager.push({'registry': None, 'request': request}) - try: - raise RuntimeError - except RuntimeError: - try: - request.invoke_exception_view() - except RuntimeError as e: - self.assertEqual(e.args[0], "Unable to retrieve registry") - else: # pragma: no cover - self.fail() - finally: - manager.pop() - - def test_it_supports_alternate_exc_info(self): - def exc_view(exc, request): - self.assertTrue(request.exc_info is exc_info) - return DummyResponse(b'foo') - self.config.add_view(exc_view, context=RuntimeError) - request = self._makeOne() - try: - raise RuntimeError - except RuntimeError: - exc_info = sys.exc_info() - response = request.invoke_exception_view(exc_info=exc_info) - self.assertEqual(response.app_iter, [b'foo']) - - def test_it_rejects_secured_view(self): - from pyramid.exceptions import Forbidden - def exc_view(exc, request): pass - self.config.testing_securitypolicy(permissive=False) - self.config.add_view(exc_view, context=RuntimeError, permission='view') - request = self._makeOne() - try: - raise RuntimeError - except RuntimeError: - self.assertRaises(Forbidden, request.invoke_exception_view) - else: # pragma: no cover - self.fail() - - def test_it_allows_secured_view(self): - def exc_view(exc, request): - return DummyResponse(b'foo') - self.config.testing_securitypolicy(permissive=False) - self.config.add_view(exc_view, context=RuntimeError, permission='view') - request = self._makeOne() - try: - raise RuntimeError - except RuntimeError: - response = request.invoke_exception_view(secure=False) - self.assertEqual(response.app_iter, [b'foo']) - else: # pragma: no cover - self.fail() - - def test_it_raises_if_not_found(self): - from pyramid.httpexceptions import HTTPNotFound - request = self._makeOne() - dummy_exc = RuntimeError() - try: - raise dummy_exc - except RuntimeError: - self.assertRaises(HTTPNotFound, request.invoke_exception_view) - else: # pragma: no cover - self.fail() - - def test_it_reraises_if_not_found(self): - request = self._makeOne() - dummy_exc = RuntimeError() - try: - raise dummy_exc - except RuntimeError: - self.assertRaises( - RuntimeError, - lambda: request.invoke_exception_view(reraise=True)) - else: # pragma: no cover - self.fail() - - def test_it_raises_predicate_mismatch(self): - from pyramid.exceptions import PredicateMismatch - def exc_view(exc, request): pass - self.config.add_view(exc_view, context=Exception, request_method='POST') - request = self._makeOne() - request.method = 'GET' - dummy_exc = RuntimeError() - try: - raise dummy_exc - except RuntimeError: - self.assertRaises(PredicateMismatch, request.invoke_exception_view) - else: # pragma: no cover - self.fail() - - def test_it_reraises_after_predicate_mismatch(self): - def exc_view(exc, request): pass - self.config.add_view(exc_view, context=Exception, request_method='POST') - request = self._makeOne() - request.method = 'GET' - dummy_exc = RuntimeError() - try: - raise dummy_exc - except RuntimeError: - self.assertRaises( - RuntimeError, - lambda: request.invoke_exception_view(reraise=True)) - else: # pragma: no cover - self.fail() - -class ExceptionResponse(Exception): - status = '404 Not Found' - app_iter = ['Not Found'] - headerlist = [] - -class DummyContext: - pass - -def make_view(response): - def view(context, request): - return response - return view - -class DummyRequest: - exception = None - request_iface = IRequest - - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - -from pyramid.interfaces import IResponse - -@implementer(IResponse) -class DummyResponse(object): - headerlist = () - app_iter = () - status = '200 OK' - environ = None - def __init__(self, body=None): - if body is None: - self.app_iter = () - else: - self.app_iter = [body] - -from zope.interface import Interface -class IContext(Interface): - pass - -class DummyVenusianInfo(object): - scope = 'notaclass' - module = sys.modules['pyramid.tests'] - codeinfo = 'codeinfo' - -class DummyVenusian(object): - def __init__(self, info=None): - if info is None: - info = DummyVenusianInfo() - self.info = info - self.attachments = [] - - def attach(self, wrapped, callback, category=None, depth=1): - self.attachments.append((wrapped, callback, category, depth)) - return self.info - -class DummyRegistry(object): - pass - -class DummyConfig(object): - def __init__(self): - self.settings = [] - self.registry = DummyRegistry() - - def add_view(self, **kw): - self.settings.append(kw) - - add_notfound_view = add_forbidden_view = add_exception_view = add_view - - def with_package(self, pkg): - self.pkg = pkg - return self - -class DummyVenusianContext(object): - def __init__(self): - self.config = DummyConfig() - -def call_venusian(venusian, context=None): - if context is None: - context = DummyVenusianContext() - for wrapped, callback, category, depth in venusian.attachments: - callback(context, None, None) - return context.config - diff --git a/src/pyramid/tests/test_viewderivers.py b/src/pyramid/tests/test_viewderivers.py deleted file mode 100644 index 6b81cc1e5..000000000 --- a/src/pyramid/tests/test_viewderivers.py +++ /dev/null @@ -1,1795 +0,0 @@ -import unittest -from zope.interface import implementer - -from pyramid import testing -from pyramid.exceptions import ConfigurationError -from pyramid.interfaces import ( - IResponse, - IRequest, - ) - -class TestDeriveView(unittest.TestCase): - - def setUp(self): - self.config = testing.setUp() - self.config.set_default_csrf_options(require_csrf=False) - - def tearDown(self): - self.config = None - testing.tearDown() - - def _makeRequest(self): - request = DummyRequest() - request.registry = self.config.registry - return request - - def _registerLogger(self): - from pyramid.interfaces import IDebugLogger - logger = DummyLogger() - self.config.registry.registerUtility(logger, IDebugLogger) - return logger - - def _registerSecurityPolicy(self, permissive): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - policy = DummySecurityPolicy(permissive) - self.config.registry.registerUtility(policy, IAuthenticationPolicy) - self.config.registry.registerUtility(policy, IAuthorizationPolicy) - - def test_function_returns_non_adaptable(self): - def view(request): - return None - result = self.config.derive_view(view) - self.assertFalse(result is view) - try: - result(None, None) - except ValueError as e: - self.assertEqual( - e.args[0], - 'Could not convert return value of the view callable function ' - 'pyramid.tests.test_viewderivers.view into a response ' - 'object. The value returned was None. You may have forgotten ' - 'to return a value from the view callable.' - ) - else: # pragma: no cover - raise AssertionError - - def test_function_returns_non_adaptable_dict(self): - def view(request): - return {'a':1} - result = self.config.derive_view(view) - self.assertFalse(result is view) - try: - result(None, None) - except ValueError as e: - self.assertEqual( - e.args[0], - "Could not convert return value of the view callable function " - "pyramid.tests.test_viewderivers.view into a response " - "object. The value returned was {'a': 1}. You may have " - "forgotten to define a renderer in the view configuration." - ) - else: # pragma: no cover - raise AssertionError - - def test_instance_returns_non_adaptable(self): - class AView(object): - def __call__(self, request): - return None - view = AView() - result = self.config.derive_view(view) - self.assertFalse(result is view) - try: - result(None, None) - except ValueError as e: - msg = e.args[0] - self.assertTrue(msg.startswith( - 'Could not convert return value of the view callable object ' - ' into a response object. The value returned was None. You ' - 'may have forgotten to return a value from the view callable.')) - else: # pragma: no cover - raise AssertionError - - def test_function_returns_true_Response_no_renderer(self): - from pyramid.response import Response - r = Response('Hello') - def view(request): - return r - result = self.config.derive_view(view) - self.assertFalse(result is view) - response = result(None, None) - self.assertEqual(response, r) - - def test_function_returns_true_Response_with_renderer(self): - from pyramid.response import Response - r = Response('Hello') - def view(request): - return r - renderer = object() - result = self.config.derive_view(view) - self.assertFalse(result is view) - response = result(None, None) - self.assertEqual(response, r) - - def test_requestonly_default_method_returns_non_adaptable(self): - request = DummyRequest() - class AView(object): - def __init__(self, request): - pass - def __call__(self): - return None - result = self.config.derive_view(AView) - self.assertFalse(result is AView) - try: - result(None, request) - except ValueError as e: - self.assertEqual( - e.args[0], - 'Could not convert return value of the view callable ' - 'method __call__ of ' - 'class pyramid.tests.test_viewderivers.AView into a ' - 'response object. The value returned was None. You may have ' - 'forgotten to return a value from the view callable.' - ) - else: # pragma: no cover - raise AssertionError - - def test_requestonly_nondefault_method_returns_non_adaptable(self): - request = DummyRequest() - class AView(object): - def __init__(self, request): - pass - def theviewmethod(self): - return None - result = self.config.derive_view(AView, attr='theviewmethod') - self.assertFalse(result is AView) - try: - result(None, request) - except ValueError as e: - self.assertEqual( - e.args[0], - 'Could not convert return value of the view callable ' - 'method theviewmethod of ' - 'class pyramid.tests.test_viewderivers.AView into a ' - 'response object. The value returned was None. You may have ' - 'forgotten to return a value from the view callable.' - ) - else: # pragma: no cover - raise AssertionError - - def test_requestonly_function(self): - response = DummyResponse() - def view(request): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(result(None, None), response) - - def test_requestonly_function_with_renderer(self): - response = DummyResponse() - class moo(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, 'OK') - self.assertEqual(view_inst, view) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - def view(request): - return 'OK' - result = self.config.derive_view(view, renderer=moo()) - self.assertFalse(result.__wraps__ is view) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_requestonly_function_with_renderer_request_override(self): - def moo(info): - def inner(value, system): - self.assertEqual(value, 'OK') - self.assertEqual(system['request'], request) - self.assertEqual(system['context'], context) - return b'moo' - return inner - def view(request): - return 'OK' - self.config.add_renderer('moo', moo) - result = self.config.derive_view(view, renderer='string') - self.assertFalse(result is view) - request = self._makeRequest() - request.override_renderer = 'moo' - context = testing.DummyResource() - self.assertEqual(result(context, request).body, b'moo') - - def test_requestonly_function_with_renderer_request_has_view(self): - response = DummyResponse() - class moo(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, 'OK') - self.assertEqual(view_inst, 'view') - self.assertEqual(ctx, context) - return response - def clone(self): - return self - def view(request): - return 'OK' - result = self.config.derive_view(view, renderer=moo()) - self.assertFalse(result.__wraps__ is view) - request = self._makeRequest() - request.__view__ = 'view' - context = testing.DummyResource() - r = result(context, request) - self.assertEqual(r, response) - self.assertFalse(hasattr(request, '__view__')) - - def test_class_without_attr(self): - response = DummyResponse() - class View(object): - def __init__(self, request): - pass - def __call__(self): - return response - result = self.config.derive_view(View) - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, View) - - def test_class_with_attr(self): - response = DummyResponse() - class View(object): - def __init__(self, request): - pass - def another(self): - return response - result = self.config.derive_view(View, attr='another') - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, View) - - def test_as_function_context_and_request(self): - def view(context, request): - return 'OK' - result = self.config.derive_view(view) - self.assertTrue(result.__wraps__ is view) - self.assertFalse(hasattr(result, '__call_permissive__')) - self.assertEqual(view(None, None), 'OK') - - def test_as_function_requestonly(self): - response = DummyResponse() - def view(request): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), response) - - def test_as_newstyle_class_context_and_request(self): - response = DummyResponse() - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, view) - - def test_as_newstyle_class_requestonly(self): - response = DummyResponse() - class view(object): - def __init__(self, context, request): - pass - def __call__(self): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, view) - - def test_as_oldstyle_class_context_and_request(self): - response = DummyResponse() - class view: - def __init__(self, context, request): - pass - def __call__(self): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, view) - - def test_as_oldstyle_class_requestonly(self): - response = DummyResponse() - class view: - def __init__(self, context, request): - pass - def __call__(self): - return response - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - self.assertEqual(result(None, request), response) - self.assertEqual(request.__view__.__class__, view) - - def test_as_instance_context_and_request(self): - response = DummyResponse() - class View: - def __call__(self, context, request): - return response - view = View() - result = self.config.derive_view(view) - self.assertTrue(result.__wraps__ is view) - self.assertFalse(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), response) - - def test_as_instance_requestonly(self): - response = DummyResponse() - class View: - def __call__(self, request): - return response - view = View() - result = self.config.derive_view(view) - self.assertFalse(result is view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertTrue('test_viewderivers' in result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - self.assertEqual(result(None, None), response) - - def test_with_debug_authorization_no_authpol(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test_with_debug_authorization_authn_policy_no_authz_policy(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict(debug_authorization=True) - from pyramid.interfaces import IAuthenticationPolicy - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthenticationPolicy) - logger = self._registerLogger() - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test_with_debug_authorization_authz_policy_no_authn_policy(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict(debug_authorization=True) - from pyramid.interfaces import IAuthorizationPolicy - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthorizationPolicy) - logger = self._registerLogger() - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed " - "(no authorization policy in use)") - - def test_with_debug_authorization_no_permission(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - self._registerSecurityPolicy(True) - logger = self._registerLogger() - result = self.config._derive_view(view) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): Allowed (" - "no permission registered)") - - def test_debug_auth_permission_authpol_permitted(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(True) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__.__wraps__, view) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): True") - - def test_debug_auth_permission_authpol_permitted_no_request(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(True) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__.__wraps__, view) - self.assertEqual(result(None, None), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url None (view name " - "None against context None): True") - - def test_debug_auth_permission_authpol_denied(self): - from pyramid.httpexceptions import HTTPForbidden - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(False) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__.__wraps__, view) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertRaises(HTTPForbidden, result, None, request) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): False") - - def test_debug_auth_permission_authpol_denied2(self): - view = lambda *arg: 'OK' - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - self._registerLogger() - self._registerSecurityPolicy(False) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - permitted = result.__permitted__(None, None) - self.assertEqual(permitted, False) - - def test_debug_auth_permission_authpol_overridden(self): - from pyramid.security import NO_PERMISSION_REQUIRED - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(False) - result = self.config._derive_view(view, permission=NO_PERMISSION_REQUIRED) - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context None): " - "Allowed (NO_PERMISSION_REQUIRED)") - - def test_debug_auth_permission_authpol_permitted_excview(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = dict( - debug_authorization=True, reload_templates=True) - logger = self._registerLogger() - self._registerSecurityPolicy(True) - result = self.config._derive_view( - view, context=Exception, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertEqual(result.__call_permissive__.__wraps__, view) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(Exception(), request), response) - self.assertEqual(len(logger.messages), 1) - self.assertEqual(logger.messages[0], - "debug_authorization of url url (view name " - "'view_name' against context Exception()): True") - - def test_secured_view_authn_policy_no_authz_policy(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = {} - from pyramid.interfaces import IAuthenticationPolicy - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthenticationPolicy) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - - def test_secured_view_authz_policy_no_authn_policy(self): - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = {} - from pyramid.interfaces import IAuthorizationPolicy - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthorizationPolicy) - result = self.config._derive_view(view, permission='view') - self.assertEqual(view.__module__, result.__module__) - self.assertEqual(view.__doc__, result.__doc__) - self.assertEqual(view.__name__, result.__name__) - self.assertFalse(hasattr(result, '__call_permissive__')) - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - self.assertEqual(result(None, request), response) - - def test_secured_view_raises_forbidden_no_name(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - from pyramid.httpexceptions import HTTPForbidden - response = DummyResponse() - view = lambda *arg: response - self.config.registry.settings = {} - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthenticationPolicy) - self.config.registry.registerUtility(policy, IAuthorizationPolicy) - result = self.config._derive_view(view, permission='view') - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - try: - result(None, request) - except HTTPForbidden as e: - self.assertEqual(e.message, - 'Unauthorized: failed permission check') - else: # pragma: no cover - raise AssertionError - - def test_secured_view_raises_forbidden_with_name(self): - from pyramid.interfaces import IAuthenticationPolicy - from pyramid.interfaces import IAuthorizationPolicy - from pyramid.httpexceptions import HTTPForbidden - def myview(request): pass - self.config.registry.settings = {} - policy = DummySecurityPolicy(False) - self.config.registry.registerUtility(policy, IAuthenticationPolicy) - self.config.registry.registerUtility(policy, IAuthorizationPolicy) - result = self.config._derive_view(myview, permission='view') - request = self._makeRequest() - request.view_name = 'view_name' - request.url = 'url' - try: - result(None, request) - except HTTPForbidden as e: - self.assertEqual(e.message, - 'Unauthorized: myview failed permission check') - else: # pragma: no cover - raise AssertionError - - def test_secured_view_skipped_by_default_on_exception_view(self): - from pyramid.request import Request - from pyramid.security import NO_PERMISSION_REQUIRED - def view(request): - raise ValueError - def excview(request): - return 'hello' - self._registerSecurityPolicy(False) - self.config.add_settings({'debug_authorization': True}) - self.config.set_default_permission('view') - self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) - self.config.add_view(excview, context=ValueError, renderer='string') - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - response = request.get_response(app) - self.assertTrue(b'hello' in response.body) - - def test_secured_view_failed_on_explicit_exception_view(self): - from pyramid.httpexceptions import HTTPForbidden - from pyramid.request import Request - from pyramid.security import NO_PERMISSION_REQUIRED - def view(request): - raise ValueError - def excview(request): pass - self._registerSecurityPolicy(False) - self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) - self.config.add_view(excview, context=ValueError, renderer='string', - permission='view') - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - try: - request.get_response(app) - except HTTPForbidden: - pass - else: # pragma: no cover - raise AssertionError - - def test_secured_view_passed_on_explicit_exception_view(self): - from pyramid.request import Request - from pyramid.security import NO_PERMISSION_REQUIRED - def view(request): - raise ValueError - def excview(request): - return 'hello' - self._registerSecurityPolicy(True) - self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) - self.config.add_view(excview, context=ValueError, renderer='string', - permission='view') - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - request.headers['X-CSRF-Token'] = 'foo' - response = request.get_response(app) - self.assertTrue(b'hello' in response.body) - - def test_predicate_mismatch_view_has_no_name(self): - from pyramid.exceptions import PredicateMismatch - response = DummyResponse() - view = lambda *arg: response - def predicate1(context, request): - return False - predicate1.text = lambda *arg: 'text' - result = self.config._derive_view(view, predicates=[predicate1]) - request = self._makeRequest() - request.method = 'POST' - try: - result(None, None) - except PredicateMismatch as e: - self.assertEqual(e.detail, - 'predicate mismatch for view (text)') - else: # pragma: no cover - raise AssertionError - - def test_predicate_mismatch_view_has_name(self): - from pyramid.exceptions import PredicateMismatch - def myview(request): pass - def predicate1(context, request): - return False - predicate1.text = lambda *arg: 'text' - result = self.config._derive_view(myview, predicates=[predicate1]) - request = self._makeRequest() - request.method = 'POST' - try: - result(None, None) - except PredicateMismatch as e: - self.assertEqual(e.detail, - 'predicate mismatch for view myview (text)') - else: # pragma: no cover - raise AssertionError - - def test_predicate_mismatch_exception_has_text_in_detail(self): - from pyramid.exceptions import PredicateMismatch - def myview(request): pass - def predicate1(context, request): - return True - predicate1.text = lambda *arg: 'pred1' - def predicate2(context, request): - return False - predicate2.text = lambda *arg: 'pred2' - result = self.config._derive_view(myview, - predicates=[predicate1, predicate2]) - request = self._makeRequest() - request.method = 'POST' - try: - result(None, None) - except PredicateMismatch as e: - self.assertEqual(e.detail, - 'predicate mismatch for view myview (pred2)') - else: # pragma: no cover - raise AssertionError - - def test_with_predicates_all(self): - response = DummyResponse() - view = lambda *arg: response - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - result = self.config._derive_view(view, - predicates=[predicate1, predicate2]) - request = self._makeRequest() - request.method = 'POST' - next = result(None, None) - self.assertEqual(next, response) - self.assertEqual(predicates, [True, True]) - - def test_with_predicates_checker(self): - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - def predicate2(context, request): - predicates.append(True) - return True - result = self.config._derive_view(view, - predicates=[predicate1, predicate2]) - request = self._makeRequest() - request.method = 'POST' - next = result.__predicated__(None, None) - self.assertEqual(next, True) - self.assertEqual(predicates, [True, True]) - - def test_with_predicates_notall(self): - from pyramid.httpexceptions import HTTPNotFound - view = lambda *arg: 'OK' - predicates = [] - def predicate1(context, request): - predicates.append(True) - return True - predicate1.text = lambda *arg: 'text' - def predicate2(context, request): - predicates.append(True) - return False - predicate2.text = lambda *arg: 'text' - result = self.config._derive_view(view, - predicates=[predicate1, predicate2]) - request = self._makeRequest() - request.method = 'POST' - self.assertRaises(HTTPNotFound, result, None, None) - self.assertEqual(predicates, [True, True]) - - def test_with_wrapper_viewname(self): - from pyramid.response import Response - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - def outer_view(context, request): - self.assertEqual(request.wrapped_response, inner_response) - self.assertEqual(request.wrapped_body, inner_response.body) - self.assertEqual(request.wrapped_view.__original_view__, - inner_view) - return Response(b'outer ' + request.wrapped_body) - self.config.registry.registerAdapter( - outer_view, (IViewClassifier, None, None), IView, 'owrap') - result = self.config._derive_view(inner_view, viewname='inner', - wrapper_viewname='owrap') - self.assertFalse(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest() - response = result(None, request) - self.assertEqual(response.body, b'outer OK') - - def test_with_wrapper_viewname_notfound(self): - from pyramid.response import Response - inner_response = Response('OK') - def inner_view(context, request): - return inner_response - wrapped = self.config._derive_view(inner_view, viewname='inner', - wrapper_viewname='owrap') - request = self._makeRequest() - self.assertRaises(ValueError, wrapped, None, request) - - def test_as_newstyle_class_context_and_request_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst.__class__, View) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View(object): - def __init__(self, context, request): - pass - def index(self): - return {'a':'1'} - result = self.config._derive_view(View, - renderer=renderer(), attr='index') - self.assertFalse(result is View) - self.assertEqual(result.__module__, View.__module__) - self.assertEqual(result.__doc__, View.__doc__) - self.assertEqual(result.__name__, View.__name__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_as_newstyle_class_requestonly_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst.__class__, View) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View(object): - def __init__(self, request): - pass - def index(self): - return {'a':'1'} - result = self.config.derive_view(View, - renderer=renderer(), attr='index') - self.assertFalse(result is View) - self.assertEqual(result.__module__, View.__module__) - self.assertEqual(result.__doc__, View.__doc__) - self.assertEqual(result.__name__, View.__name__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_as_oldstyle_cls_context_request_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst.__class__, View) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View: - def __init__(self, context, request): - pass - def index(self): - return {'a':'1'} - result = self.config.derive_view(View, - renderer=renderer(), attr='index') - self.assertFalse(result is View) - self.assertEqual(result.__module__, View.__module__) - self.assertEqual(result.__doc__, View.__doc__) - self.assertEqual(result.__name__, View.__name__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_as_oldstyle_cls_requestonly_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst.__class__, View) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View: - def __init__(self, request): - pass - def index(self): - return {'a':'1'} - result = self.config.derive_view(View, - renderer=renderer(), attr='index') - self.assertFalse(result is View) - self.assertEqual(result.__module__, View.__module__) - self.assertEqual(result.__doc__, View.__doc__) - self.assertEqual(result.__name__, View.__name__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_as_instance_context_and_request_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst, view) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View: - def index(self, context, request): - return {'a':'1'} - view = View() - result = self.config.derive_view(view, - renderer=renderer(), attr='index') - self.assertFalse(result is view) - self.assertEqual(result.__module__, view.__module__) - self.assertEqual(result.__doc__, view.__doc__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_as_instance_requestonly_attr_and_renderer(self): - response = DummyResponse() - class renderer(object): - def render_view(inself, req, resp, view_inst, ctx): - self.assertEqual(req, request) - self.assertEqual(resp, {'a':'1'}) - self.assertEqual(view_inst, view) - self.assertEqual(ctx, context) - return response - def clone(self): - return self - class View: - def index(self, request): - return {'a':'1'} - view = View() - result = self.config.derive_view(view, - renderer=renderer(), attr='index') - self.assertFalse(result is view) - self.assertEqual(result.__module__, view.__module__) - self.assertEqual(result.__doc__, view.__doc__) - request = self._makeRequest() - context = testing.DummyResource() - self.assertEqual(result(context, request), response) - - def test_with_view_mapper_config_specified(self): - response = DummyResponse() - class mapper(object): - def __init__(self, **kw): - self.kw = kw - def __call__(self, view): - def wrapped(context, request): - return response - return wrapped - def view(context, request): return 'NOTOK' - result = self.config._derive_view(view, mapper=mapper) - self.assertFalse(result.__wraps__ is view) - self.assertEqual(result(None, None), response) - - def test_with_view_mapper_view_specified(self): - from pyramid.response import Response - response = Response() - def mapper(**kw): - def inner(view): - def superinner(context, request): - self.assertEqual(request, None) - return response - return superinner - return inner - def view(context, request): return 'NOTOK' - view.__view_mapper__ = mapper - result = self.config.derive_view(view) - self.assertFalse(result.__wraps__ is view) - self.assertEqual(result(None, None), response) - - def test_with_view_mapper_default_mapper_specified(self): - from pyramid.response import Response - response = Response() - def mapper(**kw): - def inner(view): - def superinner(context, request): - self.assertEqual(request, None) - return response - return superinner - return inner - self.config.set_view_mapper(mapper) - def view(context, request): return 'NOTOK' - result = self.config.derive_view(view) - self.assertFalse(result.__wraps__ is view) - self.assertEqual(result(None, None), response) - - def test_attr_wrapped_view_branching_default_phash(self): - from pyramid.config.util import DEFAULT_PHASH - def view(context, request): pass - result = self.config._derive_view(view, phash=DEFAULT_PHASH) - self.assertEqual(result.__wraps__, view) - - def test_attr_wrapped_view_branching_nondefault_phash(self): - def view(context, request): pass - result = self.config._derive_view(view, phash='nondefault') - self.assertNotEqual(result, view) - - def test_http_cached_view_integer(self): - import datetime - from pyramid.response import Response - response = Response('OK') - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, http_cache=3600) - self.assertFalse(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest() - when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) - result = result(None, request) - self.assertEqual(result, response) - headers = dict(result.headerlist) - expires = parse_httpdate(headers['Expires']) - assert_similar_datetime(expires, when) - self.assertEqual(headers['Cache-Control'], 'max-age=3600') - - def test_http_cached_view_timedelta(self): - import datetime - from pyramid.response import Response - response = Response('OK') - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, - http_cache=datetime.timedelta(hours=1)) - self.assertFalse(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest() - when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) - result = result(None, request) - self.assertEqual(result, response) - headers = dict(result.headerlist) - expires = parse_httpdate(headers['Expires']) - assert_similar_datetime(expires, when) - self.assertEqual(headers['Cache-Control'], 'max-age=3600') - - def test_http_cached_view_tuple(self): - import datetime - from pyramid.response import Response - response = Response('OK') - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, - http_cache=(3600, {'public':True})) - self.assertFalse(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest() - when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) - result = result(None, request) - self.assertEqual(result, response) - headers = dict(result.headerlist) - expires = parse_httpdate(headers['Expires']) - assert_similar_datetime(expires, when) - self.assertEqual(headers['Cache-Control'], 'max-age=3600, public') - - def test_http_cached_view_tuple_seconds_None(self): - from pyramid.response import Response - response = Response('OK') - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, - http_cache=(None, {'public':True})) - self.assertFalse(result is inner_view) - self.assertEqual(inner_view.__module__, result.__module__) - self.assertEqual(inner_view.__doc__, result.__doc__) - request = self._makeRequest() - result = result(None, request) - self.assertEqual(result, response) - headers = dict(result.headerlist) - self.assertFalse('Expires' in headers) - self.assertEqual(headers['Cache-Control'], 'public') - - def test_http_cached_view_prevent_auto_set(self): - from pyramid.response import Response - response = Response() - response.cache_control.prevent_auto = True - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, http_cache=3600) - request = self._makeRequest() - result = result(None, request) - self.assertEqual(result, response) # doesn't blow up - headers = dict(result.headerlist) - self.assertFalse('Expires' in headers) - self.assertFalse('Cache-Control' in headers) - - def test_http_cached_prevent_http_cache_in_settings(self): - self.config.registry.settings['prevent_http_cache'] = True - from pyramid.response import Response - response = Response() - def inner_view(context, request): - return response - result = self.config._derive_view(inner_view, http_cache=3600) - request = self._makeRequest() - result = result(None, request) - self.assertEqual(result, response) - headers = dict(result.headerlist) - self.assertFalse('Expires' in headers) - self.assertFalse('Cache-Control' in headers) - - def test_http_cached_view_bad_tuple(self): - def view(request): pass - self.assertRaises(ConfigurationError, self.config._derive_view, - view, http_cache=(None,)) - - def test_csrf_view_ignores_GET(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.method = 'GET' - view = self.config._derive_view(inner_view, require_csrf=True) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_fails_with_bad_POST_header(self): - from pyramid.exceptions import BadCSRFToken - def inner_view(request): pass - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.headers = {'X-CSRF-Token': 'bar'} - view = self.config._derive_view(inner_view, require_csrf=True) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_csrf_view_passes_with_good_POST_header(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.headers = {'X-CSRF-Token': 'foo'} - view = self.config._derive_view(inner_view, require_csrf=True) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_fails_with_bad_POST_token(self): - from pyramid.exceptions import BadCSRFToken - def inner_view(request): pass - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'csrf_token': 'bar'} - view = self.config._derive_view(inner_view, require_csrf=True) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_csrf_view_passes_with_good_POST_token(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'csrf_token': 'foo'} - view = self.config._derive_view(inner_view, require_csrf=True) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_https_domain(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "https" - request.domain = "example.com" - request.host_port = "443" - request.referrer = "https://example.com/login/" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'csrf_token': 'foo'} - view = self.config._derive_view(inner_view, require_csrf=True) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_fails_on_bad_PUT_header(self): - from pyramid.exceptions import BadCSRFToken - def inner_view(request): pass - request = self._makeRequest() - request.scheme = "http" - request.method = 'PUT' - request.session = DummySession({'csrf_token': 'foo'}) - request.headers = {'X-CSRF-Token': 'bar'} - view = self.config._derive_view(inner_view, require_csrf=True) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_csrf_view_fails_on_bad_referrer(self): - from pyramid.exceptions import BadCSRFOrigin - def inner_view(request): pass - request = self._makeRequest() - request.method = "POST" - request.scheme = "https" - request.host_port = "443" - request.domain = "example.com" - request.referrer = "https://not-example.com/evil/" - request.registry.settings = {} - view = self.config._derive_view(inner_view, require_csrf=True) - self.assertRaises(BadCSRFOrigin, lambda: view(None, request)) - - def test_csrf_view_fails_on_bad_origin(self): - from pyramid.exceptions import BadCSRFOrigin - def inner_view(request): pass - request = self._makeRequest() - request.method = "POST" - request.scheme = "https" - request.host_port = "443" - request.domain = "example.com" - request.headers = {"Origin": "https://not-example.com/evil/"} - request.registry.settings = {} - view = self.config._derive_view(inner_view, require_csrf=True) - self.assertRaises(BadCSRFOrigin, lambda: view(None, request)) - - def test_csrf_view_enabled_by_default(self): - from pyramid.exceptions import BadCSRFToken - def inner_view(request): pass - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - self.config.set_default_csrf_options(require_csrf=True) - view = self.config._derive_view(inner_view) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_csrf_view_enabled_via_callback(self): - def callback(request): - return True - from pyramid.exceptions import BadCSRFToken - def inner_view(request): pass - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - self.config.set_default_csrf_options(require_csrf=True, callback=callback) - view = self.config._derive_view(inner_view) - self.assertRaises(BadCSRFToken, lambda: view(None, request)) - - def test_csrf_view_disabled_via_callback(self): - def callback(request): - return False - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - self.config.set_default_csrf_options(require_csrf=True, callback=callback) - view = self.config._derive_view(inner_view) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_uses_custom_csrf_token(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'DUMMY': 'foo'} - self.config.set_default_csrf_options(require_csrf=True, token='DUMMY') - view = self.config._derive_view(inner_view) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_uses_custom_csrf_header(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.headers = {'DUMMY': 'foo'} - self.config.set_default_csrf_options(require_csrf=True, header='DUMMY') - view = self.config._derive_view(inner_view) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_uses_custom_methods(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'PUT' - request.session = DummySession({'csrf_token': 'foo'}) - self.config.set_default_csrf_options( - require_csrf=True, safe_methods=['PUT']) - view = self.config._derive_view(inner_view) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_uses_view_option_override(self): - response = DummyResponse() - def inner_view(request): - return response - request = self._makeRequest() - request.scheme = "http" - request.method = 'POST' - request.session = DummySession({'csrf_token': 'foo'}) - request.POST = {'csrf_token': 'bar'} - self.config.set_default_csrf_options(require_csrf=True) - view = self.config._derive_view(inner_view, require_csrf=False) - result = view(None, request) - self.assertTrue(result is response) - - def test_csrf_view_skipped_by_default_on_exception_view(self): - from pyramid.request import Request - def view(request): - raise ValueError - def excview(request): - return 'hello' - self.config.set_default_csrf_options(require_csrf=True) - self.config.set_session_factory( - lambda request: DummySession({'csrf_token': 'foo'})) - self.config.add_view(view, name='foo', require_csrf=False) - self.config.add_view(excview, context=ValueError, renderer='string') - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - response = request.get_response(app) - self.assertTrue(b'hello' in response.body) - - def test_csrf_view_failed_on_explicit_exception_view(self): - from pyramid.exceptions import BadCSRFToken - from pyramid.request import Request - def view(request): - raise ValueError - def excview(request): pass - self.config.set_default_csrf_options(require_csrf=True) - self.config.set_session_factory( - lambda request: DummySession({'csrf_token': 'foo'})) - self.config.add_view(view, name='foo', require_csrf=False) - self.config.add_view(excview, context=ValueError, renderer='string', - require_csrf=True) - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - try: - request.get_response(app) - except BadCSRFToken: - pass - else: # pragma: no cover - raise AssertionError - - def test_csrf_view_passed_on_explicit_exception_view(self): - from pyramid.request import Request - def view(request): - raise ValueError - def excview(request): - return 'hello' - self.config.set_default_csrf_options(require_csrf=True) - self.config.set_session_factory( - lambda request: DummySession({'csrf_token': 'foo'})) - self.config.add_view(view, name='foo', require_csrf=False) - self.config.add_view(excview, context=ValueError, renderer='string', - require_csrf=True) - app = self.config.make_wsgi_app() - request = Request.blank('/foo', base_url='http://example.com') - request.method = 'POST' - request.headers['X-CSRF-Token'] = 'foo' - response = request.get_response(app) - self.assertTrue(b'hello' in response.body) - - -class TestDerivationOrder(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - self.config = None - testing.tearDown() - - def test_right_order_user_sorted(self): - from pyramid.interfaces import IViewDerivers - - self.config.add_view_deriver(None, 'deriv1') - self.config.add_view_deriver(None, 'deriv2', 'decorated_view', 'deriv1') - self.config.add_view_deriver(None, 'deriv3', 'deriv2', 'deriv1') - - derivers = self.config.registry.getUtility(IViewDerivers) - derivers_sorted = derivers.sorted() - dlist = [d for (d, _) in derivers_sorted] - self.assertEqual([ - 'secured_view', - 'csrf_view', - 'owrapped_view', - 'http_cached_view', - 'decorated_view', - 'deriv2', - 'deriv3', - 'deriv1', - 'rendered_view', - 'mapped_view', - ], dlist) - - def test_right_order_implicit(self): - from pyramid.interfaces import IViewDerivers - - self.config.add_view_deriver(None, 'deriv1') - self.config.add_view_deriver(None, 'deriv2') - self.config.add_view_deriver(None, 'deriv3') - - derivers = self.config.registry.getUtility(IViewDerivers) - derivers_sorted = derivers.sorted() - dlist = [d for (d, _) in derivers_sorted] - self.assertEqual([ - 'secured_view', - 'csrf_view', - 'owrapped_view', - 'http_cached_view', - 'decorated_view', - 'deriv3', - 'deriv2', - 'deriv1', - 'rendered_view', - 'mapped_view', - ], dlist) - - def test_right_order_under_rendered_view(self): - from pyramid.interfaces import IViewDerivers - - self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') - - derivers = self.config.registry.getUtility(IViewDerivers) - derivers_sorted = derivers.sorted() - dlist = [d for (d, _) in derivers_sorted] - self.assertEqual([ - 'secured_view', - 'csrf_view', - 'owrapped_view', - 'http_cached_view', - 'decorated_view', - 'rendered_view', - 'deriv1', - 'mapped_view', - ], dlist) - - - def test_right_order_under_rendered_view_others(self): - from pyramid.interfaces import IViewDerivers - - self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') - self.config.add_view_deriver(None, 'deriv2') - self.config.add_view_deriver(None, 'deriv3') - - derivers = self.config.registry.getUtility(IViewDerivers) - derivers_sorted = derivers.sorted() - dlist = [d for (d, _) in derivers_sorted] - self.assertEqual([ - 'secured_view', - 'csrf_view', - 'owrapped_view', - 'http_cached_view', - 'decorated_view', - 'deriv3', - 'deriv2', - 'rendered_view', - 'deriv1', - 'mapped_view', - ], dlist) - - -class TestAddDeriver(unittest.TestCase): - - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - self.config = None - testing.tearDown() - - def test_add_single_deriver(self): - response = DummyResponse() - response.deriv = False - view = lambda *arg: response - - def deriv(view, info): - self.assertFalse(response.deriv) - response.deriv = True - return view - - result = self.config._derive_view(view) - self.assertFalse(response.deriv) - self.config.add_view_deriver(deriv, 'test_deriv') - - result = self.config._derive_view(view) - self.assertTrue(response.deriv) - - def test_override_deriver(self): - flags = {} - - class AView: - def __init__(self): - self.response = DummyResponse() - - def deriv1(view, info): - flags['deriv1'] = True - return view - - def deriv2(view, info): - flags['deriv2'] = True - return view - - view1 = AView() - self.config.add_view_deriver(deriv1, 'test_deriv') - result = self.config._derive_view(view1) - self.assertTrue(flags.get('deriv1')) - self.assertFalse(flags.get('deriv2')) - - flags.clear() - view2 = AView() - self.config.add_view_deriver(deriv2, 'test_deriv') - result = self.config._derive_view(view2) - self.assertFalse(flags.get('deriv1')) - self.assertTrue(flags.get('deriv2')) - - def test_override_mapped_view(self): - from pyramid.viewderivers import VIEW - response = DummyResponse() - view = lambda *arg: response - flags = {} - - def deriv1(view, info): - flags['deriv1'] = True - return view - - result = self.config._derive_view(view) - self.assertFalse(flags.get('deriv1')) - - flags.clear() - self.config.add_view_deriver( - deriv1, name='mapped_view', under='rendered_view', over=VIEW) - result = self.config._derive_view(view) - self.assertTrue(flags.get('deriv1')) - - def test_add_multi_derivers_ordered(self): - from pyramid.viewderivers import INGRESS - response = DummyResponse() - view = lambda *arg: response - response.deriv = [] - - def deriv1(view, info): - response.deriv.append('deriv1') - return view - - def deriv2(view, info): - response.deriv.append('deriv2') - return view - - def deriv3(view, info): - response.deriv.append('deriv3') - return view - - self.config.add_view_deriver(deriv1, 'deriv1') - self.config.add_view_deriver(deriv2, 'deriv2', INGRESS, 'deriv1') - self.config.add_view_deriver(deriv3, 'deriv3', 'deriv2', 'deriv1') - result = self.config._derive_view(view) - self.assertEqual(response.deriv, ['deriv1', 'deriv3', 'deriv2']) - - def test_add_deriver_without_name(self): - from pyramid.interfaces import IViewDerivers - def deriv1(view, info): pass - self.config.add_view_deriver(deriv1) - derivers = self.config.registry.getUtility(IViewDerivers) - self.assertTrue('deriv1' in derivers.names) - - def test_add_deriver_reserves_ingress(self): - from pyramid.exceptions import ConfigurationError - from pyramid.viewderivers import INGRESS - def deriv1(view, info): pass - self.assertRaises( - ConfigurationError, self.config.add_view_deriver, deriv1, INGRESS) - - def test_add_deriver_enforces_ingress_is_first(self): - from pyramid.exceptions import ConfigurationError - from pyramid.viewderivers import INGRESS - def deriv1(view, info): pass - try: - self.config.add_view_deriver(deriv1, over=INGRESS) - except ConfigurationError as ex: - self.assertTrue('cannot be over INGRESS' in ex.args[0]) - else: # pragma: no cover - raise AssertionError - - def test_add_deriver_enforces_view_is_last(self): - from pyramid.exceptions import ConfigurationError - from pyramid.viewderivers import VIEW - def deriv1(view, info): pass - try: - self.config.add_view_deriver(deriv1, under=VIEW) - except ConfigurationError as ex: - self.assertTrue('cannot be under VIEW' in ex.args[0]) - else: # pragma: no cover - raise AssertionError - - def test_add_deriver_enforces_mapped_view_is_last(self): - from pyramid.exceptions import ConfigurationError - def deriv1(view, info): pass - try: - self.config.add_view_deriver(deriv1, 'deriv1', under='mapped_view') - except ConfigurationError as ex: - self.assertTrue('cannot be under "mapped_view"' in ex.args[0]) - else: # pragma: no cover - raise AssertionError - - -class TestDeriverIntegration(unittest.TestCase): - def setUp(self): - self.config = testing.setUp() - - def tearDown(self): - self.config = None - testing.tearDown() - - def _getViewCallable(self, config, ctx_iface=None, request_iface=None, - name=''): - from zope.interface import Interface - from pyramid.interfaces import IRequest - from pyramid.interfaces import IView - from pyramid.interfaces import IViewClassifier - classifier = IViewClassifier - if ctx_iface is None: - ctx_iface = Interface - if request_iface is None: - request_iface = IRequest - return config.registry.adapters.lookup( - (classifier, request_iface, ctx_iface), IView, name=name, - default=None) - - def _makeRequest(self, config): - request = DummyRequest() - request.registry = config.registry - return request - - def test_view_options(self): - response = DummyResponse() - view = lambda *arg: response - response.deriv = [] - - def deriv1(view, info): - response.deriv.append(info.options['deriv1']) - return view - deriv1.options = ('deriv1',) - - def deriv2(view, info): - response.deriv.append(info.options['deriv2']) - return view - deriv2.options = ('deriv2',) - - self.config.add_view_deriver(deriv1, 'deriv1') - self.config.add_view_deriver(deriv2, 'deriv2') - self.config.add_view(view, deriv1='test1', deriv2='test2') - - wrapper = self._getViewCallable(self.config) - request = self._makeRequest(self.config) - request.method = 'GET' - self.assertEqual(wrapper(None, request), response) - self.assertEqual(['test1', 'test2'], response.deriv) - - def test_unexpected_view_options(self): - from pyramid.exceptions import ConfigurationError - def deriv1(view, info): pass - self.config.add_view_deriver(deriv1, 'deriv1') - self.assertRaises( - ConfigurationError, - lambda: self.config.add_view(lambda r: {}, deriv1='test1')) - -@implementer(IResponse) -class DummyResponse(object): - content_type = None - default_content_type = None - body = None - -class DummyRequest: - subpath = () - matchdict = None - request_iface = IRequest - - def __init__(self, environ=None): - if environ is None: - environ = {} - self.environ = environ - self.params = {} - self.POST = {} - self.cookies = {} - self.headers = {} - self.response = DummyResponse() - -class DummyLogger: - def __init__(self): - self.messages = [] - def info(self, msg): - self.messages.append(msg) - warn = info - debug = info - -class DummySecurityPolicy: - def __init__(self, permitted=True): - self.permitted = permitted - - def effective_principals(self, request): - return [] - - def permits(self, context, principals, permission): - return self.permitted - -class DummySession(dict): - def get_csrf_token(self): - return self['csrf_token'] - -def parse_httpdate(s): - import datetime - # cannot use %Z, must use literal GMT; Jython honors timezone - # but CPython does not - return datetime.datetime.strptime(s, "%a, %d %b %Y %H:%M:%S GMT") - -def assert_similar_datetime(one, two): - for attr in ('year', 'month', 'day', 'hour', 'minute'): - one_attr = getattr(one, attr) - two_attr = getattr(two, attr) - if not one_attr == two_attr: # pragma: no cover - raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr)) diff --git a/src/pyramid/tests/test_wsgi.py b/src/pyramid/tests/test_wsgi.py deleted file mode 100644 index 4ddbc9201..000000000 --- a/src/pyramid/tests/test_wsgi.py +++ /dev/null @@ -1,130 +0,0 @@ -import unittest - -class WSGIAppTests(unittest.TestCase): - def _callFUT(self, app): - from pyramid.wsgi import wsgiapp - return wsgiapp(app) - - def test_wsgiapp_none(self): - self.assertRaises(ValueError, self._callFUT, None) - - def test_decorator(self): - context = DummyContext() - request = DummyRequest() - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - - def test_decorator_object_instance(self): - context = DummyContext() - request = DummyRequest() - app = DummyApp() - decorator = self._callFUT(app) - response = decorator(context, request) - self.assertEqual(response, app) - -class WSGIApp2Tests(unittest.TestCase): - def _callFUT(self, app): - from pyramid.wsgi import wsgiapp2 - return wsgiapp2(app) - - def test_wsgiapp2_none(self): - self.assertRaises(ValueError, self._callFUT, None) - - def test_decorator_with_subpath_and_view_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = ('subpath',) - request.environ = {'SCRIPT_NAME':'/foo', - 'PATH_INFO':'/b/view_name/subpath'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/subpath') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') - - def test_decorator_with_subpath_no_view_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = ('subpath',) - request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/subpath'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/subpath') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b') - - def test_decorator_no_subpath_with_view_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = () - request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/view_name'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') - - def test_decorator_traversed_empty_with_view_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = () - request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/view_name'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/view_name') - - def test_decorator_traversed_empty_no_view_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = () - request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo') - - def test_decorator_traversed_empty_no_view_name_no_script_name(self): - context = DummyContext() - request = DummyRequest() - request.subpath = () - request.environ = {'SCRIPT_NAME':'', 'PATH_INFO':'/'} - decorator = self._callFUT(dummyapp) - response = decorator(context, request) - self.assertEqual(response, dummyapp) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '') - - def test_decorator_on_callable_object_instance(self): - context = DummyContext() - request = DummyRequest() - request.subpath = () - request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/'} - app = DummyApp() - decorator = self._callFUT(app) - response = decorator(context, request) - self.assertEqual(response, app) - self.assertEqual(request.environ['PATH_INFO'], '/') - self.assertEqual(request.environ['SCRIPT_NAME'], '/foo') - -def dummyapp(environ, start_response): - """ """ - -class DummyApp(object): - def __call__(self, environ, start_response): - """ """ - -class DummyContext: - pass - -class DummyRequest: - def get_response(self, application): - return application - - def copy(self): - self.copied = True - return self - diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 000000000..a62c29f47 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,3 @@ + +def dummy_extend(*args): + """used to test Configurator.extend""" diff --git a/tests/fixtures/dummy.ini b/tests/fixtures/dummy.ini new file mode 100644 index 000000000..bc2281168 --- /dev/null +++ b/tests/fixtures/dummy.ini @@ -0,0 +1,4 @@ +[app:myapp] +use = call:pyramid.tests.test_paster:make_dummyapp + +foo = %(bar)s diff --git a/tests/fixtures/manifest.json b/tests/fixtures/manifest.json new file mode 100644 index 000000000..0a43bc5e3 --- /dev/null +++ b/tests/fixtures/manifest.json @@ -0,0 +1,4 @@ +{ + "css/main.css": "css/main-test.css", + "images/background.png": "images/background-a8169106.png" +} diff --git a/tests/fixtures/manifest2.json b/tests/fixtures/manifest2.json new file mode 100644 index 000000000..fd6b9a7bb --- /dev/null +++ b/tests/fixtures/manifest2.json @@ -0,0 +1,4 @@ +{ + "css/main.css": "css/main-678b7c80.css", + "images/background.png": "images/background-a8169106.png" +} diff --git a/tests/fixtures/minimal.jpg b/tests/fixtures/minimal.jpg new file mode 100644 index 000000000..1cda9a53d Binary files /dev/null and b/tests/fixtures/minimal.jpg differ diff --git a/tests/fixtures/minimal.pdf b/tests/fixtures/minimal.pdf new file mode 100755 index 000000000..e267be996 Binary files /dev/null and b/tests/fixtures/minimal.pdf differ diff --git a/tests/fixtures/minimal.txt b/tests/fixtures/minimal.txt new file mode 100644 index 000000000..18832d351 --- /dev/null +++ b/tests/fixtures/minimal.txt @@ -0,0 +1 @@ +Hello. diff --git a/tests/fixtures/minimal.xml b/tests/fixtures/minimal.xml new file mode 100644 index 000000000..1972c155d --- /dev/null +++ b/tests/fixtures/minimal.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/fixtures/nonminimal.txt b/tests/fixtures/nonminimal.txt new file mode 100644 index 000000000..9de95ec92 --- /dev/null +++ b/tests/fixtures/nonminimal.txt @@ -0,0 +1 @@ +Hello, ${name}! diff --git a/tests/fixtures/static/.hiddenfile b/tests/fixtures/static/.hiddenfile new file mode 100644 index 000000000..86d345000 --- /dev/null +++ b/tests/fixtures/static/.hiddenfile @@ -0,0 +1,2 @@ +I'm hidden + diff --git a/tests/fixtures/static/arcs.svg.tgz b/tests/fixtures/static/arcs.svg.tgz new file mode 100644 index 000000000..376c42ac8 --- /dev/null +++ b/tests/fixtures/static/arcs.svg.tgz @@ -0,0 +1,73 @@ + + + + + + + + diff --git a/tests/fixtures/static/index.html b/tests/fixtures/static/index.html new file mode 100644 index 000000000..0470710b2 --- /dev/null +++ b/tests/fixtures/static/index.html @@ -0,0 +1 @@ +static \ No newline at end of file diff --git a/tests/fixtures/static/subdir/index.html b/tests/fixtures/static/subdir/index.html new file mode 100644 index 000000000..bb84fad04 --- /dev/null +++ b/tests/fixtures/static/subdir/index.html @@ -0,0 +1 @@ +subdir diff --git a/tests/pkgs/__init__.py b/tests/pkgs/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/tests/pkgs/__init__.py @@ -0,0 +1 @@ +# package diff --git a/tests/pkgs/ccbugapp/__init__.py b/tests/pkgs/ccbugapp/__init__.py new file mode 100644 index 000000000..afe21d4e0 --- /dev/null +++ b/tests/pkgs/ccbugapp/__init__.py @@ -0,0 +1,16 @@ +from webob import Response + +def rdf_view(request): + """ """ + return Response('rdf') + +def juri_view(request): + """ """ + return Response('juri') + +def includeme(config): + config.add_route('rdf', 'licenses/:license_code/:license_version/rdf') + config.add_route('juri', + 'licenses/:license_code/:license_version/:jurisdiction') + config.add_view(rdf_view, route_name='rdf') + config.add_view(juri_view, route_name='juri') diff --git a/tests/pkgs/conflictapp/__init__.py b/tests/pkgs/conflictapp/__init__.py new file mode 100644 index 000000000..38116ab2f --- /dev/null +++ b/tests/pkgs/conflictapp/__init__.py @@ -0,0 +1,24 @@ +from pyramid.response import Response +from pyramid.authentication import AuthTktAuthenticationPolicy +from pyramid.authorization import ACLAuthorizationPolicy + +def aview(request): + return Response('a view') + +def routeview(request): + return Response('route view') + +def protectedview(request): + return Response('protected view') + +def includeme(config): + # purposely sorta-randomly ordered (route comes after view naming it, + # authz comes after views) + config.add_view(aview) + config.add_view(protectedview, name='protected', permission='view') + config.add_view(routeview, route_name='aroute') + config.add_route('aroute', '/route') + config.set_authentication_policy(AuthTktAuthenticationPolicy( + 'seekri1t', hashalg='sha512')) + config.set_authorization_policy(ACLAuthorizationPolicy()) + config.include('pyramid.tests.pkgs.conflictapp.included') diff --git a/tests/pkgs/conflictapp/included.py b/tests/pkgs/conflictapp/included.py new file mode 100644 index 000000000..0b76fb2bc --- /dev/null +++ b/tests/pkgs/conflictapp/included.py @@ -0,0 +1,6 @@ +from webob import Response + +def bview(request): return Response('b view') + +def includeme(config): + config.add_view(bview) diff --git a/tests/pkgs/defpermbugapp/__init__.py b/tests/pkgs/defpermbugapp/__init__.py new file mode 100644 index 000000000..032e8c626 --- /dev/null +++ b/tests/pkgs/defpermbugapp/__init__.py @@ -0,0 +1,26 @@ +from webob import Response +from pyramid.security import NO_PERMISSION_REQUIRED +from pyramid.view import view_config + +@view_config(name='x') +def x_view(request): # pragma: no cover + return Response('this is private!') + +@view_config(name='y', permission='private2') +def y_view(request): # pragma: no cover + return Response('this is private too!') + +@view_config(name='z', permission=NO_PERMISSION_REQUIRED) +def z_view(request): + return Response('this is public') + +def includeme(config): + from pyramid.authorization import ACLAuthorizationPolicy + from pyramid.authentication import AuthTktAuthenticationPolicy + authn_policy = AuthTktAuthenticationPolicy('seekt1t', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config.scan('pyramid.tests.pkgs.defpermbugapp') + config._set_authentication_policy(authn_policy) + config._set_authorization_policy(authz_policy) + config.set_default_permission('private') + diff --git a/tests/pkgs/eventonly/__init__.py b/tests/pkgs/eventonly/__init__.py new file mode 100644 index 000000000..7ae93ada6 --- /dev/null +++ b/tests/pkgs/eventonly/__init__.py @@ -0,0 +1,64 @@ +from pyramid.view import view_config +from pyramid.events import subscriber + +class Yup(object): + def __init__(self, val, config): + self.val = val + + def text(self): + return 'path_startswith = %s' % (self.val,) + + phash = text + + def __call__(self, event): + return getattr(event.response, 'yup', False) + +class Foo(object): + def __init__(self, response): + self.response = response + +class Bar(object): + pass + +@subscriber(Foo) +def foo(event): + event.response.text += 'foo ' + +@subscriber(Foo, yup=True) +def fooyup(event): + event.response.text += 'fooyup ' + +@subscriber([Foo, Bar]) +def foobar(event): + event.response.text += 'foobar ' + +@subscriber([Foo, Bar]) +def foobar2(event, context): + event.response.text += 'foobar2 ' + +@subscriber([Foo, Bar], yup=True) +def foobaryup(event): + event.response.text += 'foobaryup ' + +@subscriber([Foo, Bar], yup=True) +def foobaryup2(event, context): + event.response.text += 'foobaryup2 ' + +@view_config(name='sendfoo') +def sendfoo(request): + response = request.response + response.yup = True + request.registry.notify(Foo(response)) + return response + +@view_config(name='sendfoobar') +def sendfoobar(request): + response = request.response + response.yup = True + request.registry.notify(Foo(response), Bar()) + return response + +def includeme(config): + config.add_subscriber_predicate('yup', Yup) + config.scan('pyramid.tests.pkgs.eventonly') + diff --git a/tests/pkgs/exceptionviewapp/__init__.py b/tests/pkgs/exceptionviewapp/__init__.py new file mode 100644 index 000000000..ffc1b47c6 --- /dev/null +++ b/tests/pkgs/exceptionviewapp/__init__.py @@ -0,0 +1,31 @@ +from pyramid.httpexceptions import HTTPException + +def includeme(config): + config.add_route('route_raise_exception', 'route_raise_exception') + config.add_route('route_raise_httpexception', 'route_raise_httpexception') + config.add_route('route_raise_exception2', 'route_raise_exception2', + factory='.models.route_factory') + config.add_route('route_raise_exception3', 'route_raise_exception3', + factory='.models.route_factory2') + config.add_route('route_raise_exception4', 'route_raise_exception4') + config.add_view('.views.maybe') + config.add_view('.views.no', context='.models.NotAnException') + config.add_view('.views.yes', context=".models.AnException") + config.add_view('.views.raise_exception', name='raise_exception') + config.add_view('.views.raise_exception', + route_name='route_raise_exception') + config.add_view('.views.raise_exception', + route_name='route_raise_exception2') + config.add_view('.views.raise_exception', + route_name='route_raise_exception3') + config.add_view('.views.whoa', context='.models.AnException', + route_name='route_raise_exception3') + config.add_view('.views.raise_exception', + route_name='route_raise_exception4') + config.add_view('.views.whoa', context='.models.AnException', + route_name='route_raise_exception4') + config.add_view('.views.raise_httpexception', + route_name='route_raise_httpexception') + config.add_view('.views.catch_httpexception', context=HTTPException) + + diff --git a/tests/pkgs/exceptionviewapp/models.py b/tests/pkgs/exceptionviewapp/models.py new file mode 100644 index 000000000..fe407badc --- /dev/null +++ b/tests/pkgs/exceptionviewapp/models.py @@ -0,0 +1,18 @@ + +class NotAnException(object): + pass + +class AnException(Exception): + pass + +class RouteContext(object): + pass + +class RouteContext2(object): + pass + +def route_factory(*arg): + return RouteContext() + +def route_factory2(*arg): + return RouteContext2() diff --git a/tests/pkgs/exceptionviewapp/views.py b/tests/pkgs/exceptionviewapp/views.py new file mode 100644 index 000000000..4953056bc --- /dev/null +++ b/tests/pkgs/exceptionviewapp/views.py @@ -0,0 +1,24 @@ +from webob import Response +from .models import AnException +from pyramid.httpexceptions import HTTPBadRequest + +def no(request): + return Response('no') + +def yes(request): + return Response('yes') + +def maybe(request): + return Response('maybe') + +def whoa(request): + return Response('whoa') + +def raise_exception(request): + raise AnException() + +def raise_httpexception(request): + raise HTTPBadRequest + +def catch_httpexception(request): + return Response('caught') diff --git a/tests/pkgs/fixtureapp/__init__.py b/tests/pkgs/fixtureapp/__init__.py new file mode 100644 index 000000000..27063aae2 --- /dev/null +++ b/tests/pkgs/fixtureapp/__init__.py @@ -0,0 +1,12 @@ +def includeme(config): + config.add_view('.views.fixture_view') + config.add_view('.views.exception_view', context=RuntimeError) + config.add_view('.views.protected_view', name='protected.html') + config.add_view('.views.erroneous_view', name='error.html') + config.add_view('.views.fixture_view', name='dummyskin.html', + request_type='.views.IDummy') + from .models import fixture, IFixture + config.registry.registerUtility(fixture, IFixture) + config.add_view('.views.fixture_view', name='another.html') + + diff --git a/tests/pkgs/fixtureapp/models.py b/tests/pkgs/fixtureapp/models.py new file mode 100644 index 000000000..d80d14bb3 --- /dev/null +++ b/tests/pkgs/fixtureapp/models.py @@ -0,0 +1,8 @@ +from zope.interface import Interface + +class IFixture(Interface): + pass + +def fixture(): + """ """ + diff --git a/tests/pkgs/fixtureapp/subpackage/__init__.py b/tests/pkgs/fixtureapp/subpackage/__init__.py new file mode 100644 index 000000000..d3173e636 --- /dev/null +++ b/tests/pkgs/fixtureapp/subpackage/__init__.py @@ -0,0 +1 @@ +#package diff --git a/tests/pkgs/fixtureapp/views.py b/tests/pkgs/fixtureapp/views.py new file mode 100644 index 000000000..cbfc5a574 --- /dev/null +++ b/tests/pkgs/fixtureapp/views.py @@ -0,0 +1,22 @@ +from zope.interface import Interface +from webob import Response +from pyramid.httpexceptions import HTTPForbidden + +def fixture_view(context, request): + """ """ + return Response('fixture') + +def erroneous_view(context, request): + """ """ + raise RuntimeError() + +def exception_view(context, request): + """ """ + return Response('supressed') + +def protected_view(context, request): + """ """ + raise HTTPForbidden() + +class IDummy(Interface): + pass diff --git a/tests/pkgs/forbiddenapp/__init__.py b/tests/pkgs/forbiddenapp/__init__.py new file mode 100644 index 000000000..c378126fc --- /dev/null +++ b/tests/pkgs/forbiddenapp/__init__.py @@ -0,0 +1,24 @@ +from webob import Response +from pyramid.httpexceptions import HTTPForbidden +from pyramid.compat import bytes_ + +def x_view(request): # pragma: no cover + return Response('this is private!') + +def forbidden_view(context, request): + msg = context.message + result = context.result + message = msg + '\n' + str(result) + resp = HTTPForbidden() + resp.body = bytes_(message) + return resp + +def includeme(config): + from pyramid.authentication import AuthTktAuthenticationPolicy + from pyramid.authorization import ACLAuthorizationPolicy + authn_policy = AuthTktAuthenticationPolicy('seekr1t', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config._set_authentication_policy(authn_policy) + config._set_authorization_policy(authz_policy) + config.add_view(x_view, name='x', permission='private') + config.add_view(forbidden_view, context=HTTPForbidden) diff --git a/tests/pkgs/forbiddenview/__init__.py b/tests/pkgs/forbiddenview/__init__.py new file mode 100644 index 000000000..45fb8380b --- /dev/null +++ b/tests/pkgs/forbiddenview/__init__.py @@ -0,0 +1,31 @@ +from pyramid.view import forbidden_view_config, view_config +from pyramid.response import Response +from pyramid.authentication import AuthTktAuthenticationPolicy +from pyramid.authorization import ACLAuthorizationPolicy + +@forbidden_view_config(route_name='foo') +def foo_forbidden(request): # pragma: no cover + return Response('foo_forbidden') + +@forbidden_view_config() +def forbidden(request): + return Response('generic_forbidden') + +@view_config(route_name='foo') +def foo(request): # pragma: no cover + return Response('OK foo') + +@view_config(route_name='bar') +def bar(request): # pragma: no cover + return Response('OK bar') + +def includeme(config): + authn_policy = AuthTktAuthenticationPolicy('seekri1', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) + config.set_default_permission('a') + config.add_route('foo', '/foo') + config.add_route('bar', '/bar') + config.scan('pyramid.tests.pkgs.forbiddenview') + diff --git a/tests/pkgs/hybridapp/__init__.py b/tests/pkgs/hybridapp/__init__.py new file mode 100644 index 000000000..1cc2dde83 --- /dev/null +++ b/tests/pkgs/hybridapp/__init__.py @@ -0,0 +1,39 @@ +def includeme(config): + # + config.add_route('route', 'abc') + config.add_view('.views.route_view', route_name='route') + # + config.add_view('.views.global_view', + context='pyramid.traversal.DefaultRootFactory') + config.add_view('.views.global2_view', + context='pyramid.traversal.DefaultRootFactory', + name='global2') + config.add_route('route2', 'def') + # + config.add_view('.views.route2_view', route_name='route2') + + # + config.add_route('route3', 'ghi', use_global_views=True) + # + config.add_route('route4', 'jkl') + # + config.add_route('route5', 'mno/*traverse') + # + config.add_route('route6', 'pqr/*traverse', use_global_views=True) + config.add_route('route7', 'error') + config.add_view('.views.erroneous_view', route_name='route7') + config.add_route('route8', 'error2') + config.add_view('.views.erroneous_view', route_name='route8') + # + config.add_view('.views.exception_view', context=RuntimeError) + # + config.add_view('.views.exception2_view', context=RuntimeError, + route_name='route8') + config.add_route('route9', 'error_sub') + config.add_view('.views.erroneous_sub_view', route_name='route9') + # + config.add_view('.views.exception2_view', context='.views.SuperException', + route_name='route9') + # + config.add_view('.views.exception_view', context='.views.SubException') diff --git a/tests/pkgs/hybridapp/views.py b/tests/pkgs/hybridapp/views.py new file mode 100644 index 000000000..135ef8290 --- /dev/null +++ b/tests/pkgs/hybridapp/views.py @@ -0,0 +1,39 @@ +from webob import Response + +def route_view(request): + """ """ + return Response('route') + +def global_view(request): + """ """ + return Response('global') + +def global2_view(request): + """ """ + return Response('global2') + +def route2_view(request): + """ """ + return Response('route2') + +def exception_view(request): + """ """ + return Response('supressed') + +def exception2_view(request): + """ """ + return Response('supressed2') + +def erroneous_view(request): + """ """ + raise RuntimeError() + +def erroneous_sub_view(request): + """ """ + raise SubException() + +class SuperException(Exception): + """ """ + +class SubException(SuperException): + """ """ diff --git a/tests/pkgs/includeapp1/__init__.py b/tests/pkgs/includeapp1/__init__.py new file mode 100644 index 000000000..eaeeb7ef6 --- /dev/null +++ b/tests/pkgs/includeapp1/__init__.py @@ -0,0 +1 @@ +# include app diff --git a/tests/pkgs/includeapp1/root.py b/tests/pkgs/includeapp1/root.py new file mode 100644 index 000000000..f56203cfa --- /dev/null +++ b/tests/pkgs/includeapp1/root.py @@ -0,0 +1,10 @@ +from pyramid.response import Response + +def aview(request): + return Response('root') + +def configure(config): + config.add_view(aview) + config.include('pyramid.tests.pkgs.includeapp1.two.configure') + config.commit() + diff --git a/tests/pkgs/includeapp1/three.py b/tests/pkgs/includeapp1/three.py new file mode 100644 index 000000000..e7131bcf5 --- /dev/null +++ b/tests/pkgs/includeapp1/three.py @@ -0,0 +1,10 @@ +from pyramid.response import Response + +def aview(request): + return Response('three') + +def configure(config): + config.add_view(aview, name='three') + config.include('pyramid.tests.pkgs.includeapp1.two.configure') # should not cycle + config.add_view(aview) # will be overridden by root when resolved + diff --git a/tests/pkgs/includeapp1/two.py b/tests/pkgs/includeapp1/two.py new file mode 100644 index 000000000..99b0f883a --- /dev/null +++ b/tests/pkgs/includeapp1/two.py @@ -0,0 +1,9 @@ +from pyramid.response import Response + +def aview(request): + return Response('two') + +def configure(config): + config.add_view(aview, name='two') + config.include('pyramid.tests.pkgs.includeapp1.three.configure') + config.add_view(aview) # will be overridden by root when resolved diff --git a/tests/pkgs/localeapp/__init__.py b/tests/pkgs/localeapp/__init__.py new file mode 100644 index 000000000..1a35cdb4a --- /dev/null +++ b/tests/pkgs/localeapp/__init__.py @@ -0,0 +1 @@ +# a file diff --git a/tests/pkgs/localeapp/locale/GARBAGE b/tests/pkgs/localeapp/locale/GARBAGE new file mode 100644 index 000000000..032c55584 --- /dev/null +++ b/tests/pkgs/localeapp/locale/GARBAGE @@ -0,0 +1 @@ +Garbage file. diff --git a/tests/pkgs/localeapp/locale/be/LC_MESSAGES b/tests/pkgs/localeapp/locale/be/LC_MESSAGES new file mode 100644 index 000000000..909cf6a3b --- /dev/null +++ b/tests/pkgs/localeapp/locale/be/LC_MESSAGES @@ -0,0 +1 @@ +busted. diff --git a/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale/de/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..e3b2b0881 Binary files /dev/null and b/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..be055bed9 --- /dev/null +++ b/tests/pkgs/localeapp/locale/de_DE/LC_MESSAGES/deformsite.po @@ -0,0 +1,26 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "different" diff --git a/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale/en/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/localeapp/locale2/GARBAGE b/tests/pkgs/localeapp/locale2/GARBAGE new file mode 100644 index 000000000..032c55584 --- /dev/null +++ b/tests/pkgs/localeapp/locale2/GARBAGE @@ -0,0 +1 @@ +Garbage file. diff --git a/tests/pkgs/localeapp/locale2/be/LC_MESSAGES b/tests/pkgs/localeapp/locale2/be/LC_MESSAGES new file mode 100644 index 000000000..909cf6a3b --- /dev/null +++ b/tests/pkgs/localeapp/locale2/be/LC_MESSAGES @@ -0,0 +1 @@ +busted. diff --git a/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale2/de/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale2/en/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/localeapp/locale3/GARBAGE b/tests/pkgs/localeapp/locale3/GARBAGE new file mode 100644 index 000000000..032c55584 --- /dev/null +++ b/tests/pkgs/localeapp/locale3/GARBAGE @@ -0,0 +1 @@ +Garbage file. diff --git a/tests/pkgs/localeapp/locale3/be/LC_MESSAGES b/tests/pkgs/localeapp/locale3/be/LC_MESSAGES new file mode 100644 index 000000000..909cf6a3b --- /dev/null +++ b/tests/pkgs/localeapp/locale3/be/LC_MESSAGES @@ -0,0 +1 @@ +busted. diff --git a/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale3/de/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo b/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo new file mode 100644 index 000000000..2924a5eb5 Binary files /dev/null and b/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.mo differ diff --git a/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po b/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po new file mode 100644 index 000000000..17f87bc19 --- /dev/null +++ b/tests/pkgs/localeapp/locale3/en/LC_MESSAGES/deformsite.po @@ -0,0 +1,31 @@ +# German translations for deformsite. +# Copyright (C) 2010 ORGANIZATION +# This file is distributed under the same license as the deformsite project. +# FIRST AUTHOR , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: deformsite 0.0\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2010-04-22 14:17+0400\n" +"PO-Revision-Date: 2010-04-22 14:17-0400\n" +"Last-Translator: FULL NAME \n" +"Language-Team: de \n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.5\n" + +#: deformsite/__init__.py:458 +msgid "Approve" +msgstr "Genehmigen" + +#: deformsite/__init__.py:459 +msgid "Show approval" +msgstr "Zeigen Genehmigung" + +#: deformsite/__init__.py:466 +msgid "Submit" +msgstr "Beugen" + diff --git a/tests/pkgs/notfoundview/__init__.py b/tests/pkgs/notfoundview/__init__.py new file mode 100644 index 000000000..ae148ea8c --- /dev/null +++ b/tests/pkgs/notfoundview/__init__.py @@ -0,0 +1,30 @@ +from pyramid.view import notfound_view_config, view_config +from pyramid.response import Response + +@notfound_view_config(route_name='foo', append_slash=True) +def foo_notfound(request): # pragma: no cover + return Response('foo_notfound') + +@notfound_view_config(route_name='baz') +def baz_notfound(request): + return Response('baz_notfound') + +@notfound_view_config(append_slash=True) +def notfound(request): + return Response('generic_notfound') + +@view_config(route_name='bar') +def bar(request): + return Response('OK bar') + +@view_config(route_name='foo2') +def foo2(request): + return Response('OK foo2') + +def includeme(config): + config.add_route('foo', '/foo') + config.add_route('foo2', '/foo/') + config.add_route('bar', '/bar/') + config.add_route('baz', '/baz') + config.scan('pyramid.tests.pkgs.notfoundview') + diff --git a/tests/pkgs/permbugapp/__init__.py b/tests/pkgs/permbugapp/__init__.py new file mode 100644 index 000000000..4868427a5 --- /dev/null +++ b/tests/pkgs/permbugapp/__init__.py @@ -0,0 +1,22 @@ +from pyramid.compat import escape +from pyramid.security import view_execution_permitted +from pyramid.response import Response + +def x_view(request): # pragma: no cover + return Response('this is private!') + +def test(context, request): + # should return false + msg = 'Allow ./x? %s' % repr(view_execution_permitted( + context, request, 'x')) + return Response(escape(msg)) + +def includeme(config): + from pyramid.authentication import AuthTktAuthenticationPolicy + from pyramid.authorization import ACLAuthorizationPolicy + authn_policy = AuthTktAuthenticationPolicy('seekt1t', hashalg='sha512') + authz_policy = ACLAuthorizationPolicy() + config.set_authentication_policy(authn_policy) + config.set_authorization_policy(authz_policy) + config.add_view(test, name='test') + config.add_view(x_view, name='x', permission='private') diff --git a/tests/pkgs/rendererscanapp/__init__.py b/tests/pkgs/rendererscanapp/__init__.py new file mode 100644 index 000000000..f3276a063 --- /dev/null +++ b/tests/pkgs/rendererscanapp/__init__.py @@ -0,0 +1,9 @@ +from pyramid.view import view_config + +@view_config(name='one', renderer='json') +def one(request): + return {'name':'One!'} + +def includeme(config): + config.scan() + diff --git a/tests/pkgs/rendererscanapp/two/__init__.py b/tests/pkgs/rendererscanapp/two/__init__.py new file mode 100644 index 000000000..6f575dd83 --- /dev/null +++ b/tests/pkgs/rendererscanapp/two/__init__.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + +@view_config(name='two', renderer='json') +def two(request): + return {'nameagain':'Two!'} + diff --git a/tests/pkgs/restbugapp/__init__.py b/tests/pkgs/restbugapp/__init__.py new file mode 100644 index 000000000..9ad79e32e --- /dev/null +++ b/tests/pkgs/restbugapp/__init__.py @@ -0,0 +1,15 @@ +def includeme(config): + config.add_route('gameactions_pet_get_pets', '/pet', + request_method='GET') + config.add_route('gameactions_pet_care_for_pet', '/pet', + request_method='POST') + config.add_view('.views.PetRESTView', + route_name='gameactions_pet_get_pets', + attr='GET', + permission='view', + renderer='json') + config.add_view('.views.PetRESTView', + route_name='gameactions_pet_care_for_pet', + attr='POST', + permission='view', + renderer='json') diff --git a/tests/pkgs/restbugapp/views.py b/tests/pkgs/restbugapp/views.py new file mode 100644 index 000000000..2ace59fa9 --- /dev/null +++ b/tests/pkgs/restbugapp/views.py @@ -0,0 +1,15 @@ +from pyramid.response import Response + +class BaseRESTView(object): + def __init__(self, context, request): + self.context = context + self.request = request + +class PetRESTView(BaseRESTView): + """ REST Controller to control action of an avatar """ + def __init__(self, context, request): + super(PetRESTView, self).__init__(context, request) + + def GET(self): + return Response('gotten') + diff --git a/tests/pkgs/static_abspath/__init__.py b/tests/pkgs/static_abspath/__init__.py new file mode 100644 index 000000000..812cca467 --- /dev/null +++ b/tests/pkgs/static_abspath/__init__.py @@ -0,0 +1,7 @@ +import os + +def includeme(config): + here = here = os.path.dirname(__file__) + fixtures = os.path.normpath(os.path.join(here, '..', '..', 'fixtures')) + config.add_static_view('/', fixtures) + diff --git a/tests/pkgs/static_assetspec/__init__.py b/tests/pkgs/static_assetspec/__init__.py new file mode 100644 index 000000000..cd6195397 --- /dev/null +++ b/tests/pkgs/static_assetspec/__init__.py @@ -0,0 +1,3 @@ +def includeme(config): + config.add_static_view('/', 'pyramid.tests:fixtures') + diff --git a/tests/pkgs/static_routeprefix/__init__.py b/tests/pkgs/static_routeprefix/__init__.py new file mode 100644 index 000000000..9b539380a --- /dev/null +++ b/tests/pkgs/static_routeprefix/__init__.py @@ -0,0 +1,7 @@ +def includeme(config): + config.add_static_view('/static', 'pyramid.tests:fixtures') + config.include(includeme2, route_prefix='/prefix') + +def includeme2(config): + config.add_static_view('/static', 'pyramid.tests:fixtures/static') + diff --git a/tests/pkgs/staticpermapp/__init__.py b/tests/pkgs/staticpermapp/__init__.py new file mode 100644 index 000000000..cc690d937 --- /dev/null +++ b/tests/pkgs/staticpermapp/__init__.py @@ -0,0 +1,25 @@ +class RootFactory(object): + __acl__ = [('Allow', 'fred', 'view')] + def __init__(self, request): + pass + +class LocalRootFactory(object): + __acl__ = [('Allow', 'bob', 'view')] + def __init__(self, request): + pass + + +def includeme(config): + from pyramid.authentication import RemoteUserAuthenticationPolicy + from pyramid.authorization import ACLAuthorizationPolicy + authn_policy = RemoteUserAuthenticationPolicy() + authz_policy = ACLAuthorizationPolicy() + config._set_authentication_policy(authn_policy) + config._set_authorization_policy(authz_policy) + config.add_static_view('allowed', 'pyramid.tests:fixtures/static/') + config.add_static_view('protected', 'pyramid.tests:fixtures/static/', + permission='view') + config.add_static_view('factory_protected', + 'pyramid.tests:fixtures/static/', + permission='view', + factory=LocalRootFactory) diff --git a/tests/pkgs/subrequestapp/__init__.py b/tests/pkgs/subrequestapp/__init__.py new file mode 100644 index 000000000..e4b1d386a --- /dev/null +++ b/tests/pkgs/subrequestapp/__init__.py @@ -0,0 +1,52 @@ +from pyramid.config import Configurator +from pyramid.request import Request + +def view_one(request): + subreq = Request.blank('/view_two') + response = request.invoke_subrequest(subreq, use_tweens=False) + return response + +def view_two(request): + # check that request.foo is valid for a subrequest + return 'This came from view_two, foo=%s' % (request.foo,) + +def view_three(request): + subreq = Request.blank('/view_four') + try: + return request.invoke_subrequest(subreq, use_tweens=True) + except: # pragma: no cover + request.response.body = b'Value error raised' + return request.response + +def view_four(request): + raise ValueError('foo') + +def view_five(request): + subreq = Request.blank('/view_four') + try: + return request.invoke_subrequest(subreq, use_tweens=False) + except ValueError: + request.response.body = b'Value error raised' + return request.response + +def excview(request): + request.response.status_int = 500 + request.response.body = b'Bad stuff happened' + return request.response + +def main(): + config = Configurator() + config.add_route('one', '/view_one') + config.add_route('two', '/view_two') + config.add_route('three', '/view_three') + config.add_route('four', '/view_four') + config.add_route('five', '/view_five') + config.add_view(excview, context=Exception) + config.add_view(view_one, route_name='one') + config.add_view(view_two, route_name='two', renderer='string') + config.add_view(view_three, route_name='three') + config.add_view(view_four, route_name='four') + config.add_view(view_five, route_name='five') + config.add_request_method(lambda r: 'bar', 'foo', property=True) + return config + diff --git a/tests/pkgs/viewdecoratorapp/__init__.py b/tests/pkgs/viewdecoratorapp/__init__.py new file mode 100644 index 000000000..5fa98062a --- /dev/null +++ b/tests/pkgs/viewdecoratorapp/__init__.py @@ -0,0 +1,3 @@ +def includeme(config): + config.scan('pyramid.tests.pkgs.viewdecoratorapp') + diff --git a/tests/pkgs/viewdecoratorapp/views/__init__.py b/tests/pkgs/viewdecoratorapp/views/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/tests/pkgs/viewdecoratorapp/views/__init__.py @@ -0,0 +1 @@ +# package diff --git a/tests/pkgs/viewdecoratorapp/views/views.py b/tests/pkgs/viewdecoratorapp/views/views.py new file mode 100644 index 000000000..18ec78847 --- /dev/null +++ b/tests/pkgs/viewdecoratorapp/views/views.py @@ -0,0 +1,12 @@ +from pyramid.view import view_config + +@view_config(renderer='json', name='first') +def first(request): + return {'result':'OK1'} + +@view_config( + renderer='json', + name='second') +def second(request): + return {'result':'OK2'} + diff --git a/tests/pkgs/wsgiapp2app/__init__.py b/tests/pkgs/wsgiapp2app/__init__.py new file mode 100644 index 000000000..e2024198e --- /dev/null +++ b/tests/pkgs/wsgiapp2app/__init__.py @@ -0,0 +1,17 @@ +from pyramid.view import view_config +from pyramid.wsgi import wsgiapp2 + +@view_config(name='hello', renderer='string') +@wsgiapp2 +def hello(environ, start_response): + assert environ['PATH_INFO'] == '/' + assert environ['SCRIPT_NAME'] == '/hello' + response_headers = [('Content-Type', 'text/plain')] + start_response('200 OK', response_headers) + return [b'Hello!'] + +def main(): + from pyramid.config import Configurator + c = Configurator() + c.scan() + return c diff --git a/tests/test_asset.py b/tests/test_asset.py new file mode 100644 index 000000000..d3ebd5f7d --- /dev/null +++ b/tests/test_asset.py @@ -0,0 +1,88 @@ +import unittest +import os + +here = os.path.abspath(os.path.dirname(__file__)) + +class Test_resolve_asset_spec(unittest.TestCase): + def _callFUT(self, spec, package_name='__main__'): + from pyramid.resource import resolve_asset_spec + return resolve_asset_spec(spec, package_name) + + def test_abspath(self): + package_name, filename = self._callFUT(here, 'apackage') + self.assertEqual(filename, here) + self.assertEqual(package_name, None) + + def test_rel_spec(self): + pkg = 'pyramid.tests' + path = 'test_asset.py' + package_name, filename = self._callFUT(path, pkg) + self.assertEqual(package_name, 'pyramid.tests') + self.assertEqual(filename, 'test_asset.py') + + def test_abs_spec(self): + pkg = 'pyramid.tests' + path = 'pyramid.nottests:test_asset.py' + package_name, filename = self._callFUT(path, pkg) + self.assertEqual(package_name, 'pyramid.nottests') + self.assertEqual(filename, 'test_asset.py') + + def test_package_name_is_None(self): + pkg = None + path = 'test_asset.py' + package_name, filename = self._callFUT(path, pkg) + self.assertEqual(package_name, None) + self.assertEqual(filename, 'test_asset.py') + + def test_package_name_is_package_object(self): + import pyramid.tests + pkg = pyramid.tests + path = 'test_asset.py' + package_name, filename = self._callFUT(path, pkg) + self.assertEqual(package_name, 'pyramid.tests') + self.assertEqual(filename, 'test_asset.py') + + +class Test_abspath_from_asset_spec(unittest.TestCase): + def _callFUT(self, spec, pname='__main__'): + from pyramid.resource import abspath_from_asset_spec + return abspath_from_asset_spec(spec, pname) + + def test_pname_is_None_before_resolve_asset_spec(self): + result = self._callFUT('abc', None) + self.assertEqual(result, 'abc') + + def test_pname_is_None_after_resolve_asset_spec(self): + result = self._callFUT('/abc', '__main__') + self.assertEqual(result, '/abc') + + def test_pkgrelative(self): + result = self._callFUT('abc', 'pyramid.tests') + self.assertEqual(result, os.path.join(here, 'abc')) + +class Test_asset_spec_from_abspath(unittest.TestCase): + def _callFUT(self, abspath, package): + from pyramid.asset import asset_spec_from_abspath + return asset_spec_from_abspath(abspath, package) + + def test_package_name_is_main(self): + pkg = DummyPackage('__main__') + result = self._callFUT('abspath', pkg) + self.assertEqual(result, 'abspath') + + def test_abspath_startswith_package_path(self): + abspath = os.path.join(here, 'fixtureapp') + pkg = DummyPackage('pyramid.tests') + pkg.__file__ = 'file' + result = self._callFUT(abspath, pkg) + self.assertEqual(result, 'pyramid:fixtureapp') + + def test_abspath_doesnt_startwith_package_path(self): + pkg = DummyPackage('pyramid.tests') + result = self._callFUT(here, pkg) + self.assertEqual(result, here) + +class DummyPackage: + def __init__(self, name): + self.__name__ = name + diff --git a/tests/test_authentication.py b/tests/test_authentication.py new file mode 100644 index 000000000..4efd76f2b --- /dev/null +++ b/tests/test_authentication.py @@ -0,0 +1,1738 @@ +import unittest +import warnings +from pyramid import testing +from pyramid.compat import ( + text_, + bytes_, + ) + +class TestCallbackAuthenticationPolicyDebugging(unittest.TestCase): + def setUp(self): + from pyramid.interfaces import IDebugLogger + self.config = testing.setUp() + self.config.registry.registerUtility(self, IDebugLogger) + self.messages = [] + + def tearDown(self): + del self.config + + def debug(self, msg): + self.messages.append(msg) + + def _makeOne(self, userid=None, callback=None): + from pyramid.authentication import CallbackAuthenticationPolicy + class MyAuthenticationPolicy(CallbackAuthenticationPolicy): + def unauthenticated_userid(self, request): + return userid + policy = MyAuthenticationPolicy() + policy.debug = True + policy.callback = callback + return policy + + def test_authenticated_userid_no_unauthenticated_userid(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' + 'authenticated_userid: call to unauthenticated_userid returned ' + 'None; returning None') + + def test_authenticated_userid_no_callback(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='fred') + self.assertEqual(policy.authenticated_userid(request), 'fred') + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "authenticated_userid: there was no groupfinder callback; " + "returning 'fred'") + + def test_authenticated_userid_with_callback_fail(self): + request = DummyRequest(registry=self.config.registry) + def callback(userid, request): + return None + policy = self._makeOne(userid='fred', callback=callback) + self.assertEqual(policy.authenticated_userid(request), None) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' + 'authenticated_userid: groupfinder callback returned None; ' + 'returning None') + + def test_authenticated_userid_with_callback_success(self): + request = DummyRequest(registry=self.config.registry) + def callback(userid, request): + return [] + policy = self._makeOne(userid='fred', callback=callback) + self.assertEqual(policy.authenticated_userid(request), 'fred') + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "authenticated_userid: groupfinder callback returned []; " + "returning 'fred'") + + def test_authenticated_userid_fails_cleaning_as_Authenticated(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='system.Authenticated') + self.assertEqual(policy.authenticated_userid(request), None) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "authenticated_userid: use of userid 'system.Authenticated' is " + "disallowed by any built-in Pyramid security policy, returning " + "None") + + def test_authenticated_userid_fails_cleaning_as_Everyone(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='system.Everyone') + self.assertEqual(policy.authenticated_userid(request), None) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "authenticated_userid: use of userid 'system.Everyone' is " + "disallowed by any built-in Pyramid security policy, returning " + "None") + + def test_effective_principals_no_unauthenticated_userid(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), + ['system.Everyone']) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: unauthenticated_userid returned None; " + "returning ['system.Everyone']") + + def test_effective_principals_no_callback(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='fred') + self.assertEqual( + policy.effective_principals(request), + ['system.Everyone', 'system.Authenticated', 'fred']) + self.assertEqual(len(self.messages), 2) + self.assertEqual( + self.messages[0], + 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' + 'effective_principals: groupfinder callback is None, so groups ' + 'is []') + self.assertEqual( + self.messages[1], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: returning effective principals: " + "['system.Everyone', 'system.Authenticated', 'fred']") + + def test_effective_principals_with_callback_fail(self): + request = DummyRequest(registry=self.config.registry) + def callback(userid, request): + return None + policy = self._makeOne(userid='fred', callback=callback) + self.assertEqual( + policy.effective_principals(request), ['system.Everyone']) + self.assertEqual(len(self.messages), 2) + self.assertEqual( + self.messages[0], + 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' + 'effective_principals: groupfinder callback returned None as ' + 'groups') + self.assertEqual( + self.messages[1], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: returning effective principals: " + "['system.Everyone']") + + def test_effective_principals_with_callback_success(self): + request = DummyRequest(registry=self.config.registry) + def callback(userid, request): + return [] + policy = self._makeOne(userid='fred', callback=callback) + self.assertEqual( + policy.effective_principals(request), + ['system.Everyone', 'system.Authenticated', 'fred']) + self.assertEqual(len(self.messages), 2) + self.assertEqual( + self.messages[0], + 'pyramid.tests.test_authentication.MyAuthenticationPolicy.' + 'effective_principals: groupfinder callback returned [] as groups') + self.assertEqual( + self.messages[1], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: returning effective principals: " + "['system.Everyone', 'system.Authenticated', 'fred']") + + def test_effective_principals_with_unclean_principal_Authenticated(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='system.Authenticated') + self.assertEqual( + policy.effective_principals(request), + ['system.Everyone']) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: unauthenticated_userid returned disallowed " + "'system.Authenticated'; returning ['system.Everyone'] as if it " + "was None") + + def test_effective_principals_with_unclean_principal_Everyone(self): + request = DummyRequest(registry=self.config.registry) + policy = self._makeOne(userid='system.Everyone') + self.assertEqual( + policy.effective_principals(request), + ['system.Everyone']) + self.assertEqual(len(self.messages), 1) + self.assertEqual( + self.messages[0], + "pyramid.tests.test_authentication.MyAuthenticationPolicy." + "effective_principals: unauthenticated_userid returned disallowed " + "'system.Everyone'; returning ['system.Everyone'] as if it " + "was None") + +class TestRepozeWho1AuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import RepozeWho1AuthenticationPolicy + return RepozeWho1AuthenticationPolicy + + def _makeOne(self, identifier_name='auth_tkt', callback=None): + return self._getTargetClass()(identifier_name, callback) + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne()) + + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + + def test_authenticated_userid_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), 'fred') + + def test_authenticated_userid_repoze_who_userid_is_None(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':None}}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid_with_callback_returns_None(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + def callback(identity, request): + return None + policy = self._makeOne(callback=callback) + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid_with_callback_returns_something(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + def callback(identity, request): + return ['agroup'] + policy = self._makeOne(callback=callback) + self.assertEqual(policy.authenticated_userid(request), 'fred') + + def test_authenticated_userid_unclean_principal_Authenticated(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'system.Authenticated'}} + ) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid_unclean_principal_Everyone(self): + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'system.Everyone'}} + ) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_effective_principals_None(self): + from pyramid.security import Everyone + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_userid_only(self): + from pyramid.security import Everyone + from pyramid.security import Authenticated + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred'}}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), + [Everyone, Authenticated, 'fred']) + + def test_effective_principals_userid_and_groups(self): + from pyramid.security import Everyone + from pyramid.security import Authenticated + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred', + 'groups':['quux', 'biz']}}) + def callback(identity, request): + return identity['groups'] + policy = self._makeOne(callback=callback) + self.assertEqual(policy.effective_principals(request), + [Everyone, Authenticated, 'fred', 'quux', 'biz']) + + def test_effective_principals_userid_callback_returns_None(self): + from pyramid.security import Everyone + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'fred', + 'groups':['quux', 'biz']}}) + def callback(identity, request): + return None + policy = self._makeOne(callback=callback) + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_repoze_who_userid_is_None(self): + from pyramid.security import Everyone + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':None}} + ) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_repoze_who_userid_is_unclean_Everyone(self): + from pyramid.security import Everyone + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'system.Everyone'}} + ) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_repoze_who_userid_is_unclean_Authenticated( + self): + from pyramid.security import Everyone + request = DummyRequest( + {'repoze.who.identity':{'repoze.who.userid':'system.Authenticated'}} + ) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_remember_no_plugins(self): + request = DummyRequest({}) + policy = self._makeOne() + result = policy.remember(request, 'fred') + self.assertEqual(result, []) + + def test_remember(self): + authtkt = DummyWhoPlugin() + request = DummyRequest( + {'repoze.who.plugins':{'auth_tkt':authtkt}}) + policy = self._makeOne() + result = policy.remember(request, 'fred') + self.assertEqual(result[0], request.environ) + self.assertEqual(result[1], {'repoze.who.userid':'fred'}) + + def test_remember_kwargs(self): + authtkt = DummyWhoPlugin() + request = DummyRequest( + {'repoze.who.plugins':{'auth_tkt':authtkt}}) + policy = self._makeOne() + result = policy.remember(request, 'fred', max_age=23) + self.assertEqual(result[1], {'repoze.who.userid':'fred', 'max_age': 23}) + + def test_forget_no_plugins(self): + request = DummyRequest({}) + policy = self._makeOne() + result = policy.forget(request) + self.assertEqual(result, []) + + def test_forget(self): + authtkt = DummyWhoPlugin() + request = DummyRequest( + {'repoze.who.plugins':{'auth_tkt':authtkt}, + 'repoze.who.identity':{'repoze.who.userid':'fred'}, + }) + policy = self._makeOne() + result = policy.forget(request) + self.assertEqual(result[0], request.environ) + self.assertEqual(result[1], request.environ['repoze.who.identity']) + +class TestRemoteUserAuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import RemoteUserAuthenticationPolicy + return RemoteUserAuthenticationPolicy + + def _makeOne(self, environ_key='REMOTE_USER', callback=None): + return self._getTargetClass()(environ_key, callback) + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne()) + + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + + def test_authenticated_userid_None(self): + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), 'fred') + + def test_effective_principals_None(self): + from pyramid.security import Everyone + request = DummyRequest({}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals(self): + from pyramid.security import Everyone + from pyramid.security import Authenticated + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), + [Everyone, Authenticated, 'fred']) + + def test_remember(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.remember(request, 'fred') + self.assertEqual(result, []) + + def test_forget(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne() + result = policy.forget(request) + self.assertEqual(result, []) + +class TestAuthTktAuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import AuthTktAuthenticationPolicy + return AuthTktAuthenticationPolicy + + def _makeOne(self, callback, cookieidentity, **kw): + inst = self._getTargetClass()('secret', callback, **kw) + inst.cookie = DummyCookieHelper(cookieidentity) + return inst + + def setUp(self): + self.warnings = warnings.catch_warnings() + self.warnings.__enter__() + warnings.simplefilter('ignore', DeprecationWarning) + + def tearDown(self): + self.warnings.__exit__(None, None, None) + + def test_allargs(self): + # pass all known args + inst = self._getTargetClass()( + 'secret', callback=None, cookie_name=None, secure=False, + include_ip=False, timeout=None, reissue_time=None, + hashalg='sha512', samesite=None, + ) + self.assertEqual(inst.callback, None) + + def test_hashalg_override(self): + # important to ensure hashalg is passed to cookie helper + inst = self._getTargetClass()('secret', hashalg='sha512') + self.assertEqual(inst.cookie.hashalg, 'sha512') + + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest({'REMOTE_USER':'fred'}) + policy = self._makeOne(None, {'userid':'fred'}) + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + + def test_authenticated_userid_no_cookie_identity(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid_callback_returns_None(self): + request = DummyRequest({}) + def callback(userid, request): + return None + policy = self._makeOne(callback, {'userid':'fred'}) + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid(self): + request = DummyRequest({}) + def callback(userid, request): + return True + policy = self._makeOne(callback, {'userid':'fred'}) + self.assertEqual(policy.authenticated_userid(request), 'fred') + + def test_effective_principals_no_cookie_identity(self): + from pyramid.security import Everyone + request = DummyRequest({}) + policy = self._makeOne(None, None) + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_callback_returns_None(self): + from pyramid.security import Everyone + request = DummyRequest({}) + def callback(userid, request): + return None + policy = self._makeOne(callback, {'userid':'fred'}) + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals(self): + from pyramid.security import Everyone + from pyramid.security import Authenticated + request = DummyRequest({}) + def callback(userid, request): + return ['group.foo'] + policy = self._makeOne(callback, {'userid':'fred'}) + self.assertEqual(policy.effective_principals(request), + [Everyone, Authenticated, 'fred', 'group.foo']) + + def test_remember(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + result = policy.remember(request, 'fred') + self.assertEqual(result, []) + + def test_remember_with_extra_kargs(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + result = policy.remember(request, 'fred', a=1, b=2) + self.assertEqual(policy.cookie.kw, {'a':1, 'b':2}) + self.assertEqual(result, []) + + def test_forget(self): + request = DummyRequest({}) + policy = self._makeOne(None, None) + result = policy.forget(request) + self.assertEqual(result, []) + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne(None, None)) + +class TestAuthTktCookieHelper(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import AuthTktCookieHelper + return AuthTktCookieHelper + + def _makeOne(self, *arg, **kw): + helper = self._getTargetClass()(*arg, **kw) + # laziness after moving auth_tkt classes and funcs into + # authentication module + auth_tkt = DummyAuthTktModule() + helper.auth_tkt = auth_tkt + helper.AuthTicket = auth_tkt.AuthTicket + helper.parse_ticket = auth_tkt.parse_ticket + helper.BadTicket = auth_tkt.BadTicket + return helper + + def _makeRequest(self, cookie=None, ipv6=False): + environ = {'wsgi.version': (1,0)} + + if ipv6 is False: + environ['REMOTE_ADDR'] = '1.1.1.1' + else: + environ['REMOTE_ADDR'] = '::1' + environ['SERVER_NAME'] = 'localhost' + return DummyRequest(environ, cookie=cookie) + + def _cookieValue(self, cookie): + items = cookie.value.split('/') + D = {} + for item in items: + k, v = item.split('=', 1) + D[k] = v + return D + + def _parseHeaders(self, headers): + return [ self._parseHeader(header) for header in headers ] + + def _parseHeader(self, header): + cookie = self._parseCookie(header[1]) + return cookie + + def _parseCookie(self, cookie): + from pyramid.compat import SimpleCookie + cookies = SimpleCookie() + cookies.load(cookie) + return cookies.get('auth_tkt') + + def test_init_cookie_str_reissue_invalid(self): + self.assertRaises(ValueError, self._makeOne, 'secret', reissue_time='invalid value') + + def test_init_cookie_str_timeout_invalid(self): + self.assertRaises(ValueError, self._makeOne, 'secret', timeout='invalid value') + + def test_init_cookie_str_max_age_invalid(self): + self.assertRaises(ValueError, self._makeOne, 'secret', max_age='invalid value') + + def test_identify_nocookie(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.identify(request) + self.assertEqual(result, None) + + def test_identify_cookie_value_is_None(self): + helper = self._makeOne('secret') + request = self._makeRequest(None) + result = helper.identify(request) + self.assertEqual(result, None) + + def test_identify_good_cookie_include_ip(self): + helper = self._makeOne('secret', include_ip=True) + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 'userid') + self.assertEqual(result['userdata'], '') + self.assertEqual(result['timestamp'], 0) + self.assertEqual(helper.auth_tkt.value, 'ticket') + self.assertEqual(helper.auth_tkt.remote_addr, '1.1.1.1') + self.assertEqual(helper.auth_tkt.secret, 'secret') + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_include_ipv6(self): + helper = self._makeOne('secret', include_ip=True) + request = self._makeRequest('ticket', ipv6=True) + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 'userid') + self.assertEqual(result['userdata'], '') + self.assertEqual(result['timestamp'], 0) + self.assertEqual(helper.auth_tkt.value, 'ticket') + self.assertEqual(helper.auth_tkt.remote_addr, '::1') + self.assertEqual(helper.auth_tkt.secret, 'secret') + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_dont_include_ip(self): + helper = self._makeOne('secret', include_ip=False) + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 'userid') + self.assertEqual(result['userdata'], '') + self.assertEqual(result['timestamp'], 0) + self.assertEqual(helper.auth_tkt.value, 'ticket') + self.assertEqual(helper.auth_tkt.remote_addr, '0.0.0.0') + self.assertEqual(helper.auth_tkt.secret, 'secret') + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_int_useridtype(self): + helper = self._makeOne('secret', include_ip=False) + helper.auth_tkt.userid = '1' + helper.auth_tkt.user_data = 'userid_type:int' + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 1) + self.assertEqual(result['userdata'], 'userid_type:int') + self.assertEqual(result['timestamp'], 0) + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:int') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_nonuseridtype_user_data(self): + helper = self._makeOne('secret', include_ip=False) + helper.auth_tkt.userid = '1' + helper.auth_tkt.user_data = 'bogus:int' + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], '1') + self.assertEqual(result['userdata'], 'bogus:int') + self.assertEqual(result['timestamp'], 0) + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'bogus:int') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_unknown_useridtype(self): + helper = self._makeOne('secret', include_ip=False) + helper.auth_tkt.userid = 'abc' + helper.auth_tkt.user_data = 'userid_type:unknown' + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], 'abc') + self.assertEqual(result['userdata'], 'userid_type:unknown') + self.assertEqual(result['timestamp'], 0) + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:unknown') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_b64str_useridtype(self): + from base64 import b64encode + helper = self._makeOne('secret', include_ip=False) + helper.auth_tkt.userid = b64encode(b'encoded').strip() + helper.auth_tkt.user_data = 'userid_type:b64str' + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], b'encoded') + self.assertEqual(result['userdata'], 'userid_type:b64str') + self.assertEqual(result['timestamp'], 0) + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64str') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_good_cookie_b64unicode_useridtype(self): + from base64 import b64encode + helper = self._makeOne('secret', include_ip=False) + helper.auth_tkt.userid = b64encode(b'\xc3\xa9ncoded').strip() + helper.auth_tkt.user_data = 'userid_type:b64unicode' + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(len(result), 4) + self.assertEqual(result['tokens'], ()) + self.assertEqual(result['userid'], text_(b'\xc3\xa9ncoded', 'utf-8')) + self.assertEqual(result['userdata'], 'userid_type:b64unicode') + self.assertEqual(result['timestamp'], 0) + environ = request.environ + self.assertEqual(environ['REMOTE_USER_TOKENS'], ()) + self.assertEqual(environ['REMOTE_USER_DATA'],'userid_type:b64unicode') + self.assertEqual(environ['AUTH_TYPE'],'cookie') + + def test_identify_bad_cookie(self): + helper = self._makeOne('secret', include_ip=True) + helper.auth_tkt.parse_raise = True + request = self._makeRequest('ticket') + result = helper.identify(request) + self.assertEqual(result, None) + + def test_identify_cookie_timeout(self): + helper = self._makeOne('secret', timeout=1) + self.assertEqual(helper.timeout, 1) + + def test_identify_cookie_str_timeout(self): + helper = self._makeOne('secret', timeout='1') + self.assertEqual(helper.timeout, 1) + + def test_identify_cookie_timeout_aged(self): + import time + helper = self._makeOne('secret', timeout=10) + now = time.time() + helper.auth_tkt.timestamp = now - 1 + helper.now = now + 10 + helper.auth_tkt.tokens = (text_('a'), ) + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertFalse(result) + + def test_identify_cookie_reissue(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time=0) + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + helper.auth_tkt.tokens = (text_('a'), ) + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + response = DummyResponse() + request.callbacks[0](request, response) + self.assertEqual(len(response.headerlist), 3) + self.assertEqual(response.headerlist[0][0], 'Set-Cookie') + + def test_identify_cookie_str_reissue(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time='0') + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + helper.auth_tkt.tokens = (text_('a'), ) + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + response = DummyResponse() + request.callbacks[0](request, response) + self.assertEqual(len(response.headerlist), 3) + self.assertEqual(response.headerlist[0][0], 'Set-Cookie') + + def test_identify_cookie_reissue_already_reissued_this_request(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time=0) + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + request = self._makeRequest('bogus') + request._authtkt_reissued = True + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 0) + + def test_identify_cookie_reissue_notyet(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time=10) + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 0) + + def test_identify_cookie_reissue_revoked_by_forget(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time=0) + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + result = helper.forget(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + response = DummyResponse() + request.callbacks[0](request, response) + self.assertEqual(len(response.headerlist), 0) + + def test_identify_cookie_reissue_revoked_by_remember(self): + import time + helper = self._makeOne('secret', timeout=10, reissue_time=0) + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + result = helper.remember(request, 'bob') + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + response = DummyResponse() + request.callbacks[0](request, response) + self.assertEqual(len(response.headerlist), 0) + + def test_identify_cookie_reissue_with_tokens_default(self): + # see https://github.com/Pylons/pyramid/issues#issue/108 + import time + helper = self._makeOne('secret', timeout=10, reissue_time=0) + auth_tkt = DummyAuthTktModule(tokens=['']) + helper.auth_tkt = auth_tkt + helper.AuthTicket = auth_tkt.AuthTicket + helper.parse_ticket = auth_tkt.parse_ticket + helper.BadTicket = auth_tkt.BadTicket + now = time.time() + helper.auth_tkt.timestamp = now + helper.now = now + 1 + request = self._makeRequest('bogus') + result = helper.identify(request) + self.assertTrue(result) + self.assertEqual(len(request.callbacks), 1) + response = DummyResponse() + request.callbacks[0](None, response) + self.assertEqual(len(response.headerlist), 3) + self.assertEqual(response.headerlist[0][0], 'Set-Cookie') + self.assertTrue("/tokens=/" in response.headerlist[0][1]) + + def test_remember(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 'userid') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/; SameSite=Lax')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue(result[2][1].endswith( + '; Domain=.localhost; Path=/; SameSite=Lax')) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_nondefault_samesite(self): + helper = self._makeOne('secret', samesite='Strict') + request = self._makeRequest() + result = helper.remember(request, 'userid') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Strict')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/; SameSite=Strict')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue(result[2][1].endswith( + '; Domain=.localhost; Path=/; SameSite=Strict')) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_None_samesite(self): + helper = self._makeOne('secret', samesite=None) + request = self._makeRequest() + result = helper.remember(request, 'userid') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/')) # no samesite + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue(result[2][1].endswith( + '; Domain=.localhost; Path=/')) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_include_ip(self): + helper = self._makeOne('secret', include_ip=True) + request = self._makeRequest() + result = helper.remember(request, 'other') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/; SameSite=Lax')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue(result[2][1].endswith( + '; Domain=.localhost; Path=/; SameSite=Lax')) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_path(self): + helper = self._makeOne('secret', include_ip=True, + path="/cgi-bin/app.cgi/") + request = self._makeRequest() + result = helper.remember(request, 'other') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith( + '; Path=/cgi-bin/app.cgi/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/cgi-bin/app.cgi/; SameSite=Lax')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue(result[2][1].endswith( + '; Domain=.localhost; Path=/cgi-bin/app.cgi/; SameSite=Lax')) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_http_only(self): + helper = self._makeOne('secret', include_ip=True, http_only=True) + request = self._makeRequest() + result = helper.remember(request, 'other') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; HttpOnly; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue('; HttpOnly' in result[1][1]) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue('; HttpOnly' in result[2][1]) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_secure(self): + helper = self._makeOne('secret', include_ip=True, secure=True) + request = self._makeRequest() + result = helper.remember(request, 'other') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue('; secure' in result[0][1]) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue('; secure' in result[1][1]) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue('; secure' in result[2][1]) + self.assertTrue(result[2][1].startswith('auth_tkt=')) + + def test_remember_wild_domain_disabled(self): + helper = self._makeOne('secret', wild_domain=False) + request = self._makeRequest() + result = helper.remember(request, 'other') + self.assertEqual(len(result), 2) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith('; Path=/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue(result[1][1].endswith( + '; Domain=localhost; Path=/; SameSite=Lax')) + self.assertTrue(result[1][1].startswith('auth_tkt=')) + + def test_remember_parent_domain(self): + helper = self._makeOne('secret', parent_domain=True) + request = self._makeRequest() + request.domain = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith( + '; Domain=.example.com; Path=/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + def test_remember_parent_domain_supercedes_wild_domain(self): + helper = self._makeOne('secret', parent_domain=True, wild_domain=True) + request = self._makeRequest() + request.domain = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + self.assertTrue(result[0][1].endswith( + '; Domain=.example.com; Path=/; SameSite=Lax')) + + def test_remember_explicit_domain(self): + helper = self._makeOne('secret', domain='pyramid.bazinga') + request = self._makeRequest() + request.domain = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue(result[0][1].endswith( + '; Domain=pyramid.bazinga; Path=/; SameSite=Lax')) + self.assertTrue(result[0][1].startswith('auth_tkt=')) + + def test_remember_domain_supercedes_parent_and_wild_domain(self): + helper = self._makeOne('secret', domain='pyramid.bazinga', + parent_domain=True, wild_domain=True) + request = self._makeRequest() + request.domain = 'www.example.com' + result = helper.remember(request, 'other') + self.assertEqual(len(result), 1) + self.assertTrue(result[0][1].endswith( + '; Domain=pyramid.bazinga; Path=/; SameSite=Lax')) + + def test_remember_binary_userid(self): + import base64 + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, b'userid') + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + val = self._cookieValue(values[0]) + self.assertEqual(val['userid'], + text_(base64.b64encode(b'userid').strip())) + self.assertEqual(val['user_data'], 'userid_type:b64str') + + def test_remember_int_userid(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 1) + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + val = self._cookieValue(values[0]) + self.assertEqual(val['userid'], '1') + self.assertEqual(val['user_data'], 'userid_type:int') + + def test_remember_long_userid(self): + from pyramid.compat import long + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, long(1)) + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + val = self._cookieValue(values[0]) + self.assertEqual(val['userid'], '1') + self.assertEqual(val['user_data'], 'userid_type:int') + + def test_remember_unicode_userid(self): + import base64 + helper = self._makeOne('secret') + request = self._makeRequest() + userid = text_(b'\xc2\xa9', 'utf-8') + result = helper.remember(request, userid) + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + val = self._cookieValue(values[0]) + self.assertEqual(val['userid'], + text_(base64.b64encode(userid.encode('utf-8')))) + self.assertEqual(val['user_data'], 'userid_type:b64unicode') + + def test_remember_insane_userid(self): + helper = self._makeOne('secret') + request = self._makeRequest() + userid = object() + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter('always', RuntimeWarning) + result = helper.remember(request, userid) + self.assertTrue(str(w[-1].message).startswith('userid is of type')) + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + value = values[0] + self.assertTrue('userid' in value.value) + + def test_remember_max_age(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 'userid', max_age=500) + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + + self.assertEqual(values[0]['max-age'], '500') + self.assertTrue(values[0]['expires']) + + def test_remember_str_max_age(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 'userid', max_age='500') + values = self._parseHeaders(result) + self.assertEqual(len(result), 3) + + self.assertEqual(values[0]['max-age'], '500') + self.assertTrue(values[0]['expires']) + + def test_remember_str_max_age_invalid(self): + helper = self._makeOne('secret') + request = self._makeRequest() + self.assertRaises(ValueError, helper.remember, request, 'userid', max_age='invalid value') + + def test_remember_tokens(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 'other', tokens=('foo', 'bar')) + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + self.assertTrue("/tokens=foo|bar/" in result[0][1]) + + self.assertEqual(result[1][0], 'Set-Cookie') + self.assertTrue("/tokens=foo|bar/" in result[1][1]) + + self.assertEqual(result[2][0], 'Set-Cookie') + self.assertTrue("/tokens=foo|bar/" in result[2][1]) + + def test_remember_samesite_nondefault(self): + helper = self._makeOne('secret', samesite='Strict') + request = self._makeRequest() + result = helper.remember(request, 'userid') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + cookieval = result[0][1] + self.assertTrue('SameSite=Strict' in + [x.strip() for x in cookieval.split(';')], cookieval) + + self.assertEqual(result[1][0], 'Set-Cookie') + cookieval = result[1][1] + self.assertTrue('SameSite=Strict' in + [x.strip() for x in cookieval.split(';')], cookieval) + + self.assertEqual(result[2][0], 'Set-Cookie') + cookieval = result[2][1] + self.assertTrue('SameSite=Strict' in + [x.strip() for x in cookieval.split(';')], cookieval) + + def test_remember_samesite_default(self): + helper = self._makeOne('secret') + request = self._makeRequest() + result = helper.remember(request, 'userid') + self.assertEqual(len(result), 3) + + self.assertEqual(result[0][0], 'Set-Cookie') + cookieval = result[0][1] + self.assertTrue('SameSite=Lax' in + [x.strip() for x in cookieval.split(';')], cookieval) + + self.assertEqual(result[1][0], 'Set-Cookie') + cookieval = result[1][1] + self.assertTrue('SameSite=Lax' in + [x.strip() for x in cookieval.split(';')], cookieval) + + self.assertEqual(result[2][0], 'Set-Cookie') + cookieval = result[2][1] + self.assertTrue('SameSite=Lax' in + [x.strip() for x in cookieval.split(';')], cookieval) + + def test_remember_unicode_but_ascii_token(self): + helper = self._makeOne('secret') + request = self._makeRequest() + la = text_(b'foo', 'utf-8') + result = helper.remember(request, 'other', tokens=(la,)) + # tokens must be str type on both Python 2 and 3 + self.assertTrue("/tokens=foo/" in result[0][1]) + + def test_remember_nonascii_token(self): + helper = self._makeOne('secret') + request = self._makeRequest() + la = text_(b'La Pe\xc3\xb1a', 'utf-8') + self.assertRaises(ValueError, helper.remember, request, 'other', + tokens=(la,)) + + def test_remember_invalid_token_format(self): + helper = self._makeOne('secret') + request = self._makeRequest() + self.assertRaises(ValueError, helper.remember, request, 'other', + tokens=('foo bar',)) + self.assertRaises(ValueError, helper.remember, request, 'other', + tokens=('1bar',)) + + def test_forget(self): + helper = self._makeOne('secret') + request = self._makeRequest() + headers = helper.forget(request) + self.assertEqual(len(headers), 3) + name, value = headers[0] + self.assertEqual(name, 'Set-Cookie') + self.assertEqual( + value, + 'auth_tkt=; Max-Age=0; Path=/; ' + 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' + ) + name, value = headers[1] + self.assertEqual(name, 'Set-Cookie') + self.assertEqual( + value, + 'auth_tkt=; Domain=localhost; Max-Age=0; Path=/; ' + 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' + ) + name, value = headers[2] + self.assertEqual(name, 'Set-Cookie') + self.assertEqual( + value, + 'auth_tkt=; Domain=.localhost; Max-Age=0; Path=/; ' + 'expires=Wed, 31-Dec-97 23:59:59 GMT; SameSite=Lax' + ) + +class TestAuthTicket(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.authentication import AuthTicket + return AuthTicket(*arg, **kw) + + def test_ctor_with_tokens(self): + ticket = self._makeOne('secret', 'userid', 'ip', tokens=('a', 'b')) + self.assertEqual(ticket.tokens, 'a,b') + + def test_ctor_with_time(self): + ticket = self._makeOne('secret', 'userid', 'ip', time='time') + self.assertEqual(ticket.time, 'time') + + def test_digest(self): + ticket = self._makeOne('secret', 'userid', '0.0.0.0', time=10) + result = ticket.digest() + self.assertEqual(result, '126fd6224912187ee9ffa80e0b81420c') + + def test_digest_sha512(self): + ticket = self._makeOne('secret', 'userid', '0.0.0.0', + time=10, hashalg='sha512') + result = ticket.digest() + self.assertEqual(result, '74770b2e0d5b1a54c2a466ec567a40f7d7823576aa49'\ + '3c65fc3445e9b44097f4a80410319ef8cb256a2e60b9'\ + 'c2002e48a9e33a3e8ee4379352c04ef96d2cb278') + + def test_cookie_value(self): + ticket = self._makeOne('secret', 'userid', '0.0.0.0', time=10, + tokens=('a', 'b')) + result = ticket.cookie_value() + self.assertEqual(result, + '66f9cc3e423dc57c91df696cf3d1f0d80000000auserid!a,b!') + + def test_ipv4(self): + ticket = self._makeOne('secret', 'userid', '198.51.100.1', + time=10, hashalg='sha256') + result = ticket.cookie_value() + self.assertEqual(result, 'b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b'\ + '798400ecdade8d76c530000000auserid!') + + def test_ipv6(self): + ticket = self._makeOne('secret', 'userid', '2001:db8::1', + time=10, hashalg='sha256') + result = ticket.cookie_value() + self.assertEqual(result, 'd025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c8'\ + '5becf8760cd7a2fa4910000000auserid!') + +class TestBadTicket(unittest.TestCase): + def _makeOne(self, msg, expected=None): + from pyramid.authentication import BadTicket + return BadTicket(msg, expected) + + def test_it(self): + exc = self._makeOne('msg', expected=True) + self.assertEqual(exc.expected, True) + self.assertTrue(isinstance(exc, Exception)) + +class Test_parse_ticket(unittest.TestCase): + def _callFUT(self, secret, ticket, ip, hashalg='md5'): + from pyramid.authentication import parse_ticket + return parse_ticket(secret, ticket, ip, hashalg) + + def _assertRaisesBadTicket(self, secret, ticket, ip, hashalg='md5'): + from pyramid.authentication import BadTicket + self.assertRaises(BadTicket,self._callFUT, secret, ticket, ip, hashalg) + + def test_bad_timestamp(self): + ticket = 'x' * 64 + self._assertRaisesBadTicket('secret', ticket, 'ip') + + def test_bad_userid_or_data(self): + ticket = 'x' * 32 + '11111111' + 'x' * 10 + self._assertRaisesBadTicket('secret', ticket, 'ip') + + def test_digest_sig_incorrect(self): + ticket = 'x' * 32 + '11111111' + 'a!b!c' + self._assertRaisesBadTicket('secret', ticket, '0.0.0.0') + + def test_correct_with_user_data(self): + ticket = text_('66f9cc3e423dc57c91df696cf3d1f0d80000000auserid!a,b!') + result = self._callFUT('secret', ticket, '0.0.0.0') + self.assertEqual(result, (10, 'userid', ['a', 'b'], '')) + + def test_correct_with_user_data_sha512(self): + ticket = text_('7d947cdef99bad55f8e3382a8bd089bb9dd0547f7925b7d189adc1' + '160cab0ec0e6888faa41eba641a18522b26f19109f3ffafb769767' + 'ba8a26d02aaeae56599a0000000auserid!a,b!') + result = self._callFUT('secret', ticket, '0.0.0.0', 'sha512') + self.assertEqual(result, (10, 'userid', ['a', 'b'], '')) + + def test_ipv4(self): + ticket = text_('b3e7156db4f8abde4439c4a6499a0668f9e7ffd7fa27b798400ecd' + 'ade8d76c530000000auserid!') + result = self._callFUT('secret', ticket, '198.51.100.1', 'sha256') + self.assertEqual(result, (10, 'userid', [''], '')) + + def test_ipv6(self): + ticket = text_('d025b601a0f12ca6d008aa35ff3a22b7d8f3d1c1456c85becf8760' + 'cd7a2fa4910000000auserid!') + result = self._callFUT('secret', ticket, '2001:db8::1', 'sha256') + self.assertEqual(result, (10, 'userid', [''], '')) + +class TestSessionAuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import SessionAuthenticationPolicy + return SessionAuthenticationPolicy + + def _makeOne(self, callback=None, prefix=''): + return self._getTargetClass()(prefix=prefix, callback=callback) + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IAuthenticationPolicy + verifyObject(IAuthenticationPolicy, self._makeOne()) + + def test_unauthenticated_userid_returns_None(self): + request = DummyRequest() + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid(self): + request = DummyRequest(session={'userid':'fred'}) + policy = self._makeOne() + self.assertEqual(policy.unauthenticated_userid(request), 'fred') + + def test_authenticated_userid_no_cookie_identity(self): + request = DummyRequest() + policy = self._makeOne() + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid_callback_returns_None(self): + request = DummyRequest(session={'userid':'fred'}) + def callback(userid, request): + return None + policy = self._makeOne(callback) + self.assertEqual(policy.authenticated_userid(request), None) + + def test_authenticated_userid(self): + request = DummyRequest(session={'userid':'fred'}) + def callback(userid, request): + return True + policy = self._makeOne(callback) + self.assertEqual(policy.authenticated_userid(request), 'fred') + + def test_effective_principals_no_identity(self): + from pyramid.security import Everyone + request = DummyRequest() + policy = self._makeOne() + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals_callback_returns_None(self): + from pyramid.security import Everyone + request = DummyRequest(session={'userid':'fred'}) + def callback(userid, request): + return None + policy = self._makeOne(callback) + self.assertEqual(policy.effective_principals(request), [Everyone]) + + def test_effective_principals(self): + from pyramid.security import Everyone + from pyramid.security import Authenticated + request = DummyRequest(session={'userid':'fred'}) + def callback(userid, request): + return ['group.foo'] + policy = self._makeOne(callback) + self.assertEqual(policy.effective_principals(request), + [Everyone, Authenticated, 'fred', 'group.foo']) + + def test_remember(self): + request = DummyRequest() + policy = self._makeOne() + result = policy.remember(request, 'fred') + self.assertEqual(request.session.get('userid'), 'fred') + self.assertEqual(result, []) + + def test_forget(self): + request = DummyRequest(session={'userid':'fred'}) + policy = self._makeOne() + result = policy.forget(request) + self.assertEqual(request.session.get('userid'), None) + self.assertEqual(result, []) + + def test_forget_no_identity(self): + request = DummyRequest() + policy = self._makeOne() + result = policy.forget(request) + self.assertEqual(request.session.get('userid'), None) + self.assertEqual(result, []) + +class TestBasicAuthAuthenticationPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.authentication import BasicAuthAuthenticationPolicy as cls + return cls + + def _makeOne(self, check): + return self._getTargetClass()(check, realm='SomeRealm') + + def test_class_implements_IAuthenticationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthenticationPolicy + verifyClass(IAuthenticationPolicy, self._getTargetClass()) + + def test_unauthenticated_userid(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic %s' % base64.b64encode( + bytes_('chrisr:password')).decode('ascii') + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), 'chrisr') + + def test_unauthenticated_userid_no_credentials(self): + request = testing.DummyRequest() + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_bad_header(self): + request = testing.DummyRequest() + request.headers['Authorization'] = '...' + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid_not_basic(self): + request = testing.DummyRequest() + request.headers['Authorization'] = 'Complicated things' + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_unauthenticated_userid_corrupt_base64(self): + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic chrisr:password' + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_authenticated_userid(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic %s' % base64.b64encode( + bytes_('chrisr:password')).decode('ascii') + def check(username, password, request): + return [] + policy = self._makeOne(check) + self.assertEqual(policy.authenticated_userid(request), 'chrisr') + + def test_authenticated_userid_utf8(self): + import base64 + request = testing.DummyRequest() + inputs = (b'm\xc3\xb6rk\xc3\xb6:' + b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('utf-8')).decode('latin-1')) + def check(username, password, request): + return [] + policy = self._makeOne(check) + self.assertEqual(policy.authenticated_userid(request), + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) + + def test_authenticated_userid_latin1(self): + import base64 + request = testing.DummyRequest() + inputs = (b'm\xc3\xb6rk\xc3\xb6:' + b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('latin-1')).decode('latin-1')) + def check(username, password, request): + return [] + policy = self._makeOne(check) + self.assertEqual(policy.authenticated_userid(request), + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8')) + + def test_unauthenticated_userid_invalid_payload(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic %s' % base64.b64encode( + bytes_('chrisrpassword')).decode('ascii') + policy = self._makeOne(None) + self.assertEqual(policy.unauthenticated_userid(request), None) + + def test_remember(self): + policy = self._makeOne(None) + self.assertEqual(policy.remember(None, None), []) + + def test_forget(self): + policy = self._makeOne(None) + self.assertEqual(policy.forget(None), [ + ('WWW-Authenticate', 'Basic realm="SomeRealm"')]) + + +class TestExtractHTTPBasicCredentials(unittest.TestCase): + def _get_func(self): + from pyramid.authentication import extract_http_basic_credentials + return extract_http_basic_credentials + + def test_no_auth_header(self): + request = testing.DummyRequest() + fn = self._get_func() + + self.assertIsNone(fn(request)) + + def test_invalid_payload(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic %s' % base64.b64encode( + bytes_('chrisrpassword')).decode('ascii') + fn = self._get_func() + self.assertIsNone(fn(request)) + + def test_not_a_basic_auth_scheme(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'OtherScheme %s' % base64.b64encode( + bytes_('chrisr:password')).decode('ascii') + fn = self._get_func() + self.assertIsNone(fn(request)) + + def test_no_base64_encoding(self): + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic ...' + fn = self._get_func() + self.assertIsNone(fn(request)) + + def test_latin1_payload(self): + import base64 + request = testing.DummyRequest() + inputs = (b'm\xc3\xb6rk\xc3\xb6:' + b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('latin-1')).decode('latin-1')) + fn = self._get_func() + self.assertEqual(fn(request), ( + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8'), + b'm\xc3\xb6rk\xc3\xb6password'.decode('utf-8') + )) + + def test_utf8_payload(self): + import base64 + request = testing.DummyRequest() + inputs = (b'm\xc3\xb6rk\xc3\xb6:' + b'm\xc3\xb6rk\xc3\xb6password').decode('utf-8') + request.headers['Authorization'] = 'Basic %s' % ( + base64.b64encode(inputs.encode('utf-8')).decode('latin-1')) + fn = self._get_func() + self.assertEqual(fn(request), ( + b'm\xc3\xb6rk\xc3\xb6'.decode('utf-8'), + b'm\xc3\xb6rk\xc3\xb6password'.decode('utf-8') + )) + + def test_namedtuple_return(self): + import base64 + request = testing.DummyRequest() + request.headers['Authorization'] = 'Basic %s' % base64.b64encode( + bytes_('chrisr:pass')).decode('ascii') + fn = self._get_func() + result = fn(request) + + self.assertEqual(result.username, 'chrisr') + self.assertEqual(result.password, 'pass') + +class DummyContext: + pass + +class DummyCookies(object): + def __init__(self, cookie): + self.cookie = cookie + + def get(self, name): + return self.cookie + +class DummyRequest: + domain = 'localhost' + def __init__(self, environ=None, session=None, registry=None, cookie=None): + self.environ = environ or {} + self.session = session or {} + self.registry = registry + self.callbacks = [] + self.cookies = DummyCookies(cookie) + + def add_response_callback(self, callback): + self.callbacks.append(callback) + +class DummyWhoPlugin: + def remember(self, environ, identity): + return environ, identity + + def forget(self, environ, identity): + return environ, identity + +class DummyCookieHelper: + def __init__(self, result): + self.result = result + + def identify(self, *arg, **kw): + return self.result + + def remember(self, *arg, **kw): + self.kw = kw + return [] + + def forget(self, *arg): + return [] + +class DummyAuthTktModule(object): + def __init__(self, timestamp=0, userid='userid', tokens=(), user_data='', + parse_raise=False, hashalg="md5"): + self.timestamp = timestamp + self.userid = userid + self.tokens = tokens + self.user_data = user_data + self.parse_raise = parse_raise + self.hashalg = hashalg + def parse_ticket(secret, value, remote_addr, hashalg): + self.secret = secret + self.value = value + self.remote_addr = remote_addr + if self.parse_raise: + raise self.BadTicket() + return self.timestamp, self.userid, self.tokens, self.user_data + self.parse_ticket = parse_ticket + + class AuthTicket(object): + def __init__(self, secret, userid, remote_addr, **kw): + self.secret = secret + self.userid = userid + self.remote_addr = remote_addr + self.kw = kw + + def cookie_value(self): + result = { + 'secret':self.secret, + 'userid':self.userid, + 'remote_addr':self.remote_addr + } + result.update(self.kw) + tokens = result.pop('tokens', None) + if tokens is not None: + tokens = '|'.join(tokens) + result['tokens'] = tokens + items = sorted(result.items()) + new_items = [] + for k, v in items: + if isinstance(v, bytes): + v = text_(v) + new_items.append((k,v)) + result = '/'.join(['%s=%s' % (k, v) for k,v in new_items ]) + return result + self.AuthTicket = AuthTicket + + class BadTicket(Exception): + pass + +class DummyResponse: + def __init__(self): + self.headerlist = [] + diff --git a/tests/test_authorization.py b/tests/test_authorization.py new file mode 100644 index 000000000..05cd3b4f8 --- /dev/null +++ b/tests/test_authorization.py @@ -0,0 +1,259 @@ +import unittest + +from pyramid.testing import cleanUp + +class TestACLAuthorizationPolicy(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from pyramid.authorization import ACLAuthorizationPolicy + return ACLAuthorizationPolicy + + def _makeOne(self): + return self._getTargetClass()() + + def test_class_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IAuthorizationPolicy + verifyClass(IAuthorizationPolicy, self._getTargetClass()) + + def test_instance_implements_IAuthorizationPolicy(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IAuthorizationPolicy + verifyObject(IAuthorizationPolicy, self._makeOne()) + + def test_permits_no_acl(self): + context = DummyContext() + policy = self._makeOne() + self.assertEqual(policy.permits(context, [], 'view'), False) + + def test_permits(self): + from pyramid.security import Deny + from pyramid.security import Allow + from pyramid.security import Everyone + from pyramid.security import Authenticated + from pyramid.security import ALL_PERMISSIONS + from pyramid.security import DENY_ALL + root = DummyContext() + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ + (Allow, Authenticated, VIEW), + ] + community.__acl__ = [ + (Allow, 'fred', ALL_PERMISSIONS), + (Allow, 'wilma', VIEW), + DENY_ALL, + ] + blog.__acl__ = [ + (Allow, 'barney', MEMBER_PERMS), + (Allow, 'wilma', VIEW), + ] + + policy = self._makeOne() + + result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'wilma', VIEW)) + self.assertEqual(result.acl, blog.__acl__) + + result = policy.permits(blog, [Everyone, Authenticated, 'wilma'], + 'delete') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + self.assertEqual(result.acl, community.__acl__) + + result = policy.permits(blog, [Everyone, Authenticated, 'fred'], 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + result = policy.permits(blog, [Everyone, Authenticated, 'fred'], + 'doesntevenexistyet') + self.assertEqual(result, True) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Allow, 'fred', ALL_PERMISSIONS)) + self.assertEqual(result.acl, community.__acl__) + + result = policy.permits(blog, [Everyone, Authenticated, 'barney'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, blog) + self.assertEqual(result.ace, (Allow, 'barney', MEMBER_PERMS)) + result = policy.permits(blog, [Everyone, Authenticated, 'barney'], + 'administer') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + self.assertEqual(result.acl, community.__acl__) + + result = policy.permits(root, [Everyone, Authenticated, 'someguy'], + 'view') + self.assertEqual(result, True) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, (Allow, Authenticated, VIEW)) + result = policy.permits(blog, + [Everyone, Authenticated, 'someguy'], 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, community) + self.assertEqual(result.ace, (Deny, Everyone, ALL_PERMISSIONS)) + self.assertEqual(result.acl, community.__acl__) + + result = policy.permits(root, [Everyone], 'view') + self.assertEqual(result, False) + self.assertEqual(result.context, root) + self.assertEqual(result.ace, '') + self.assertEqual(result.acl, root.__acl__) + + context = DummyContext() + result = policy.permits(context, [Everyone], 'view') + self.assertEqual(result, False) + self.assertEqual(result.ace, '') + self.assertEqual( + result.acl, + '') + + def test_permits_string_permissions_in_acl(self): + from pyramid.security import Allow + root = DummyContext() + root.__acl__ = [ + (Allow, 'wilma', 'view_stuff'), + ] + + policy = self._makeOne() + + result = policy.permits(root, ['wilma'], 'view') + # would be True if matching against 'view_stuff' instead of against + # ['view_stuff'] + self.assertEqual(result, False) + + def test_principals_allowed_by_permission_direct(self): + from pyramid.security import Allow + from pyramid.security import DENY_ALL + context = DummyContext() + acl = [ (Allow, 'chrism', ('read', 'write')), + DENY_ALL, + (Allow, 'other', 'read') ] + context.__acl__ = acl + policy = self._makeOne() + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, ['chrism']) + + def test_principals_allowed_by_permission_callable_acl(self): + from pyramid.security import Allow + from pyramid.security import DENY_ALL + context = DummyContext() + acl = lambda: [ (Allow, 'chrism', ('read', 'write')), + DENY_ALL, + (Allow, 'other', 'read') ] + context.__acl__ = acl + policy = self._makeOne() + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, ['chrism']) + + def test_principals_allowed_by_permission_string_permission(self): + from pyramid.security import Allow + context = DummyContext() + acl = [ (Allow, 'chrism', 'read_it')] + context.__acl__ = acl + policy = self._makeOne() + result = policy.principals_allowed_by_permission(context, 'read') + # would be ['chrism'] if 'read' were compared against 'read_it' instead + # of against ['read_it'] + self.assertEqual(list(result), []) + + def test_principals_allowed_by_permission(self): + from pyramid.security import Allow + from pyramid.security import Deny + from pyramid.security import DENY_ALL + from pyramid.security import ALL_PERMISSIONS + root = DummyContext(__name__='', __parent__=None) + community = DummyContext(__name__='community', __parent__=root) + blog = DummyContext(__name__='blog', __parent__=community) + root.__acl__ = [ (Allow, 'chrism', ('read', 'write')), + (Allow, 'other', ('read',)), + (Allow, 'jim', ALL_PERMISSIONS)] + community.__acl__ = [ (Deny, 'flooz', 'read'), + (Allow, 'flooz', 'read'), + (Allow, 'mork', 'read'), + (Deny, 'jim', 'read'), + (Allow, 'someguy', 'manage')] + blog.__acl__ = [ (Allow, 'fred', 'read'), + DENY_ALL] + + policy = self._makeOne() + + result = sorted(policy.principals_allowed_by_permission(blog, 'read')) + self.assertEqual(result, ['fred']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + self.assertEqual(result, ['chrism', 'mork', 'other']) + result = sorted(policy.principals_allowed_by_permission(community, + 'read')) + result = sorted(policy.principals_allowed_by_permission(root, 'read')) + self.assertEqual(result, ['chrism', 'jim', 'other']) + + def test_principals_allowed_by_permission_no_acls(self): + context = DummyContext() + policy = self._makeOne() + result = sorted(policy.principals_allowed_by_permission(context,'read')) + self.assertEqual(result, []) + + def test_principals_allowed_by_permission_deny_not_permission_in_acl(self): + from pyramid.security import Deny + from pyramid.security import Everyone + context = DummyContext() + acl = [ (Deny, Everyone, 'write') ] + context.__acl__ = acl + policy = self._makeOne() + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, []) + + def test_principals_allowed_by_permission_deny_permission_in_acl(self): + from pyramid.security import Deny + from pyramid.security import Everyone + context = DummyContext() + acl = [ (Deny, Everyone, 'read') ] + context.__acl__ = acl + policy = self._makeOne() + result = sorted( + policy.principals_allowed_by_permission(context, 'read')) + self.assertEqual(result, []) + + def test_callable_acl(self): + from pyramid.security import Allow + context = DummyContext() + fn = lambda self: [(Allow, 'bob', 'read')] + context.__acl__ = fn.__get__(context, context.__class__) + policy = self._makeOne() + result = policy.permits(context, ['bob'], 'read') + self.assertTrue(result) + + +class DummyContext: + def __init__(self, *arg, **kw): + self.__dict__.update(kw) + + +VIEW = 'view' +EDIT = 'edit' +CREATE = 'create' +DELETE = 'delete' +MODERATE = 'moderate' +ADMINISTER = 'administer' +COMMENT = 'comment' + +GUEST_PERMS = (VIEW, COMMENT) +MEMBER_PERMS = GUEST_PERMS + (EDIT, CREATE, DELETE) +MODERATOR_PERMS = MEMBER_PERMS + (MODERATE,) +ADMINISTRATOR_PERMS = MODERATOR_PERMS + (ADMINISTER,) + diff --git a/tests/test_compat.py b/tests/test_compat.py new file mode 100644 index 000000000..23ccce82e --- /dev/null +++ b/tests/test_compat.py @@ -0,0 +1,26 @@ +import unittest +from pyramid.compat import is_unbound_method + +class TestUnboundMethods(unittest.TestCase): + def test_old_style_bound(self): + self.assertFalse(is_unbound_method(OldStyle().run)) + + def test_new_style_bound(self): + self.assertFalse(is_unbound_method(NewStyle().run)) + + def test_old_style_unbound(self): + self.assertTrue(is_unbound_method(OldStyle.run)) + + def test_new_style_unbound(self): + self.assertTrue(is_unbound_method(NewStyle.run)) + + def test_normal_func_unbound(self): + def func(): return 'OK' + + self.assertFalse(is_unbound_method(func)) + +class OldStyle: + def run(self): return 'OK' + +class NewStyle(object): + def run(self): return 'OK' diff --git a/tests/test_config/__init__.py b/tests/test_config/__init__.py new file mode 100644 index 000000000..81d9f4965 --- /dev/null +++ b/tests/test_config/__init__.py @@ -0,0 +1,53 @@ +# package + +from zope.interface import implementer +from zope.interface import Interface + +class IFactory(Interface): + pass + +def dummy_tween_factory(handler, registry): pass + +def dummy_tween_factory2(handler, registry): pass + +def dummy_include(config): + config.registry.included = True + config.action('discrim', None, config.package) + +def dummy_include2(config): + config.registry.also_included = True + config.action('discrim', None, config.package) + +includeme = dummy_include + +class DummyContext: + pass + +@implementer(IFactory) +class DummyFactory(object): + def __call__(self): + """ """ + +def dummyfactory(request): + """ """ + +class IDummy(Interface): + pass + +def dummy_view(request): + return 'OK' + +def dummy_extend(config, discrim): + config.action(discrim, None, config.package) + +def dummy_extend2(config, discrim): + config.action(discrim, None, config.registry) + +from functools import partial +dummy_partial = partial(dummy_extend, discrim='partial') + +class DummyCallable(object): + def __call__(self, config, discrim): + config.action(discrim, None, config.package) +dummy_callable = DummyCallable() + diff --git a/tests/test_config/files/assets/dummy.txt b/tests/test_config/files/assets/dummy.txt new file mode 100644 index 000000000..18832d351 --- /dev/null +++ b/tests/test_config/files/assets/dummy.txt @@ -0,0 +1 @@ +Hello. diff --git a/tests/test_config/files/minimal.txt b/tests/test_config/files/minimal.txt new file mode 100644 index 000000000..19fe66dfa --- /dev/null +++ b/tests/test_config/files/minimal.txt @@ -0,0 +1 @@ +
diff --git a/tests/test_config/path/scanerror/__init__.py b/tests/test_config/path/scanerror/__init__.py new file mode 100644 index 000000000..86770ad89 --- /dev/null +++ b/tests/test_config/path/scanerror/__init__.py @@ -0,0 +1,3 @@ +# scan error package + + diff --git a/tests/test_config/path/scanerror/will_raise_error.py b/tests/test_config/path/scanerror/will_raise_error.py new file mode 100644 index 000000000..9098ff1fe --- /dev/null +++ b/tests/test_config/path/scanerror/will_raise_error.py @@ -0,0 +1 @@ +import wont.exist diff --git a/tests/test_config/pkgs/__init__.py b/tests/test_config/pkgs/__init__.py new file mode 100644 index 000000000..ed88d78b4 --- /dev/null +++ b/tests/test_config/pkgs/__init__.py @@ -0,0 +1,2 @@ +# package + diff --git a/tests/test_config/pkgs/asset/__init__.py b/tests/test_config/pkgs/asset/__init__.py new file mode 100644 index 000000000..db5619fbc --- /dev/null +++ b/tests/test_config/pkgs/asset/__init__.py @@ -0,0 +1,3 @@ +# package + + diff --git a/tests/test_config/pkgs/asset/subpackage/__init__.py b/tests/test_config/pkgs/asset/subpackage/__init__.py new file mode 100644 index 000000000..d3173e636 --- /dev/null +++ b/tests/test_config/pkgs/asset/subpackage/__init__.py @@ -0,0 +1 @@ +#package diff --git a/tests/test_config/pkgs/asset/subpackage/templates/bar.pt b/tests/test_config/pkgs/asset/subpackage/templates/bar.pt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_config/pkgs/scanextrakw/__init__.py b/tests/test_config/pkgs/scanextrakw/__init__.py new file mode 100644 index 000000000..ce5e07238 --- /dev/null +++ b/tests/test_config/pkgs/scanextrakw/__init__.py @@ -0,0 +1,14 @@ +import venusian + +def foo(wrapped): + def bar(scanner, name, wrapped): + scanner.config.a = scanner.a + venusian.attach(wrapped, bar) + return wrapped + +@foo +def hello(): + pass + +hello() # appease coverage + diff --git a/tests/test_config/pkgs/scannable/__init__.py b/tests/test_config/pkgs/scannable/__init__.py new file mode 100644 index 000000000..562413a41 --- /dev/null +++ b/tests/test_config/pkgs/scannable/__init__.py @@ -0,0 +1,96 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(renderer=null_renderer) +def grokked(context, request): + return 'grokked' + +@view_config(request_method='POST', renderer=null_renderer) +def grokked_post(context, request): + return 'grokked_post' + +@view_config(name='stacked2', renderer=null_renderer) +@view_config(name='stacked1', renderer=null_renderer) +def stacked(context, request): + return 'stacked' + +class stacked_class(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'stacked_class' + +stacked_class = view_config(name='stacked_class1', + renderer=null_renderer)(stacked_class) +stacked_class = view_config(name='stacked_class2', + renderer=null_renderer)(stacked_class) + +class oldstyle_grokked_class: + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'oldstyle_grokked_class' + +oldstyle_grokked_class = view_config(name='oldstyle_grokked_class', + renderer=null_renderer)( + oldstyle_grokked_class) + +class grokked_class(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'grokked_class' + +grokked_class = view_config(name='grokked_class', + renderer=null_renderer)(grokked_class) + +class Foo(object): + def __call__(self, context, request): + return 'grokked_instance' + +grokked_instance = Foo() +grokked_instance = view_config(name='grokked_instance', + renderer=null_renderer)(grokked_instance) + +class Base(object): + @view_config(name='basemethod', renderer=null_renderer) + def basemethod(self): + """ """ + +class MethodViews(Base): + def __init__(self, context, request): + self.context = context + self.request = request + + @view_config(name='method1', renderer=null_renderer) + def method1(self): + return 'method1' + + @view_config(name='method2', renderer=null_renderer) + def method2(self): + return 'method2' + + @view_config(name='stacked_method2', renderer=null_renderer) + @view_config(name='stacked_method1', renderer=null_renderer) + def stacked(self): + return 'stacked_method' + +# ungrokkable + +A = 1 +B = {} + +def stuff(): + """ """ + +class Whatever(object): + pass + +class Whatever2: + pass diff --git a/tests/test_config/pkgs/scannable/another.py b/tests/test_config/pkgs/scannable/another.py new file mode 100644 index 000000000..529821b5c --- /dev/null +++ b/tests/test_config/pkgs/scannable/another.py @@ -0,0 +1,69 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(name='another', renderer=null_renderer) +def grokked(context, request): + return 'another_grokked' + +@view_config(request_method='POST', name='another', renderer=null_renderer) +def grokked_post(context, request): + return 'another_grokked_post' + +@view_config(name='another_stacked2', renderer=null_renderer) +@view_config(name='another_stacked1', renderer=null_renderer) +def stacked(context, request): + return 'another_stacked' + +class stacked_class(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'another_stacked_class' + +stacked_class = view_config(name='another_stacked_class1', + renderer=null_renderer)(stacked_class) +stacked_class = view_config(name='another_stacked_class2', + renderer=null_renderer)(stacked_class) + +class oldstyle_grokked_class: + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'another_oldstyle_grokked_class' + +oldstyle_grokked_class = view_config(name='another_oldstyle_grokked_class', + renderer=null_renderer)( + oldstyle_grokked_class) + +class grokked_class(object): + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'another_grokked_class' + +grokked_class = view_config(name='another_grokked_class', + renderer=null_renderer)(grokked_class) + +class Foo(object): + def __call__(self, context, request): + return 'another_grokked_instance' + +grokked_instance = Foo() +grokked_instance = view_config(name='another_grokked_instance', + renderer=null_renderer)( + grokked_instance) + +# ungrokkable + +A = 1 +B = {} + +def stuff(): + """ """ + diff --git a/tests/test_config/pkgs/scannable/pod/notinit.py b/tests/test_config/pkgs/scannable/pod/notinit.py new file mode 100644 index 000000000..91dcd161b --- /dev/null +++ b/tests/test_config/pkgs/scannable/pod/notinit.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(name='pod_notinit', renderer=null_renderer) +def subpackage_notinit(context, request): + return 'pod_notinit' diff --git a/tests/test_config/pkgs/scannable/subpackage/__init__.py b/tests/test_config/pkgs/scannable/subpackage/__init__.py new file mode 100644 index 000000000..9e0ddacbd --- /dev/null +++ b/tests/test_config/pkgs/scannable/subpackage/__init__.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(name='subpackage_init', renderer=null_renderer) +def subpackage_init(context, request): + return 'subpackage_init' diff --git a/tests/test_config/pkgs/scannable/subpackage/notinit.py b/tests/test_config/pkgs/scannable/subpackage/notinit.py new file mode 100644 index 000000000..f7edd0c68 --- /dev/null +++ b/tests/test_config/pkgs/scannable/subpackage/notinit.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(name='subpackage_notinit', renderer=null_renderer) +def subpackage_notinit(context, request): + return 'subpackage_notinit' diff --git a/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py b/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py new file mode 100644 index 000000000..fdda0dffe --- /dev/null +++ b/tests/test_config/pkgs/scannable/subpackage/subsubpackage/__init__.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config +from pyramid.renderers import null_renderer + +@view_config(name='subsubpackage_init', renderer=null_renderer) +def subpackage_init(context, request): + return 'subsubpackage_init' diff --git a/tests/test_config/pkgs/selfscan/__init__.py b/tests/test_config/pkgs/selfscan/__init__.py new file mode 100644 index 000000000..779ea3eed --- /dev/null +++ b/tests/test_config/pkgs/selfscan/__init__.py @@ -0,0 +1,11 @@ +from pyramid.view import view_config + +@view_config(renderer='string') +def abc(request): + return 'root' + +def main(): + from pyramid.config import Configurator + c = Configurator() + c.scan() + return c diff --git a/tests/test_config/pkgs/selfscan/another.py b/tests/test_config/pkgs/selfscan/another.py new file mode 100644 index 000000000..a30ad3297 --- /dev/null +++ b/tests/test_config/pkgs/selfscan/another.py @@ -0,0 +1,6 @@ +from pyramid.view import view_config + +@view_config(name='two', renderer='string') +def two(request): + return 'two' + diff --git a/tests/test_config/test_adapters.py b/tests/test_config/test_adapters.py new file mode 100644 index 000000000..ab5d6ef61 --- /dev/null +++ b/tests/test_config/test_adapters.py @@ -0,0 +1,365 @@ +import unittest + +from pyramid.compat import PY2 +from pyramid.tests.test_config import IDummy + +class AdaptersConfiguratorMixinTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_add_subscriber_defaults(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): + L.append(event) + config = self._makeOne(autocommit=True) + config.add_subscriber(subscriber) + event = Event() + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 2) + + def test_add_subscriber_iface_specified(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): + L.append(event) + config = self._makeOne(autocommit=True) + config.add_subscriber(subscriber, IEvent) + event = Event() + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 1) + + def test_add_subscriber_dottednames(self): + import pyramid.tests.test_config + from pyramid.interfaces import INewRequest + config = self._makeOne(autocommit=True) + config.add_subscriber('pyramid.tests.test_config', + 'pyramid.interfaces.INewRequest') + handlers = list(config.registry.registeredHandlers()) + self.assertEqual(len(handlers), 1) + handler = handlers[0] + self.assertEqual(handler.handler, pyramid.tests.test_config) + self.assertEqual(handler.required, (INewRequest,)) + + def test_add_object_event_subscriber(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + object = 'foo' + event = Event() + L = [] + def subscriber(object, event): + L.append(event) + config = self._makeOne(autocommit=True) + config.add_subscriber(subscriber, (Interface, IEvent)) + config.registry.subscribers((event.object, event), None) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.subscribers((event.object, IDummy), None) + self.assertEqual(len(L), 1) + + def test_add_subscriber_with_specific_type_and_predicates_True(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): + L.append(event) + config = self._makeOne(autocommit=True) + predlist = config.get_predlist('subscriber') + jam_predicate = predicate_maker('jam') + jim_predicate = predicate_maker('jim') + predlist.add('jam', jam_predicate) + predlist.add('jim', jim_predicate) + config.add_subscriber(subscriber, IEvent, jam=True, jim=True) + event = Event() + event.jam = True + event.jim = True + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 1) + + def test_add_subscriber_with_default_type_predicates_True(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): + L.append(event) + config = self._makeOne(autocommit=True) + predlist = config.get_predlist('subscriber') + jam_predicate = predicate_maker('jam') + jim_predicate = predicate_maker('jim') + predlist.add('jam', jam_predicate) + predlist.add('jim', jim_predicate) + config.add_subscriber(subscriber, jam=True, jim=True) + event = Event() + event.jam = True + event.jim = True + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 1) + + def test_add_subscriber_with_specific_type_and_predicates_False(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): L.append(event) + config = self._makeOne(autocommit=True) + predlist = config.get_predlist('subscriber') + jam_predicate = predicate_maker('jam') + jim_predicate = predicate_maker('jim') + predlist.add('jam', jam_predicate) + predlist.add('jim', jim_predicate) + config.add_subscriber(subscriber, IEvent, jam=True, jim=True) + event = Event() + event.jam = True + event.jim = False + config.registry.notify(event) + self.assertEqual(len(L), 0) + + def test_add_subscriber_with_default_type_predicates_False(self): + from zope.interface import implementer + from zope.interface import Interface + class IEvent(Interface): + pass + @implementer(IEvent) + class Event: + pass + L = [] + def subscriber(event): L.append(event) + config = self._makeOne(autocommit=True) + predlist = config.get_predlist('subscriber') + jam_predicate = predicate_maker('jam') + jim_predicate = predicate_maker('jim') + predlist.add('jam', jam_predicate) + predlist.add('jim', jim_predicate) + config.add_subscriber(subscriber, jam=True, jim=True) + event = Event() + event.jam = False + event.jim = True + config.registry.notify(event) + self.assertEqual(len(L), 0) + + def test_add_subscriber_predicate(self): + config = self._makeOne() + L = [] + def add_predicate(type, name, factory, weighs_less_than=None, + weighs_more_than=None): + self.assertEqual(type, 'subscriber') + self.assertEqual(name, 'name') + self.assertEqual(factory, 'factory') + self.assertEqual(weighs_more_than, 1) + self.assertEqual(weighs_less_than, 2) + L.append(1) + config._add_predicate = add_predicate + config.add_subscriber_predicate('name', 'factory', 1, 2) + self.assertTrue(L) + + def test_add_response_adapter(self): + from pyramid.interfaces import IResponse + config = self._makeOne(autocommit=True) + class Adapter(object): + def __init__(self, other): + self.other = other + config.add_response_adapter(Adapter, str) + result = config.registry.queryAdapter('foo', IResponse) + self.assertTrue(result.other, 'foo') + + def test_add_response_adapter_self(self): + from pyramid.interfaces import IResponse + config = self._makeOne(autocommit=True) + class Adapter(object): + pass + config.add_response_adapter(None, Adapter) + adapter = Adapter() + result = config.registry.queryAdapter(adapter, IResponse) + self.assertTrue(result is adapter) + + def test_add_response_adapter_dottednames(self): + from pyramid.interfaces import IResponse + config = self._makeOne(autocommit=True) + if PY2: + str_name = '__builtin__.str' + else: + str_name = 'builtins.str' + config.add_response_adapter('pyramid.response.Response', str_name) + result = config.registry.queryAdapter('foo', IResponse) + self.assertTrue(result.body, b'foo') + + def test_add_traverser_dotted_names(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser( + 'pyramid.tests.test_config.test_adapters.DummyTraverser', + 'pyramid.tests.test_config.test_adapters.DummyIface') + iface = DummyIface() + traverser = config.registry.getAdapter(iface, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + self.assertEqual(traverser.root, iface) + + def test_add_traverser_default_iface_means_Interface(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser(DummyTraverser) + traverser = config.registry.getAdapter(None, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + + def test_add_traverser_nondefault_iface(self): + from pyramid.interfaces import ITraverser + config = self._makeOne(autocommit=True) + config.add_traverser(DummyTraverser, DummyIface) + iface = DummyIface() + traverser = config.registry.getAdapter(iface, ITraverser) + self.assertEqual(traverser.__class__, DummyTraverser) + self.assertEqual(traverser.root, iface) + + def test_add_traverser_introspectables(self): + config = self._makeOne() + config.add_traverser(DummyTraverser, DummyIface) + actions = config.action_state.actions + self.assertEqual(len(actions), 1) + intrs = actions[0]['introspectables'] + self.assertEqual(len(intrs), 1) + intr = intrs[0] + self.assertEqual(intr.type_name, 'traverser') + self.assertEqual(intr.discriminator, ('traverser', DummyIface)) + self.assertEqual(intr.category_name, 'traversers') + self.assertEqual(intr.title, 'traverser for %r' % DummyIface) + self.assertEqual(intr['adapter'], DummyTraverser) + self.assertEqual(intr['iface'], DummyIface) + + def test_add_resource_url_adapter_dotted_names(self): + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter( + 'pyramid.tests.test_config.test_adapters.DummyResourceURL', + 'pyramid.tests.test_config.test_adapters.DummyIface', + ) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + + def test_add_resource_url_default_resource_iface_means_Interface(self): + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter(DummyResourceURL) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + + def test_add_resource_url_nodefault_resource_iface(self): + from zope.interface import Interface + from pyramid.interfaces import IResourceURL + config = self._makeOne(autocommit=True) + config.add_resource_url_adapter(DummyResourceURL, DummyIface) + iface = DummyIface() + adapter = config.registry.getMultiAdapter((iface, iface), + IResourceURL) + self.assertEqual(adapter.__class__, DummyResourceURL) + self.assertEqual(adapter.resource, iface) + self.assertEqual(adapter.request, iface) + bad_result = config.registry.queryMultiAdapter( + (Interface, Interface), + IResourceURL, + ) + self.assertEqual(bad_result, None) + + def test_add_resource_url_adapter_introspectables(self): + config = self._makeOne() + config.add_resource_url_adapter(DummyResourceURL, DummyIface) + actions = config.action_state.actions + self.assertEqual(len(actions), 1) + intrs = actions[0]['introspectables'] + self.assertEqual(len(intrs), 1) + intr = intrs[0] + self.assertEqual(intr.type_name, 'resource url adapter') + self.assertEqual(intr.discriminator, + ('resource url adapter', DummyIface)) + self.assertEqual(intr.category_name, 'resource url adapters') + self.assertEqual( + intr.title, + "resource url adapter for resource iface " + "" + ) + self.assertEqual(intr['adapter'], DummyResourceURL) + self.assertEqual(intr['resource_iface'], DummyIface) + +class Test_eventonly(unittest.TestCase): + def _callFUT(self, callee): + from pyramid.config.adapters import eventonly + return eventonly(callee) + + def test_defaults(self): + def acallable(event, a=1, b=2): pass + self.assertTrue(self._callFUT(acallable)) + +class DummyTraverser(object): + def __init__(self, root): + self.root = root + +class DummyIface(object): + pass + +class DummyResourceURL(object): + def __init__(self, resource, request): + self.resource = resource + self.request = request + +def predicate_maker(name): + class Predicate(object): + def __init__(self, val, config): + self.val = val + def phash(self): + return 'phash' + text = phash + def __call__(self, event): + return getattr(event, name, None) == self.val + return Predicate + diff --git a/tests/test_config/test_assets.py b/tests/test_config/test_assets.py new file mode 100644 index 000000000..842c73da6 --- /dev/null +++ b/tests/test_config/test_assets.py @@ -0,0 +1,945 @@ +import os.path +import unittest +from pyramid.testing import cleanUp + +# we use this folder +here = os.path.dirname(os.path.abspath(__file__)) + +class TestAssetsConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_override_asset_samename(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, 'a', 'a') + + def test_override_asset_directory_with_file(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo/', + 'pyramid.tests.test_config.pkgs.asset:foo.pt') + + def test_override_asset_file_with_directory(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo.pt', + 'pyramid.tests.test_config.pkgs.asset:templates/') + + def test_override_asset_file_with_package(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo.pt', + 'pyramid.tests.test_config.pkgs.asset') + + def test_override_asset_file_with_file(self): + from pyramid.config.assets import PackageAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset:templates/foo.pt', + 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/bar.pt', + _override=override) + from pyramid.tests.test_config.pkgs import asset + from pyramid.tests.test_config.pkgs.asset import subpackage + self.assertEqual(override.package, asset) + self.assertEqual(override.path, 'templates/foo.pt') + source = override.source + self.assertTrue(isinstance(source, PackageAssetSource)) + self.assertEqual(source.package, subpackage) + self.assertEqual(source.prefix, 'templates/bar.pt') + + resource_name = '' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_package_with_package(self): + from pyramid.config.assets import PackageAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset', + 'pyramid.tests.test_config.pkgs.asset.subpackage', + _override=override) + from pyramid.tests.test_config.pkgs import asset + from pyramid.tests.test_config.pkgs.asset import subpackage + self.assertEqual(override.package, asset) + self.assertEqual(override.path, '') + source = override.source + self.assertTrue(isinstance(source, PackageAssetSource)) + self.assertEqual(source.package, subpackage) + self.assertEqual(source.prefix, '') + + resource_name = 'templates/bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_directory_with_directory(self): + from pyramid.config.assets import PackageAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset:templates/', + 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/', + _override=override) + from pyramid.tests.test_config.pkgs import asset + from pyramid.tests.test_config.pkgs.asset import subpackage + self.assertEqual(override.package, asset) + self.assertEqual(override.path, 'templates/') + source = override.source + self.assertTrue(isinstance(source, PackageAssetSource)) + self.assertEqual(source.package, subpackage) + self.assertEqual(source.prefix, 'templates/') + + resource_name = 'bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_directory_with_package(self): + from pyramid.config.assets import PackageAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset:templates/', + 'pyramid.tests.test_config.pkgs.asset.subpackage', + _override=override) + from pyramid.tests.test_config.pkgs import asset + from pyramid.tests.test_config.pkgs.asset import subpackage + self.assertEqual(override.package, asset) + self.assertEqual(override.path, 'templates/') + source = override.source + self.assertTrue(isinstance(source, PackageAssetSource)) + self.assertEqual(source.package, subpackage) + self.assertEqual(source.prefix, '') + + resource_name = 'templates/bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_package_with_directory(self): + from pyramid.config.assets import PackageAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset', + 'pyramid.tests.test_config.pkgs.asset.subpackage:templates/', + _override=override) + from pyramid.tests.test_config.pkgs import asset + from pyramid.tests.test_config.pkgs.asset import subpackage + self.assertEqual(override.package, asset) + self.assertEqual(override.path, '') + source = override.source + self.assertTrue(isinstance(source, PackageAssetSource)) + self.assertEqual(source.package, subpackage) + self.assertEqual(source.prefix, 'templates/') + + resource_name = 'bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_directory_with_absfile(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo/', + os.path.join(here, 'pkgs', 'asset', 'foo.pt')) + + def test_override_asset_file_with_absdirectory(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo.pt', + abspath) + + def test_override_asset_file_with_missing_abspath(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.override_asset, + 'a:foo.pt', + os.path.join(here, 'wont_exist')) + + def test_override_asset_file_with_absfile(self): + from pyramid.config.assets import FSAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', + 'templates', 'bar.pt') + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset:templates/foo.pt', + abspath, + _override=override) + from pyramid.tests.test_config.pkgs import asset + self.assertEqual(override.package, asset) + self.assertEqual(override.path, 'templates/foo.pt') + source = override.source + self.assertTrue(isinstance(source, FSAssetSource)) + self.assertEqual(source.prefix, abspath) + + resource_name = '' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_directory_with_absdirectory(self): + from pyramid.config.assets import FSAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset:templates/', + abspath, + _override=override) + from pyramid.tests.test_config.pkgs import asset + self.assertEqual(override.package, asset) + self.assertEqual(override.path, 'templates/') + source = override.source + self.assertTrue(isinstance(source, FSAssetSource)) + self.assertEqual(source.prefix, abspath) + + resource_name = 'bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test_override_asset_package_with_absdirectory(self): + from pyramid.config.assets import FSAssetSource + config = self._makeOne(autocommit=True) + override = DummyUnderOverride() + abspath = os.path.join(here, 'pkgs', 'asset', 'subpackage', 'templates') + config.override_asset( + 'pyramid.tests.test_config.pkgs.asset', + abspath, + _override=override) + from pyramid.tests.test_config.pkgs import asset + self.assertEqual(override.package, asset) + self.assertEqual(override.path, '') + source = override.source + self.assertTrue(isinstance(source, FSAssetSource)) + self.assertEqual(source.prefix, abspath) + + resource_name = 'bar.pt' + expected = os.path.join(here, 'pkgs', 'asset', + 'subpackage', 'templates', 'bar.pt') + self.assertEqual(override.source.get_filename(resource_name), + expected) + + def test__override_not_yet_registered(self): + from pyramid.interfaces import IPackageOverrides + package = DummyPackage('package') + source = DummyAssetSource() + config = self._makeOne() + config._override(package, 'path', source, + PackageOverrides=DummyPackageOverrides) + overrides = config.registry.queryUtility(IPackageOverrides, + name='package') + self.assertEqual(overrides.inserted, [('path', source)]) + self.assertEqual(overrides.package, package) + + def test__override_already_registered(self): + from pyramid.interfaces import IPackageOverrides + package = DummyPackage('package') + source = DummyAssetSource() + overrides = DummyPackageOverrides(package) + config = self._makeOne() + config.registry.registerUtility(overrides, IPackageOverrides, + name='package') + config._override(package, 'path', source, + PackageOverrides=DummyPackageOverrides) + self.assertEqual(overrides.inserted, [('path', source)]) + self.assertEqual(overrides.package, package) + + +class TestOverrideProvider(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from pyramid.config.assets import OverrideProvider + return OverrideProvider + + def _makeOne(self, module): + klass = self._getTargetClass() + return klass(module) + + def _registerOverrides(self, overrides, name='pyramid.tests.test_config'): + from pyramid.interfaces import IPackageOverrides + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + reg.registerUtility(overrides, IPackageOverrides, name=name) + + def test_get_resource_filename_no_overrides(self): + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + expected = os.path.join(here, resource_name) + result = provider.get_resource_filename(None, resource_name) + self.assertEqual(result, expected) + + def test_get_resource_stream_no_overrides(self): + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + with provider.get_resource_stream(None, resource_name) as result: + _assertBody(result.read(), os.path.join(here, resource_name)) + + def test_get_resource_string_no_overrides(self): + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.get_resource_string(None, resource_name) + _assertBody(result, os.path.join(here, resource_name)) + + def test_has_resource_no_overrides(self): + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.has_resource(resource_name) + self.assertEqual(result, True) + + def test_resource_isdir_no_overrides(self): + file_resource_name = 'test_assets.py' + directory_resource_name = 'files' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_isdir(file_resource_name) + self.assertEqual(result, False) + result = provider.resource_isdir(directory_resource_name) + self.assertEqual(result, True) + + def test_resource_listdir_no_overrides(self): + resource_name = 'files' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_listdir(resource_name) + self.assertTrue(result) + + def test_get_resource_filename_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + expected = os.path.join(here, resource_name) + result = provider.get_resource_filename(None, resource_name) + self.assertEqual(result, expected) + + def test_get_resource_stream_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + with provider.get_resource_stream(None, resource_name) as result: + _assertBody(result.read(), os.path.join(here, resource_name)) + + def test_get_resource_string_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.get_resource_string(None, resource_name) + _assertBody(result, os.path.join(here, resource_name)) + + def test_has_resource_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'test_assets.py' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.has_resource(resource_name) + self.assertEqual(result, True) + + def test_resource_isdir_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'files' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_isdir(resource_name) + self.assertEqual(result, True) + + def test_resource_listdir_override_returns_None(self): + overrides = DummyOverrides(None) + self._registerOverrides(overrides) + resource_name = 'files' + import pyramid.tests.test_config + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_listdir(resource_name) + self.assertTrue(result) + + def test_get_resource_filename_override_returns_value(self): + overrides = DummyOverrides('value') + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + result = provider.get_resource_filename(None, 'test_assets.py') + self.assertEqual(result, 'value') + + def test_get_resource_stream_override_returns_value(self): + from io import BytesIO + overrides = DummyOverrides(BytesIO(b'value')) + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + with provider.get_resource_stream(None, 'test_assets.py') as stream: + self.assertEqual(stream.getvalue(), b'value') + + def test_get_resource_string_override_returns_value(self): + overrides = DummyOverrides('value') + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + result = provider.get_resource_string(None, 'test_assets.py') + self.assertEqual(result, 'value') + + def test_has_resource_override_returns_True(self): + overrides = DummyOverrides(True) + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + result = provider.has_resource('test_assets.py') + self.assertEqual(result, True) + + def test_resource_isdir_override_returns_False(self): + overrides = DummyOverrides(False) + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_isdir('files') + self.assertEqual(result, False) + + def test_resource_listdir_override_returns_values(self): + overrides = DummyOverrides(['a']) + import pyramid.tests.test_config + self._registerOverrides(overrides) + provider = self._makeOne(pyramid.tests.test_config) + result = provider.resource_listdir('files') + self.assertEqual(result, ['a']) + +class TestPackageOverrides(unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.assets import PackageOverrides + return PackageOverrides + + def _makeOne(self, package=None, pkg_resources=None): + if package is None: + package = DummyPackage('package') + klass = self._getTargetClass() + if pkg_resources is None: + pkg_resources = DummyPkgResources() + return klass(package, pkg_resources=pkg_resources) + + def test_class_conforms_to_IPackageOverrides(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IPackageOverrides + verifyClass(IPackageOverrides, self._getTargetClass()) + + def test_instance_conforms_to_IPackageOverrides(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IPackageOverrides + verifyObject(IPackageOverrides, self._makeOne()) + + def test_class_conforms_to_IPEP302Loader(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IPEP302Loader + verifyClass(IPEP302Loader, self._getTargetClass()) + + def test_instance_conforms_to_IPEP302Loader(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IPEP302Loader + verifyObject(IPEP302Loader, self._makeOne()) + + def test_ctor_package_already_has_loader_of_different_type(self): + package = DummyPackage('package') + loader = package.__loader__ = DummyLoader() + po = self._makeOne(package) + self.assertTrue(package.__loader__ is po) + self.assertTrue(po.real_loader is loader) + + def test_ctor_package_already_has_loader_of_same_type(self): + package = DummyPackage('package') + package.__loader__ = self._makeOne(package) + po = self._makeOne(package) + self.assertEqual(package.__loader__, po) + + def test_ctor_sets_loader(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertEqual(package.__loader__, po) + + def test_ctor_registers_loader_type(self): + from pyramid.config.assets import OverrideProvider + dummy_pkg_resources = DummyPkgResources() + package = DummyPackage('package') + po = self._makeOne(package, dummy_pkg_resources) + self.assertEqual(dummy_pkg_resources.registered, [(po.__class__, + OverrideProvider)]) + + def test_ctor_sets_local_state(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertEqual(po.overrides, []) + self.assertEqual(po.overridden_package_name, 'package') + + def test_insert_directory(self): + from pyramid.config.assets import DirectoryOverride + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = [None] + po.insert('foo/', DummyAssetSource()) + self.assertEqual(len(po.overrides), 2) + override = po.overrides[0] + self.assertEqual(override.__class__, DirectoryOverride) + + def test_insert_file(self): + from pyramid.config.assets import FileOverride + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = [None] + po.insert('foo.pt', DummyAssetSource()) + self.assertEqual(len(po.overrides), 2) + override = po.overrides[0] + self.assertEqual(override.__class__, FileOverride) + + def test_insert_emptystring(self): + # XXX is this a valid case for a directory? + from pyramid.config.assets import DirectoryOverride + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = [None] + source = DummyAssetSource() + po.insert('', source) + self.assertEqual(len(po.overrides), 2) + override = po.overrides[0] + self.assertEqual(override.__class__, DirectoryOverride) + + def test_filtered_sources(self): + overrides = [ DummyOverride(None), DummyOverride('foo')] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(list(po.filtered_sources('whatever')), ['foo']) + + def test_get_filename(self): + source = DummyAssetSource(filename='foo.pt') + overrides = [ DummyOverride(None), DummyOverride((source, ''))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + result = po.get_filename('whatever') + self.assertEqual(result, 'foo.pt') + self.assertEqual(source.resource_name, '') + + def test_get_filename_file_doesnt_exist(self): + source = DummyAssetSource(filename=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.get_filename('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + def test_get_stream(self): + source = DummyAssetSource(stream='a stream?') + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.get_stream('whatever'), 'a stream?') + self.assertEqual(source.resource_name, 'foo.pt') + + def test_get_stream_file_doesnt_exist(self): + source = DummyAssetSource(stream=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.get_stream('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + def test_get_string(self): + source = DummyAssetSource(string='a string') + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.get_string('whatever'), 'a string') + self.assertEqual(source.resource_name, 'foo.pt') + + def test_get_string_file_doesnt_exist(self): + source = DummyAssetSource(string=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.get_string('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + def test_has_resource(self): + source = DummyAssetSource(exists=True) + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.has_resource('whatever'), True) + self.assertEqual(source.resource_name, 'foo.pt') + + def test_has_resource_file_doesnt_exist(self): + source = DummyAssetSource(exists=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.has_resource('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + def test_isdir_false(self): + source = DummyAssetSource(isdir=False) + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.isdir('whatever'), False) + self.assertEqual(source.resource_name, 'foo.pt') + + def test_isdir_true(self): + source = DummyAssetSource(isdir=True) + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.isdir('whatever'), True) + self.assertEqual(source.resource_name, 'foo.pt') + + def test_isdir_doesnt_exist(self): + source = DummyAssetSource(isdir=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.isdir('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + def test_listdir(self): + source = DummyAssetSource(listdir=True) + overrides = [DummyOverride(None), DummyOverride((source, 'foo.pt'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.listdir('whatever'), True) + self.assertEqual(source.resource_name, 'foo.pt') + + def test_listdir_doesnt_exist(self): + source = DummyAssetSource(listdir=None) + overrides = [DummyOverride(None), DummyOverride((source, 'wont_exist'))] + package = DummyPackage('package') + po = self._makeOne(package) + po.overrides = overrides + self.assertEqual(po.listdir('whatever'), None) + self.assertEqual(source.resource_name, 'wont_exist') + + # PEP 302 __loader__ extensions: use the "real" __loader__, if present. + def test_get_data_pkg_has_no___loader__(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertRaises(NotImplementedError, po.get_data, 'whatever') + + def test_get_data_pkg_has___loader__(self): + package = DummyPackage('package') + loader = package.__loader__ = DummyLoader() + po = self._makeOne(package) + self.assertEqual(po.get_data('whatever'), b'DEADBEEF') + self.assertEqual(loader._got_data, 'whatever') + + def test_is_package_pkg_has_no___loader__(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertRaises(NotImplementedError, po.is_package, 'whatever') + + def test_is_package_pkg_has___loader__(self): + package = DummyPackage('package') + loader = package.__loader__ = DummyLoader() + po = self._makeOne(package) + self.assertTrue(po.is_package('whatever')) + self.assertEqual(loader._is_package, 'whatever') + + def test_get_code_pkg_has_no___loader__(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertRaises(NotImplementedError, po.get_code, 'whatever') + + def test_get_code_pkg_has___loader__(self): + package = DummyPackage('package') + loader = package.__loader__ = DummyLoader() + po = self._makeOne(package) + self.assertEqual(po.get_code('whatever'), b'DEADBEEF') + self.assertEqual(loader._got_code, 'whatever') + + def test_get_source_pkg_has_no___loader__(self): + package = DummyPackage('package') + po = self._makeOne(package) + self.assertRaises(NotImplementedError, po.get_source, 'whatever') + + def test_get_source_pkg_has___loader__(self): + package = DummyPackage('package') + loader = package.__loader__ = DummyLoader() + po = self._makeOne(package) + self.assertEqual(po.get_source('whatever'), 'def foo():\n pass') + self.assertEqual(loader._got_source, 'whatever') + +class AssetSourceIntegrationTests(object): + + def test_get_filename(self): + source = self._makeOne('') + self.assertEqual(source.get_filename('test_assets.py'), + os.path.join(here, 'test_assets.py')) + + def test_get_filename_with_prefix(self): + source = self._makeOne('test_assets.py') + self.assertEqual(source.get_filename(''), + os.path.join(here, 'test_assets.py')) + + def test_get_filename_file_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.get_filename('wont_exist'), None) + + def test_get_stream(self): + source = self._makeOne('') + with source.get_stream('test_assets.py') as stream: + _assertBody(stream.read(), os.path.join(here, 'test_assets.py')) + + def test_get_stream_with_prefix(self): + source = self._makeOne('test_assets.py') + with source.get_stream('') as stream: + _assertBody(stream.read(), os.path.join(here, 'test_assets.py')) + + def test_get_stream_file_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.get_stream('wont_exist'), None) + + def test_get_string(self): + source = self._makeOne('') + _assertBody(source.get_string('test_assets.py'), + os.path.join(here, 'test_assets.py')) + + def test_get_string_with_prefix(self): + source = self._makeOne('test_assets.py') + _assertBody(source.get_string(''), + os.path.join(here, 'test_assets.py')) + + def test_get_string_file_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.get_string('wont_exist'), None) + + def test_exists(self): + source = self._makeOne('') + self.assertEqual(source.exists('test_assets.py'), True) + + def test_exists_with_prefix(self): + source = self._makeOne('test_assets.py') + self.assertEqual(source.exists(''), True) + + def test_exists_file_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.exists('wont_exist'), None) + + def test_isdir_false(self): + source = self._makeOne('') + self.assertEqual(source.isdir('test_assets.py'), False) + + def test_isdir_true(self): + source = self._makeOne('') + self.assertEqual(source.isdir('files'), True) + + def test_isdir_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.isdir('wont_exist'), None) + + def test_listdir(self): + source = self._makeOne('') + self.assertTrue(source.listdir('files')) + + def test_listdir_doesnt_exist(self): + source = self._makeOne('') + self.assertEqual(source.listdir('wont_exist'), None) + +class TestPackageAssetSource(AssetSourceIntegrationTests, unittest.TestCase): + + def _getTargetClass(self): + from pyramid.config.assets import PackageAssetSource + return PackageAssetSource + + def _makeOne(self, prefix, package='pyramid.tests.test_config'): + klass = self._getTargetClass() + return klass(package, prefix) + +class TestFSAssetSource(AssetSourceIntegrationTests, unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.assets import FSAssetSource + return FSAssetSource + + def _makeOne(self, prefix, base_prefix=here): + klass = self._getTargetClass() + return klass(os.path.join(base_prefix, prefix)) + +class TestDirectoryOverride(unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.assets import DirectoryOverride + return DirectoryOverride + + def _makeOne(self, path, source): + klass = self._getTargetClass() + return klass(path, source) + + def test_it_match(self): + source = DummyAssetSource() + o = self._makeOne('foo/', source) + result = o('foo/something.pt') + self.assertEqual(result, (source, 'something.pt')) + + def test_it_no_match(self): + source = DummyAssetSource() + o = self._makeOne('foo/', source) + result = o('baz/notfound.pt') + self.assertEqual(result, None) + +class TestFileOverride(unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.assets import FileOverride + return FileOverride + + def _makeOne(self, path, source): + klass = self._getTargetClass() + return klass(path, source) + + def test_it_match(self): + source = DummyAssetSource() + o = self._makeOne('foo.pt', source) + result = o('foo.pt') + self.assertEqual(result, (source, '')) + + def test_it_no_match(self): + source = DummyAssetSource() + o = self._makeOne('foo.pt', source) + result = o('notfound.pt') + self.assertEqual(result, None) + +class DummyOverride: + def __init__(self, result): + self.result = result + + def __call__(self, resource_name): + return self.result + +class DummyOverrides: + def __init__(self, result): + self.result = result + + def get_filename(self, resource_name): + return self.result + + listdir = isdir = has_resource = get_stream = get_string = get_filename + +class DummyPackageOverrides: + def __init__(self, package): + self.package = package + self.inserted = [] + + def insert(self, path, source): + self.inserted.append((path, source)) + +class DummyPkgResources: + def __init__(self): + self.registered = [] + + def register_loader_type(self, typ, inst): + self.registered.append((typ, inst)) + +class DummyPackage: + def __init__(self, name): + self.__name__ = name + +class DummyAssetSource: + def __init__(self, **kw): + self.kw = kw + + def get_filename(self, resource_name): + self.resource_name = resource_name + return self.kw['filename'] + + def get_stream(self, resource_name): + self.resource_name = resource_name + return self.kw['stream'] + + def get_string(self, resource_name): + self.resource_name = resource_name + return self.kw['string'] + + def exists(self, resource_name): + self.resource_name = resource_name + return self.kw['exists'] + + def isdir(self, resource_name): + self.resource_name = resource_name + return self.kw['isdir'] + + def listdir(self, resource_name): + self.resource_name = resource_name + return self.kw['listdir'] + +class DummyLoader: + _got_data = _is_package = None + def get_data(self, path): + self._got_data = path + return b'DEADBEEF' + def is_package(self, fullname): + self._is_package = fullname + return True + def get_code(self, fullname): + self._got_code = fullname + return b'DEADBEEF' + def get_source(self, fullname): + self._got_source = fullname + return 'def foo():\n pass' + +class DummyUnderOverride: + def __call__(self, package, path, source, _info=''): + self.package = package + self.path = path + self.source = source + +def read_(src): + with open(src, 'rb') as f: + contents = f.read() + return contents + +def _assertBody(body, filename): + # strip both \n and \r for windows + body = body.replace(b'\r', b'') + body = body.replace(b'\n', b'') + data = read_(filename) + data = data.replace(b'\r', b'') + data = data.replace(b'\n', b'') + assert(body == data) diff --git a/tests/test_config/test_factories.py b/tests/test_config/test_factories.py new file mode 100644 index 000000000..7e6ea0476 --- /dev/null +++ b/tests/test_config/test_factories.py @@ -0,0 +1,163 @@ +import unittest + +from pyramid.tests.test_config import dummyfactory + +class TestFactoriesMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_set_request_factory(self): + from pyramid.interfaces import IRequestFactory + config = self._makeOne(autocommit=True) + factory = object() + config.set_request_factory(factory) + self.assertEqual(config.registry.getUtility(IRequestFactory), factory) + + def test_set_request_factory_dottedname(self): + from pyramid.interfaces import IRequestFactory + config = self._makeOne(autocommit=True) + config.set_request_factory( + 'pyramid.tests.test_config.dummyfactory') + self.assertEqual(config.registry.getUtility(IRequestFactory), + dummyfactory) + + def test_set_response_factory(self): + from pyramid.interfaces import IResponseFactory + config = self._makeOne(autocommit=True) + factory = lambda r: object() + config.set_response_factory(factory) + self.assertEqual(config.registry.getUtility(IResponseFactory), factory) + + def test_set_response_factory_dottedname(self): + from pyramid.interfaces import IResponseFactory + config = self._makeOne(autocommit=True) + config.set_response_factory( + 'pyramid.tests.test_config.dummyfactory') + self.assertEqual(config.registry.getUtility(IResponseFactory), + dummyfactory) + + def test_set_root_factory(self): + from pyramid.interfaces import IRootFactory + config = self._makeOne() + config.set_root_factory(dummyfactory) + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(IRootFactory), dummyfactory) + + def test_set_root_factory_as_None(self): + from pyramid.interfaces import IRootFactory + from pyramid.traversal import DefaultRootFactory + config = self._makeOne() + config.set_root_factory(None) + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(IRootFactory), + DefaultRootFactory) + + def test_set_root_factory_dottedname(self): + from pyramid.interfaces import IRootFactory + config = self._makeOne() + config.set_root_factory('pyramid.tests.test_config.dummyfactory') + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(IRootFactory), dummyfactory) + + def test_set_session_factory(self): + from pyramid.interfaces import ISessionFactory + config = self._makeOne() + config.set_session_factory(dummyfactory) + self.assertEqual(config.registry.queryUtility(ISessionFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(ISessionFactory), + dummyfactory) + + def test_set_session_factory_dottedname(self): + from pyramid.interfaces import ISessionFactory + config = self._makeOne() + config.set_session_factory('pyramid.tests.test_config.dummyfactory') + self.assertEqual(config.registry.queryUtility(ISessionFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(ISessionFactory), + dummyfactory) + + def test_add_request_method_with_callable(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + callable = lambda x: None + config.add_request_method(callable, name='foo') + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.methods) + + def test_add_request_method_with_unnamed_callable(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + def foo(self): pass + config.add_request_method(foo) + exts = config.registry.getUtility(IRequestExtensions) + self.assertTrue('foo' in exts.methods) + + def test_set_multiple_request_methods_conflict(self): + from pyramid.exceptions import ConfigurationConflictError + config = self._makeOne() + def foo(self): pass + def bar(self): pass + config.add_request_method(foo, name='bar') + config.add_request_method(bar, name='bar') + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_request_method_with_None_callable(self): + from pyramid.interfaces import IRequestExtensions + config = self._makeOne(autocommit=True) + config.add_request_method(name='foo') + exts = config.registry.queryUtility(IRequestExtensions) + self.assertTrue(exts is None) + + def test_add_request_method_with_None_callable_conflict(self): + from pyramid.exceptions import ConfigurationConflictError + config = self._makeOne() + def bar(self): pass + config.add_request_method(name='foo') + config.add_request_method(bar, name='foo') + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_request_method_with_None_callable_and_no_name(self): + config = self._makeOne(autocommit=True) + self.assertRaises(AttributeError, config.add_request_method) + + def test_add_request_method_with_text_type_name(self): + from pyramid.interfaces import IRequestExtensions + from pyramid.compat import text_, PY2 + from pyramid.exceptions import ConfigurationError + + config = self._makeOne(autocommit=True) + def boomshaka(r): pass + + def get_bad_name(): + if PY2: + name = text_(b'La Pe\xc3\xb1a', 'utf-8') + else: + name = b'La Pe\xc3\xb1a' + + config.add_request_method(boomshaka, name=name) + + self.assertRaises(ConfigurationError, get_bad_name) + + def test_set_execution_policy(self): + from pyramid.interfaces import IExecutionPolicy + config = self._makeOne(autocommit=True) + def dummy_policy(environ, router): pass + config.set_execution_policy(dummy_policy) + registry = config.registry + result = registry.queryUtility(IExecutionPolicy) + self.assertEqual(result, dummy_policy) + + def test_set_execution_policy_to_None(self): + from pyramid.interfaces import IExecutionPolicy + from pyramid.router import default_execution_policy + config = self._makeOne(autocommit=True) + config.set_execution_policy(None) + registry = config.registry + result = registry.queryUtility(IExecutionPolicy) + self.assertEqual(result, default_execution_policy) diff --git a/tests/test_config/test_i18n.py b/tests/test_config/test_i18n.py new file mode 100644 index 000000000..c10ab6bdb --- /dev/null +++ b/tests/test_config/test_i18n.py @@ -0,0 +1,132 @@ +import os +import unittest + +from pyramid.tests.test_config import dummyfactory + +here = os.path.dirname(__file__) +locale = os.path.abspath( + os.path.join(here, '..', 'pkgs', 'localeapp', 'locale')) +locale2 = os.path.abspath( + os.path.join(here, '..', 'pkgs', 'localeapp', 'locale2')) +locale3 = os.path.abspath( + os.path.join(here, '..', 'pkgs', 'localeapp', 'locale3')) + +class TestI18NConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_set_locale_negotiator(self): + from pyramid.interfaces import ILocaleNegotiator + config = self._makeOne(autocommit=True) + def negotiator(request): pass + config.set_locale_negotiator(negotiator) + self.assertEqual(config.registry.getUtility(ILocaleNegotiator), + negotiator) + + def test_set_locale_negotiator_dottedname(self): + from pyramid.interfaces import ILocaleNegotiator + config = self._makeOne(autocommit=True) + config.set_locale_negotiator( + 'pyramid.tests.test_config.dummyfactory') + self.assertEqual(config.registry.getUtility(ILocaleNegotiator), + dummyfactory) + + def test_add_translation_dirs_missing_dir(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + config.add_translation_dirs('/wont/exist/on/my/system') + self.assertRaises(ConfigurationError, config.commit) + + def test_add_translation_dirs_no_specs(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne() + config.add_translation_dirs() + self.assertEqual(config.registry.queryUtility(ITranslationDirectories), + None) + + def test_add_translation_dirs_asset_spec(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale]) + + def test_add_translation_dirs_asset_spec_existing_translation_dirs(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + directories = ['abc'] + config.registry.registerUtility(directories, ITranslationDirectories) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + result = config.registry.getUtility(ITranslationDirectories) + self.assertEqual(result, [locale, 'abc']) + + def test_add_translation_dirs_multiple_specs(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + 'pyramid.tests.pkgs.localeapp:locale2') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale, locale2]) + + def test_add_translation_dirs_multiple_specs_multiple_calls(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + 'pyramid.tests.pkgs.localeapp:locale2') + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale3, locale, locale2]) + + def test_add_translation_dirs_override_multiple_specs_multiple_calls(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + 'pyramid.tests.pkgs.localeapp:locale2') + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale3', + override=True) + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale, locale2, locale3]) + + def test_add_translation_dirs_invalid_kwargs(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + with self.assertRaises(TypeError): + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale', + foo=1) + + def test_add_translation_dirs_abspath(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs(locale) + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale]) + + def test_add_translation_dirs_uses_override_out_of_order(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne() + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + config.commit() + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale2]) + + def test_add_translation_dirs_doesnt_use_override_w_autocommit(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale]) + + def test_add_translation_dirs_uses_override_w_autocommit(self): + from pyramid.interfaces import ITranslationDirectories + config = self._makeOne(autocommit=True) + config.override_asset('pyramid.tests.pkgs.localeapp:locale/', + 'pyramid.tests.pkgs.localeapp:locale2/') + config.add_translation_dirs('pyramid.tests.pkgs.localeapp:locale') + self.assertEqual(config.registry.getUtility(ITranslationDirectories), + [locale2]) diff --git a/tests/test_config/test_init.py b/tests/test_config/test_init.py new file mode 100644 index 000000000..76a3d703d --- /dev/null +++ b/tests/test_config/test_init.py @@ -0,0 +1,2068 @@ +import unittest + +import os + +from pyramid.compat import im_func +from pyramid.testing import skip_on + +from pyramid.tests.test_config import dummy_tween_factory +from pyramid.tests.test_config import dummy_include +from pyramid.tests.test_config import dummy_extend +from pyramid.tests.test_config import dummy_extend2 +from pyramid.tests.test_config import IDummy +from pyramid.tests.test_config import DummyContext + +from pyramid.exceptions import ConfigurationExecutionError +from pyramid.exceptions import ConfigurationConflictError + +from pyramid.interfaces import IRequest + +class ConfiguratorTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def _getViewCallable(self, config, ctx_iface=None, request_iface=None, + name='', exception_view=False): + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + if exception_view: # pragma: no cover + classifier = IExceptionViewClassifier + else: + classifier = IViewClassifier + if ctx_iface is None: + ctx_iface = Interface + if request_iface is None: + request_iface = IRequest + return config.registry.adapters.lookup( + (classifier, request_iface, ctx_iface), IView, name=name, + default=None) + + def _registerEventListener(self, config, event_iface=None): + if event_iface is None: # pragma: no cover + from zope.interface import Interface + event_iface = Interface + L = [] + def subscriber(*event): + L.extend(event) + config.registry.registerHandler(subscriber, (event_iface,)) + return L + + def _makeRequest(self, config): + request = DummyRequest() + request.registry = config.registry + return request + + def test_ctor_no_registry(self): + import sys + from pyramid.interfaces import ISettings + from pyramid.config import Configurator + from pyramid.interfaces import IRendererFactory + config = Configurator() + this_pkg = sys.modules['pyramid.tests.test_config'] + self.assertTrue(config.registry.getUtility(ISettings)) + self.assertEqual(config.package, this_pkg) + config.commit() + self.assertTrue(config.registry.getUtility(IRendererFactory, 'json')) + self.assertTrue(config.registry.getUtility(IRendererFactory, 'string')) + + def test_begin(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + config.manager = manager + config.begin() + self.assertEqual(manager.pushed, + {'registry':config.registry, 'request':None}) + self.assertEqual(manager.popped, False) + + def test_begin_with_request(self): + from pyramid.config import Configurator + config = Configurator() + request = object() + manager = DummyThreadLocalManager() + config.manager = manager + config.begin(request=request) + self.assertEqual(manager.pushed, + {'registry':config.registry, 'request':request}) + self.assertEqual(manager.popped, False) + + def test_begin_overrides_request(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + # set it up for auto-propagation + pushed = {'registry': config.registry, 'request': None} + manager.pushed = pushed + config.manager = manager + config.begin(req) + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], req) + self.assertEqual(manager.pushed['registry'], config.registry) + + def test_begin_propagates_request_for_same_registry(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + pushed = {'registry': config.registry, 'request': req} + manager.pushed = pushed + config.manager = manager + config.begin() + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], req) + self.assertEqual(manager.pushed['registry'], config.registry) + + def test_begin_does_not_propagate_request_for_diff_registry(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + req = object() + pushed = {'registry': object(), 'request': req} + manager.pushed = pushed + config.manager = manager + config.begin() + self.assertTrue(manager.pushed is not pushed) + self.assertEqual(manager.pushed['request'], None) + self.assertEqual(manager.pushed['registry'], config.registry) + + def test_end(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + pushed = manager.pushed + config.manager = manager + config.end() + self.assertEqual(manager.pushed, pushed) + self.assertEqual(manager.popped, True) + + def test_context_manager(self): + from pyramid.config import Configurator + config = Configurator() + manager = DummyThreadLocalManager() + config.manager = manager + view = lambda r: None + with config as ctx: + self.assertTrue(config is ctx) + self.assertEqual(manager.pushed, + {'registry': config.registry, 'request': None}) + self.assertFalse(manager.popped) + config.add_view(view) + self.assertTrue(manager.popped) + config.add_view(view) # did not raise a conflict because of commit + config.commit() + + def test_ctor_with_package_registry(self): + import sys + from pyramid.config import Configurator + pkg = sys.modules['pyramid'] + config = Configurator(package=pkg) + self.assertEqual(config.package, pkg) + + def test_ctor_noreg_custom_settings(self): + from pyramid.interfaces import ISettings + settings = {'reload_templates':True, + 'mysetting':True} + config = self._makeOne(settings=settings) + settings = config.registry.getUtility(ISettings) + self.assertEqual(settings['reload_templates'], True) + self.assertEqual(settings['debug_authorization'], False) + self.assertEqual(settings['mysetting'], True) + + def test_ctor_noreg_debug_logger_None_default(self): + from pyramid.interfaces import IDebugLogger + config = self._makeOne() + logger = config.registry.getUtility(IDebugLogger) + self.assertEqual(logger.name, 'pyramid.tests.test_config') + + def test_ctor_noreg_debug_logger_non_None(self): + from pyramid.interfaces import IDebugLogger + logger = object() + config = self._makeOne(debug_logger=logger) + result = config.registry.getUtility(IDebugLogger) + self.assertEqual(logger, result) + + def test_ctor_authentication_policy(self): + from pyramid.interfaces import IAuthenticationPolicy + policy = object() + config = self._makeOne(authentication_policy=policy) + config.commit() + result = config.registry.getUtility(IAuthenticationPolicy) + self.assertEqual(policy, result) + + def test_ctor_authorization_policy_only(self): + policy = object() + config = self._makeOne(authorization_policy=policy) + self.assertRaises(ConfigurationExecutionError, config.commit) + + def test_ctor_no_root_factory(self): + from pyramid.interfaces import IRootFactory + config = self._makeOne() + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + + def test_ctor_with_root_factory(self): + from pyramid.interfaces import IRootFactory + factory = object() + config = self._makeOne(root_factory=factory) + self.assertEqual(config.registry.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(config.registry.queryUtility(IRootFactory), factory) + + def test_ctor_alternate_renderers(self): + from pyramid.interfaces import IRendererFactory + renderer = object() + config = self._makeOne(renderers=[('yeah', renderer)]) + config.commit() + self.assertEqual(config.registry.getUtility(IRendererFactory, 'yeah'), + renderer) + + def test_ctor_default_renderers(self): + from pyramid.interfaces import IRendererFactory + from pyramid.renderers import json_renderer_factory + config = self._makeOne() + self.assertEqual(config.registry.getUtility(IRendererFactory, 'json'), + json_renderer_factory) + + def test_ctor_default_permission(self): + from pyramid.interfaces import IDefaultPermission + config = self._makeOne(default_permission='view') + config.commit() + self.assertEqual(config.registry.getUtility(IDefaultPermission), 'view') + + def test_ctor_session_factory(self): + from pyramid.interfaces import ISessionFactory + factory = object() + config = self._makeOne(session_factory=factory) + self.assertEqual(config.registry.queryUtility(ISessionFactory), None) + config.commit() + self.assertEqual(config.registry.getUtility(ISessionFactory), factory) + + def test_ctor_default_view_mapper(self): + from pyramid.interfaces import IViewMapperFactory + mapper = object() + config = self._makeOne(default_view_mapper=mapper) + config.commit() + self.assertEqual(config.registry.getUtility(IViewMapperFactory), + mapper) + + def test_ctor_httpexception_view_default(self): + from pyramid.interfaces import IExceptionResponse + from pyramid.httpexceptions import default_exceptionresponse_view + from pyramid.interfaces import IRequest + config = self._makeOne() + view = self._getViewCallable(config, + ctx_iface=IExceptionResponse, + request_iface=IRequest) + self.assertTrue(view.__wraps__ is default_exceptionresponse_view) + + def test_ctor_exceptionresponse_view_None(self): + from pyramid.interfaces import IExceptionResponse + from pyramid.interfaces import IRequest + config = self._makeOne(exceptionresponse_view=None) + view = self._getViewCallable(config, + ctx_iface=IExceptionResponse, + request_iface=IRequest) + self.assertTrue(view is None) + + def test_ctor_exceptionresponse_view_custom(self): + from pyramid.interfaces import IExceptionResponse + from pyramid.interfaces import IRequest + def exceptionresponse_view(context, request): pass + config = self._makeOne(exceptionresponse_view=exceptionresponse_view) + view = self._getViewCallable(config, + ctx_iface=IExceptionResponse, + request_iface=IRequest) + self.assertTrue(view.__wraps__ is exceptionresponse_view) + + def test_ctor_with_introspection(self): + config = self._makeOne(introspection=False) + self.assertEqual(config.introspection, False) + + def test_ctor_default_webob_response_adapter_registered(self): + from webob import Response as WebobResponse + response = WebobResponse() + from pyramid.interfaces import IResponse + config = self._makeOne(autocommit=True) + result = config.registry.queryAdapter(response, IResponse) + self.assertEqual(result, response) + + def test_with_package_module(self): + from pyramid.tests.test_config import test_init + import pyramid.tests + config = self._makeOne() + newconfig = config.with_package(test_init) + self.assertEqual(newconfig.package, pyramid.tests.test_config) + + def test_with_package_package(self): + import pyramid.tests.test_config + config = self._makeOne() + newconfig = config.with_package(pyramid.tests.test_config) + self.assertEqual(newconfig.package, pyramid.tests.test_config) + + def test_with_package(self): + import pyramid.tests + config = self._makeOne() + config.basepath = 'basepath' + config.info = 'info' + config.includepath = ('spec',) + config.autocommit = True + config.route_prefix = 'prefix' + newconfig = config.with_package(pyramid.tests) + self.assertEqual(newconfig.package, pyramid.tests) + self.assertEqual(newconfig.registry, config.registry) + self.assertEqual(newconfig.autocommit, True) + self.assertEqual(newconfig.route_prefix, 'prefix') + self.assertEqual(newconfig.info, 'info') + self.assertEqual(newconfig.basepath, 'basepath') + self.assertEqual(newconfig.includepath, ('spec',)) + + def test_maybe_dotted_string_success(self): + import pyramid.tests.test_config + config = self._makeOne() + result = config.maybe_dotted('pyramid.tests.test_config') + self.assertEqual(result, pyramid.tests.test_config) + + def test_maybe_dotted_string_fail(self): + config = self._makeOne() + self.assertRaises(ImportError, config.maybe_dotted, 'cant.be.found') + + def test_maybe_dotted_notstring_success(self): + import pyramid.tests.test_config + config = self._makeOne() + result = config.maybe_dotted(pyramid.tests.test_config) + self.assertEqual(result, pyramid.tests.test_config) + + def test_absolute_asset_spec_already_absolute(self): + import pyramid.tests.test_config + config = self._makeOne(package=pyramid.tests.test_config) + result = config.absolute_asset_spec('already:absolute') + self.assertEqual(result, 'already:absolute') + + def test_absolute_asset_spec_notastring(self): + import pyramid.tests.test_config + config = self._makeOne(package=pyramid.tests.test_config) + result = config.absolute_asset_spec(None) + self.assertEqual(result, None) + + def test_absolute_asset_spec_relative(self): + import pyramid.tests.test_config + config = self._makeOne(package=pyramid.tests.test_config) + result = config.absolute_asset_spec('files') + self.assertEqual(result, 'pyramid.tests.test_config:files') + + def test__fix_registry_has_listeners(self): + reg = DummyRegistry() + config = self._makeOne(reg) + config._fix_registry() + self.assertEqual(reg.has_listeners, True) + + def test__fix_registry_notify(self): + reg = DummyRegistry() + config = self._makeOne(reg) + config._fix_registry() + self.assertEqual(reg.notify(1), None) + self.assertEqual(reg.events, (1,)) + + def test__fix_registry_queryAdapterOrSelf(self): + from zope.interface import Interface + from zope.interface import implementer + class IFoo(Interface): + pass + @implementer(IFoo) + class Foo(object): + pass + class Bar(object): + pass + adaptation = () + foo = Foo() + bar = Bar() + reg = DummyRegistry(adaptation) + config = self._makeOne(reg) + config._fix_registry() + self.assertTrue(reg.queryAdapterOrSelf(foo, IFoo) is foo) + self.assertTrue(reg.queryAdapterOrSelf(bar, IFoo) is adaptation) + + def test__fix_registry_registerSelfAdapter(self): + reg = DummyRegistry() + config = self._makeOne(reg) + config._fix_registry() + reg.registerSelfAdapter('required', 'provided', name='abc') + self.assertEqual(len(reg.adapters), 1) + args, kw = reg.adapters[0] + self.assertEqual(args[0]('abc'), 'abc') + self.assertEqual(kw, + {'info': '', 'provided': 'provided', + 'required': 'required', 'name': 'abc', 'event': True}) + + def test__fix_registry_adds__lock(self): + reg = DummyRegistry() + config = self._makeOne(reg) + config._fix_registry() + self.assertTrue(hasattr(reg, '_lock')) + + def test__fix_registry_adds_clear_view_lookup_cache(self): + reg = DummyRegistry() + config = self._makeOne(reg) + self.assertFalse(hasattr(reg, '_clear_view_lookup_cache')) + config._fix_registry() + self.assertFalse(hasattr(reg, '_view_lookup_cache')) + reg._clear_view_lookup_cache() + self.assertEqual(reg._view_lookup_cache, {}) + + def test_setup_registry_calls_fix_registry(self): + reg = DummyRegistry() + config = self._makeOne(reg) + config.add_view = lambda *arg, **kw: False + config._add_tween = lambda *arg, **kw: False + config.setup_registry() + self.assertEqual(reg.has_listeners, True) + + def test_setup_registry_registers_default_exceptionresponse_views(self): + from webob.exc import WSGIHTTPException + from pyramid.interfaces import IExceptionResponse + from pyramid.view import default_exceptionresponse_view + reg = DummyRegistry() + config = self._makeOne(reg) + views = [] + config.add_view = lambda *arg, **kw: views.append((arg, kw)) + config.add_default_view_predicates = lambda *arg: None + config._add_tween = lambda *arg, **kw: False + config.setup_registry() + self.assertEqual(views[0], ((default_exceptionresponse_view,), + {'context':IExceptionResponse})) + self.assertEqual(views[1], ((default_exceptionresponse_view,), + {'context':WSGIHTTPException})) + + def test_setup_registry_registers_default_view_predicates(self): + reg = DummyRegistry() + config = self._makeOne(reg) + vp_called = [] + config.add_view = lambda *arg, **kw: None + config.add_default_view_predicates = lambda *arg: vp_called.append(True) + config._add_tween = lambda *arg, **kw: False + config.setup_registry() + self.assertTrue(vp_called) + + def test_setup_registry_registers_default_webob_iresponse_adapter(self): + from webob import Response + from pyramid.interfaces import IResponse + config = self._makeOne() + config.setup_registry() + response = Response() + self.assertTrue( + config.registry.queryAdapter(response, IResponse) is response) + + def test_setup_registry_explicit_notfound_trumps_iexceptionresponse(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.httpexceptions import HTTPNotFound + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg, autocommit=True) + config.setup_registry() # registers IExceptionResponse default view + def myview(context, request): + return 'OK' + config.add_view(myview, context=HTTPNotFound, renderer=null_renderer) + request = self._makeRequest(config) + view = self._getViewCallable(config, + ctx_iface=implementedBy(HTTPNotFound), + request_iface=IRequest) + result = view(None, request) + self.assertEqual(result, 'OK') + + def test_setup_registry_custom_settings(self): + from pyramid.registry import Registry + from pyramid.interfaces import ISettings + settings = {'reload_templates':True, + 'mysetting':True} + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(settings=settings) + settings = reg.getUtility(ISettings) + self.assertEqual(settings['reload_templates'], True) + self.assertEqual(settings['debug_authorization'], False) + self.assertEqual(settings['mysetting'], True) + + def test_setup_registry_debug_logger_None_default(self): + from pyramid.registry import Registry + from pyramid.interfaces import IDebugLogger + reg = Registry() + config = self._makeOne(reg) + config.setup_registry() + logger = reg.getUtility(IDebugLogger) + self.assertEqual(logger.name, 'pyramid.tests.test_config') + + def test_setup_registry_debug_logger_non_None(self): + from pyramid.registry import Registry + from pyramid.interfaces import IDebugLogger + logger = object() + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(debug_logger=logger) + result = reg.getUtility(IDebugLogger) + self.assertEqual(logger, result) + + def test_setup_registry_debug_logger_name(self): + from pyramid.registry import Registry + from pyramid.interfaces import IDebugLogger + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(debug_logger='foo') + result = reg.getUtility(IDebugLogger) + self.assertEqual(result.name, 'foo') + + def test_setup_registry_authentication_policy(self): + from pyramid.registry import Registry + from pyramid.interfaces import IAuthenticationPolicy + policy = object() + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(authentication_policy=policy) + config.commit() + result = reg.getUtility(IAuthenticationPolicy) + self.assertEqual(policy, result) + + def test_setup_registry_authentication_policy_dottedname(self): + from pyramid.registry import Registry + from pyramid.interfaces import IAuthenticationPolicy + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(authentication_policy='pyramid.tests.test_config') + config.commit() + result = reg.getUtility(IAuthenticationPolicy) + import pyramid.tests.test_config + self.assertEqual(result, pyramid.tests.test_config) + + def test_setup_registry_authorization_policy_dottedname(self): + from pyramid.registry import Registry + from pyramid.interfaces import IAuthorizationPolicy + reg = Registry() + config = self._makeOne(reg) + dummy = object() + config.setup_registry(authentication_policy=dummy, + authorization_policy='pyramid.tests.test_config') + config.commit() + result = reg.getUtility(IAuthorizationPolicy) + import pyramid.tests.test_config + self.assertEqual(result, pyramid.tests.test_config) + + def test_setup_registry_authorization_policy_only(self): + from pyramid.registry import Registry + policy = object() + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(authorization_policy=policy) + config = self.assertRaises(ConfigurationExecutionError, config.commit) + + def test_setup_registry_no_default_root_factory(self): + from pyramid.registry import Registry + from pyramid.interfaces import IRootFactory + reg = Registry() + config = self._makeOne(reg) + config.setup_registry() + config.commit() + self.assertEqual(reg.queryUtility(IRootFactory), None) + + def test_setup_registry_dottedname_root_factory(self): + from pyramid.registry import Registry + from pyramid.interfaces import IRootFactory + reg = Registry() + config = self._makeOne(reg) + import pyramid.tests.test_config + config.setup_registry(root_factory='pyramid.tests.test_config') + self.assertEqual(reg.queryUtility(IRootFactory), None) + config.commit() + self.assertEqual(reg.getUtility(IRootFactory), + pyramid.tests.test_config) + + def test_setup_registry_locale_negotiator_dottedname(self): + from pyramid.registry import Registry + from pyramid.interfaces import ILocaleNegotiator + reg = Registry() + config = self._makeOne(reg) + import pyramid.tests.test_config + config.setup_registry(locale_negotiator='pyramid.tests.test_config') + self.assertEqual(reg.queryUtility(ILocaleNegotiator), None) + config.commit() + utility = reg.getUtility(ILocaleNegotiator) + self.assertEqual(utility, pyramid.tests.test_config) + + def test_setup_registry_locale_negotiator(self): + from pyramid.registry import Registry + from pyramid.interfaces import ILocaleNegotiator + reg = Registry() + config = self._makeOne(reg) + negotiator = object() + config.setup_registry(locale_negotiator=negotiator) + self.assertEqual(reg.queryUtility(ILocaleNegotiator), None) + config.commit() + utility = reg.getUtility(ILocaleNegotiator) + self.assertEqual(utility, negotiator) + + def test_setup_registry_request_factory(self): + from pyramid.registry import Registry + from pyramid.interfaces import IRequestFactory + reg = Registry() + config = self._makeOne(reg) + factory = object() + config.setup_registry(request_factory=factory) + self.assertEqual(reg.queryUtility(IRequestFactory), None) + config.commit() + utility = reg.getUtility(IRequestFactory) + self.assertEqual(utility, factory) + + def test_setup_registry_response_factory(self): + from pyramid.registry import Registry + from pyramid.interfaces import IResponseFactory + reg = Registry() + config = self._makeOne(reg) + factory = lambda r: object() + config.setup_registry(response_factory=factory) + self.assertEqual(reg.queryUtility(IResponseFactory), None) + config.commit() + utility = reg.getUtility(IResponseFactory) + self.assertEqual(utility, factory) + + def test_setup_registry_request_factory_dottedname(self): + from pyramid.registry import Registry + from pyramid.interfaces import IRequestFactory + reg = Registry() + config = self._makeOne(reg) + import pyramid.tests.test_config + config.setup_registry(request_factory='pyramid.tests.test_config') + self.assertEqual(reg.queryUtility(IRequestFactory), None) + config.commit() + utility = reg.getUtility(IRequestFactory) + self.assertEqual(utility, pyramid.tests.test_config) + + def test_setup_registry_alternate_renderers(self): + from pyramid.registry import Registry + from pyramid.interfaces import IRendererFactory + renderer = object() + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(renderers=[('yeah', renderer)]) + config.commit() + self.assertEqual(reg.getUtility(IRendererFactory, 'yeah'), + renderer) + + def test_setup_registry_default_permission(self): + from pyramid.registry import Registry + from pyramid.interfaces import IDefaultPermission + reg = Registry() + config = self._makeOne(reg) + config.setup_registry(default_permission='view') + config.commit() + self.assertEqual(reg.getUtility(IDefaultPermission), 'view') + + def test_setup_registry_includes(self): + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg) + settings = { + 'pyramid.includes': +"""pyramid.tests.test_config.dummy_include +pyramid.tests.test_config.dummy_include2""", + } + config.setup_registry(settings=settings) + self.assertTrue(reg.included) + self.assertTrue(reg.also_included) + + def test_setup_registry_includes_spaces(self): + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg) + settings = { + 'pyramid.includes': +"""pyramid.tests.test_config.dummy_include pyramid.tests.test_config.dummy_include2""", + } + config.setup_registry(settings=settings) + self.assertTrue(reg.included) + self.assertTrue(reg.also_included) + + def test_setup_registry_tweens(self): + from pyramid.interfaces import ITweens + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg) + settings = { + 'pyramid.tweens': + 'pyramid.tests.test_config.dummy_tween_factory' + } + config.setup_registry(settings=settings) + config.commit() + tweens = config.registry.getUtility(ITweens) + self.assertEqual( + tweens.explicit, + [('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory)]) + + def test_introspector_decorator(self): + inst = self._makeOne() + default = inst.introspector + self.assertTrue(hasattr(default, 'add')) + self.assertEqual(inst.introspector, inst.registry.introspector) + introspector = object() + inst.introspector = introspector + new = inst.introspector + self.assertTrue(new is introspector) + self.assertEqual(inst.introspector, inst.registry.introspector) + del inst.introspector + default = inst.introspector + self.assertFalse(default is new) + self.assertTrue(hasattr(default, 'add')) + + def test_make_wsgi_app(self): + import pyramid.config + from pyramid.router import Router + from pyramid.interfaces import IApplicationCreated + manager = DummyThreadLocalManager() + config = self._makeOne() + subscriber = self._registerEventListener(config, IApplicationCreated) + config.manager = manager + app = config.make_wsgi_app() + self.assertEqual(app.__class__, Router) + self.assertEqual(manager.pushed['registry'], config.registry) + self.assertEqual(manager.pushed['request'], None) + self.assertTrue(manager.popped) + self.assertEqual(pyramid.config.global_registries.last, app.registry) + self.assertEqual(len(subscriber), 1) + self.assertTrue(IApplicationCreated.providedBy(subscriber[0])) + pyramid.config.global_registries.empty() + + def test_include_with_dotted_name(self): + from pyramid.tests import test_config + config = self._makeOne() + config.include('pyramid.tests.test_config.dummy_include') + after = config.action_state + actions = after.actions + self.assertEqual(len(actions), 1) + action = after.actions[0] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_include_with_python_callable(self): + from pyramid.tests import test_config + config = self._makeOne() + config.include(dummy_include) + after = config.action_state + actions = after.actions + self.assertEqual(len(actions), 1) + action = actions[0] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_include_with_module_defaults_to_includeme(self): + from pyramid.tests import test_config + config = self._makeOne() + config.include('pyramid.tests.test_config') + after = config.action_state + actions = after.actions + self.assertEqual(len(actions), 1) + action = actions[0] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_include_with_module_defaults_to_includeme_missing(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.include, 'pyramid.tests') + + def test_include_with_route_prefix(self): + root_config = self._makeOne(autocommit=True) + def dummy_subapp(config): + self.assertEqual(config.route_prefix, 'root') + root_config.include(dummy_subapp, route_prefix='root') + + def test_include_with_nested_route_prefix(self): + root_config = self._makeOne(autocommit=True, route_prefix='root') + def dummy_subapp2(config): + self.assertEqual(config.route_prefix, 'root/nested') + def dummy_subapp3(config): + self.assertEqual(config.route_prefix, 'root/nested/nested2') + config.include(dummy_subapp4) + def dummy_subapp4(config): + self.assertEqual(config.route_prefix, 'root/nested/nested2') + def dummy_subapp(config): + self.assertEqual(config.route_prefix, 'root/nested') + config.include(dummy_subapp2) + config.include(dummy_subapp3, route_prefix='nested2') + + root_config.include(dummy_subapp, route_prefix='nested') + + def test_include_with_missing_source_file(self): + from pyramid.exceptions import ConfigurationError + import inspect + config = self._makeOne() + class DummyInspect(object): + def getmodule(self, c): + return inspect.getmodule(c) + def getsourcefile(self, c): + return None + config.inspect = DummyInspect() + try: + config.include('pyramid.tests.test_config.dummy_include') + except ConfigurationError as e: + self.assertEqual( + e.args[0], + "No source file for module 'pyramid.tests.test_config' (.py " + "file must exist, refusing to use orphan .pyc or .pyo file).") + else: # pragma: no cover + raise AssertionError + + def test_include_constant_root_package(self): + from pyramid import tests + from pyramid.tests import test_config + config = self._makeOne(root_package=tests) + results = {} + def include(config): + results['package'] = config.package + results['root_package'] = config.root_package + config.include(include) + self.assertEqual(results['root_package'], tests) + self.assertEqual(results['package'], test_config) + + def test_include_threadlocals_active(self): + from pyramid.tests import test_config + from pyramid.threadlocal import get_current_registry + stack = [] + def include(config): + stack.append(get_current_registry()) + config = self._makeOne() + config.include(include) + self.assertTrue(stack[0] is config.registry) + + def test_action_branching_kw_is_None(self): + config = self._makeOne(autocommit=True) + self.assertEqual(config.action('discrim'), None) + + def test_action_branching_kw_is_not_None(self): + config = self._makeOne(autocommit=True) + self.assertEqual(config.action('discrim', kw={'a':1}), None) + + def test_action_autocommit_with_introspectables(self): + from pyramid.config.util import ActionInfo + config = self._makeOne(autocommit=True) + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual(len(intr.registered), 1) + self.assertEqual(intr.registered[0][0], config.introspector) + self.assertEqual(intr.registered[0][1].__class__, ActionInfo) + + def test_action_autocommit_with_introspectables_introspection_off(self): + config = self._makeOne(autocommit=True) + config.introspection = False + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual(len(intr.registered), 0) + + def test_action_branching_nonautocommit_with_config_info(self): + config = self._makeOne(autocommit=False) + config.info = 'abc' + state = DummyActionState() + state.autocommit = False + config.action_state = state + config.action('discrim', kw={'a':1}) + self.assertEqual( + state.actions, + [((), + {'args': (), + 'callable': None, + 'discriminator': 'discrim', + 'includepath': (), + 'info': 'abc', + 'introspectables': (), + 'kw': {'a': 1}, + 'order': 0})]) + + def test_action_branching_nonautocommit_without_config_info(self): + config = self._makeOne(autocommit=False) + config.info = '' + config._ainfo = ['z'] + state = DummyActionState() + config.action_state = state + state.autocommit = False + config.action('discrim', kw={'a':1}) + self.assertEqual( + state.actions, + [((), + {'args': (), + 'callable': None, + 'discriminator': 'discrim', + 'includepath': (), + 'info': 'z', + 'introspectables': (), + 'kw': {'a': 1}, + 'order': 0})]) + + def test_action_branching_nonautocommit_with_introspectables(self): + config = self._makeOne(autocommit=False) + config.info = '' + config._ainfo = [] + state = DummyActionState() + config.action_state = state + state.autocommit = False + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual( + state.actions[0][1]['introspectables'], (intr,)) + + def test_action_nonautocommit_with_introspectables_introspection_off(self): + config = self._makeOne(autocommit=False) + config.info = '' + config._ainfo = [] + config.introspection = False + state = DummyActionState() + config.action_state = state + state.autocommit = False + intr = DummyIntrospectable() + config.action('discrim', introspectables=(intr,)) + self.assertEqual( + state.actions[0][1]['introspectables'], ()) + + def test_scan_integration(self): + from zope.interface import alsoProvides + from pyramid.interfaces import IRequest + from pyramid.view import render_view_to_response + import pyramid.tests.test_config.pkgs.scannable as package + config = self._makeOne(autocommit=True) + config.scan(package) + + ctx = DummyContext() + req = DummyRequest() + alsoProvides(req, IRequest) + req.registry = config.registry + + req.method = 'GET' + result = render_view_to_response(ctx, req, '') + self.assertEqual(result, 'grokked') + + req.method = 'POST' + result = render_view_to_response(ctx, req, '') + self.assertEqual(result, 'grokked_post') + + result= render_view_to_response(ctx, req, 'grokked_class') + self.assertEqual(result, 'grokked_class') + + result= render_view_to_response(ctx, req, 'grokked_instance') + self.assertEqual(result, 'grokked_instance') + + result= render_view_to_response(ctx, req, 'oldstyle_grokked_class') + self.assertEqual(result, 'oldstyle_grokked_class') + + req.method = 'GET' + result = render_view_to_response(ctx, req, 'another') + self.assertEqual(result, 'another_grokked') + + req.method = 'POST' + result = render_view_to_response(ctx, req, 'another') + self.assertEqual(result, 'another_grokked_post') + + result= render_view_to_response(ctx, req, 'another_grokked_class') + self.assertEqual(result, 'another_grokked_class') + + result= render_view_to_response(ctx, req, 'another_grokked_instance') + self.assertEqual(result, 'another_grokked_instance') + + result= render_view_to_response(ctx, req, + 'another_oldstyle_grokked_class') + self.assertEqual(result, 'another_oldstyle_grokked_class') + + result = render_view_to_response(ctx, req, 'stacked1') + self.assertEqual(result, 'stacked') + + result = render_view_to_response(ctx, req, 'stacked2') + self.assertEqual(result, 'stacked') + + result = render_view_to_response(ctx, req, 'another_stacked1') + self.assertEqual(result, 'another_stacked') + + result = render_view_to_response(ctx, req, 'another_stacked2') + self.assertEqual(result, 'another_stacked') + + result = render_view_to_response(ctx, req, 'stacked_class1') + self.assertEqual(result, 'stacked_class') + + result = render_view_to_response(ctx, req, 'stacked_class2') + self.assertEqual(result, 'stacked_class') + + result = render_view_to_response(ctx, req, 'another_stacked_class1') + self.assertEqual(result, 'another_stacked_class') + + result = render_view_to_response(ctx, req, 'another_stacked_class2') + self.assertEqual(result, 'another_stacked_class') + + # NB: on Jython, a class without an __init__ apparently accepts + # any number of arguments without raising a TypeError, so the next + # assertion may fail there. We don't support Jython at the moment, + # this is just a note to a future self. + + self.assertRaises(TypeError, + render_view_to_response, ctx, req, 'basemethod') + + result = render_view_to_response(ctx, req, 'method1') + self.assertEqual(result, 'method1') + + result = render_view_to_response(ctx, req, 'method2') + self.assertEqual(result, 'method2') + + result = render_view_to_response(ctx, req, 'stacked_method1') + self.assertEqual(result, 'stacked_method') + + result = render_view_to_response(ctx, req, 'stacked_method2') + self.assertEqual(result, 'stacked_method') + + result = render_view_to_response(ctx, req, 'subpackage_init') + self.assertEqual(result, 'subpackage_init') + + result = render_view_to_response(ctx, req, 'subpackage_notinit') + self.assertEqual(result, 'subpackage_notinit') + + result = render_view_to_response(ctx, req, 'subsubpackage_init') + self.assertEqual(result, 'subsubpackage_init') + + result = render_view_to_response(ctx, req, 'pod_notinit') + self.assertEqual(result, None) + + def test_scan_integration_with_ignore(self): + from zope.interface import alsoProvides + from pyramid.interfaces import IRequest + from pyramid.view import render_view_to_response + import pyramid.tests.test_config.pkgs.scannable as package + config = self._makeOne(autocommit=True) + config.scan(package, + ignore='pyramid.tests.test_config.pkgs.scannable.another') + + ctx = DummyContext() + req = DummyRequest() + alsoProvides(req, IRequest) + req.registry = config.registry + + req.method = 'GET' + result = render_view_to_response(ctx, req, '') + self.assertEqual(result, 'grokked') + + # ignored + v = render_view_to_response(ctx, req, 'another_stacked_class2') + self.assertEqual(v, None) + + def test_scan_integration_dottedname_package(self): + from zope.interface import alsoProvides + from pyramid.interfaces import IRequest + from pyramid.view import render_view_to_response + config = self._makeOne(autocommit=True) + config.scan('pyramid.tests.test_config.pkgs.scannable') + + ctx = DummyContext() + req = DummyRequest() + alsoProvides(req, IRequest) + req.registry = config.registry + + req.method = 'GET' + result = render_view_to_response(ctx, req, '') + self.assertEqual(result, 'grokked') + + def test_scan_integration_with_extra_kw(self): + config = self._makeOne(autocommit=True) + config.scan('pyramid.tests.test_config.pkgs.scanextrakw', a=1) + self.assertEqual(config.a, 1) + + def test_scan_integration_with_onerror(self): + # fancy sys.path manipulation here to appease "setup.py test" which + # fails miserably when it can't import something in the package + import sys + try: + here = os.path.dirname(__file__) + path = os.path.join(here, 'path') + sys.path.append(path) + config = self._makeOne(autocommit=True) + class FooException(Exception): + pass + def onerror(name): + raise FooException + self.assertRaises(FooException, config.scan, 'scanerror', + onerror=onerror) + finally: + sys.path.remove(path) + + def test_scan_integration_conflict(self): + from pyramid.tests.test_config.pkgs import selfscan + from pyramid.config import Configurator + c = Configurator() + c.scan(selfscan) + c.scan(selfscan) + try: + c.commit() + except ConfigurationConflictError as why: + def scanconflicts(e): + conflicts = e._conflicts.values() + for conflict in conflicts: + for confinst in conflict: + yield confinst.src + which = list(scanconflicts(why)) + self.assertEqual(len(which), 4) + self.assertTrue("@view_config(renderer='string')" in which) + self.assertTrue("@view_config(name='two', renderer='string')" in + which) + + @skip_on('py3') + def test_hook_zca(self): + from zope.component import getSiteManager + def foo(): + '123' + try: + config = self._makeOne() + config.hook_zca() + config.begin() + sm = getSiteManager() + self.assertEqual(sm, config.registry) + finally: + getSiteManager.reset() + + @skip_on('py3') + def test_unhook_zca(self): + from zope.component import getSiteManager + def foo(): + '123' + try: + getSiteManager.sethook(foo) + config = self._makeOne() + config.unhook_zca() + sm = getSiteManager() + self.assertNotEqual(sm, '123') + finally: + getSiteManager.reset() + + def test_commit_conflict_simple(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + config.add_view(view1) + config.add_view(view2) + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_commit_conflict_resolved_with_include(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + def includeme(config): + config.add_view(view2) + config.add_view(view1) + config.include(includeme) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view1') + + def test_commit_conflict_with_two_includes(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + def includeme1(config): + config.add_view(view1) + def includeme2(config): + config.add_view(view2) + config.include(includeme1) + config.include(includeme2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'includeme1') + self.assertEqual(c2, 'includeme2') + else: #pragma: no cover + raise AssertionError + + def test_commit_conflict_resolved_with_two_includes_and_local(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + def view3(request): pass + def includeme1(config): + config.add_view(view1) + def includeme2(config): + config.add_view(view2) + config.include(includeme1) + config.include(includeme2) + config.add_view(view3) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view3') + + def test_autocommit_no_conflicts(self): + from pyramid.renderers import null_renderer + config = self._makeOne(autocommit=True) + def view1(request): pass + def view2(request): pass + def view3(request): pass + config.add_view(view1, renderer=null_renderer) + config.add_view(view2, renderer=null_renderer) + config.add_view(view3, renderer=null_renderer) + config.commit() + registeredview = self._getViewCallable(config) + self.assertEqual(registeredview.__name__, 'view3') + + def test_conflict_set_notfound_view(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + config.set_notfound_view(view1) + config.set_notfound_view(view2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'test_conflict_set_notfound_view') + self.assertEqual(c2, 'test_conflict_set_notfound_view') + else: # pragma: no cover + raise AssertionError + + def test_conflict_set_forbidden_view(self): + config = self._makeOne() + def view1(request): pass + def view2(request): pass + config.set_forbidden_view(view1) + config.set_forbidden_view(view2) + try: + config.commit() + except ConfigurationConflictError as why: + c1, c2 = _conflictFunctions(why) + self.assertEqual(c1, 'test_conflict_set_forbidden_view') + self.assertEqual(c2, 'test_conflict_set_forbidden_view') + else: # pragma: no cover + raise AssertionError + + def test___getattr__missing_when_directives_exist(self): + config = self._makeOne() + directives = {} + config.registry._directives = directives + self.assertRaises(AttributeError, config.__getattr__, 'wontexist') + + def test___getattr__missing_when_directives_dont_exist(self): + config = self._makeOne() + self.assertRaises(AttributeError, config.__getattr__, 'wontexist') + + def test___getattr__matches(self): + config = self._makeOne() + def foo(config): pass + directives = {'foo':(foo, True)} + config.registry._directives = directives + foo_meth = config.foo + self.assertTrue(getattr(foo_meth, im_func).__docobj__ is foo) + + def test___getattr__matches_no_action_wrap(self): + config = self._makeOne() + def foo(config): pass + directives = {'foo':(foo, False)} + config.registry._directives = directives + foo_meth = config.foo + self.assertTrue(getattr(foo_meth, im_func) is foo) + +class TestConfigurator_add_directive(unittest.TestCase): + + def setUp(self): + from pyramid.config import Configurator + self.config = Configurator() + + def test_extend_with_dotted_name(self): + from pyramid.tests import test_config + config = self.config + config.add_directive( + 'dummy_extend', 'pyramid.tests.test_config.dummy_extend') + self.assertTrue(hasattr(config, 'dummy_extend')) + config.dummy_extend('discrim') + after = config.action_state + action = after.actions[-1] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_add_directive_with_partial(self): + from pyramid.tests import test_config + config = self.config + config.add_directive( + 'dummy_partial', 'pyramid.tests.test_config.dummy_partial') + self.assertTrue(hasattr(config, 'dummy_partial')) + config.dummy_partial() + after = config.action_state + action = after.actions[-1] + self.assertEqual(action['discriminator'], 'partial') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_add_directive_with_custom_callable(self): + from pyramid.tests import test_config + config = self.config + config.add_directive( + 'dummy_callable', 'pyramid.tests.test_config.dummy_callable') + self.assertTrue(hasattr(config, 'dummy_callable')) + config.dummy_callable('discrim') + after = config.action_state + action = after.actions[-1] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_extend_with_python_callable(self): + from pyramid.tests import test_config + config = self.config + config.add_directive( + 'dummy_extend', dummy_extend) + self.assertTrue(hasattr(config, 'dummy_extend')) + config.dummy_extend('discrim') + after = config.action_state + action = after.actions[-1] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], test_config) + + def test_extend_same_name_doesnt_conflict(self): + config = self.config + config.add_directive( + 'dummy_extend', dummy_extend) + config.add_directive( + 'dummy_extend', dummy_extend2) + self.assertTrue(hasattr(config, 'dummy_extend')) + config.dummy_extend('discrim') + after = config.action_state + action = after.actions[-1] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], config.registry) + + def test_extend_action_method_successful(self): + config = self.config + config.add_directive( + 'dummy_extend', dummy_extend) + config.dummy_extend('discrim') + config.dummy_extend('discrim') + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_directive_persists_across_configurator_creations(self): + config = self.config + config.add_directive('dummy_extend', dummy_extend) + config2 = config.with_package('pyramid.tests') + config2.dummy_extend('discrim') + after = config2.action_state + actions = after.actions + self.assertEqual(len(actions), 1) + action = actions[0] + self.assertEqual(action['discriminator'], 'discrim') + self.assertEqual(action['callable'], None) + self.assertEqual(action['args'], config2.package) + +class TestConfigurator__add_predicate(unittest.TestCase): + def _makeOne(self): + from pyramid.config import Configurator + return Configurator() + + def test_factory_as_object(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), kw=None, + order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate('route', 'testing', DummyPredicate) + + def test_factory_as_dotted_name(self): + config = self._makeOne() + + def _fakeAction(discriminator, callable=None, args=(), + kw=None, order=0, introspectables=(), **extra): + self.assertEqual(len(introspectables), 1) + self.assertEqual(introspectables[0]['name'], 'testing') + self.assertEqual(introspectables[0]['factory'], DummyPredicate) + + config.action = _fakeAction + config._add_predicate( + 'route', + 'testing', + 'pyramid.tests.test_config.test_init.DummyPredicate' + ) + +class TestActionState(unittest.TestCase): + def _makeOne(self): + from pyramid.config import ActionState + return ActionState() + + def test_it(self): + c = self._makeOne() + self.assertEqual(c.actions, []) + + def test_action_simple(self): + from pyramid.tests.test_config import dummyfactory as f + c = self._makeOne() + c.actions = [] + c.action(1, f, (1,), {'x':1}) + self.assertEqual( + c.actions, + [{'args': (1,), + 'callable': f, + 'discriminator': 1, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {'x': 1}, + 'order': 0}]) + c.action(None) + self.assertEqual( + c.actions, + [{'args': (1,), + 'callable': f, + 'discriminator': 1, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {'x': 1}, + 'order': 0}, + + {'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {}, + 'order': 0},]) + + def test_action_with_includepath(self): + c = self._makeOne() + c.actions = [] + c.action(None, includepath=('abc',)) + self.assertEqual( + c.actions, + [{'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': ('abc',), + 'info': None, + 'introspectables': (), + 'kw': {}, + 'order': 0}]) + + def test_action_with_info(self): + c = self._makeOne() + c.action(None, info='abc') + self.assertEqual( + c.actions, + [{'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': 'abc', + 'introspectables': (), + 'kw': {}, + 'order': 0}]) + + def test_action_with_includepath_and_info(self): + c = self._makeOne() + c.action(None, includepath=('spec',), info='bleh') + self.assertEqual( + c.actions, + [{'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': ('spec',), + 'info': 'bleh', + 'introspectables': (), + 'kw': {}, + 'order': 0}]) + + def test_action_with_order(self): + c = self._makeOne() + c.actions = [] + c.action(None, order=99999) + self.assertEqual( + c.actions, + [{'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': None, + 'introspectables': (), + 'kw': {}, + 'order': 99999}]) + + def test_action_with_introspectables(self): + c = self._makeOne() + c.actions = [] + intr = DummyIntrospectable() + c.action(None, introspectables=(intr,)) + self.assertEqual( + c.actions, + [{'args': (), + 'callable': None, + 'discriminator': None, + 'includepath': (), + 'info': None, + 'introspectables': (intr,), + 'kw': {}, + 'order': 0}]) + + def test_processSpec(self): + c = self._makeOne() + self.assertTrue(c.processSpec('spec')) + self.assertFalse(c.processSpec('spec')) + + def test_execute_actions_tuples(self): + output = [] + def f(*a, **k): + output.append((a, k)) + c = self._makeOne() + c.actions = [ + (1, f, (1,)), + (1, f, (11,), {}, ('x', )), + (2, f, (2,)), + (None, None), + ] + c.execute_actions() + self.assertEqual(output, [((1,), {}), ((2,), {})]) + + def test_execute_actions_dicts(self): + output = [] + def f(*a, **k): + output.append((a, k)) + c = self._makeOne() + c.actions = [ + {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{}, + 'order':0, 'includepath':(), 'info':None, + 'introspectables':()}, + {'discriminator':1, 'callable':f, 'args':(11,), 'kw':{}, + 'includepath':('x',), 'order': 0, 'info':None, + 'introspectables':()}, + {'discriminator':2, 'callable':f, 'args':(2,), 'kw':{}, + 'order':0, 'includepath':(), 'info':None, + 'introspectables':()}, + {'discriminator':None, 'callable':None, 'args':(), 'kw':{}, + 'order':0, 'includepath':(), 'info':None, + 'introspectables':()}, + ] + c.execute_actions() + self.assertEqual(output, [((1,), {}), ((2,), {})]) + + def test_execute_actions_with_introspectables(self): + output = [] + def f(*a, **k): + output.append((a, k)) + c = self._makeOne() + intr = DummyIntrospectable() + c.actions = [ + {'discriminator':1, 'callable':f, 'args':(1,), 'kw':{}, + 'order':0, 'includepath':(), 'info':None, + 'introspectables':(intr,)}, + ] + introspector = object() + c.execute_actions(introspector=introspector) + self.assertEqual(output, [((1,), {})]) + self.assertEqual(intr.registered, [(introspector, None)]) + + def test_execute_actions_with_introspectable_no_callable(self): + c = self._makeOne() + intr = DummyIntrospectable() + c.actions = [ + {'discriminator':1, 'callable':None, 'args':(1,), 'kw':{}, + 'order':0, 'includepath':(), 'info':None, + 'introspectables':(intr,)}, + ] + introspector = object() + c.execute_actions(introspector=introspector) + self.assertEqual(intr.registered, [(introspector, None)]) + + def test_execute_actions_error(self): + output = [] + def f(*a, **k): + output.append(('f', a, k)) + def bad(): + raise NotImplementedError + c = self._makeOne() + c.actions = [ + (1, f, (1,)), + (1, f, (11,), {}, ('x', )), + (2, f, (2,)), + (3, bad, (), {}, (), 'oops') + ] + self.assertRaises(ConfigurationExecutionError, c.execute_actions) + self.assertEqual(output, [('f', (1,), {}), ('f', (2,), {})]) + + def test_reentrant_action(self): + output = [] + c = self._makeOne() + def f(*a, **k): + output.append(('f', a, k)) + c.actions.append((3, g, (8,), {})) + def g(*a, **k): + output.append(('g', a, k)) + c.actions = [ + (1, f, (1,)), + ] + c.execute_actions() + self.assertEqual(output, [('f', (1,), {}), ('g', (8,), {})]) + + def test_reentrant_action_with_deferred_discriminator(self): + # see https://github.com/Pylons/pyramid/issues/2697 + from pyramid.registry import Deferred + output = [] + c = self._makeOne() + def f(*a, **k): + output.append(('f', a, k)) + c.actions.append((4, g, (4,), {}, (), None, 2)) + def g(*a, **k): + output.append(('g', a, k)) + def h(*a, **k): + output.append(('h', a, k)) + def discrim(): + self.assertEqual(output, [('f', (1,), {}), ('g', (2,), {})]) + return 3 + d = Deferred(discrim) + c.actions = [ + (d, h, (3,), {}, (), None, 1), # order 1 + (1, f, (1,)), # order 0 + (2, g, (2,)), # order 0 + ] + c.execute_actions() + self.assertEqual(output, [ + ('f', (1,), {}), ('g', (2,), {}), ('h', (3,), {}), ('g', (4,), {})]) + + def test_reentrant_action_error(self): + from pyramid.exceptions import ConfigurationError + c = self._makeOne() + def f(*a, **k): + c.actions.append((3, g, (8,), {}, (), None, -1)) + def g(*a, **k): pass + c.actions = [ + (1, f, (1,)), + ] + self.assertRaises(ConfigurationError, c.execute_actions) + + def test_reentrant_action_without_clear(self): + c = self._makeOne() + def f(*a, **k): + c.actions.append((3, g, (8,))) + def g(*a, **k): pass + c.actions = [ + (1, f, (1,)), + ] + c.execute_actions(clear=False) + self.assertEqual(c.actions, [ + (1, f, (1,)), + (3, g, (8,)), + ]) + + def test_executing_conflicting_action_across_orders(self): + from pyramid.exceptions import ConfigurationConflictError + c = self._makeOne() + def f(*a, **k): pass + def g(*a, **k): pass + c.actions = [ + (1, f, (1,), {}, (), None, -1), + (1, g, (2,)), + ] + self.assertRaises(ConfigurationConflictError, c.execute_actions) + + def test_executing_conflicting_action_across_reentrant_orders(self): + from pyramid.exceptions import ConfigurationConflictError + c = self._makeOne() + def f(*a, **k): + c.actions.append((1, g, (8,))) + def g(*a, **k): pass + c.actions = [ + (1, f, (1,), {}, (), None, -1), + ] + self.assertRaises(ConfigurationConflictError, c.execute_actions) + +class Test_reentrant_action_functional(unittest.TestCase): + def _makeConfigurator(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_functional(self): + def add_auto_route(config, name, view): + def register(): + config.add_view(route_name=name, view=view) + config.add_route(name, '/' + name) + config.action( + ('auto route', name), register, order=-30 + ) + config = self._makeConfigurator() + config.add_directive('add_auto_route', add_auto_route) + def my_view(request): return request.response + config.add_auto_route('foo', my_view) + config.commit() + from pyramid.interfaces import IRoutesMapper + mapper = config.registry.getUtility(IRoutesMapper) + routes = mapper.get_routes() + route = routes[0] + self.assertEqual(len(routes), 1) + self.assertEqual(route.name, 'foo') + self.assertEqual(route.path, '/foo') + + def test_deferred_discriminator(self): + # see https://github.com/Pylons/pyramid/issues/2697 + from pyramid.config import PHASE0_CONFIG + config = self._makeConfigurator() + def deriver(view, info): return view + deriver.options = ('foo',) + config.add_view_deriver(deriver, 'foo_view') + # add_view uses a deferred discriminator and will fail if executed + # prior to add_view_deriver executing its action + config.add_view(lambda r: r.response, name='', foo=1) + def dummy_action(): + # trigger a re-entrant action + config.action(None, lambda: None) + config.action(None, dummy_action, order=PHASE0_CONFIG) + config.commit() + +class Test_resolveConflicts(unittest.TestCase): + def _callFUT(self, actions): + from pyramid.config import resolveConflicts + return resolveConflicts(actions) + + def test_it_success_tuples(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (None, f), + (1, f, (1,), {}, (), 'first'), + (1, f, (2,), {}, ('x',), 'second'), + (1, f, (3,), {}, ('y',), 'third'), + (4, f, (4,), {}, ('y',), 'should be last', 99999), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ]) + result = list(result) + self.assertEqual( + result, + [{'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0}, + + {'info': 'first', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 0}, + + {'info': None, + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': ('y',), + 'order': 0}, + + {'info': None, + 'args': (5,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': ('y',), + 'order': 0}, + + {'info': 'should be last', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': ('y',), + 'order': 99999} + ] + ) + + def test_it_success_dicts(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (None, f), + (1, f, (1,), {}, (), 'first'), + (1, f, (2,), {}, ('x',), 'second'), + (1, f, (3,), {}, ('y',), 'third'), + (4, f, (4,), {}, ('y',), 'should be last', 99999), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ]) + result = list(result) + self.assertEqual( + result, + [{'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0}, + + {'info': 'first', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 0}, + + {'info': None, + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': ('y',), + 'order': 0}, + + {'info': None, + 'args': (5,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': ('y',), + 'order': 0}, + + {'info': 'should be last', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': ('y',), + 'order': 99999} + ] + ) + + def test_it_conflict(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (None, f), + (1, f, (2,), {}, ('x',), 'eek'), # will conflict + (1, f, (3,), {}, ('y',), 'ack'), # will conflict + (4, f, (4,), {}, ('y',)), + (3, f, (3,), {}, ('y',)), + (None, f, (5,), {}, ('y',)), + ]) + self.assertRaises(ConfigurationConflictError, list, result) + + def test_it_with_actions_grouped_by_order(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (None, f), # X + (1, f, (1,), {}, (), 'third', 10), # X + (1, f, (2,), {}, ('x',), 'fourth', 10), + (1, f, (3,), {}, ('y',), 'fifth', 10), + (2, f, (1,), {}, (), 'sixth', 10), # X + (3, f, (1,), {}, (), 'seventh', 10), # X + (5, f, (4,), {}, ('y',), 'eighth', 99999), # X + (4, f, (3,), {}, (), 'first', 5), # X + (4, f, (5,), {}, ('y',), 'second', 5), + ]) + result = list(result) + self.assertEqual(len(result), 6) + # resolved actions should be grouped by (order, i) + self.assertEqual( + result, + [{'info': None, + 'args': (), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': None, + 'includepath': (), + 'order': 0}, + + {'info': 'first', + 'args': (3,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 4, + 'includepath': (), + 'order': 5}, + + {'info': 'third', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': (), + 'order': 10}, + + {'info': 'sixth', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 2, + 'includepath': (), + 'order': 10}, + + {'info': 'seventh', + 'args': (1,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 3, + 'includepath': (), + 'order': 10}, + + {'info': 'eighth', + 'args': (4,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 5, + 'includepath': ('y',), + 'order': 99999} + ] + ) + + def test_override_success_across_orders(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (1, f, (2,), {}, ('x',), 'eek', 0), + (1, f, (3,), {}, ('x', 'y'), 'ack', 10), + ]) + result = list(result) + self.assertEqual(result, [ + {'info': 'eek', + 'args': (2,), + 'callable': f, + 'introspectables': (), + 'kw': {}, + 'discriminator': 1, + 'includepath': ('x',), + 'order': 0}, + ]) + + def test_conflicts_across_orders(self): + from pyramid.tests.test_config import dummyfactory as f + result = self._callFUT([ + (1, f, (2,), {}, ('x', 'y'), 'eek', 0), + (1, f, (3,), {}, ('x'), 'ack', 10), + ]) + self.assertRaises(ConfigurationConflictError, list, result) + +class TestGlobalRegistriesIntegration(unittest.TestCase): + def setUp(self): + from pyramid.config import global_registries + global_registries.empty() + + tearDown = setUp + + def _makeConfigurator(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_global_registries_empty(self): + from pyramid.config import global_registries + self.assertEqual(global_registries.last, None) + + def test_global_registries(self): + from pyramid.config import global_registries + config1 = self._makeConfigurator() + config1.make_wsgi_app() + self.assertEqual(global_registries.last, config1.registry) + config2 = self._makeConfigurator() + config2.make_wsgi_app() + self.assertEqual(global_registries.last, config2.registry) + self.assertEqual(list(global_registries), + [config1.registry, config2.registry]) + global_registries.remove(config2.registry) + self.assertEqual(global_registries.last, config1.registry) + +class DummyRequest: + subpath = () + matchdict = None + request_iface = IRequest + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + self.params = {} + self.cookies = {} + +class DummyThreadLocalManager(object): + def __init__(self): + self.pushed = {'registry': None, 'request': None} + self.popped = False + def push(self, d): + self.pushed = d + def get(self): + return self.pushed + def pop(self): + self.popped = True + +from zope.interface import implementer +@implementer(IDummy) +class DummyEvent: + pass + +class DummyRegistry(object): + def __init__(self, adaptation=None, util=None): + self.utilities = [] + self.adapters = [] + self.adaptation = adaptation + self.util = util + def subscribers(self, events, name): + self.events = events + return events + def registerUtility(self, *arg, **kw): + self.utilities.append((arg, kw)) + def registerAdapter(self, *arg, **kw): + self.adapters.append((arg, kw)) + def queryAdapter(self, *arg, **kw): + return self.adaptation + def queryUtility(self, *arg, **kw): + return self.util + +from zope.interface import Interface +class IOther(Interface): + pass + +def _conflictFunctions(e): + conflicts = e._conflicts.values() + for conflict in conflicts: + for confinst in conflict: + yield confinst.function + +class DummyActionState(object): + autocommit = False + info = '' + def __init__(self): + self.actions = [] + def action(self, *arg, **kw): + self.actions.append((arg, kw)) + +class DummyIntrospectable(object): + def __init__(self): + self.registered = [] + def register(self, introspector, action_info): + self.registered.append((introspector, action_info)) + +class DummyPredicate(object): + pass diff --git a/tests/test_config/test_rendering.py b/tests/test_config/test_rendering.py new file mode 100644 index 000000000..cede64d3a --- /dev/null +++ b/tests/test_config/test_rendering.py @@ -0,0 +1,34 @@ +import unittest + +class TestRenderingConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_add_default_renderers(self): + from pyramid.config.rendering import DEFAULT_RENDERERS + from pyramid.interfaces import IRendererFactory + config = self._makeOne(autocommit=True) + config.add_default_renderers() + for name, impl in DEFAULT_RENDERERS: + self.assertTrue( + config.registry.queryUtility(IRendererFactory, name) is not None + ) + + def test_add_renderer(self): + from pyramid.interfaces import IRendererFactory + config = self._makeOne(autocommit=True) + renderer = object() + config.add_renderer('name', renderer) + self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), + renderer) + + def test_add_renderer_dottedname_factory(self): + from pyramid.interfaces import IRendererFactory + config = self._makeOne(autocommit=True) + import pyramid.tests.test_config + config.add_renderer('name', 'pyramid.tests.test_config') + self.assertEqual(config.registry.getUtility(IRendererFactory, 'name'), + pyramid.tests.test_config) + diff --git a/tests/test_config/test_routes.py b/tests/test_config/test_routes.py new file mode 100644 index 000000000..9f4ce9bc6 --- /dev/null +++ b/tests/test_config/test_routes.py @@ -0,0 +1,297 @@ +import unittest + +from pyramid.tests.test_config import dummyfactory +from pyramid.tests.test_config import DummyContext +from pyramid.compat import text_ + +class RoutesConfiguratorMixinTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def _assertRoute(self, config, name, path, num_predicates=0): + from pyramid.interfaces import IRoutesMapper + mapper = config.registry.getUtility(IRoutesMapper) + routes = mapper.get_routes() + route = routes[0] + self.assertEqual(len(routes), 1) + self.assertEqual(route.name, name) + self.assertEqual(route.path, path) + self.assertEqual(len(routes[0].predicates), num_predicates) + return route + + def _makeRequest(self, config): + request = DummyRequest() + request.registry = config.registry + return request + + def test_get_routes_mapper_not_yet_registered(self): + config = self._makeOne() + mapper = config.get_routes_mapper() + self.assertEqual(mapper.routelist, []) + + def test_get_routes_mapper_already_registered(self): + from pyramid.interfaces import IRoutesMapper + config = self._makeOne() + mapper = object() + config.registry.registerUtility(mapper, IRoutesMapper) + result = config.get_routes_mapper() + self.assertEqual(result, mapper) + + def test_add_route_defaults(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path') + self._assertRoute(config, 'name', 'path') + + def test_add_route_with_route_prefix(self): + config = self._makeOne(autocommit=True) + config.route_prefix = 'root' + config.add_route('name', 'path') + self._assertRoute(config, 'name', 'root/path') + + def test_add_route_discriminator(self): + config = self._makeOne() + config.add_route('name', 'path') + self.assertEqual(config.action_state.actions[-1]['discriminator'], + ('route', 'name')) + + def test_add_route_with_factory(self): + config = self._makeOne(autocommit=True) + factory = object() + config.add_route('name', 'path', factory=factory) + route = self._assertRoute(config, 'name', 'path') + self.assertEqual(route.factory, factory) + + def test_add_route_with_static(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path/{foo}', static=True) + mapper = config.get_routes_mapper() + self.assertEqual(len(mapper.get_routes()), 0) + self.assertEqual(mapper.generate('name', {"foo":"a"}), '/path/a') + + def test_add_route_with_factory_dottedname(self): + config = self._makeOne(autocommit=True) + config.add_route( + 'name', 'path', + factory='pyramid.tests.test_config.dummyfactory') + route = self._assertRoute(config, 'name', 'path') + self.assertEqual(route.factory, dummyfactory) + + def test_add_route_with_xhr(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', xhr=True) + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.is_xhr = True + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.is_xhr = False + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_request_method(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', request_method='GET') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.method = 'GET' + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.method = 'POST' + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_path_info(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', path_info='/foo') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.upath_info = '/foo' + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.upath_info = '/' + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_path_info_highorder(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', + path_info=text_(b'/La Pe\xc3\xb1a', 'utf-8')) + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.upath_info = text_(b'/La Pe\xc3\xb1a', 'utf-8') + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.upath_info = text_('/') + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_path_info_regex(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', + path_info=text_(br'/La Pe\w*', 'utf-8')) + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.upath_info = text_(b'/La Pe\xc3\xb1a', 'utf-8') + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.upath_info = text_('/') + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_request_param(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', request_param='abc') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.params = {'abc':'123'} + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.params = {} + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_custom_predicates(self): + import warnings + config = self._makeOne(autocommit=True) + def pred1(context, request): pass + def pred2(context, request): pass + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_route('name', 'path', custom_predicates=(pred1, pred2)) + self.assertEqual(len(w), 1) + route = self._assertRoute(config, 'name', 'path', 2) + self.assertEqual(len(route.predicates), 2) + + def test_add_route_with_header(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', header='Host') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.headers = {'Host':'example.com'} + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.headers = {} + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_accept(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', accept='text/xml') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.accept = DummyAccept('text/xml') + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.accept = DummyAccept('text/html') + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_accept_list(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', accept=['text/xml', 'text/plain']) + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.accept = DummyAccept('text/xml') + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.accept = DummyAccept('text/plain') + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.accept = DummyAccept('text/html') + self.assertEqual(predicate(None, request), False) + + def test_add_route_with_wildcard_accept(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'path', accept='text/*') + route = self._assertRoute(config, 'name', 'path', 1) + predicate = route.predicates[0] + request = self._makeRequest(config) + request.accept = DummyAccept('text/xml', contains=True) + self.assertEqual(predicate(None, request), True) + request = self._makeRequest(config) + request.accept = DummyAccept('application/json', contains=False) + self.assertEqual(predicate(None, request), False) + + def test_add_route_no_pattern_with_path(self): + config = self._makeOne(autocommit=True) + config.add_route('name', path='path') + self._assertRoute(config, 'name', 'path') + + def test_add_route_no_path_no_pattern(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_route, 'name') + + def test_add_route_with_pregenerator(self): + config = self._makeOne(autocommit=True) + config.add_route('name', 'pattern', pregenerator='123') + route = self._assertRoute(config, 'name', 'pattern') + self.assertEqual(route.pregenerator, '123') + + def test_add_route_no_view_with_view_attr(self): + config = self._makeOne(autocommit=True) + from pyramid.exceptions import ConfigurationError + try: + config.add_route('name', '/pattern', view_attr='abc') + except ConfigurationError: + pass + else: # pragma: no cover + raise AssertionError + + def test_add_route_no_view_with_view_context(self): + config = self._makeOne(autocommit=True) + from pyramid.exceptions import ConfigurationError + try: + config.add_route('name', '/pattern', view_context=DummyContext) + except ConfigurationError: + pass + else: # pragma: no cover + raise AssertionError + + def test_add_route_no_view_with_view_permission(self): + config = self._makeOne(autocommit=True) + from pyramid.exceptions import ConfigurationError + try: + config.add_route('name', '/pattern', view_permission='edit') + except ConfigurationError: + pass + else: # pragma: no cover + raise AssertionError + + def test_add_route_no_view_with_view_renderer(self): + config = self._makeOne(autocommit=True) + from pyramid.exceptions import ConfigurationError + try: + config.add_route('name', '/pattern', view_renderer='json') + except ConfigurationError: + pass + else: # pragma: no cover + raise AssertionError + +class DummyRequest: + subpath = () + matchdict = None + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + self.params = {} + self.cookies = {} + +class DummyAccept(object): + def __init__(self, *matches, **kw): + self.matches = list(matches) + self.contains = kw.pop('contains', False) + + def acceptable_offers(self, offers): + results = [] + for match in self.matches: + if match in offers: + results.append((match, 1.0)) + return results + + def __contains__(self, value): + return self.contains diff --git a/tests/test_config/test_security.py b/tests/test_config/test_security.py new file mode 100644 index 000000000..5db8e21fc --- /dev/null +++ b/tests/test_config/test_security.py @@ -0,0 +1,125 @@ +import unittest + +from pyramid.exceptions import ConfigurationExecutionError +from pyramid.exceptions import ConfigurationError + +class ConfiguratorSecurityMethodsTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_set_authentication_policy_no_authz_policy(self): + config = self._makeOne() + policy = object() + config.set_authentication_policy(policy) + self.assertRaises(ConfigurationExecutionError, config.commit) + + def test_set_authentication_policy_no_authz_policy_autocommit(self): + config = self._makeOne(autocommit=True) + policy = object() + self.assertRaises(ConfigurationError, + config.set_authentication_policy, policy) + + def test_set_authentication_policy_with_authz_policy(self): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + config = self._makeOne() + authn_policy = object() + authz_policy = object() + config.registry.registerUtility(authz_policy, IAuthorizationPolicy) + config.set_authentication_policy(authn_policy) + config.commit() + self.assertEqual( + config.registry.getUtility(IAuthenticationPolicy), authn_policy) + + def test_set_authentication_policy_with_authz_policy_autocommit(self): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + config = self._makeOne(autocommit=True) + authn_policy = object() + authz_policy = object() + config.registry.registerUtility(authz_policy, IAuthorizationPolicy) + config.set_authentication_policy(authn_policy) + config.commit() + self.assertEqual( + config.registry.getUtility(IAuthenticationPolicy), authn_policy) + + def test_set_authorization_policy_no_authn_policy(self): + config = self._makeOne() + policy = object() + config.set_authorization_policy(policy) + self.assertRaises(ConfigurationExecutionError, config.commit) + + def test_set_authorization_policy_no_authn_policy_autocommit(self): + from pyramid.interfaces import IAuthorizationPolicy + config = self._makeOne(autocommit=True) + policy = object() + config.set_authorization_policy(policy) + self.assertEqual( + config.registry.getUtility(IAuthorizationPolicy), policy) + + def test_set_authorization_policy_with_authn_policy(self): + from pyramid.interfaces import IAuthorizationPolicy + from pyramid.interfaces import IAuthenticationPolicy + config = self._makeOne() + authn_policy = object() + authz_policy = object() + config.registry.registerUtility(authn_policy, IAuthenticationPolicy) + config.set_authorization_policy(authz_policy) + config.commit() + self.assertEqual( + config.registry.getUtility(IAuthorizationPolicy), authz_policy) + + def test_set_authorization_policy_with_authn_policy_autocommit(self): + from pyramid.interfaces import IAuthorizationPolicy + from pyramid.interfaces import IAuthenticationPolicy + config = self._makeOne(autocommit=True) + authn_policy = object() + authz_policy = object() + config.registry.registerUtility(authn_policy, IAuthenticationPolicy) + config.set_authorization_policy(authz_policy) + self.assertEqual( + config.registry.getUtility(IAuthorizationPolicy), authz_policy) + + def test_set_default_permission(self): + from pyramid.interfaces import IDefaultPermission + config = self._makeOne(autocommit=True) + config.set_default_permission('view') + self.assertEqual(config.registry.getUtility(IDefaultPermission), + 'view') + + def test_add_permission(self): + config = self._makeOne(autocommit=True) + config.add_permission('perm') + cat = config.registry.introspector.get_category('permissions') + self.assertEqual(len(cat), 1) + D = cat[0] + intr = D['introspectable'] + self.assertEqual(intr['value'], 'perm') + + def test_set_default_csrf_options(self): + from pyramid.interfaces import IDefaultCSRFOptions + config = self._makeOne(autocommit=True) + config.set_default_csrf_options() + result = config.registry.getUtility(IDefaultCSRFOptions) + self.assertEqual(result.require_csrf, True) + self.assertEqual(result.token, 'csrf_token') + self.assertEqual(result.header, 'X-CSRF-Token') + self.assertEqual(list(sorted(result.safe_methods)), + ['GET', 'HEAD', 'OPTIONS', 'TRACE']) + self.assertTrue(result.callback is None) + + def test_changing_set_default_csrf_options(self): + from pyramid.interfaces import IDefaultCSRFOptions + config = self._makeOne(autocommit=True) + def callback(request): return True + config.set_default_csrf_options( + require_csrf=False, token='DUMMY', header=None, + safe_methods=('PUT',), callback=callback) + result = config.registry.getUtility(IDefaultCSRFOptions) + self.assertEqual(result.require_csrf, False) + self.assertEqual(result.token, 'DUMMY') + self.assertEqual(result.header, None) + self.assertEqual(list(sorted(result.safe_methods)), ['PUT']) + self.assertTrue(result.callback is callback) diff --git a/tests/test_config/test_settings.py b/tests/test_config/test_settings.py new file mode 100644 index 000000000..a3afd24e7 --- /dev/null +++ b/tests/test_config/test_settings.py @@ -0,0 +1,582 @@ +import unittest + + +class TestSettingsConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test__set_settings_as_None(self): + config = self._makeOne() + settings = config._set_settings(None) + self.assertTrue(settings) + + def test__set_settings_does_not_uses_original_dict(self): + config = self._makeOne() + dummy = {} + result = config._set_settings(dummy) + self.assertTrue(dummy is not result) + self.assertNotIn('pyramid.debug_all', dummy) + + def test__set_settings_as_dictwithvalues(self): + config = self._makeOne() + settings = config._set_settings({'a':'1'}) + self.assertEqual(settings['a'], '1') + + def test_get_settings_nosettings(self): + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg) + self.assertEqual(config.get_settings(), None) + + def test_get_settings_withsettings(self): + settings = {'a':1} + config = self._makeOne() + config.registry.settings = settings + self.assertEqual(config.get_settings(), settings) + + def test_add_settings_settings_already_registered(self): + from pyramid.registry import Registry + reg = Registry() + config = self._makeOne(reg) + config._set_settings({'a':1}) + config.add_settings({'b':2}) + settings = reg.settings + self.assertEqual(settings['a'], 1) + self.assertEqual(settings['b'], 2) + + def test_add_settings_settings_not_yet_registered(self): + from pyramid.registry import Registry + from pyramid.interfaces import ISettings + reg = Registry() + config = self._makeOne(reg) + config.add_settings({'a':1}) + settings = reg.getUtility(ISettings) + self.assertEqual(settings['a'], 1) + + def test_add_settings_settings_None(self): + from pyramid.registry import Registry + from pyramid.interfaces import ISettings + reg = Registry() + config = self._makeOne(reg) + config.add_settings(None, a=1) + settings = reg.getUtility(ISettings) + self.assertEqual(settings['a'], 1) + + def test_settings_parameter_dict_is_never_updated(self): + class ReadOnlyDict(dict): + def __readonly__(self, *args, **kwargs): # pragma: no cover + raise RuntimeError("Cannot modify ReadOnlyDict") + __setitem__ = __readonly__ + __delitem__ = __readonly__ + pop = __readonly__ + popitem = __readonly__ + clear = __readonly__ + update = __readonly__ + setdefault = __readonly__ + del __readonly__ + + initial = ReadOnlyDict() + config = self._makeOne(settings=initial) + config._set_settings({'a': '1'}) + + +class TestSettings(unittest.TestCase): + + def _getTargetClass(self): + from pyramid.config.settings import Settings + return Settings + + def _makeOne(self, d=None, environ=None): + if environ is None: + environ = {} + klass = self._getTargetClass() + return klass(d, _environ_=environ) + + def test_noargs(self): + settings = self._makeOne() + self.assertEqual(settings['debug_authorization'], False) + self.assertEqual(settings['debug_notfound'], False) + self.assertEqual(settings['debug_routematch'], False) + self.assertEqual(settings['reload_templates'], False) + self.assertEqual(settings['reload_resources'], False) + + self.assertEqual(settings['pyramid.debug_authorization'], False) + self.assertEqual(settings['pyramid.debug_notfound'], False) + self.assertEqual(settings['pyramid.debug_routematch'], False) + self.assertEqual(settings['pyramid.reload_templates'], False) + self.assertEqual(settings['pyramid.reload_resources'], False) + + def test_prevent_http_cache(self): + settings = self._makeOne({}) + self.assertEqual(settings['prevent_http_cache'], False) + self.assertEqual(settings['pyramid.prevent_http_cache'], False) + result = self._makeOne({'prevent_http_cache':'false'}) + self.assertEqual(result['prevent_http_cache'], False) + self.assertEqual(result['pyramid.prevent_http_cache'], False) + result = self._makeOne({'prevent_http_cache':'t'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + result = self._makeOne({'prevent_http_cache':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + result = self._makeOne({'pyramid.prevent_http_cache':'t'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + result = self._makeOne({}, {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + result = self._makeOne({'prevent_http_cache':'false', + 'pyramid.prevent_http_cache':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + result = self._makeOne({'prevent_http_cache':'false', + 'pyramid.prevent_http_cache':'f'}, + {'PYRAMID_PREVENT_HTTP_CACHE':'1'}) + self.assertEqual(result['prevent_http_cache'], True) + self.assertEqual(result['pyramid.prevent_http_cache'], True) + + def test_prevent_cachebust(self): + settings = self._makeOne({}) + self.assertEqual(settings['prevent_cachebust'], False) + self.assertEqual(settings['pyramid.prevent_cachebust'], False) + result = self._makeOne({'prevent_cachebust':'false'}) + self.assertEqual(result['prevent_cachebust'], False) + self.assertEqual(result['pyramid.prevent_cachebust'], False) + result = self._makeOne({'prevent_cachebust':'t'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + result = self._makeOne({'prevent_cachebust':'1'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + result = self._makeOne({'pyramid.prevent_cachebust':'t'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + result = self._makeOne({}, {'PYRAMID_PREVENT_CACHEBUST':'1'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + result = self._makeOne({'prevent_cachebust':'false', + 'pyramid.prevent_cachebust':'1'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + result = self._makeOne({'prevent_cachebust':'false', + 'pyramid.prevent_cachebust':'f'}, + {'PYRAMID_PREVENT_CACHEBUST':'1'}) + self.assertEqual(result['prevent_cachebust'], True) + self.assertEqual(result['pyramid.prevent_cachebust'], True) + + def test_reload_templates(self): + settings = self._makeOne({}) + self.assertEqual(settings['reload_templates'], False) + self.assertEqual(settings['pyramid.reload_templates'], False) + result = self._makeOne({'reload_templates':'false'}) + self.assertEqual(result['reload_templates'], False) + self.assertEqual(result['pyramid.reload_templates'], False) + result = self._makeOne({'reload_templates':'t'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + result = self._makeOne({'reload_templates':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + result = self._makeOne({'pyramid.reload_templates':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + result = self._makeOne({}, {'PYRAMID_RELOAD_TEMPLATES':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + result = self._makeOne({'reload_templates':'false', + 'pyramid.reload_templates':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + result = self._makeOne({'reload_templates':'false'}, + {'PYRAMID_RELOAD_TEMPLATES':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + + def test_reload_resources(self): + # alias for reload_assets + result = self._makeOne({}) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + result = self._makeOne({'reload_resources':'false'}) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + result = self._makeOne({'reload_resources':'t'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_resources':'1'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'pyramid.reload_resources':'1'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({}, {'PYRAMID_RELOAD_RESOURCES':'1'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_resources':'false', + 'pyramid.reload_resources':'1'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_resources':'false', + 'pyramid.reload_resources':'false'}, + {'PYRAMID_RELOAD_RESOURCES':'1'}) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + + def test_reload_assets(self): + # alias for reload_resources + result = self._makeOne({}) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + result = self._makeOne({'reload_assets':'false'}) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + result = self._makeOne({'reload_assets':'t'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + result = self._makeOne({'reload_assets':'1'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + result = self._makeOne({'pyramid.reload_assets':'1'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + result = self._makeOne({}, {'PYRAMID_RELOAD_ASSETS':'1'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + result = self._makeOne({'reload_assets':'false', + 'pyramid.reload_assets':'1'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + result = self._makeOne({'reload_assets':'false', + 'pyramid.reload_assets':'false'}, + {'PYRAMID_RELOAD_ASSETS':'1'}) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + + def test_reload_all(self): + result = self._makeOne({}) + self.assertEqual(result['reload_templates'], False) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['pyramid.reload_templates'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + result = self._makeOne({'reload_all':'false'}) + self.assertEqual(result['reload_templates'], False) + self.assertEqual(result['reload_resources'], False) + self.assertEqual(result['reload_assets'], False) + self.assertEqual(result['pyramid.reload_templates'], False) + self.assertEqual(result['pyramid.reload_resources'], False) + self.assertEqual(result['pyramid.reload_assets'], False) + result = self._makeOne({'reload_all':'t'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_all':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'pyramid.reload_all':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({}, {'PYRAMID_RELOAD_ALL':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_all':'false', + 'pyramid.reload_all':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + result = self._makeOne({'reload_all':'false', + 'pyramid.reload_all':'false'}, + {'PYRAMID_RELOAD_ALL':'1'}) + self.assertEqual(result['reload_templates'], True) + self.assertEqual(result['reload_resources'], True) + self.assertEqual(result['reload_assets'], True) + self.assertEqual(result['pyramid.reload_templates'], True) + self.assertEqual(result['pyramid.reload_resources'], True) + self.assertEqual(result['pyramid.reload_assets'], True) + + def test_debug_authorization(self): + result = self._makeOne({}) + self.assertEqual(result['debug_authorization'], False) + self.assertEqual(result['pyramid.debug_authorization'], False) + result = self._makeOne({'debug_authorization':'false'}) + self.assertEqual(result['debug_authorization'], False) + self.assertEqual(result['pyramid.debug_authorization'], False) + result = self._makeOne({'debug_authorization':'t'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + result = self._makeOne({'debug_authorization':'1'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + result = self._makeOne({'pyramid.debug_authorization':'1'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + result = self._makeOne({}, {'PYRAMID_DEBUG_AUTHORIZATION':'1'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + result = self._makeOne({'debug_authorization':'false', + 'pyramid.debug_authorization':'1'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + result = self._makeOne({'debug_authorization':'false', + 'pyramid.debug_authorization':'false'}, + {'PYRAMID_DEBUG_AUTHORIZATION':'1'}) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + + def test_debug_notfound(self): + result = self._makeOne({}) + self.assertEqual(result['debug_notfound'], False) + self.assertEqual(result['pyramid.debug_notfound'], False) + result = self._makeOne({'debug_notfound':'false'}) + self.assertEqual(result['debug_notfound'], False) + self.assertEqual(result['pyramid.debug_notfound'], False) + result = self._makeOne({'debug_notfound':'t'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + result = self._makeOne({'debug_notfound':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + result = self._makeOne({'pyramid.debug_notfound':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + result = self._makeOne({}, {'PYRAMID_DEBUG_NOTFOUND':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + result = self._makeOne({'debug_notfound':'false', + 'pyramid.debug_notfound':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + result = self._makeOne({'debug_notfound':'false', + 'pyramid.debug_notfound':'false'}, + {'PYRAMID_DEBUG_NOTFOUND':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + + def test_debug_routematch(self): + result = self._makeOne({}) + self.assertEqual(result['debug_routematch'], False) + self.assertEqual(result['pyramid.debug_routematch'], False) + result = self._makeOne({'debug_routematch':'false'}) + self.assertEqual(result['debug_routematch'], False) + self.assertEqual(result['pyramid.debug_routematch'], False) + result = self._makeOne({'debug_routematch':'t'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + result = self._makeOne({'debug_routematch':'1'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + result = self._makeOne({'pyramid.debug_routematch':'1'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + result = self._makeOne({}, {'PYRAMID_DEBUG_ROUTEMATCH':'1'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + result = self._makeOne({'debug_routematch':'false', + 'pyramid.debug_routematch':'1'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + result = self._makeOne({'debug_routematch':'false', + 'pyramid.debug_routematch':'false'}, + {'PYRAMID_DEBUG_ROUTEMATCH':'1'}) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + + def test_debug_templates(self): + result = self._makeOne({}) + self.assertEqual(result['debug_templates'], False) + self.assertEqual(result['pyramid.debug_templates'], False) + result = self._makeOne({'debug_templates':'false'}) + self.assertEqual(result['debug_templates'], False) + self.assertEqual(result['pyramid.debug_templates'], False) + result = self._makeOne({'debug_templates':'t'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_templates':'1'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'pyramid.debug_templates':'1'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({}, {'PYRAMID_DEBUG_TEMPLATES':'1'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_templates':'false', + 'pyramid.debug_templates':'1'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_templates':'false', + 'pyramid.debug_templates':'false'}, + {'PYRAMID_DEBUG_TEMPLATES':'1'}) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + + def test_debug_all(self): + result = self._makeOne({}) + self.assertEqual(result['debug_notfound'], False) + self.assertEqual(result['debug_routematch'], False) + self.assertEqual(result['debug_authorization'], False) + self.assertEqual(result['debug_templates'], False) + self.assertEqual(result['pyramid.debug_notfound'], False) + self.assertEqual(result['pyramid.debug_routematch'], False) + self.assertEqual(result['pyramid.debug_authorization'], False) + self.assertEqual(result['pyramid.debug_templates'], False) + result = self._makeOne({'debug_all':'false'}) + self.assertEqual(result['debug_notfound'], False) + self.assertEqual(result['debug_routematch'], False) + self.assertEqual(result['debug_authorization'], False) + self.assertEqual(result['debug_templates'], False) + self.assertEqual(result['pyramid.debug_notfound'], False) + self.assertEqual(result['pyramid.debug_routematch'], False) + self.assertEqual(result['pyramid.debug_authorization'], False) + self.assertEqual(result['pyramid.debug_templates'], False) + result = self._makeOne({'debug_all':'t'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_all':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'pyramid.debug_all':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({}, {'PYRAMID_DEBUG_ALL':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_all':'false', + 'pyramid.debug_all':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + result = self._makeOne({'debug_all':'false', + 'pyramid.debug_all':'false'}, + {'PYRAMID_DEBUG_ALL':'1'}) + self.assertEqual(result['debug_notfound'], True) + self.assertEqual(result['debug_routematch'], True) + self.assertEqual(result['debug_authorization'], True) + self.assertEqual(result['debug_templates'], True) + self.assertEqual(result['pyramid.debug_notfound'], True) + self.assertEqual(result['pyramid.debug_routematch'], True) + self.assertEqual(result['pyramid.debug_authorization'], True) + self.assertEqual(result['pyramid.debug_templates'], True) + + def test_default_locale_name(self): + result = self._makeOne({}) + self.assertEqual(result['default_locale_name'], 'en') + self.assertEqual(result['pyramid.default_locale_name'], 'en') + result = self._makeOne({'default_locale_name':'abc'}) + self.assertEqual(result['default_locale_name'], 'abc') + self.assertEqual(result['pyramid.default_locale_name'], 'abc') + result = self._makeOne({'pyramid.default_locale_name':'abc'}) + self.assertEqual(result['default_locale_name'], 'abc') + self.assertEqual(result['pyramid.default_locale_name'], 'abc') + result = self._makeOne({}, {'PYRAMID_DEFAULT_LOCALE_NAME':'abc'}) + self.assertEqual(result['default_locale_name'], 'abc') + self.assertEqual(result['pyramid.default_locale_name'], 'abc') + result = self._makeOne({'default_locale_name':'def', + 'pyramid.default_locale_name':'abc'}) + self.assertEqual(result['default_locale_name'], 'abc') + self.assertEqual(result['pyramid.default_locale_name'], 'abc') + result = self._makeOne({'default_locale_name':'def', + 'pyramid.default_locale_name':'ghi'}, + {'PYRAMID_DEFAULT_LOCALE_NAME':'abc'}) + self.assertEqual(result['default_locale_name'], 'abc') + self.assertEqual(result['pyramid.default_locale_name'], 'abc') + + def test_csrf_trusted_origins(self): + result = self._makeOne({}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], []) + result = self._makeOne({'pyramid.csrf_trusted_origins': 'example.com'}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) + result = self._makeOne({'pyramid.csrf_trusted_origins': ['example.com']}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], ['example.com']) + result = self._makeOne({'pyramid.csrf_trusted_origins': ( + 'example.com foo.example.com\nasdf.example.com')}) + self.assertEqual(result['pyramid.csrf_trusted_origins'], [ + 'example.com', 'foo.example.com', 'asdf.example.com']) + + def test_originals_kept(self): + result = self._makeOne({'a':'i am so a'}) + self.assertEqual(result['a'], 'i am so a') + + diff --git a/tests/test_config/test_testing.py b/tests/test_config/test_testing.py new file mode 100644 index 000000000..05561bfe9 --- /dev/null +++ b/tests/test_config/test_testing.py @@ -0,0 +1,205 @@ +import unittest + +from pyramid.compat import text_ +from pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin +from pyramid.tests.test_config import IDummy + +class TestingConfiguratorMixinTests(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_testing_securitypolicy(self): + from pyramid.testing import DummySecurityPolicy + config = self._makeOne(autocommit=True) + config.testing_securitypolicy('user', ('group1', 'group2'), + permissive=False) + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + ut = config.registry.getUtility(IAuthenticationPolicy) + self.assertTrue(isinstance(ut, DummySecurityPolicy)) + ut = config.registry.getUtility(IAuthorizationPolicy) + self.assertEqual(ut.userid, 'user') + self.assertEqual(ut.groupids, ('group1', 'group2')) + self.assertEqual(ut.permissive, False) + + def test_testing_securitypolicy_remember_result(self): + from pyramid.security import remember + config = self._makeOne(autocommit=True) + pol = config.testing_securitypolicy( + 'user', ('group1', 'group2'), + permissive=False, remember_result=True) + request = DummyRequest() + request.registry = config.registry + val = remember(request, 'fred') + self.assertEqual(pol.remembered, 'fred') + self.assertEqual(val, True) + + def test_testing_securitypolicy_forget_result(self): + from pyramid.security import forget + config = self._makeOne(autocommit=True) + pol = config.testing_securitypolicy( + 'user', ('group1', 'group2'), + permissive=False, forget_result=True) + request = DummyRequest() + request.registry = config.registry + val = forget(request) + self.assertEqual(pol.forgotten, True) + self.assertEqual(val, True) + + def test_testing_resources(self): + from pyramid.traversal import find_resource + from pyramid.interfaces import ITraverser + ob1 = object() + ob2 = object() + resources = {'/ob1':ob1, '/ob2':ob2} + config = self._makeOne(autocommit=True) + config.testing_resources(resources) + adapter = config.registry.getAdapter(None, ITraverser) + result = adapter(DummyRequest({'PATH_INFO':'/ob1'})) + self.assertEqual(result['context'], ob1) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (text_('ob1'),)) + self.assertEqual(result['virtual_root'], ob1) + self.assertEqual(result['virtual_root_path'], ()) + result = adapter(DummyRequest({'PATH_INFO':'/ob2'})) + self.assertEqual(result['context'], ob2) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (text_('ob2'),)) + self.assertEqual(result['virtual_root'], ob2) + self.assertEqual(result['virtual_root_path'], ()) + self.assertRaises(KeyError, adapter, DummyRequest({'PATH_INFO':'/ob3'})) + try: + config.begin() + self.assertEqual(find_resource(None, '/ob1'), ob1) + finally: + config.end() + + def test_testing_add_subscriber_single(self): + config = self._makeOne(autocommit=True) + L = config.testing_add_subscriber(IDummy) + event = DummyEvent() + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 1) + + def test_testing_add_subscriber_dottedname(self): + config = self._makeOne(autocommit=True) + L = config.testing_add_subscriber( + 'pyramid.tests.test_config.test_init.IDummy') + event = DummyEvent() + config.registry.notify(event) + self.assertEqual(len(L), 1) + self.assertEqual(L[0], event) + config.registry.notify(object()) + self.assertEqual(len(L), 1) + + def test_testing_add_subscriber_multiple(self): + from zope.interface import Interface + config = self._makeOne(autocommit=True) + L = config.testing_add_subscriber((Interface, IDummy)) + event = DummyEvent() + event.object = 'foo' + # the below is the equivalent of z.c.event.objectEventNotify(event) + config.registry.subscribers((event.object, event), None) + self.assertEqual(len(L), 2) + self.assertEqual(L[0], 'foo') + self.assertEqual(L[1], event) + + def test_testing_add_subscriber_defaults(self): + config = self._makeOne(autocommit=True) + L = config.testing_add_subscriber() + event = object() + config.registry.notify(event) + self.assertEqual(L[-1], event) + event2 = object() + config.registry.notify(event2) + self.assertEqual(L[-1], event2) + + def test_testing_add_renderer(self): + config = self._makeOne(autocommit=True) + renderer = config.testing_add_renderer('templates/foo.pt') + from pyramid.testing import DummyTemplateRenderer + self.assertTrue(isinstance(renderer, DummyTemplateRenderer)) + from pyramid.renderers import render_to_response + # must provide request to pass in registry (this is a functest) + request = DummyRequest() + request.registry = config.registry + render_to_response( + 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) + renderer.assert_(foo=1) + renderer.assert_(bar=2) + renderer.assert_(request=request) + + def test_testing_add_renderer_twice(self): + config = self._makeOne(autocommit=True) + renderer1 = config.testing_add_renderer('templates/foo.pt') + renderer2 = config.testing_add_renderer('templates/bar.pt') + from pyramid.testing import DummyTemplateRenderer + self.assertTrue(isinstance(renderer1, DummyTemplateRenderer)) + self.assertTrue(isinstance(renderer2, DummyTemplateRenderer)) + from pyramid.renderers import render_to_response + # must provide request to pass in registry (this is a functest) + request = DummyRequest() + request.registry = config.registry + render_to_response( + 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) + renderer1.assert_(foo=1) + renderer1.assert_(bar=2) + renderer1.assert_(request=request) + render_to_response( + 'templates/bar.pt', {'foo':1, 'bar':2}, request=request) + renderer2.assert_(foo=1) + renderer2.assert_(bar=2) + renderer2.assert_(request=request) + + def test_testing_add_renderer_explicitrenderer(self): + config = self._makeOne(autocommit=True) + class E(Exception): pass + def renderer(kw, system): + self.assertEqual(kw, {'foo':1, 'bar':2}) + raise E + renderer = config.testing_add_renderer('templates/foo.pt', renderer) + from pyramid.renderers import render_to_response + # must provide request to pass in registry (this is a functest) + request = DummyRequest() + request.registry = config.registry + try: + render_to_response( + 'templates/foo.pt', {'foo':1, 'bar':2}, request=request) + except E: + pass + else: # pragma: no cover + raise AssertionError + + def test_testing_add_template(self): + config = self._makeOne(autocommit=True) + renderer = config.testing_add_template('templates/foo.pt') + from pyramid.testing import DummyTemplateRenderer + self.assertTrue(isinstance(renderer, DummyTemplateRenderer)) + from pyramid.renderers import render_to_response + # must provide request to pass in registry (this is a functest) + request = DummyRequest() + request.registry = config.registry + render_to_response('templates/foo.pt', dict(foo=1, bar=2), + request=request) + renderer.assert_(foo=1) + renderer.assert_(bar=2) + renderer.assert_(request=request) + +from zope.interface import implementer +@implementer(IDummy) +class DummyEvent: + pass + +class DummyRequest(AuthenticationAPIMixin, AuthorizationAPIMixin): + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + diff --git a/tests/test_config/test_tweens.py b/tests/test_config/test_tweens.py new file mode 100644 index 000000000..9c3433468 --- /dev/null +++ b/tests/test_config/test_tweens.py @@ -0,0 +1,410 @@ +import unittest + +from pyramid.tests.test_config import dummy_tween_factory +from pyramid.tests.test_config import dummy_tween_factory2 + +from pyramid.exceptions import ConfigurationConflictError + +class TestTweensConfiguratorMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_add_tweens_names_distinct(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + def factory1(handler, registry): return handler + def factory2(handler, registry): return handler + config = self._makeOne() + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory') + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory2') + config.commit() + tweens = config.registry.queryUtility(ITweens) + implicit = tweens.implicit() + self.assertEqual( + implicit, + [ + ('pyramid.tests.test_config.dummy_tween_factory2', + dummy_tween_factory2), + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tweens.excview_tween_factory', + excview_tween_factory), + ] + ) + + def test_add_tweens_names_with_underover(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + from pyramid.tweens import MAIN + config = self._makeOne() + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory', + over=MAIN) + config.add_tween( + 'pyramid.tests.test_config.dummy_tween_factory2', + over=MAIN, + under='pyramid.tests.test_config.dummy_tween_factory') + config.commit() + tweens = config.registry.queryUtility(ITweens) + implicit = tweens.implicit() + self.assertEqual( + implicit, + [ + ('pyramid.tweens.excview_tween_factory', excview_tween_factory), + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tests.test_config.dummy_tween_factory2', + dummy_tween_factory2), + ]) + + def test_add_tweens_names_with_under_nonstringoriter(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises( + ConfigurationError, config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=False) + + def test_add_tweens_names_with_over_nonstringoriter(self): + from pyramid.exceptions import ConfigurationError + config = self._makeOne() + self.assertRaises( + ConfigurationError, config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=False) + + def test_add_tween_dottedname(self): + from pyramid.interfaces import ITweens + from pyramid.tweens import excview_tween_factory + config = self._makeOne() + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + config.commit() + tweens = config.registry.queryUtility(ITweens) + self.assertEqual( + tweens.implicit(), + [ + ('pyramid.tests.test_config.dummy_tween_factory', + dummy_tween_factory), + ('pyramid.tweens.excview_tween_factory', + excview_tween_factory), + ]) + + def test_add_tween_instance(self): + from pyramid.exceptions import ConfigurationError + class ATween(object): pass + atween = ATween() + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, atween) + + def test_add_tween_unsuitable(self): + from pyramid.exceptions import ConfigurationError + import pyramid.tests.test_config + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, + pyramid.tests.test_config) + + def test_add_tween_name_ingress(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, INGRESS) + + def test_add_tween_name_main(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises(ConfigurationError, config.add_tween, MAIN) + + def test_add_tweens_conflict(self): + config = self._makeOne() + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + config.add_tween('pyramid.tests.test_config.dummy_tween_factory') + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_tween_over_ingress(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=INGRESS) + + def test_add_tween_over_ingress_iterable(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import INGRESS + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + over=('a', INGRESS)) + + def test_add_tween_under_main(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=MAIN) + + def test_add_tween_under_main_iterable(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + config = self._makeOne() + self.assertRaises( + ConfigurationError, + config.add_tween, + 'pyramid.tests.test_config.dummy_tween_factory', + under=('a', MAIN)) + +class TestTweens(unittest.TestCase): + def _makeOne(self): + from pyramid.config.tweens import Tweens + return Tweens() + + def test_add_explicit(self): + tweens = self._makeOne() + tweens.add_explicit('name', 'factory') + self.assertEqual(tweens.explicit, [('name', 'factory')]) + tweens.add_explicit('name2', 'factory2') + self.assertEqual(tweens.explicit, [('name', 'factory'), + ('name2', 'factory2')]) + + def test_add_implicit(self): + tweens = self._makeOne() + tweens.add_implicit('name', 'factory') + tweens.add_implicit('name2', 'factory2') + self.assertEqual(tweens.sorter.sorted(), + [('name2', 'factory2'), + ('name', 'factory')]) + + def test___call___explicit(self): + tweens = self._makeOne() + def factory1(handler, registry): + return handler + def factory2(handler, registry): + return '123' + tweens.explicit = [('name', factory1), ('name', factory2)] + self.assertEqual(tweens(None, None), '123') + + def test___call___implicit(self): + tweens = self._makeOne() + def factory1(handler, registry): + return handler + def factory2(handler, registry): + return '123' + tweens.add_implicit('name2', factory2) + tweens.add_implicit('name1', factory1) + self.assertEqual(tweens(None, None), '123') + + def test_implicit_ordering_1(self): + tweens = self._makeOne() + tweens.add_implicit('name1', 'factory1') + tweens.add_implicit('name2', 'factory2') + self.assertEqual(tweens.implicit(), + [ + ('name2', 'factory2'), + ('name1', 'factory1'), + ]) + + def test_implicit_ordering_2(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + tweens.add_implicit('name1', 'factory1') + tweens.add_implicit('name2', 'factory2', over=MAIN) + self.assertEqual(tweens.implicit(), + [ + ('name1', 'factory1'), + ('name2', 'factory2'), + ]) + + def test_implicit_ordering_3(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('auth', 'auth_factory', under='browserid') + add('dbt', 'dbt_factory') + add('retry', 'retry_factory', over='txnmgr', under='exceptionview') + add('browserid', 'browserid_factory') + add('txnmgr', 'txnmgr_factory', under='exceptionview') + add('exceptionview', 'excview_factory', over=MAIN) + self.assertEqual(tweens.implicit(), + [ + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('dbt', 'dbt_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ]) + + def test_implicit_ordering_4(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('auth', 'auth_factory', under='browserid') + add('retry', 'retry_factory', over='txnmgr', under='exceptionview') + add('browserid', 'browserid_factory') + add('txnmgr', 'txnmgr_factory', under='exceptionview') + add('dbt', 'dbt_factory') + self.assertEqual(tweens.implicit(), + [ + ('dbt', 'dbt_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ]) + + def test_implicit_ordering_5(self): + from pyramid.tweens import MAIN, INGRESS + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('auth', 'auth_factory', under=INGRESS) + add('retry', 'retry_factory', over='txnmgr', under='exceptionview') + add('browserid', 'browserid_factory', under=INGRESS) + add('txnmgr', 'txnmgr_factory', under='exceptionview', over=MAIN) + add('dbt', 'dbt_factory') + self.assertEqual(tweens.implicit(), + [ + ('dbt', 'dbt_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ]) + + def test_implicit_ordering_missing_over_partial(self): + from pyramid.exceptions import ConfigurationError + tweens = self._makeOne() + add = tweens.add_implicit + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', under='browserid') + add('retry', 'retry_factory', over='txnmgr', under='exceptionview') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, tweens.implicit) + + def test_implicit_ordering_missing_under_partial(self): + from pyramid.exceptions import ConfigurationError + tweens = self._makeOne() + add = tweens.add_implicit + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', under='txnmgr') + add('retry', 'retry_factory', over='dbt', under='exceptionview') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, tweens.implicit) + + def test_implicit_ordering_missing_over_and_under_partials(self): + from pyramid.exceptions import ConfigurationError + tweens = self._makeOne() + add = tweens.add_implicit + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', under='browserid') + add('retry', 'retry_factory', over='foo', under='txnmgr') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, tweens.implicit) + + def test_implicit_ordering_missing_over_partial_with_fallback(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('auth', 'auth_factory', under='browserid') + add('retry', 'retry_factory', over=('txnmgr',MAIN), + under='exceptionview') + add('browserid', 'browserid_factory') + add('dbt', 'dbt_factory') + self.assertEqual(tweens.implicit(), + [ + ('dbt', 'dbt_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_implicit_ordering_missing_under_partial_with_fallback(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('auth', 'auth_factory', under=('txnmgr','browserid')) + add('retry', 'retry_factory', under='exceptionview') + add('browserid', 'browserid_factory') + add('dbt', 'dbt_factory') + self.assertEqual(tweens.implicit(), + [ + ('dbt', 'dbt_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_implicit_ordering_with_partial_fallbacks(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=('wontbethere', MAIN)) + add('retry', 'retry_factory', under='exceptionview') + add('browserid', 'browserid_factory', over=('wont2', 'exceptionview')) + self.assertEqual(tweens.implicit(), + [ + ('browserid', 'browserid_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_implicit_ordering_with_multiple_matching_fallbacks(self): + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('retry', 'retry_factory', under='exceptionview') + add('browserid', 'browserid_factory', over=('retry', 'exceptionview')) + self.assertEqual(tweens.implicit(), + [ + ('browserid', 'browserid_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_implicit_ordering_with_missing_fallbacks(self): + from pyramid.exceptions import ConfigurationError + from pyramid.tweens import MAIN + tweens = self._makeOne() + add = tweens.add_implicit + add('exceptionview', 'excview_factory', over=MAIN) + add('retry', 'retry_factory', under='exceptionview') + add('browserid', 'browserid_factory', over=('txnmgr', 'auth')) + self.assertRaises(ConfigurationError, tweens.implicit) + + def test_implicit_ordering_conflict_direct(self): + from pyramid.exceptions import CyclicDependencyError + tweens = self._makeOne() + add = tweens.add_implicit + add('browserid', 'browserid_factory') + add('auth', 'auth_factory', over='browserid', under='browserid') + self.assertRaises(CyclicDependencyError, tweens.implicit) + + def test_implicit_ordering_conflict_indirect(self): + from pyramid.exceptions import CyclicDependencyError + tweens = self._makeOne() + add = tweens.add_implicit + add('browserid', 'browserid_factory') + add('auth', 'auth_factory', over='browserid') + add('dbt', 'dbt_factory', under='browserid', over='auth') + self.assertRaises(CyclicDependencyError, tweens.implicit) + diff --git a/tests/test_config/test_util.py b/tests/test_config/test_util.py new file mode 100644 index 000000000..540f3d14c --- /dev/null +++ b/tests/test_config/test_util.py @@ -0,0 +1,497 @@ +import unittest + +from pyramid.compat import text_ + +class TestActionInfo(unittest.TestCase): + def _getTargetClass(self): + from pyramid.config.util import ActionInfo + return ActionInfo + + def _makeOne(self, filename, lineno, function, linerepr): + return self._getTargetClass()(filename, lineno, function, linerepr) + + def test_class_conforms(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IActionInfo + verifyClass(IActionInfo, self._getTargetClass()) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IActionInfo + verifyObject(IActionInfo, self._makeOne('f', 0, 'f', 'f')) + + def test_ctor(self): + inst = self._makeOne('filename', 10, 'function', 'src') + self.assertEqual(inst.file, 'filename') + self.assertEqual(inst.line, 10) + self.assertEqual(inst.function, 'function') + self.assertEqual(inst.src, 'src') + + def test___str__(self): + inst = self._makeOne('filename', 0, 'function', ' linerepr ') + self.assertEqual(str(inst), + "Line 0 of file filename:\n linerepr ") + + +class TestPredicateList(unittest.TestCase): + + def _makeOne(self): + from pyramid.config.util import PredicateList + from pyramid import predicates + inst = PredicateList() + for name, factory in ( + ('xhr', predicates.XHRPredicate), + ('request_method', predicates.RequestMethodPredicate), + ('path_info', predicates.PathInfoPredicate), + ('request_param', predicates.RequestParamPredicate), + ('header', predicates.HeaderPredicate), + ('accept', predicates.AcceptPredicate), + ('containment', predicates.ContainmentPredicate), + ('request_type', predicates.RequestTypePredicate), + ('match_param', predicates.MatchParamPredicate), + ('custom', predicates.CustomPredicate), + ('traverse', predicates.TraversePredicate), + ): + inst.add(name, factory) + return inst + + def _callFUT(self, **kw): + inst = self._makeOne() + config = DummyConfigurator() + return inst.make(config, **kw) + + def test_ordering_xhr_and_request_method_trump_only_containment(self): + order1, _, _ = self._callFUT(xhr=True, request_method='GET') + order2, _, _ = self._callFUT(containment=True) + self.assertTrue(order1 < order2) + + def test_ordering_number_of_predicates(self): + from pyramid.config.util import predvalseq + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + custom=predvalseq([DummyCustomPredicate()]), + ) + order2, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + custom=predvalseq([DummyCustomPredicate()]), + ) + order3, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + ) + order4, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + containment='containment', + ) + order5, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + accept='accept', + ) + order6, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + header='header', + ) + order7, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + match_param='foo=bar', + ) + order8, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + ) + order9, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + ) + order10, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + ) + order11, _, _ = self._callFUT( + xhr='xhr', + ) + order12, _, _ = self._callFUT( + ) + self.assertEqual(order1, order2) + self.assertTrue(order3 > order2) + self.assertTrue(order4 > order3) + self.assertTrue(order5 > order4) + self.assertTrue(order6 > order5) + self.assertTrue(order7 > order6) + self.assertTrue(order8 > order7) + self.assertTrue(order9 > order8) + self.assertTrue(order10 > order9) + self.assertTrue(order11 > order10) + self.assertTrue(order12 > order10) + + def test_ordering_importance_of_predicates(self): + from pyramid.config.util import predvalseq + order1, _, _ = self._callFUT( + xhr='xhr', + ) + order2, _, _ = self._callFUT( + request_method='request_method', + ) + order3, _, _ = self._callFUT( + path_info='path_info', + ) + order4, _, _ = self._callFUT( + request_param='param', + ) + order5, _, _ = self._callFUT( + header='header', + ) + order6, _, _ = self._callFUT( + accept='accept', + ) + order7, _, _ = self._callFUT( + containment='containment', + ) + order8, _, _ = self._callFUT( + request_type='request_type', + ) + order9, _, _ = self._callFUT( + match_param='foo=bar', + ) + order10, _, _ = self._callFUT( + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 > order2) + self.assertTrue(order2 > order3) + self.assertTrue(order3 > order4) + self.assertTrue(order4 > order5) + self.assertTrue(order5 > order6) + self.assertTrue(order6 > order7) + self.assertTrue(order7 > order8) + self.assertTrue(order8 > order9) + self.assertTrue(order9 > order10) + + def test_ordering_importance_and_number(self): + from pyramid.config.util import predvalseq + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + ) + order2, _, _ = self._callFUT( + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 < order2) + + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + ) + order2, _, _ = self._callFUT( + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 > order2) + + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + ) + order2, _, _ = self._callFUT( + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 < order2) + + order1, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + ) + order2, _, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + custom=predvalseq([DummyCustomPredicate()]), + ) + self.assertTrue(order1 > order2) + + def test_different_custom_predicates_with_same_hash(self): + from pyramid.config.util import predvalseq + class PredicateWithHash(object): + def __hash__(self): + return 1 + a = PredicateWithHash() + b = PredicateWithHash() + _, _, a_phash = self._callFUT(custom=predvalseq([a])) + _, _, b_phash = self._callFUT(custom=predvalseq([b])) + self.assertEqual(a_phash, b_phash) + + def test_traverse_has_remainder_already(self): + order, predicates, phash = self._callFUT(traverse='/1/:a/:b') + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'traverse':'abc'} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'traverse':'abc'}) + + def test_traverse_matches(self): + order, predicates, phash = self._callFUT(traverse='/1/:a/:b') + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'match':{'a':'a', 'b':'b'}} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'match': + {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) + + def test_traverse_matches_with_highorder_chars(self): + order, predicates, phash = self._callFUT( + traverse=text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) + self.assertEqual(len(predicates), 1) + pred = predicates[0] + info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} + request = DummyRequest() + result = pred(info, request) + self.assertEqual(result, True) + self.assertEqual( + info['match']['traverse'], + (text_(b'La Pe\xc3\xb1a', 'utf-8'), + text_(b'Qu\xc3\xa9bec', 'utf-8')) + ) + + def test_custom_predicates_can_affect_traversal(self): + from pyramid.config.util import predvalseq + def custom(info, request): + m = info['match'] + m['dummy'] = 'foo' + return True + _, predicates, _ = self._callFUT( + custom=predvalseq([custom]), + traverse='/1/:dummy/:a') + self.assertEqual(len(predicates), 2) + info = {'match':{'a':'a'}} + request = DummyRequest() + self.assertTrue(all([p(info, request) for p in predicates])) + self.assertEqual(info, {'match': + {'a':'a', 'dummy':'foo', + 'traverse':('1', 'foo', 'a')}}) + + def test_predicate_text_is_correct(self): + from pyramid.config.util import predvalseq + _, predicates, _ = self._callFUT( + xhr='xhr', + request_method='request_method', + path_info='path_info', + request_param='param', + header='header', + accept='accept', + containment='containment', + request_type='request_type', + custom=predvalseq( + [ + DummyCustomPredicate(), + DummyCustomPredicate.classmethod_predicate, + DummyCustomPredicate.classmethod_predicate_no_text, + ] + ), + match_param='foo=bar') + self.assertEqual(predicates[0].text(), 'xhr = True') + self.assertEqual(predicates[1].text(), + "request_method = request_method") + self.assertEqual(predicates[2].text(), 'path_info = path_info') + self.assertEqual(predicates[3].text(), 'request_param param') + self.assertEqual(predicates[4].text(), 'header header') + self.assertEqual(predicates[5].text(), 'accept = accept') + self.assertEqual(predicates[6].text(), 'containment = containment') + self.assertEqual(predicates[7].text(), 'request_type = request_type') + self.assertEqual(predicates[8].text(), "match_param foo=bar") + self.assertEqual(predicates[9].text(), 'custom predicate') + self.assertEqual(predicates[10].text(), 'classmethod predicate') + self.assertTrue(predicates[11].text().startswith('custom predicate')) + + def test_match_param_from_string(self): + _, predicates, _ = self._callFUT(match_param='foo=bar') + request = DummyRequest() + request.matchdict = {'foo':'bar', 'baz':'bum'} + self.assertTrue(predicates[0](Dummy(), request)) + + def test_match_param_from_string_fails(self): + _, predicates, _ = self._callFUT(match_param='foo=bar') + request = DummyRequest() + request.matchdict = {'foo':'bum', 'baz':'bum'} + self.assertFalse(predicates[0](Dummy(), request)) + + def test_match_param_from_dict(self): + _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum')) + request = DummyRequest() + request.matchdict = {'foo':'bar', 'baz':'bum'} + self.assertTrue(predicates[0](Dummy(), request)) + + def test_match_param_from_dict_fails(self): + _, predicates, _ = self._callFUT(match_param=('foo=bar','baz=bum')) + request = DummyRequest() + request.matchdict = {'foo':'bar', 'baz':'foo'} + self.assertFalse(predicates[0](Dummy(), request)) + + def test_request_method_sequence(self): + _, predicates, _ = self._callFUT(request_method=('GET', 'HEAD')) + request = DummyRequest() + request.method = 'HEAD' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'GET' + self.assertTrue(predicates[0](Dummy(), request)) + request.method = 'POST' + self.assertFalse(predicates[0](Dummy(), request)) + + def test_request_method_ordering_hashes_same(self): + hash1, _, __= self._callFUT(request_method=('GET', 'HEAD')) + hash2, _, __= self._callFUT(request_method=('HEAD', 'GET')) + self.assertEqual(hash1, hash2) + hash1, _, __= self._callFUT(request_method=('GET',)) + hash2, _, __= self._callFUT(request_method='GET') + self.assertEqual(hash1, hash2) + + def test_unknown_predicate(self): + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, self._callFUT, unknown=1) + + def test_predicate_close_matches(self): + from pyramid.exceptions import ConfigurationError + with self.assertRaises(ConfigurationError) as context: + self._callFUT(method='GET') + expected_msg = ( + "Unknown predicate values: {'method': 'GET'} " + "(did you mean request_method)" + ) + self.assertEqual(context.exception.args[0], expected_msg) + + def test_notted(self): + from pyramid.config import not_ + from pyramid.testing import DummyRequest + request = DummyRequest() + _, predicates, _ = self._callFUT( + xhr='xhr', + request_method=not_('POST'), + header=not_('header'), + ) + self.assertEqual(predicates[0].text(), 'xhr = True') + self.assertEqual(predicates[1].text(), + "!request_method = POST") + self.assertEqual(predicates[2].text(), '!header header') + self.assertEqual(predicates[1](None, request), True) + self.assertEqual(predicates[2](None, request), True) + +class TestDeprecatedPredicates(unittest.TestCase): + def test_it(self): + import warnings + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + from pyramid.config.predicates import XHRPredicate + self.assertEqual(len(w), 1) + +class Test_sort_accept_offers(unittest.TestCase): + def _callFUT(self, offers, order=None): + from pyramid.config.util import sort_accept_offers + return sort_accept_offers(offers, order) + + def test_default_specificities(self): + result = self._callFUT(['text/html', 'text/html;charset=utf8']) + self.assertEqual(result, [ + 'text/html;charset=utf8', 'text/html', + ]) + + def test_specific_type_order(self): + result = self._callFUT( + ['text/html', 'application/json', 'text/html;charset=utf8', 'text/plain'], + ['application/json', 'text/html'], + ) + self.assertEqual(result, [ + 'application/json', 'text/html;charset=utf8', 'text/html', 'text/plain', + ]) + + def test_params_order(self): + result = self._callFUT( + ['text/html;charset=utf8', 'text/html;charset=latin1', 'text/html;foo=bar'], + ['text/html;charset=latin1', 'text/html;charset=utf8'], + ) + self.assertEqual(result, [ + 'text/html;charset=latin1', 'text/html;charset=utf8', 'text/html;foo=bar', + ]) + + def test_params_inherit_type_prefs(self): + result = self._callFUT( + ['text/html;charset=utf8', 'text/plain;charset=latin1'], + ['text/plain', 'text/html'], + ) + self.assertEqual(result, ['text/plain;charset=latin1', 'text/html;charset=utf8']) + +class DummyCustomPredicate(object): + def __init__(self): + self.__text__ = 'custom predicate' + + def classmethod_predicate(*args): pass + classmethod_predicate.__text__ = 'classmethod predicate' + classmethod_predicate = classmethod(classmethod_predicate) + + @classmethod + def classmethod_predicate_no_text(*args): pass # pragma: no cover + +class Dummy(object): + def __init__(self, **kw): + self.__dict__.update(**kw) + +class DummyRequest: + subpath = () + matchdict = None + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + self.params = {} + self.cookies = {} + +class DummyConfigurator(object): + def maybe_dotted(self, thing): + return thing diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py new file mode 100644 index 000000000..6565a35d5 --- /dev/null +++ b/tests/test_config/test_views.py @@ -0,0 +1,3632 @@ +import os +import unittest +from pyramid import testing + +from pyramid.tests.test_config import IDummy + +from pyramid.tests.test_config import dummy_view + +from pyramid.compat import ( + im_func, + text_, + ) +from pyramid.exceptions import ConfigurationError +from pyramid.exceptions import ConfigurationExecutionError +from pyramid.exceptions import ConfigurationConflictError + +class TestViewsConfigurationMixin(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + config.set_default_csrf_options(require_csrf=False) + return config + + def _getViewCallable(self, config, ctx_iface=None, exc_iface=None, + request_iface=None, name=''): + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + if exc_iface: + classifier = IExceptionViewClassifier + ctx_iface = exc_iface + else: + classifier = IViewClassifier + if ctx_iface is None: + ctx_iface = Interface + if request_iface is None: + request_iface = IRequest + return config.registry.adapters.lookup( + (classifier, request_iface, ctx_iface), IView, name=name, + default=None) + + def _registerRenderer(self, config, name='.txt'): + from pyramid.interfaces import IRendererFactory + class Renderer: + def __init__(self, info): + self.__class__.info = info + def __call__(self, *arg): + return b'Hello!' + config.registry.registerUtility(Renderer, IRendererFactory, name=name) + return Renderer + + def _makeRequest(self, config): + request = DummyRequest() + request.registry = config.registry + return request + + def _assertNotFound(self, wrapper, *arg): + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, wrapper, *arg) + + def _getRouteRequestIface(self, config, name): + from pyramid.interfaces import IRouteRequest + iface = config.registry.getUtility(IRouteRequest, name) + return iface + + def _assertRoute(self, config, name, path, num_predicates=0): + from pyramid.interfaces import IRoutesMapper + mapper = config.registry.getUtility(IRoutesMapper) + routes = mapper.get_routes() + route = routes[0] + self.assertEqual(len(routes), 1) + self.assertEqual(route.name, name) + self.assertEqual(route.path, path) + self.assertEqual(len(routes[0].predicates), num_predicates) + return route + + def test_add_view_view_callable_None_no_renderer(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, config.add_view) + + def test_add_view_with_request_type_and_route_name(self): + config = self._makeOne(autocommit=True) + view = lambda *arg: 'OK' + self.assertRaises(ConfigurationError, config.add_view, view, '', None, + None, True, True) + + def test_add_view_with_request_type(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + from pyramid.interfaces import IRequest + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, + request_type='pyramid.interfaces.IRequest', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = DummyRequest() + self._assertNotFound(wrapper, None, request) + directlyProvides(request, IRequest) + result = wrapper(None, request) + self.assertEqual(result, 'OK') + + def test_add_view_view_callable_None_with_renderer(self): + config = self._makeOne(autocommit=True) + self._registerRenderer(config, name='dummy') + config.add_view(renderer='dummy') + view = self._getViewCallable(config) + self.assertTrue(b'Hello!' in view(None, None).body) + + def test_add_view_with_tmpl_renderer_factory_introspector_missing(self): + config = self._makeOne(autocommit=True) + config.introspection = False + config.introspector = None + config.add_view(renderer='dummy.pt') + view = self._getViewCallable(config) + self.assertRaises(ValueError, view, None, None) + + def test_add_view_with_tmpl_renderer_factory_no_renderer_factory(self): + config = self._makeOne(autocommit=True) + introspector = DummyIntrospector() + config.introspector = introspector + config.add_view(renderer='dummy.pt') + self.assertFalse(('renderer factories', '.pt') in + introspector.related[-1]) + view = self._getViewCallable(config) + self.assertRaises(ValueError, view, None, None) + + def test_add_view_with_tmpl_renderer_factory_with_renderer_factory(self): + config = self._makeOne(autocommit=True) + introspector = DummyIntrospector(True) + config.introspector = introspector + def dummy_factory(helper): + return lambda val, system_vals: 'Hello!' + config.add_renderer('.pt', dummy_factory) + config.add_view(renderer='dummy.pt') + self.assertTrue( + ('renderer factories', '.pt') in introspector.related[-1]) + view = self._getViewCallable(config) + self.assertTrue(b'Hello!' in view(None, None).body) + + def test_add_view_wrapped_view_is_decorated(self): + def view(request): # request-only wrapper + """ """ + config = self._makeOne(autocommit=True) + config.add_view(view=view) + wrapper = self._getViewCallable(config) + self.assertEqual(wrapper.__module__, view.__module__) + self.assertEqual(wrapper.__name__, view.__name__) + self.assertEqual(wrapper.__doc__, view.__doc__) + self.assertEqual(wrapper.__discriminator__(None, None).resolve()[0], + 'view') + + def test_add_view_view_callable_dottedname(self): + from pyramid.renderers import null_renderer + config = self._makeOne(autocommit=True) + config.add_view(view='pyramid.tests.test_config.dummy_view', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_with_function_callable(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_with_function_callable_requestonly(self): + from pyramid.renderers import null_renderer + def view(request): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_with_name(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, name='abc', renderer=null_renderer) + wrapper = self._getViewCallable(config, name='abc') + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_with_name_unicode(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + name = text_(b'La Pe\xc3\xb1a', 'utf-8') + config.add_view(view=view, name=name, renderer=null_renderer) + wrapper = self._getViewCallable(config, name=name) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_with_decorator(self): + from pyramid.renderers import null_renderer + def view(request): + """ ABC """ + return 'OK' + def view_wrapper(fn): + def inner(context, request): + return fn(context, request) + return inner + config = self._makeOne(autocommit=True) + config.add_view(view=view, decorator=view_wrapper, + renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertFalse(wrapper is view) + self.assertEqual(wrapper.__doc__, view.__doc__) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_with_decorator_tuple(self): + from pyramid.renderers import null_renderer + def view(request): + """ ABC """ + return 'OK' + def view_wrapper1(fn): + def inner(context, request): + return 'wrapped1' + fn(context, request) + return inner + def view_wrapper2(fn): + def inner(context, request): + return 'wrapped2' + fn(context, request) + return inner + config = self._makeOne(autocommit=True) + config.add_view(view=view, decorator=(view_wrapper2, view_wrapper1), + renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertFalse(wrapper is view) + self.assertEqual(wrapper.__doc__, view.__doc__) + result = wrapper(None, None) + self.assertEqual(result, 'wrapped2wrapped1OK') + + def test_add_view_with_http_cache(self): + import datetime + from pyramid.response import Response + response = Response('OK') + def view(request): + """ ABC """ + return response + config = self._makeOne(autocommit=True) + config.add_view(view=view, http_cache=(86400, {'public':True})) + wrapper = self._getViewCallable(config) + self.assertFalse(wrapper is view) + self.assertEqual(wrapper.__doc__, view.__doc__) + request = testing.DummyRequest() + when = datetime.datetime.utcnow() + datetime.timedelta(days=1) + result = wrapper(None, request) + self.assertEqual(result, response) + headers = dict(response.headerlist) + self.assertEqual(headers['Cache-Control'], 'max-age=86400, public') + expires = parse_httpdate(headers['Expires']) + assert_similar_datetime(expires, when) + + def test_add_view_as_instance(self): + from pyramid.renderers import null_renderer + class AView: + def __call__(self, context, request): + """ """ + return 'OK' + view = AView() + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_as_instancemethod(self): + from pyramid.renderers import null_renderer + class View: + def index(self, context, request): + return 'OK' + view = View() + config=self._makeOne(autocommit=True) + config.add_view(view=view.index, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_as_instancemethod_requestonly(self): + from pyramid.renderers import null_renderer + class View: + def index(self, request): + return 'OK' + view = View() + config=self._makeOne(autocommit=True) + config.add_view(view=view.index, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_as_instance_requestonly(self): + from pyramid.renderers import null_renderer + class AView: + def __call__(self, request): + """ """ + return 'OK' + view = AView() + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + result = wrapper(None, None) + self.assertEqual(result, 'OK') + + def test_add_view_as_oldstyle_class(self): + from pyramid.renderers import null_renderer + class view: + def __init__(self, context, request): + self.context = context + self.request = request + + def __call__(self): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result, 'OK') + self.assertEqual(request.__view__.__class__, view) + + def test_add_view_as_oldstyle_class_requestonly(self): + from pyramid.renderers import null_renderer + class view: + def __init__(self, request): + self.request = request + + def __call__(self): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result, 'OK') + self.assertEqual(request.__view__.__class__, view) + + def test_add_view_context_as_class(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + view = lambda *arg: 'OK' + class Foo: + pass + config = self._makeOne(autocommit=True) + config.add_view(context=Foo, view=view, renderer=null_renderer) + foo = implementedBy(Foo) + wrapper = self._getViewCallable(config, foo) + self.assertEqual(wrapper, view) + + def test_add_view_context_as_iface(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(context=IDummy, view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config, IDummy) + self.assertEqual(wrapper, view) + + def test_add_view_context_as_dottedname(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(context='pyramid.tests.test_config.IDummy', + view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config, IDummy) + self.assertEqual(wrapper, view) + + def test_add_view_for__as_dottedname(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(for_='pyramid.tests.test_config.IDummy', + view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config, IDummy) + self.assertEqual(wrapper, view) + + def test_add_view_for_as_class(self): + # ``for_`` is older spelling for ``context`` + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + view = lambda *arg: 'OK' + class Foo: + pass + config = self._makeOne(autocommit=True) + config.add_view(for_=Foo, view=view, renderer=null_renderer) + foo = implementedBy(Foo) + wrapper = self._getViewCallable(config, foo) + self.assertEqual(wrapper, view) + + def test_add_view_for_as_iface(self): + # ``for_`` is older spelling for ``context`` + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(for_=IDummy, view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config, IDummy) + self.assertEqual(wrapper, view) + + def test_add_view_context_trumps_for(self): + # ``for_`` is older spelling for ``context`` + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + class Foo: + pass + config.add_view(context=IDummy, for_=Foo, view=view, + renderer=null_renderer) + wrapper = self._getViewCallable(config, IDummy) + self.assertEqual(wrapper, view) + + def test_add_view_register_secured_view(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import ISecuredView + from pyramid.interfaces import IViewClassifier + view = lambda *arg: 'OK' + view.__call_permissive__ = view + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + wrapper = config.registry.adapters.lookup( + (IViewClassifier, IRequest, Interface), + ISecuredView, name='', default=None) + self.assertEqual(wrapper, view) + + def test_add_view_exception_register_secured_view(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IExceptionViewClassifier + view = lambda *arg: 'OK' + view.__call_permissive__ = view + config = self._makeOne(autocommit=True) + config.add_view(view=view, context=RuntimeError, renderer=null_renderer) + wrapper = config.registry.adapters.lookup( + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='', default=None) + self.assertEqual(wrapper, view) + + def test_add_view_same_phash_overrides_existing_single_view(self): + from pyramid.renderers import null_renderer + from hashlib import md5 + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + phash = md5() + phash.update(b'xhr = True') + view = lambda *arg: 'NOT OK' + view.__phash__ = phash.hexdigest() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, xhr=True, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_exc_same_phash_overrides_existing_single_view(self): + from pyramid.renderers import null_renderer + from hashlib import md5 + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IMultiView + phash = md5() + phash.update(b'xhr = True') + view = lambda *arg: 'NOT OK' + view.__phash__ = phash.hexdigest() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, xhr=True, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_default_phash_overrides_no_phash(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'NOT OK' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_exc_default_phash_overrides_no_phash(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'NOT OK' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_default_phash_overrides_default_phash(self): + from pyramid.config.util import DEFAULT_PHASH + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'NOT OK' + view.__phash__ = DEFAULT_PHASH + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_exc_default_phash_overrides_default_phash(self): + from pyramid.config.util import DEFAULT_PHASH + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'NOT OK' + view.__phash__ = DEFAULT_PHASH + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + def newview(context, request): + return 'OK' + config.add_view(view=newview, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertFalse(IMultiView.providedBy(wrapper)) + request = DummyRequest() + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_multiview_replaces_existing_view(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'OK' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_exc_multiview_replaces_existing_view(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'OK' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.add_view(view=view, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_multiview_replaces_existing_securedview(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import ISecuredView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + view = lambda *arg: 'OK' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), + ISecuredView, name='') + config.add_view(view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_exc_multiview_replaces_existing_securedview(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import ISecuredView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + view = lambda *arg: 'OK' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + ISecuredView, name='') + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + ISecuredView, name='') + config.add_view(view=view, context=RuntimeError, renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_with_accept_multiview_replaces_existing_view(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + def view(context, request): + return 'OK' + def view2(context, request): + return 'OK2' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + config.add_view(view=view2, accept='text/html', renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(len(wrapper.views), 1) + self.assertEqual(len(wrapper.media_views), 1) + self.assertEqual(wrapper(None, None), 'OK') + request = DummyRequest() + request.accept = DummyAccept('text/html', 'text/html') + self.assertEqual(wrapper(None, request), 'OK2') + + def test_add_view_mixed_case_replaces_existing_view(self): + from pyramid.renderers import null_renderer + def view(context, request): return 'OK' + def view2(context, request): return 'OK2' + def view3(context, request): return 'OK3' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + config.add_view(view=view2, accept='text/html', renderer=null_renderer) + config.add_view(view=view3, accept='text/HTML', renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(len(wrapper.media_views.items()),1) + self.assertFalse('text/HTML' in wrapper.media_views) + self.assertEqual(wrapper(None, None), 'OK') + request = DummyRequest() + request.accept = DummyAccept('text/html', 'text/html') + self.assertEqual(wrapper(None, request), 'OK3') + + def test_add_views_with_accept_multiview_replaces_existing(self): + from pyramid.renderers import null_renderer + def view(context, request): return 'OK' + def view2(context, request): return 'OK2' + def view3(context, request): return 'OK3' + config = self._makeOne(autocommit=True) + config.add_view(view=view, renderer=null_renderer) + config.add_view(view=view2, accept='text/html', renderer=null_renderer) + config.add_view(view=view3, accept='text/html', renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertEqual(len(wrapper.media_views['text/html']), 1) + self.assertEqual(wrapper(None, None), 'OK') + request = DummyRequest() + request.accept = DummyAccept('text/html', 'text/html') + self.assertEqual(wrapper(None, request), 'OK3') + + def test_add_view_exc_with_accept_multiview_replaces_existing_view(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + def view(context, request): + return 'OK' + def view2(context, request): + return 'OK2' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.add_view(view=view2, accept='text/html', context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(len(wrapper.views), 1) + self.assertEqual(len(wrapper.media_views), 1) + self.assertEqual(wrapper(None, None), 'OK') + request = DummyRequest() + request.accept = DummyAccept('text/html', 'text/html') + self.assertEqual(wrapper(None, request), 'OK2') + + def test_add_view_multiview_replaces_existing_view_with___accept__(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + def view(context, request): + return 'OK' + def view2(context, request): + return 'OK2' + view.__accept__ = 'text/html' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + config.add_view(view=view2, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(len(wrapper.views), 1) + self.assertEqual(len(wrapper.media_views), 1) + self.assertEqual(wrapper(None, None), 'OK2') + request = DummyRequest() + request.accept = DummyAccept('text/html') + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_exc_mulview_replaces_existing_view_with___accept__(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + def view(context, request): + return 'OK' + def view2(context, request): + return 'OK2' + view.__accept__ = 'text/html' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.registry.registerAdapter( + view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IView, name='') + config.add_view(view=view2, context=RuntimeError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual(len(wrapper.views), 1) + self.assertEqual(len(wrapper.media_views), 1) + self.assertEqual(wrapper(None, None), 'OK2') + request = DummyRequest() + request.accept = DummyAccept('text/html') + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_multiview_replaces_multiview(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + view = DummyMultiView() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), + IMultiView, name='') + view2 = lambda *arg: 'OK2' + config.add_view(view=view2, renderer=null_renderer) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + self.assertEqual([(x[0], x[2]) for x in wrapper.views], [(view2, None)]) + self.assertEqual(wrapper(None, None), 'OK1') + + def test_add_view_exc_multiview_replaces_multiviews(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + hot_view = DummyMultiView() + exc_view = DummyMultiView() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + hot_view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + config.registry.registerAdapter( + exc_view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + view2 = lambda *arg: 'OK2' + config.add_view(view=view2, context=RuntimeError, + renderer=null_renderer) + hot_wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(hot_wrapper)) + self.assertEqual([(x[0], x[2]) for x in hot_wrapper.views], [(view2, None)]) + self.assertEqual(hot_wrapper(None, None), 'OK1') + + exc_wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(exc_wrapper)) + self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)]) + self.assertEqual(exc_wrapper(None, None), 'OK1') + + def test_add_view_exc_multiview_replaces_only_exc_multiview(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + hot_view = DummyMultiView() + exc_view = DummyMultiView() + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + hot_view, + (IViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + config.registry.registerAdapter( + exc_view, + (IExceptionViewClassifier, IRequest, implementedBy(RuntimeError)), + IMultiView, name='') + view2 = lambda *arg: 'OK2' + config.add_view(view=view2, context=RuntimeError, exception_only=True, + renderer=null_renderer) + hot_wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(hot_wrapper)) + self.assertEqual(len(hot_wrapper.views), 0) + self.assertEqual(hot_wrapper(None, None), 'OK1') + + exc_wrapper = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError)) + self.assertTrue(IMultiView.providedBy(exc_wrapper)) + self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)]) + self.assertEqual(exc_wrapper(None, None), 'OK1') + + def test_add_view_multiview_context_superclass_then_subclass(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + class ISuper(Interface): + pass + class ISub(ISuper): + pass + view = lambda *arg: 'OK' + view2 = lambda *arg: 'OK2' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, ISuper), IView, name='') + config.add_view(view=view2, for_=ISub, renderer=null_renderer) + wrapper = self._getViewCallable(config, ctx_iface=ISuper, + request_iface=IRequest) + self.assertFalse(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK') + wrapper = self._getViewCallable(config, ctx_iface=ISub, + request_iface=IRequest) + self.assertFalse(IMultiView.providedBy(wrapper)) + self.assertEqual(wrapper(None, None), 'OK2') + + def test_add_view_multiview_exception_superclass_then_subclass(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + class Super(Exception): + pass + class Sub(Super): + pass + view = lambda *arg: 'OK' + view2 = lambda *arg: 'OK2' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Super), IView, name='') + config.registry.registerAdapter( + view, (IExceptionViewClassifier, IRequest, Super), IView, name='') + config.add_view(view=view2, for_=Sub, renderer=null_renderer) + wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(Super), request_iface=IRequest) + wrapper_exc_view = self._getViewCallable( + config, exc_iface=implementedBy(Super), request_iface=IRequest) + self.assertEqual(wrapper_exc_view, wrapper) + self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) + self.assertEqual(wrapper_exc_view(None, None), 'OK') + wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(Sub), request_iface=IRequest) + wrapper_exc_view = self._getViewCallable( + config, exc_iface=implementedBy(Sub), request_iface=IRequest) + self.assertEqual(wrapper_exc_view, wrapper) + self.assertFalse(IMultiView.providedBy(wrapper_exc_view)) + self.assertEqual(wrapper_exc_view(None, None), 'OK2') + + def test_add_view_multiview_call_ordering(self): + from pyramid.renderers import null_renderer as nr + from zope.interface import directlyProvides + def view1(context, request): return 'view1' + def view2(context, request): return 'view2' + def view3(context, request): return 'view3' + def view4(context, request): return 'view4' + def view5(context, request): return 'view5' + def view6(context, request): return 'view6' + def view7(context, request): return 'view7' + def view8(context, request): return 'view8' + config = self._makeOne(autocommit=True) + config.add_view(view=view1, renderer=nr) + config.add_view(view=view2, request_method='POST', renderer=nr) + config.add_view(view=view3,request_param='param', renderer=nr) + config.add_view(view=view4, containment=IDummy, renderer=nr) + config.add_view(view=view5, request_method='POST', + request_param='param', renderer=nr) + config.add_view(view=view6, request_method='POST', containment=IDummy, + renderer=nr) + config.add_view(view=view7, request_param='param', containment=IDummy, + renderer=nr) + config.add_view(view=view8, request_method='POST',request_param='param', + containment=IDummy, renderer=nr) + + + wrapper = self._getViewCallable(config) + + ctx = DummyContext() + request = self._makeRequest(config) + request.method = 'GET' + request.params = {} + self.assertEqual(wrapper(ctx, request), 'view1') + + ctx = DummyContext() + request = self._makeRequest(config) + request.params = {} + request.method = 'POST' + self.assertEqual(wrapper(ctx, request), 'view2') + + ctx = DummyContext() + request = self._makeRequest(config) + request.params = {'param':'1'} + request.method = 'GET' + self.assertEqual(wrapper(ctx, request), 'view3') + + ctx = DummyContext() + directlyProvides(ctx, IDummy) + request = self._makeRequest(config) + request.method = 'GET' + request.params = {} + self.assertEqual(wrapper(ctx, request), 'view4') + + ctx = DummyContext() + request = self._makeRequest(config) + request.method = 'POST' + request.params = {'param':'1'} + self.assertEqual(wrapper(ctx, request), 'view5') + + ctx = DummyContext() + directlyProvides(ctx, IDummy) + request = self._makeRequest(config) + request.params = {} + request.method = 'POST' + self.assertEqual(wrapper(ctx, request), 'view6') + + ctx = DummyContext() + directlyProvides(ctx, IDummy) + request = self._makeRequest(config) + request.method = 'GET' + request.params = {'param':'1'} + self.assertEqual(wrapper(ctx, request), 'view7') + + ctx = DummyContext() + directlyProvides(ctx, IDummy) + request = self._makeRequest(config) + request.method = 'POST' + request.params = {'param':'1'} + self.assertEqual(wrapper(ctx, request), 'view8') + + def test_view_with_most_specific_predicate(self): + from pyramid.renderers import null_renderer as nr + from pyramid.router import Router + + class OtherBase(object): pass + class Int1(object): pass + class Int2(object): pass + + class Resource(OtherBase, Int1, Int2): + def __init__(self, request): pass + + def unknown(context, request): return 'unknown' + def view(context, request): return 'hello' + + config = self._makeOne(autocommit=True) + config.add_route('root', '/', factory=Resource) + config.add_view(unknown, route_name='root', renderer=nr) + config.add_view( + view, renderer=nr, route_name='root', + context=Int1, request_method='GET' + ) + config.add_view( + view=view, renderer=nr, route_name='root', + context=Int2, request_method='POST' + ) + request = self._makeRequest(config) + request.method = 'POST' + request.params = {} + router = Router(config.registry) + response = router.handle_request(request) + self.assertEqual(response, 'hello') + + def test_view_with_most_specific_predicate_with_mismatch(self): + from pyramid.renderers import null_renderer as nr + from pyramid.router import Router + + class OtherBase(object): pass + class Int1(object): pass + class Int2(object): pass + + class Resource(OtherBase, Int1, Int2): + def __init__(self, request): pass + + def unknown(context, request): return 'unknown' + def view(context, request): return 'hello' + + config = self._makeOne(autocommit=True) + config.add_route('root', '/', factory=Resource) + + config.add_view( + unknown, + route_name='root', + renderer=nr, + request_method=('POST',), + xhr=True, + ) + + config.add_view( + view, renderer=nr, route_name='root', + context=Int1, request_method='GET' + ) + config.add_view( + view=view, renderer=nr, route_name='root', + context=Int2, request_method='POST' + ) + request = self._makeRequest(config) + request.method = 'POST' + request.params = {} + router = Router(config.registry) + response = router.handle_request(request) + self.assertEqual(response, 'hello') + + def test_add_view_multiview___discriminator__(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + class IFoo(Interface): + pass + class IBar(Interface): + pass + @implementer(IFoo) + class Foo(object): + pass + @implementer(IBar) + class Bar(object): + pass + foo = Foo() + bar = Bar() + + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + view = lambda *arg: 'OK' + view.__phash__ = 'abc' + config = self._makeOne(autocommit=True) + config.registry.registerAdapter( + view, (IViewClassifier, IRequest, Interface), IView, name='') + config.add_view(view=view, renderer=null_renderer, + containment=IFoo) + config.add_view(view=view, renderer=null_renderer, + containment=IBar) + wrapper = self._getViewCallable(config) + self.assertTrue(IMultiView.providedBy(wrapper)) + request = self._makeRequest(config) + self.assertNotEqual( + wrapper.__discriminator__(foo, request), + wrapper.__discriminator__(bar, request), + ) + + def test_add_view_with_template_renderer(self): + from pyramid.tests import test_config + from pyramid.interfaces import ISettings + class view(object): + def __init__(self, context, request): + self.request = request + self.context = context + + def __call__(self): + return {'a':'1'} + config = self._makeOne(autocommit=True) + renderer = self._registerRenderer(config) + fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False + config.add_view(view=view, renderer=fixture) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result.body, b'Hello!') + settings = config.registry.queryUtility(ISettings) + result = renderer.info + self.assertEqual(result.registry, config.registry) + self.assertEqual(result.type, '.txt') + self.assertEqual(result.package, test_config) + self.assertEqual(result.name, fixture) + self.assertEqual(result.settings, settings) + + def test_add_view_with_default_renderer(self): + class view(object): + def __init__(self, context, request): + self.request = request + self.context = context + + def __call__(self): + return {'a':'1'} + config = self._makeOne(autocommit=True) + class moo(object): + def __init__(self, *arg, **kw): + pass + def __call__(self, *arg, **kw): + return b'moo' + config.add_renderer(None, moo) + config.add_view(view=view) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result.body, b'moo') + + def test_add_view_with_template_renderer_no_callable(self): + from pyramid.tests import test_config + from pyramid.interfaces import ISettings + config = self._makeOne(autocommit=True) + renderer = self._registerRenderer(config) + fixture = 'pyramid.tests.test_config:files/minimal.txt' + config.introspection = False + config.add_view(view=None, renderer=fixture) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + result = wrapper(None, request) + self.assertEqual(result.body, b'Hello!') + settings = config.registry.queryUtility(ISettings) + result = renderer.info + self.assertEqual(result.registry, config.registry) + self.assertEqual(result.type, '.txt') + self.assertEqual(result.package, test_config) + self.assertEqual(result.name, fixture) + self.assertEqual(result.settings, settings) + + def test_add_view_with_request_type_as_iface(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + def view(context, request): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(request_type=IDummy, view=view, renderer=null_renderer) + wrapper = self._getViewCallable(config, None) + request = self._makeRequest(config) + directlyProvides(request, IDummy) + result = wrapper(None, request) + self.assertEqual(result, 'OK') + + def test_add_view_with_request_type_as_noniface(self): + view = lambda *arg: 'OK' + config = self._makeOne() + self.assertRaises(ConfigurationError, + config.add_view, view, '', None, None, object) + + def test_add_view_with_route_name(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view(view=view, route_name='foo', renderer=null_renderer) + request_iface = self._getRouteRequestIface(config, 'foo') + self.assertNotEqual(request_iface, None) + wrapper = self._getViewCallable(config, request_iface=request_iface) + self.assertNotEqual(wrapper, None) + self.assertEqual(wrapper(None, None), 'OK') + + def test_add_view_with_nonexistant_route_name(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne() + config.add_view(view=view, route_name='foo', renderer=null_renderer) + self.assertRaises(ConfigurationExecutionError, config.commit) + + def test_add_view_with_route_name_exception(self): + from pyramid.renderers import null_renderer + from zope.interface import implementedBy + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view(view=view, route_name='foo', context=RuntimeError, + renderer=null_renderer) + request_iface = self._getRouteRequestIface(config, 'foo') + wrapper_exc_view = self._getViewCallable( + config, exc_iface=implementedBy(RuntimeError), + request_iface=request_iface) + self.assertNotEqual(wrapper_exc_view, None) + wrapper = self._getViewCallable( + config, ctx_iface=implementedBy(RuntimeError), + request_iface=request_iface) + self.assertEqual(wrapper_exc_view, wrapper) + self.assertEqual(wrapper_exc_view(None, None), 'OK') + + def test_add_view_with_request_method_true(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method='POST', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'POST' + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_request_method_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method='POST') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'GET' + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_request_method_sequence_true(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method=('POST', 'GET'), + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'POST' + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_request_method_sequence_conflict(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne() + config.add_view(view=view, request_method=('POST', 'GET'), + renderer=null_renderer) + config.add_view(view=view, request_method=('GET', 'POST'), + renderer=null_renderer) + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_view_with_request_method_sequence_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method=('POST', 'HEAD')) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'GET' + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_request_method_get_implies_head(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method='GET', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'HEAD' + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_request_param_noval_true(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_param='abc', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.params = {'abc':''} + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_request_param_noval_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_param='abc') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.params = {} + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_request_param_val_true(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_param='abc=123', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.params = {'abc':'123'} + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_request_param_val_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_param='abc=123') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.params = {'abc':''} + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_xhr_true(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, xhr=True, renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_xhr_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, xhr=True) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.is_xhr = False + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_header_badregex(self): + view = lambda *arg: 'OK' + config = self._makeOne() + config.add_view(view, header='Host:a\\') + self.assertRaises(ConfigurationError, config.commit) + + def test_add_view_with_header_noval_match(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, header='Host', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.headers = {'Host':'whatever'} + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_header_noval_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, header='Host') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.headers = {'NotHost':'whatever'} + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_header_val_match(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, header=r'Host:\d', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.headers = {'Host':'1'} + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_header_val_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, header=r'Host:\d') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.headers = {'Host':'abc'} + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_header_val_missing(self): + from pyramid.httpexceptions import HTTPNotFound + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, header=r'Host:\d') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.headers = {'NoHost':'1'} + self.assertRaises(HTTPNotFound, wrapper, None, request) + + def test_add_view_with_accept_match(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, accept='text/xml', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.accept = DummyAccept('text/xml') + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_accept_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, accept='text/xml') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.accept = DummyAccept('text/html') + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_range_accept_match(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, accept='text/*', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.accept = DummyAccept('text/html', contains=True) + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_range_accept_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, accept='text/*') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.accept = DummyAccept('application/json', contains=False) + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_containment_true(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, containment=IDummy, renderer=null_renderer) + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + self.assertEqual(wrapper(context, None), 'OK') + + def test_add_view_with_containment_false(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, containment=IDummy) + wrapper = self._getViewCallable(config) + context = DummyContext() + self._assertNotFound(wrapper, context, None) + + def test_add_view_with_containment_dottedname(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view( + view=view, + containment='pyramid.tests.test_config.IDummy', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + self.assertEqual(wrapper(context, None), 'OK') + + def test_add_view_with_path_info_badregex(self): + view = lambda *arg: 'OK' + config = self._makeOne() + config.add_view(view, path_info='\\') + self.assertRaises(ConfigurationError, config.commit) + + def test_add_view_with_path_info_match(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, path_info='/foo', renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.upath_info = text_(b'/foo') + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_path_info_nomatch(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, path_info='/foo') + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.upath_info = text_('/') + self._assertNotFound(wrapper, None, request) + + def test_add_view_with_check_csrf_predicates_match(self): + import warnings + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, check_csrf=True, renderer=null_renderer) + self.assertEqual(len(w), 1) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = "POST" + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'csrf_token': 'foo'} + request.headers = {} + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_custom_predicates_match(self): + import warnings + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + def pred1(context, request): + return True + def pred2(context, request): + return True + predicates = (pred1, pred2) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=predicates, + renderer=null_renderer) + self.assertEqual(len(w), 1) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_with_custom_predicates_nomatch(self): + import warnings + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + def pred1(context, request): + return True + def pred2(context, request): + return False + predicates = (pred1, pred2) + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=predicates) + self.assertEqual(len(w), 1) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + self._assertNotFound(wrapper, None, request) + + def test_add_view_custom_predicate_bests_standard_predicate(self): + import warnings + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + view2 = lambda *arg: 'NOT OK' + config = self._makeOne(autocommit=True) + def pred1(context, request): + return True + with warnings.catch_warnings(record=True) as w: + warnings.filterwarnings('always') + config.add_view(view=view, custom_predicates=(pred1,), + renderer=null_renderer) + config.add_view(view=view2, request_method='GET', + renderer=null_renderer) + self.assertEqual(len(w), 1) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'GET' + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_custom_more_preds_first_bests_fewer_preds_last(self): + from pyramid.renderers import null_renderer + view = lambda *arg: 'OK' + view2 = lambda *arg: 'NOT OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view, request_method='GET', xhr=True, + renderer=null_renderer) + config.add_view(view=view2, request_method='GET', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + request = self._makeRequest(config) + request.method = 'GET' + request.is_xhr = True + self.assertEqual(wrapper(None, request), 'OK') + + def test_add_view_same_predicates(self): + view2 = lambda *arg: 'second' + view1 = lambda *arg: 'first' + config = self._makeOne() + config.add_view(view=view1) + config.add_view(view=view2) + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_view_with_csrf_param(self): + from pyramid.renderers import null_renderer + def view(request): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view, require_csrf='st', renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + request.scheme = "http" + request.method = 'POST' + request.POST = {'st': 'foo'} + request.headers = {} + request.session = DummySession({'csrf_token': 'foo'}) + self.assertEqual(view(None, request), 'OK') + + def test_add_view_with_csrf_header(self): + from pyramid.renderers import null_renderer + def view(request): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view, require_csrf=True, renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + request.scheme = "http" + request.method = 'POST' + request.POST = {} + request.headers = {'X-CSRF-Token': 'foo'} + request.session = DummySession({'csrf_token': 'foo'}) + self.assertEqual(view(None, request), 'OK') + + def test_add_view_with_missing_csrf_header(self): + from pyramid.exceptions import BadCSRFToken + from pyramid.renderers import null_renderer + def view(request): return 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view, require_csrf=True, renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + request.scheme = "http" + request.method = 'POST' + request.POST = {} + request.headers = {} + request.session = DummySession({'csrf_token': 'foo'}) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_add_view_with_permission(self): + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + outerself = self + class DummyPolicy(object): + def effective_principals(self, r): + outerself.assertEqual(r, request) + return ['abc'] + def permits(self, context, principals, permission): + outerself.assertEqual(context, None) + outerself.assertEqual(principals, ['abc']) + outerself.assertEqual(permission, 'view') + return True + policy = DummyPolicy() + config = self._makeOne(authorization_policy=policy, + authentication_policy=policy, + autocommit=True) + config.add_view(view=view1, permission='view', renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(view(None, request), 'OK') + + def test_add_view_with_default_permission_no_explicit_permission(self): + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + outerself = self + class DummyPolicy(object): + def effective_principals(self, r): + outerself.assertEqual(r, request) + return ['abc'] + def permits(self, context, principals, permission): + outerself.assertEqual(context, None) + outerself.assertEqual(principals, ['abc']) + outerself.assertEqual(permission, 'view') + return True + policy = DummyPolicy() + config = self._makeOne(authorization_policy=policy, + authentication_policy=policy, + default_permission='view', + autocommit=True) + config.add_view(view=view1, renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(view(None, request), 'OK') + + def test_add_view_with_no_default_permission_no_explicit_permission(self): + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + class DummyPolicy(object): pass # wont be called + policy = DummyPolicy() + config = self._makeOne(authorization_policy=policy, + authentication_policy=policy, + autocommit=True) + config.add_view(view=view1, renderer=null_renderer) + view = self._getViewCallable(config) + request = self._makeRequest(config) + self.assertEqual(view(None, request), 'OK') + + def test_add_view_with_mapper(self): + from pyramid.renderers import null_renderer + class Mapper(object): + def __init__(self, **kw): + self.__class__.kw = kw + def __call__(self, view): + return view + config = self._makeOne(autocommit=True) + def view(context, request): return 'OK' + config.add_view(view=view, mapper=Mapper, renderer=null_renderer) + view = self._getViewCallable(config) + self.assertEqual(view(None, None), 'OK') + self.assertEqual(Mapper.kw['mapper'], Mapper) + + def test_add_view_with_view_defaults(self): + from pyramid.renderers import null_renderer + from pyramid.exceptions import PredicateMismatch + from zope.interface import directlyProvides + class view(object): + __view_defaults__ = { + 'containment':'pyramid.tests.test_config.IDummy' + } + def __init__(self, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_view( + view=view, + renderer=null_renderer) + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + context = DummyContext() + request = self._makeRequest(config) + self.assertRaises(PredicateMismatch, wrapper, context, request) + + def test_add_view_with_view_defaults_viewname_is_dottedname_kwarg(self): + from pyramid.renderers import null_renderer + from pyramid.exceptions import PredicateMismatch + from zope.interface import directlyProvides + config = self._makeOne(autocommit=True) + config.add_view( + view='pyramid.tests.test_config.test_views.DummyViewDefaultsClass', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + context = DummyContext() + request = self._makeRequest(config) + self.assertRaises(PredicateMismatch, wrapper, context, request) + + def test_add_view_with_view_defaults_viewname_is_dottedname_nonkwarg(self): + from pyramid.renderers import null_renderer + from pyramid.exceptions import PredicateMismatch + from zope.interface import directlyProvides + config = self._makeOne(autocommit=True) + config.add_view( + 'pyramid.tests.test_config.test_views.DummyViewDefaultsClass', + renderer=null_renderer) + wrapper = self._getViewCallable(config) + context = DummyContext() + directlyProvides(context, IDummy) + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + context = DummyContext() + request = self._makeRequest(config) + self.assertRaises(PredicateMismatch, wrapper, context, request) + + def test_add_view_with_view_config_and_view_defaults_doesnt_conflict(self): + from pyramid.renderers import null_renderer + class view(object): + __view_defaults__ = { + 'containment':'pyramid.tests.test_config.IDummy' + } + class view2(object): + __view_defaults__ = { + 'containment':'pyramid.tests.test_config.IFactory' + } + config = self._makeOne(autocommit=False) + config.add_view( + view=view, + renderer=null_renderer) + config.add_view( + view=view2, + renderer=null_renderer) + config.commit() # does not raise + + def test_add_view_with_view_config_and_view_defaults_conflicts(self): + from pyramid.renderers import null_renderer + class view(object): + __view_defaults__ = { + 'containment':'pyramid.tests.test_config.IDummy' + } + class view2(object): + __view_defaults__ = { + 'containment':'pyramid.tests.test_config.IDummy' + } + config = self._makeOne(autocommit=False) + config.add_view( + view=view, + renderer=null_renderer) + config.add_view( + view=view2, + renderer=null_renderer) + self.assertRaises(ConfigurationConflictError, config.commit) + + def test_add_view_class_method_no_attr(self): + from pyramid.renderers import null_renderer + from zope.interface import directlyProvides + from pyramid.exceptions import ConfigurationError + + config = self._makeOne(autocommit=True) + class DummyViewClass(object): + def run(self): pass + + def configure_view(): + config.add_view(view=DummyViewClass.run, renderer=null_renderer) + + self.assertRaises(ConfigurationError, configure_view) + + def test_add_view_exception_only_no_regular_view(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view1, context=Exception, exception_only=True, + renderer=null_renderer) + view = self._getViewCallable(config, ctx_iface=implementedBy(Exception)) + self.assertTrue(view is None) + + def test_add_view_exception_only(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_view(view=view1, context=Exception, exception_only=True, + renderer=null_renderer) + view = self._getViewCallable( + config, exc_iface=implementedBy(Exception)) + self.assertEqual(view1, view) + + def test_add_view_exception_only_misconfiguration(self): + view = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + class NotAnException(object): + pass + self.assertRaises( + ConfigurationError, + config.add_view, view, context=NotAnException, exception_only=True) + + def test_add_exception_view(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_exception_view(view=view1, renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(Exception)) + context = Exception() + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + + def test_add_exception_view_with_subclass(self): + from zope.interface import implementedBy + from pyramid.renderers import null_renderer + view1 = lambda *arg: 'OK' + config = self._makeOne(autocommit=True) + config.add_exception_view(view=view1, context=ValueError, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(ValueError)) + context = ValueError() + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + + def test_add_exception_view_disallows_name(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, + config.add_exception_view, + context=Exception(), + name='foo') + + def test_add_exception_view_disallows_permission(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, + config.add_exception_view, + context=Exception(), + permission='foo') + + def test_add_exception_view_disallows_require_csrf(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, + config.add_exception_view, + context=Exception(), + require_csrf=True) + + def test_add_exception_view_disallows_for_(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, + config.add_exception_view, + context=Exception(), + for_='foo') + + def test_add_exception_view_disallows_exception_only(self): + config = self._makeOne(autocommit=True) + self.assertRaises(ConfigurationError, + config.add_exception_view, + context=Exception(), + exception_only=True) + + def test_add_exception_view_with_view_defaults(self): + from pyramid.renderers import null_renderer + from pyramid.exceptions import PredicateMismatch + from zope.interface import directlyProvides + from zope.interface import implementedBy + class view(object): + __view_defaults__ = { + 'containment': 'pyramid.tests.test_config.IDummy' + } + def __init__(self, request): + pass + def __call__(self): + return 'OK' + config = self._makeOne(autocommit=True) + config.add_exception_view( + view=view, + context=Exception, + renderer=null_renderer) + wrapper = self._getViewCallable( + config, exc_iface=implementedBy(Exception)) + context = DummyContext() + directlyProvides(context, IDummy) + request = self._makeRequest(config) + self.assertEqual(wrapper(context, request), 'OK') + context = DummyContext() + request = self._makeRequest(config) + self.assertRaises(PredicateMismatch, wrapper, context, request) + + def test_derive_view_function(self): + from pyramid.renderers import null_renderer + def view(request): + return 'OK' + config = self._makeOne() + result = config.derive_view(view, renderer=null_renderer) + self.assertFalse(result is view) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_dottedname(self): + from pyramid.renderers import null_renderer + config = self._makeOne() + result = config.derive_view( + 'pyramid.tests.test_config.dummy_view', + renderer=null_renderer) + self.assertFalse(result is dummy_view) + self.assertEqual(result(None, None), 'OK') + + def test_derive_view_with_default_renderer_no_explicit_renderer(self): + config = self._makeOne() + class moo(object): + def __init__(self, view): + pass + def __call__(self, *arg, **kw): + return 'moo' + config.add_renderer(None, moo) + config.commit() + def view(request): + return 'OK' + result = config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(result(None, None).body, b'moo') + + def test_derive_view_with_default_renderer_with_explicit_renderer(self): + class moo(object): pass + class foo(object): + def __init__(self, view): + pass + def __call__(self, *arg, **kw): + return b'foo' + def view(request): + return 'OK' + config = self._makeOne() + config.add_renderer(None, moo) + config.add_renderer('foo', foo) + config.commit() + result = config.derive_view(view, renderer='foo') + self.assertFalse(result is view) + request = self._makeRequest(config) + self.assertEqual(result(None, request).body, b'foo') + + def test_add_static_view_here_no_utility_registered(self): + from pyramid.renderers import null_renderer + from zope.interface import Interface + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + config = self._makeOne(autocommit=True) + config.add_static_view('static', 'files', renderer=null_renderer) + request_type = self._getRouteRequestIface(config, '__static/') + self._assertRoute(config, '__static/', 'static/*subpath') + wrapped = config.registry.adapters.lookup( + (IViewClassifier, request_type, Interface), IView, name='') + from pyramid.request import Request + request = Request.blank('/static/minimal.txt') + request.subpath = ('minimal.txt', ) + result = wrapped(None, request) + self.assertEqual(result.status, '200 OK') + self.assertTrue(result.body.startswith(b'' in body) + + def test__default_app_iter_with_comment_html(self): + cls = self._getTargetSubclass() + exc = cls(comment='comment & comment') + environ = _makeEnviron() + environ['HTTP_ACCEPT'] = 'text/html' + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + self.assertTrue(b'' in body) + + def test__default_app_iter_with_comment_json(self): + cls = self._getTargetSubclass() + exc = cls(comment='comment & comment') + environ = _makeEnviron() + environ['HTTP_ACCEPT'] = 'application/json' + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + import json + retval = json.loads(body.decode('UTF-8')) + self.assertEqual(retval['code'], '200 OK') + self.assertEqual(retval['title'], 'OK') + + def test__default_app_iter_with_custom_json(self): + def json_formatter(status, body, title, environ): + return {'message': body, + 'code': status, + 'title': title, + 'custom': environ['CUSTOM_VARIABLE'] + } + cls = self._getTargetSubclass() + exc = cls(comment='comment', json_formatter=json_formatter) + environ = _makeEnviron() + environ['HTTP_ACCEPT'] = 'application/json' + environ['CUSTOM_VARIABLE'] = 'custom!' + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + import json + retval = json.loads(body.decode('UTF-8')) + self.assertEqual(retval['code'], '200 OK') + self.assertEqual(retval['title'], 'OK') + self.assertEqual(retval['custom'], 'custom!') + + def test_custom_body_template(self): + cls = self._getTargetSubclass() + exc = cls(body_template='${REQUEST_METHOD}') + environ = _makeEnviron() + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + self.assertEqual(body, b'200 OK\n\nGET') + + def test_custom_body_template_with_custom_variable_doesnt_choke(self): + cls = self._getTargetSubclass() + exc = cls(body_template='${REQUEST_METHOD}') + environ = _makeEnviron() + class Choke(object): + def __str__(self): # pragma no cover + raise ValueError + environ['gardentheory.user'] = Choke() + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + self.assertEqual(body, b'200 OK\n\nGET') + + def test_body_template_unicode(self): + cls = self._getTargetSubclass() + la = text_(b'/La Pe\xc3\xb1a', 'utf-8') + environ = _makeEnviron(unicodeval=la) + exc = cls(body_template='${unicodeval}') + start_response = DummyStartResponse() + body = list(exc(environ, start_response))[0] + self.assertEqual(body, b'200 OK\n\n/La Pe\xc3\xb1a') + + def test_allow_detail_non_str(self): + exc = self._makeOne(detail={'error': 'This is a test'}) + self.assertIsInstance(exc.__str__(), string_types) + + +class TestRenderAllExceptionsWithoutArguments(unittest.TestCase): + def _doit(self, content_type): + from pyramid.httpexceptions import status_map + L = [] + self.assertTrue(status_map) + for v in status_map.values(): + environ = _makeEnviron() + start_response = DummyStartResponse() + exc = v() + exc.content_type = content_type + result = list(exc(environ, start_response))[0] + if exc.empty_body: + self.assertEqual(result, b'') + else: + self.assertTrue(bytes_(exc.status) in result) + L.append(result) + self.assertEqual(len(L), len(status_map)) + + def test_it_plain(self): + self._doit('text/plain') + + def test_it_html(self): + self._doit('text/html') + +class Test_HTTPMove(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.httpexceptions import _HTTPMove + return _HTTPMove(*arg, **kw) + + def test_it_location_none_valueerrors(self): + # Constructing a HTTPMove instance with location=None should + # throw a ValueError from __init__ so that a more-confusing + # exception won't be thrown later from .prepare(environ) + self.assertRaises(ValueError, self._makeOne, location=None) + + def test_it_location_not_passed(self): + exc = self._makeOne() + self.assertEqual(exc.location, '') + + def test_it_location_passed(self): + exc = self._makeOne(location='foo') + self.assertEqual(exc.location, 'foo') + + def test_it_location_firstarg(self): + exc = self._makeOne('foo') + self.assertEqual(exc.location, 'foo') + + def test_it_call_with_default_body_tmpl(self): + exc = self._makeOne(location='foo') + environ = _makeEnviron() + start_response = DummyStartResponse() + app_iter = exc(environ, start_response) + self.assertEqual(app_iter[0], + (b'520 Unknown Error\n\nThe resource has been moved to foo; ' + b'you should be redirected automatically.\n\n')) + +class TestHTTPForbidden(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.httpexceptions import HTTPForbidden + return HTTPForbidden(*arg, **kw) + + def test_it_result_not_passed(self): + exc = self._makeOne() + self.assertEqual(exc.result, None) + + def test_it_result_passed(self): + exc = self._makeOne(result='foo') + self.assertEqual(exc.result, 'foo') + +class TestHTTPMethodNotAllowed(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.httpexceptions import HTTPMethodNotAllowed + return HTTPMethodNotAllowed(*arg, **kw) + + def test_it_with_default_body_tmpl(self): + exc = self._makeOne() + environ = _makeEnviron() + start_response = DummyStartResponse() + app_iter = exc(environ, start_response) + self.assertEqual(app_iter[0], + (b'405 Method Not Allowed\n\nThe method GET is not ' + b'allowed for this resource. \n\n\n')) + + +class DummyRequest(object): + exception = None + +class DummyStartResponse(object): + def __call__(self, status, headerlist): + self.status = status + self.headerlist = headerlist + +def _makeEnviron(**kw): + environ = {'REQUEST_METHOD': 'GET', + 'wsgi.url_scheme': 'http', + 'SERVER_NAME': 'localhost', + 'SERVER_PORT': '80'} + environ.update(kw) + return environ diff --git a/tests/test_i18n.py b/tests/test_i18n.py new file mode 100644 index 000000000..d72d0d480 --- /dev/null +++ b/tests/test_i18n.py @@ -0,0 +1,508 @@ +# -*- coding: utf-8 -*- +# +import os + +here = os.path.dirname(__file__) +localedir = os.path.join(here, 'pkgs', 'localeapp', 'locale') + +import unittest +from pyramid import testing + +class TestTranslationString(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.i18n import TranslationString + return TranslationString(*arg, **kw) + + def test_it(self): + # this is part of the API, we don't actually need to test much more + # than that it's importable + ts = self._makeOne('a') + self.assertEqual(ts, 'a') + +class TestTranslationStringFactory(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.i18n import TranslationStringFactory + return TranslationStringFactory(*arg, **kw) + + def test_it(self): + # this is part of the API, we don't actually need to test much more + # than that it's importable + factory = self._makeOne('a') + self.assertEqual(factory('').domain, 'a') + +class TestLocalizer(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.i18n import Localizer + return Localizer(*arg, **kw) + + def test_ctor(self): + localizer = self._makeOne('en_US', None) + self.assertEqual(localizer.locale_name, 'en_US') + self.assertEqual(localizer.translations, None) + + def test_translate(self): + translations = DummyTranslations() + localizer = self._makeOne(None, translations) + self.assertEqual(localizer.translate('123', domain='1', + mapping={}), '123') + self.assertTrue(localizer.translator) + + def test_pluralize(self): + translations = DummyTranslations() + localizer = self._makeOne(None, translations) + result = localizer.pluralize('singular', 'plural', 1, + domain='1', mapping={}) + self.assertEqual(result, 'singular') + self.assertTrue(localizer.pluralizer) + + def test_pluralize_pluralizer_already_added(self): + translations = DummyTranslations() + localizer = self._makeOne(None, translations) + def pluralizer(*arg, **kw): + return arg, kw + localizer.pluralizer = pluralizer + result = localizer.pluralize('singular', 'plural', 1, domain='1', + mapping={}) + self.assertEqual( + result, + (('singular', 'plural', 1), {'domain': '1', 'mapping': {}}) + ) + self.assertTrue(localizer.pluralizer is pluralizer) + + def test_pluralize_default_translations(self): + # test that even without message ids loaded that + # "localizer.pluralize" "works" instead of raising an inscrutable + # "translations object has no attr 'plural' error; see + # see https://github.com/Pylons/pyramid/issues/235 + from pyramid.i18n import Translations + translations = Translations() + translations._catalog = {} + localizer = self._makeOne(None, translations) + result = localizer.pluralize('singular', 'plural', 2, domain='1', + mapping={}) + self.assertEqual(result, 'plural') + +class Test_negotiate_locale_name(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request): + from pyramid.i18n import negotiate_locale_name + return negotiate_locale_name(request) + + def _registerImpl(self, impl): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + from pyramid.interfaces import ILocaleNegotiator + registry.registerUtility(impl, ILocaleNegotiator) + + def test_no_registry_on_request(self): + self._registerImpl(dummy_negotiator) + request = DummyRequest() + result = self._callFUT(request) + self.assertEqual(result, 'bogus') + + def test_with_registry_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + self._registerImpl(dummy_negotiator) + request = DummyRequest() + request.registry = registry + result = self._callFUT(request) + self.assertEqual(result, 'bogus') + + def test_default_from_settings(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + settings = {'default_locale_name':'settings'} + registry.settings = settings + request = DummyRequest() + request.registry = registry + result = self._callFUT(request) + self.assertEqual(result, 'settings') + + def test_use_default_locale_negotiator(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = DummyRequest() + request.registry = registry + request._LOCALE_ = 'locale' + result = self._callFUT(request) + self.assertEqual(result, 'locale') + + def test_default_default(self): + request = DummyRequest() + result = self._callFUT(request) + self.assertEqual(result, 'en') + +class Test_get_locale_name(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request): + from pyramid.i18n import get_locale_name + return get_locale_name(request) + + def test_name_on_request(self): + request = DummyRequest() + request.locale_name = 'ie' + result = self._callFUT(request) + self.assertEqual(result, 'ie') + +class Test_make_localizer(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, locale, tdirs): + from pyramid.i18n import make_localizer + return make_localizer(locale, tdirs) + + def test_locale_from_mo(self): + from pyramid.i18n import Localizer + localedirs = [localedir] + locale_name = 'de' + result = self._callFUT(locale_name, localedirs) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Genehmigen') + self.assertEqual(result.translate('Approve'), 'Approve') + self.assertTrue(hasattr(result, 'pluralize')) + + def test_locale_from_mo_bad_mo(self): + from pyramid.i18n import Localizer + localedirs = [localedir] + locale_name = 'be' + result = self._callFUT(locale_name, localedirs) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Approve') + + def test_locale_from_mo_mo_isdir(self): + from pyramid.i18n import Localizer + localedirs = [localedir] + locale_name = 'gb' + result = self._callFUT(locale_name, localedirs) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Approve') + + def test_territory_fallback(self): + from pyramid.i18n import Localizer + localedirs = [localedir] + locale_name = 'de_DE' + result = self._callFUT(locale_name, localedirs) + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Submit', 'deformsite'), + 'different') # prefer translations from de_DE locale + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Genehmigen') # missing from de_DE locale, but in de + +class Test_get_localizer(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request): + from pyramid.i18n import get_localizer + return get_localizer(request) + + def test_it(self): + request = DummyRequest() + request.localizer = 'localizer' + self.assertEqual(self._callFUT(request), 'localizer') + +class Test_default_locale_negotiator(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request): + from pyramid.i18n import default_locale_negotiator + return default_locale_negotiator(request) + + def test_from_none(self): + request = DummyRequest() + result = self._callFUT(request) + self.assertEqual(result, None) + + def test_from_request_attr(self): + request = DummyRequest() + request._LOCALE_ = 'foo' + result = self._callFUT(request) + self.assertEqual(result, 'foo') + + def test_from_params(self): + request = DummyRequest() + request.params['_LOCALE_'] = 'foo' + result = self._callFUT(request) + self.assertEqual(result, 'foo') + + def test_from_cookies(self): + request = DummyRequest() + request.cookies['_LOCALE_'] = 'foo' + result = self._callFUT(request) + self.assertEqual(result, 'foo') + +class TestTranslations(unittest.TestCase): + def _getTargetClass(self): + from pyramid.i18n import Translations + return Translations + + def _makeOne(self): + messages1 = [ + ('foo', 'Voh'), + (('foo1', 1), 'Voh1'), + ] + messages2 = [ + ('foo', 'VohD'), + (('foo1', 1), 'VohD1'), + ] + + klass = self._getTargetClass() + + translations1 = klass(None, domain='messages') + translations1._catalog = dict(messages1) + translations1.plural = lambda *arg: 1 + translations2 = klass(None, domain='messages1') + translations2._catalog = dict(messages2) + translations2.plural = lambda *arg: 1 + translations = translations1.add(translations2, merge=False) + return translations + + def test_load_locales_None(self): + import gettext + klass = self._getTargetClass() + result = klass.load(localedir, None, domain=None) + self.assertEqual(result.__class__, gettext.NullTranslations) + + def test_load_domain_None(self): + import gettext + locales = ['de', 'en'] + klass = self._getTargetClass() + result = klass.load(localedir, locales, domain=None) + self.assertEqual(result.__class__, gettext.NullTranslations) + + def test_load_found_locale_and_domain(self): + locales = ['de', 'en'] + klass = self._getTargetClass() + result = klass.load(localedir, locales, domain='deformsite') + self.assertEqual(result.__class__, klass) + + def test_load_found_locale_and_domain_locale_is_string(self): + locales = 'de' + klass = self._getTargetClass() + result = klass.load(localedir, locales, domain='deformsite') + self.assertEqual(result.__class__, klass) + + def test___repr__(self): + inst = self._makeOne() + result = repr(inst) + self.assertEqual(result, '') + + def test_merge_not_gnutranslations(self): + inst = self._makeOne() + self.assertEqual(inst.merge(None), inst) + + def test_merge_gnutranslations(self): + inst = self._makeOne() + inst2 = self._makeOne() + inst2._catalog['a'] = 'b' + inst.merge(inst2) + self.assertEqual(inst._catalog['a'], 'b') + + def test_merge_gnutranslations_not_translations(self): + import gettext + t = gettext.GNUTranslations() + t._catalog = {'a':'b'} + inst = self._makeOne() + inst.merge(t) + self.assertEqual(inst._catalog['a'], 'b') + + def test_add_different_domain_merge_true_notexisting(self): + inst = self._makeOne() + inst2 = self._makeOne() + inst2.domain = 'domain2' + inst.add(inst2) + self.assertEqual(inst._domains['domain2'], inst2) + + def test_add_different_domain_merge_true_existing(self): + inst = self._makeOne() + inst2 = self._makeOne() + inst3 = self._makeOne() + inst2.domain = 'domain2' + inst2._catalog['a'] = 'b' + inst3.domain = 'domain2' + inst._domains['domain2'] = inst3 + inst.add(inst2) + self.assertEqual(inst._domains['domain2'], inst3) + self.assertEqual(inst3._catalog['a'], 'b') + + def test_add_same_domain_merge_true(self): + inst = self._makeOne() + inst2 = self._makeOne() + inst2._catalog['a'] = 'b' + inst.add(inst2) + self.assertEqual(inst._catalog['a'], 'b') + + def test_add_default_domain_replaces_plural_first_time(self): + # Create three empty message catalogs in the default domain + inst = self._getTargetClass()(None, domain='messages') + inst2 = self._getTargetClass()(None, domain='messages') + inst3 = self._getTargetClass()(None, domain='messages') + inst._catalog = {} + inst2._catalog = {} + inst3._catalog = {} + + # The default plural scheme is the germanic one + self.assertEqual(inst.plural(0), 1) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + + # inst2 represents a message file that declares french plurals + inst2.plural = lambda n: n > 1 + inst.add(inst2) + # that plural rule should now apply to inst + self.assertEqual(inst.plural(0), 0) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + + # We load a second message file with different plural rules + inst3.plural = lambda n: n > 0 + inst.add(inst3) + # It doesn't override the previously loaded rule + self.assertEqual(inst.plural(0), 0) + self.assertEqual(inst.plural(1), 0) + self.assertEqual(inst.plural(2), 1) + + def test_dgettext(self): + t = self._makeOne() + self.assertEqual(t.dgettext('messages', 'foo'), 'Voh') + self.assertEqual(t.dgettext('messages1', 'foo'), 'VohD') + + def test_ldgettext(self): + t = self._makeOne() + self.assertEqual(t.ldgettext('messages', 'foo'), b'Voh') + self.assertEqual(t.ldgettext('messages1', 'foo'), b'VohD') + + def test_dugettext(self): + t = self._makeOne() + self.assertEqual(t.dugettext('messages', 'foo'), 'Voh') + self.assertEqual(t.dugettext('messages1', 'foo'), 'VohD') + + def test_dngettext(self): + t = self._makeOne() + self.assertEqual(t.dngettext('messages', 'foo1', 'foos1', 1), 'Voh1') + self.assertEqual(t.dngettext('messages1', 'foo1', 'foos1', 1), 'VohD1') + + def test_ldngettext(self): + t = self._makeOne() + self.assertEqual(t.ldngettext('messages', 'foo1', 'foos1', 1), b'Voh1') + self.assertEqual(t.ldngettext('messages1', 'foo1', 'foos1', 1),b'VohD1') + + def test_dungettext(self): + t = self._makeOne() + self.assertEqual(t.dungettext('messages', 'foo1', 'foos1', 1), 'Voh1') + self.assertEqual(t.dungettext('messages1', 'foo1', 'foos1', 1), 'VohD1') + + def test_default_germanic_pluralization(self): + t = self._getTargetClass()() + t._catalog = {} + result = t.dungettext('messages', 'foo1', 'foos1', 2) + self.assertEqual(result, 'foos1') + +class TestLocalizerRequestMixin(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self): + from pyramid.i18n import LocalizerRequestMixin + request = LocalizerRequestMixin() + request.registry = self.config.registry + request.cookies = {} + request.params = {} + return request + + def test_default_localizer(self): + # `localizer` returns a default localizer for `en` + from pyramid.i18n import Localizer + request = self._makeOne() + self.assertEqual(request.localizer.__class__, Localizer) + self.assertEqual(request.locale_name, 'en') + + def test_custom_localizer_for_default_locale(self): + from pyramid.interfaces import ILocalizer + dummy = object() + self.config.registry.registerUtility(dummy, ILocalizer, name='en') + request = self._makeOne() + self.assertEqual(request.localizer, dummy) + + def test_custom_localizer_for_custom_locale(self): + from pyramid.interfaces import ILocalizer + dummy = object() + self.config.registry.registerUtility(dummy, ILocalizer, name='ie') + request = self._makeOne() + request._LOCALE_ = 'ie' + self.assertEqual(request.localizer, dummy) + + def test_localizer_from_mo(self): + from pyramid.interfaces import ITranslationDirectories + from pyramid.i18n import Localizer + localedirs = [localedir] + self.config.registry.registerUtility( + localedirs, ITranslationDirectories) + request = self._makeOne() + request._LOCALE_ = 'de' + result = request.localizer + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Genehmigen') + self.assertEqual(result.translate('Approve'), 'Approve') + self.assertTrue(hasattr(result, 'pluralize')) + + def test_localizer_from_mo_bad_mo(self): + from pyramid.interfaces import ITranslationDirectories + from pyramid.i18n import Localizer + localedirs = [localedir] + self.config.registry.registerUtility( + localedirs, ITranslationDirectories) + request = self._makeOne() + request._LOCALE_ = 'be' + result = request.localizer + self.assertEqual(result.__class__, Localizer) + self.assertEqual(result.translate('Approve', 'deformsite'), + 'Approve') + +class DummyRequest(object): + def __init__(self): + self.params = {} + self.cookies = {} + +def dummy_negotiator(request): + return 'bogus' + +class DummyTranslations(object): + def ugettext(self, text): + return text + + gettext = ugettext + + def ungettext(self, singular, plural, n): + return singular + + ngettext = ungettext diff --git a/tests/test_integration.py b/tests/test_integration.py new file mode 100644 index 000000000..eedc145ad --- /dev/null +++ b/tests/test_integration.py @@ -0,0 +1,848 @@ +# -*- coding: utf-8 -*- + +import datetime +import gc +import locale +import os +import unittest + +from pyramid.wsgi import wsgiapp +from pyramid.view import view_config +from pyramid.static import static_view +from pyramid.testing import skip_on +from pyramid.compat import ( + text_, + url_quote, + ) + +from zope.interface import Interface +from webtest import TestApp + +# 5 years from now (more or less) +fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) + +defaultlocale = locale.getdefaultlocale()[1] + +class INothing(Interface): + pass + +@view_config(for_=INothing) +@wsgiapp +def wsgiapptest(environ, start_response): + """ """ + return '123' + +class WGSIAppPlusViewConfigTests(unittest.TestCase): + def test_it(self): + from venusian import ATTACH_ATTR + import types + self.assertTrue(getattr(wsgiapptest, ATTACH_ATTR)) + self.assertTrue(type(wsgiapptest) is types.FunctionType) + context = DummyContext() + request = DummyRequest() + result = wsgiapptest(context, request) + self.assertEqual(result, '123') + + def test_scanned(self): + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + from pyramid.config import Configurator + from pyramid.tests import test_integration + config = Configurator() + config.scan(test_integration) + config.commit() + reg = config.registry + view = reg.adapters.lookup( + (IViewClassifier, IRequest, INothing), IView, name='') + self.assertEqual(view.__original_view__, wsgiapptest) + +class IntegrationBase(object): + root_factory = None + package = None + def setUp(self): + from pyramid.config import Configurator + config = Configurator(root_factory=self.root_factory, + package=self.package) + config.include(self.package) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + self.config = config + + def tearDown(self): + self.config.end() + +here = os.path.dirname(__file__) + +class StaticAppBase(IntegrationBase): + def test_basic(self): + res = self.testapp.get('/minimal.txt', status=200) + _assertBody(res.body, os.path.join(here, 'fixtures/minimal.txt')) + + def test_hidden(self): + res = self.testapp.get('/static/.hiddenfile', status=200) + _assertBody(res.body, os.path.join(here, 'fixtures/static/.hiddenfile')) + + if defaultlocale is not None: # pragma: no cover + # These tests are expected to fail on LANG=C systems due to decode + # errors and on non-Linux systems due to git highchar handling + # vagaries + def test_highchars_in_pathelement(self): + path = os.path.join( + here, + text_('fixtures/static/héhé/index.html', 'utf-8')) + pathdir = os.path.dirname(path) + body = b'hehe\n' + try: + os.makedirs(pathdir) + with open(path, 'wb') as fp: + fp.write(body) + url = url_quote('/static/héhé/index.html') + res = self.testapp.get(url, status=200) + self.assertEqual(res.body, body) + finally: + os.unlink(path) + os.rmdir(pathdir) + + def test_highchars_in_filename(self): + path = os.path.join( + here, + text_('fixtures/static/héhé.html', 'utf-8')) + body = b'hehe file\n' + with open(path, 'wb') as fp: + fp.write(body) + try: + url = url_quote('/static/héhé.html') + res = self.testapp.get(url, status=200) + self.assertEqual(res.body, body) + finally: + os.unlink(path) + + def test_not_modified(self): + self.testapp.extra_environ = { + 'HTTP_IF_MODIFIED_SINCE':httpdate(fiveyrsfuture)} + res = self.testapp.get('/minimal.txt', status=304) + self.assertEqual(res.body, b'') + + def test_file_in_subdir(self): + fn = os.path.join(here, 'fixtures/static/index.html') + res = self.testapp.get('/static/index.html', status=200) + _assertBody(res.body, fn) + + def test_directory_noslash_redir(self): + res = self.testapp.get('/static', status=301) + self.assertEqual(res.headers['Location'], 'http://localhost/static/') + + def test_directory_noslash_redir_preserves_qs(self): + res = self.testapp.get('/static?a=1&b=2', status=301) + self.assertEqual(res.headers['Location'], + 'http://localhost/static/?a=1&b=2') + + def test_directory_noslash_redir_with_scriptname(self): + self.testapp.extra_environ = {'SCRIPT_NAME':'/script_name'} + res = self.testapp.get('/static', status=301) + self.assertEqual(res.headers['Location'], + 'http://localhost/script_name/static/') + + def test_directory_withslash(self): + fn = os.path.join(here, 'fixtures/static/index.html') + res = self.testapp.get('/static/', status=200) + _assertBody(res.body, fn) + + def test_range_inclusive(self): + self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1-2'} + res = self.testapp.get('/static/index.html', status=206) + self.assertEqual(res.body, b'ht') + + def test_range_tilend(self): + self.testapp.extra_environ = {'HTTP_RANGE':'bytes=-5'} + res = self.testapp.get('/static/index.html', status=206) + self.assertEqual(res.body, b'html>') + + def test_range_notbytes(self): + self.testapp.extra_environ = {'HTTP_RANGE':'kHz=-5'} + res = self.testapp.get('/static/index.html', status=200) + _assertBody(res.body, + os.path.join(here, 'fixtures/static/index.html')) + + def test_range_multiple(self): + res = self.testapp.get('/static/index.html', + [('HTTP_RANGE', 'bytes=10-11,11-12')], + status=200) + _assertBody(res.body, + os.path.join(here, 'fixtures/static/index.html')) + + def test_range_oob(self): + self.testapp.extra_environ = {'HTTP_RANGE':'bytes=1000-1002'} + self.testapp.get('/static/index.html', status=416) + + def test_notfound(self): + self.testapp.get('/static/wontbefound.html', status=404) + + def test_oob_dotdotslash(self): + self.testapp.get('/static/../../test_integration.py', status=404) + + def test_oob_dotdotslash_encoded(self): + self.testapp.get('/static/%2E%2E%2F/test_integration.py', status=404) + + def test_oob_slash(self): + self.testapp.get('/%2F/test_integration.py', status=404) + +class TestEventOnlySubscribers(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.eventonly' + + def test_sendfoo(self): + res = self.testapp.get('/sendfoo', status=200) + self.assertEqual(sorted(res.body.split()), [b'foo', b'fooyup']) + + def test_sendfoobar(self): + res = self.testapp.get('/sendfoobar', status=200) + self.assertEqual(sorted(res.body.split()), + [b'foobar', b'foobar2', b'foobaryup', b'foobaryup2']) + +class TestStaticAppUsingAbsPath(StaticAppBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.static_abspath' + +class TestStaticAppUsingAssetSpec(StaticAppBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.static_assetspec' + +class TestStaticAppNoSubpath(unittest.TestCase): + staticapp = static_view(os.path.join(here, 'fixtures'), use_subpath=False) + def _makeRequest(self, extra): + from pyramid.request import Request + from io import BytesIO + kw = {'PATH_INFO':'', + 'SCRIPT_NAME':'', + 'SERVER_NAME':'localhost', + 'SERVER_PORT':'80', + 'REQUEST_METHOD':'GET', + 'wsgi.version':(1,0), + 'wsgi.url_scheme':'http', + 'wsgi.input':BytesIO()} + kw.update(extra) + request = Request(kw) + return request + + def test_basic(self): + request = self._makeRequest({'PATH_INFO':'/minimal.txt'}) + context = DummyContext() + result = self.staticapp(context, request) + self.assertEqual(result.status, '200 OK') + _assertBody(result.body, os.path.join(here, 'fixtures/minimal.txt')) + +class TestStaticAppWithRoutePrefix(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.static_routeprefix' + + def test_includelevel1(self): + res = self.testapp.get('/static/minimal.txt', status=200) + _assertBody(res.body, + os.path.join(here, 'fixtures/minimal.txt')) + + def test_includelevel2(self): + res = self.testapp.get('/prefix/static/index.html', status=200) + _assertBody(res.body, + os.path.join(here, 'fixtures/static/index.html')) + + +class TestFixtureApp(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.fixtureapp' + def test_another(self): + res = self.testapp.get('/another.html', status=200) + self.assertEqual(res.body, b'fixture') + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertEqual(res.body, b'fixture') + + def test_dummyskin(self): + self.testapp.get('/dummyskin.html', status=404) + + def test_error(self): + res = self.testapp.get('/error.html', status=200) + self.assertEqual(res.body, b'supressed') + + def test_protected(self): + self.testapp.get('/protected.html', status=403) + +class TestStaticPermApp(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.staticpermapp' + root_factory = 'pyramid.tests.pkgs.staticpermapp:RootFactory' + def test_allowed(self): + result = self.testapp.get('/allowed/index.html', status=200) + _assertBody(result.body, + os.path.join(here, 'fixtures/static/index.html')) + + def test_denied_via_acl_global_root_factory(self): + self.testapp.extra_environ = {'REMOTE_USER':'bob'} + self.testapp.get('/protected/index.html', status=403) + + def test_allowed_via_acl_global_root_factory(self): + self.testapp.extra_environ = {'REMOTE_USER':'fred'} + result = self.testapp.get('/protected/index.html', status=200) + _assertBody(result.body, + os.path.join(here, 'fixtures/static/index.html')) + + def test_denied_via_acl_local_root_factory(self): + self.testapp.extra_environ = {'REMOTE_USER':'fred'} + self.testapp.get('/factory_protected/index.html', status=403) + + def test_allowed_via_acl_local_root_factory(self): + self.testapp.extra_environ = {'REMOTE_USER':'bob'} + result = self.testapp.get('/factory_protected/index.html', status=200) + _assertBody(result.body, + os.path.join(here, 'fixtures/static/index.html')) + +class TestCCBug(IntegrationBase, unittest.TestCase): + # "unordered" as reported in IRC by author of + # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ + package = 'pyramid.tests.pkgs.ccbugapp' + def test_rdf(self): + res = self.testapp.get('/licenses/1/v1/rdf', status=200) + self.assertEqual(res.body, b'rdf') + + def test_juri(self): + res = self.testapp.get('/licenses/1/v1/juri', status=200) + self.assertEqual(res.body, b'juri') + +class TestHybridApp(IntegrationBase, unittest.TestCase): + # make sure views registered for a route "win" over views registered + # without one, even though the context of the non-route view may + # be more specific than the route view. + package = 'pyramid.tests.pkgs.hybridapp' + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertEqual(res.body, b'global') + + def test_abc(self): + res = self.testapp.get('/abc', status=200) + self.assertEqual(res.body, b'route') + + def test_def(self): + res = self.testapp.get('/def', status=200) + self.assertEqual(res.body, b'route2') + + def test_ghi(self): + res = self.testapp.get('/ghi', status=200) + self.assertEqual(res.body, b'global') + + def test_jkl(self): + self.testapp.get('/jkl', status=404) + + def test_mno(self): + self.testapp.get('/mno', status=404) + + def test_pqr_global2(self): + res = self.testapp.get('/pqr/global2', status=200) + self.assertEqual(res.body, b'global2') + + def test_error(self): + res = self.testapp.get('/error', status=200) + self.assertEqual(res.body, b'supressed') + + def test_error2(self): + res = self.testapp.get('/error2', status=200) + self.assertEqual(res.body, b'supressed2') + + def test_error_sub(self): + res = self.testapp.get('/error_sub', status=200) + self.assertEqual(res.body, b'supressed2') + +class TestRestBugApp(IntegrationBase, unittest.TestCase): + # test bug reported by delijati 2010/2/3 (http://pastebin.com/d4cc15515) + package = 'pyramid.tests.pkgs.restbugapp' + def test_it(self): + res = self.testapp.get('/pet', status=200) + self.assertEqual(res.body, b'gotten') + +class TestForbiddenAppHasResult(IntegrationBase, unittest.TestCase): + # test that forbidden exception has ACLDenied result attached + package = 'pyramid.tests.pkgs.forbiddenapp' + def test_it(self): + res = self.testapp.get('/x', status=403) + message, result = [x.strip() for x in res.body.split(b'\n')] + self.assertTrue(message.endswith(b'failed permission check')) + self.assertTrue( + result.startswith(b"ACLDenied permission 'private' via ACE " + b"'' in ACL " + b"'' on context")) + self.assertTrue( + result.endswith(b"for principals ['system.Everyone']")) + +class TestViewDecoratorApp(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.viewdecoratorapp' + + def test_first(self): + res = self.testapp.get('/first', status=200) + self.assertTrue(b'OK' in res.body) + + def test_second(self): + res = self.testapp.get('/second', status=200) + self.assertTrue(b'OK2' in res.body) + +class TestNotFoundView(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.notfoundview' + + def test_it(self): + res = self.testapp.get('/wontbefound', status=200) + self.assertTrue(b'generic_notfound' in res.body) + res = self.testapp.get('/bar', status=307) + self.assertEqual(res.location, 'http://localhost/bar/') + res = self.testapp.get('/bar/', status=200) + self.assertTrue(b'OK bar' in res.body) + res = self.testapp.get('/foo', status=307) + self.assertEqual(res.location, 'http://localhost/foo/') + res = self.testapp.get('/foo/', status=200) + self.assertTrue(b'OK foo2' in res.body) + res = self.testapp.get('/baz', status=200) + self.assertTrue(b'baz_notfound' in res.body) + +class TestForbiddenView(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.forbiddenview' + + def test_it(self): + res = self.testapp.get('/foo', status=200) + self.assertTrue(b'foo_forbidden' in res.body) + res = self.testapp.get('/bar', status=200) + self.assertTrue(b'generic_forbidden' in res.body) + +class TestViewPermissionBug(IntegrationBase, unittest.TestCase): + # view_execution_permitted bug as reported by Shane at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003603.html + package = 'pyramid.tests.pkgs.permbugapp' + def test_test(self): + res = self.testapp.get('/test', status=200) + self.assertTrue(b'ACLDenied' in res.body) + + def test_x(self): + self.testapp.get('/x', status=403) + +class TestDefaultViewPermissionBug(IntegrationBase, unittest.TestCase): + # default_view_permission bug as reported by Wiggy at http://lists.repoze.org/pipermail/repoze-dev/2010-October/003602.html + package = 'pyramid.tests.pkgs.defpermbugapp' + def test_x(self): + res = self.testapp.get('/x', status=403) + self.assertTrue(b'failed permission check' in res.body) + + def test_y(self): + res = self.testapp.get('/y', status=403) + self.assertTrue(b'failed permission check' in res.body) + + def test_z(self): + res = self.testapp.get('/z', status=200) + self.assertTrue(b'public' in res.body) + +from pyramid.tests.pkgs.exceptionviewapp.models import \ + AnException, NotAnException +excroot = {'anexception':AnException(), + 'notanexception':NotAnException()} + +class TestExceptionViewsApp(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.exceptionviewapp' + root_factory = lambda *arg: excroot + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'maybe' in res.body) + + def test_notanexception(self): + res = self.testapp.get('/notanexception', status=200) + self.assertTrue(b'no' in res.body) + + def test_anexception(self): + res = self.testapp.get('/anexception', status=200) + self.assertTrue(b'yes' in res.body) + + def test_route_raise_exception(self): + res = self.testapp.get('/route_raise_exception', status=200) + self.assertTrue(b'yes' in res.body) + + def test_route_raise_exception2(self): + res = self.testapp.get('/route_raise_exception2', status=200) + self.assertTrue(b'yes' in res.body) + + def test_route_raise_exception3(self): + res = self.testapp.get('/route_raise_exception3', status=200) + self.assertTrue(b'whoa' in res.body) + + def test_route_raise_exception4(self): + res = self.testapp.get('/route_raise_exception4', status=200) + self.assertTrue(b'whoa' in res.body) + + def test_raise_httpexception(self): + res = self.testapp.get('/route_raise_httpexception', status=200) + self.assertTrue(b'caught' in res.body) + +class TestConflictApp(unittest.TestCase): + package = 'pyramid.tests.pkgs.conflictapp' + def _makeConfig(self): + from pyramid.config import Configurator + config = Configurator() + return config + + def test_autoresolved_view(self): + config = self._makeConfig() + config.include(self.package) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + res = self.testapp.get('/') + self.assertTrue(b'a view' in res.body) + res = self.testapp.get('/route') + self.assertTrue(b'route view' in res.body) + + def test_overridden_autoresolved_view(self): + from pyramid.response import Response + config = self._makeConfig() + config.include(self.package) + def thisview(request): + return Response('this view') + config.add_view(thisview) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + res = self.testapp.get('/') + self.assertTrue(b'this view' in res.body) + + def test_overridden_route_view(self): + from pyramid.response import Response + config = self._makeConfig() + config.include(self.package) + def thisview(request): + return Response('this view') + config.add_view(thisview, route_name='aroute') + app = config.make_wsgi_app() + self.testapp = TestApp(app) + res = self.testapp.get('/route') + self.assertTrue(b'this view' in res.body) + + def test_nonoverridden_authorization_policy(self): + config = self._makeConfig() + config.include(self.package) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + res = self.testapp.get('/protected', status=403) + self.assertTrue(b'403 Forbidden' in res.body) + + def test_overridden_authorization_policy(self): + config = self._makeConfig() + config.include(self.package) + from pyramid.testing import DummySecurityPolicy + config.set_authorization_policy(DummySecurityPolicy('fred')) + config.set_authentication_policy(DummySecurityPolicy(permissive=True)) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + res = self.testapp.get('/protected', status=200) + self.assertTrue('protected view' in res) + +class ImperativeIncludeConfigurationTest(unittest.TestCase): + def setUp(self): + from pyramid.config import Configurator + config = Configurator() + from pyramid.tests.pkgs.includeapp1.root import configure + configure(config) + app = config.make_wsgi_app() + self.testapp = TestApp(app) + self.config = config + + def tearDown(self): + self.config.end() + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'root' in res.body) + + def test_two(self): + res = self.testapp.get('/two', status=200) + self.assertTrue(b'two' in res.body) + + def test_three(self): + res = self.testapp.get('/three', status=200) + self.assertTrue(b'three' in res.body) + +class SelfScanAppTest(unittest.TestCase): + def setUp(self): + from pyramid.tests.test_config.pkgs.selfscan import main + config = main() + app = config.make_wsgi_app() + self.testapp = TestApp(app) + self.config = config + + def tearDown(self): + self.config.end() + + def test_root(self): + res = self.testapp.get('/', status=200) + self.assertTrue(b'root' in res.body) + + def test_two(self): + res = self.testapp.get('/two', status=200) + self.assertTrue(b'two' in res.body) + +class WSGIApp2AppTest(unittest.TestCase): + def setUp(self): + from pyramid.tests.pkgs.wsgiapp2app import main + config = main() + app = config.make_wsgi_app() + self.testapp = TestApp(app) + self.config = config + + def tearDown(self): + self.config.end() + + def test_hello(self): + res = self.testapp.get('/hello', status=200) + self.assertTrue(b'Hello' in res.body) + +class SubrequestAppTest(unittest.TestCase): + def setUp(self): + from pyramid.tests.pkgs.subrequestapp import main + config = main() + app = config.make_wsgi_app() + self.testapp = TestApp(app) + self.config = config + + def tearDown(self): + self.config.end() + + def test_one(self): + res = self.testapp.get('/view_one', status=200) + self.assertTrue(b'This came from view_two, foo=bar' in res.body) + + def test_three(self): + res = self.testapp.get('/view_three', status=500) + self.assertTrue(b'Bad stuff happened' in res.body) + + def test_five(self): + res = self.testapp.get('/view_five', status=200) + self.assertTrue(b'Value error raised' in res.body) + +class RendererScanAppTest(IntegrationBase, unittest.TestCase): + package = 'pyramid.tests.pkgs.rendererscanapp' + def test_root(self): + res = self.testapp.get('/one', status=200) + self.assertTrue(b'One!' in res.body) + + def test_two(self): + res = self.testapp.get('/two', status=200) + self.assertTrue(b'Two!' in res.body) + + def test_rescan(self): + self.config.scan('pyramid.tests.pkgs.rendererscanapp') + app = self.config.make_wsgi_app() + testapp = TestApp(app) + res = testapp.get('/one', status=200) + self.assertTrue(b'One!' in res.body) + res = testapp.get('/two', status=200) + self.assertTrue(b'Two!' in res.body) + +class UnicodeInURLTest(unittest.TestCase): + def _makeConfig(self): + from pyramid.config import Configurator + config = Configurator() + return config + + def _makeTestApp(self, config): + app = config.make_wsgi_app() + return TestApp(app) + + def test_unicode_in_url_404(self): + request_path = '/avalia%C3%A7%C3%A3o_participante' + request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') + + config = self._makeConfig() + testapp = self._makeTestApp(config) + + res = testapp.get(request_path, status=404) + + # Pyramid default 404 handler outputs: + # u'404 Not Found\n\nThe resource could not be found.\n\n\n' + # u'/avalia\xe7\xe3o_participante\n\n' + self.assertTrue(request_path_unicode in res.text) + + def test_unicode_in_url_200(self): + request_path = '/avalia%C3%A7%C3%A3o_participante' + request_path_unicode = b'/avalia\xc3\xa7\xc3\xa3o_participante'.decode('utf-8') + + def myview(request): + return 'XXX' + + config = self._makeConfig() + config.add_route('myroute', request_path_unicode) + config.add_view(myview, route_name='myroute', renderer='json') + testapp = self._makeTestApp(config) + + res = testapp.get(request_path, status=200) + + self.assertEqual(res.text, '"XXX"') + + +class AcceptContentTypeTest(unittest.TestCase): + def _makeConfig(self): + def hello_view(request): + return {'message': 'Hello!'} + from pyramid.config import Configurator + config = Configurator() + config.add_route('hello', '/hello') + config.add_view(hello_view, route_name='hello', + accept='text/plain', renderer='string') + config.add_view(hello_view, route_name='hello', + accept='application/json', renderer='json') + def hello_fallback_view(request): + request.response.content_type = 'text/x-fallback' + return 'hello fallback' + config.add_view(hello_fallback_view, route_name='hello', + renderer='string') + return config + + def _makeTestApp(self, config): + app = config.make_wsgi_app() + return TestApp(app) + + def tearDown(self): + import pyramid.config + pyramid.config.global_registries.empty() + + def test_client_side_ordering(self): + config = self._makeConfig() + app = self._makeTestApp(config) + res = app.get('/hello', headers={ + 'Accept': 'application/json; q=1.0, text/plain; q=0.9', + }, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={ + 'Accept': 'text/plain; q=0.9, application/json; q=1.0', + }, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={'Accept': 'application/*'}, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={'Accept': 'text/*'}, status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) + self.assertEqual(res.content_type, 'text/x-fallback') + + def test_default_server_side_ordering(self): + config = self._makeConfig() + app = self._makeTestApp(config) + res = app.get('/hello', headers={ + 'Accept': 'application/json, text/plain', + }, status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', headers={ + 'Accept': 'text/plain, application/json', + }, status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', headers={'Accept': '*/*'}, status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) + self.assertEqual(res.content_type, 'text/plain') + res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) + self.assertEqual(res.content_type, 'text/x-fallback') + + def test_custom_server_side_ordering(self): + config = self._makeConfig() + config.add_accept_view_order( + 'application/json', weighs_more_than='text/plain') + app = self._makeTestApp(config) + res = app.get('/hello', headers={ + 'Accept': 'application/json, text/plain', + }, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={ + 'Accept': 'text/plain, application/json', + }, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={'Accept': '*/*'}, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={'Accept': 'invalid'}, status=200) + self.assertEqual(res.content_type, 'application/json') + res = app.get('/hello', headers={'Accept': 'something/else'}, status=200) + self.assertEqual(res.content_type, 'text/x-fallback') + + def test_deprecated_ranges_in_route_predicate(self): + config = self._makeConfig() + config.add_route('foo', '/foo', accept='text/*') + config.add_view(lambda r: 'OK', route_name='foo', renderer='string') + app = self._makeTestApp(config) + res = app.get('/foo', headers={ + 'Accept': 'application/json; q=1.0, text/plain; q=0.9', + }, status=200) + self.assertEqual(res.content_type, 'text/plain') + self.assertEqual(res.body, b'OK') + res = app.get('/foo', headers={ + 'Accept': 'application/json', + }, status=404) + self.assertEqual(res.content_type, 'application/json') + + def test_deprecated_ranges_in_view_predicate(self): + config = self._makeConfig() + config.add_route('foo', '/foo') + config.add_view(lambda r: 'OK', route_name='foo', + accept='text/*', renderer='string') + app = self._makeTestApp(config) + res = app.get('/foo', headers={ + 'Accept': 'application/json; q=1.0, text/plain; q=0.9', + }, status=200) + self.assertEqual(res.content_type, 'text/plain') + self.assertEqual(res.body, b'OK') + res = app.get('/foo', headers={ + 'Accept': 'application/json', + }, status=404) + self.assertEqual(res.content_type, 'application/json') + + +class DummyContext(object): + pass + +class DummyRequest: + subpath = ('__init__.py',) + traversed = None + environ = {'REQUEST_METHOD':'GET', 'wsgi.version':(1,0)} + def get_response(self, application): + return application(None, None) + +def httpdate(ts): + return ts.strftime("%a, %d %b %Y %H:%M:%S GMT") + +def read_(filename): + with open(filename, 'rb') as fp: + val = fp.read() + return val + +def _assertBody(body, filename): + if defaultlocale is None: # pragma: no cover + # If system locale does not have an encoding then default to utf-8 + filename = filename.encode('utf-8') + # strip both \n and \r for windows + body = body.replace(b'\r', b'') + body = body.replace(b'\n', b'') + data = read_(filename) + data = data.replace(b'\r', b'') + data = data.replace(b'\n', b'') + assert(body == data) + + +class MemoryLeaksTest(unittest.TestCase): + + def tearDown(self): + import pyramid.config + pyramid.config.global_registries.empty() + + def get_gc_count(self): + last_collected = 0 + while True: + collected = gc.collect() + if collected == last_collected: + break + last_collected = collected + return len(gc.get_objects()) + + @skip_on('pypy') + def test_memory_leaks(self): + from pyramid.config import Configurator + Configurator().make_wsgi_app() # Initialize all global objects + + initial_count = self.get_gc_count() + Configurator().make_wsgi_app() + current_count = self.get_gc_count() + self.assertEqual(current_count, initial_count) diff --git a/tests/test_location.py b/tests/test_location.py new file mode 100644 index 000000000..e1f47f4ab --- /dev/null +++ b/tests/test_location.py @@ -0,0 +1,40 @@ +import unittest + +class TestInside(unittest.TestCase): + def _callFUT(self, one, two): + from pyramid.location import inside + return inside(one, two) + + def test_inside(self): + o1 = Location() + o2 = Location(); o2.__parent__ = o1 + o3 = Location(); o3.__parent__ = o2 + o4 = Location(); o4.__parent__ = o3 + + self.assertEqual(self._callFUT(o1, o1), True) + self.assertEqual(self._callFUT(o2, o1), True) + self.assertEqual(self._callFUT(o3, o1), True) + self.assertEqual(self._callFUT(o4, o1), True) + self.assertEqual(self._callFUT(o1, o4), False) + self.assertEqual(self._callFUT(o1, None), False) + +class TestLineage(unittest.TestCase): + def _callFUT(self, context): + from pyramid.location import lineage + return lineage(context) + + def test_lineage(self): + o1 = Location() + o2 = Location(); o2.__parent__ = o1 + o3 = Location(); o3.__parent__ = o2 + o4 = Location(); o4.__parent__ = o3 + result = list(self._callFUT(o3)) + self.assertEqual(result, [o3, o2, o1]) + result = list(self._callFUT(o1)) + self.assertEqual(result, [o1]) + +from pyramid.interfaces import ILocation +from zope.interface import implementer +@implementer(ILocation) +class Location(object): + __name__ = __parent__ = None diff --git a/tests/test_paster.py b/tests/test_paster.py new file mode 100644 index 000000000..784458647 --- /dev/null +++ b/tests/test_paster.py @@ -0,0 +1,168 @@ +import os +import unittest +from pyramid.tests.test_scripts.dummy import DummyLoader + +here = os.path.dirname(__file__) + +class Test_get_app(unittest.TestCase): + def _callFUT(self, config_file, section_name, options=None, _loader=None): + import pyramid.paster + old_loader = pyramid.paster.get_config_loader + try: + if _loader is not None: + pyramid.paster.get_config_loader = _loader + return pyramid.paster.get_app(config_file, section_name, + options=options) + finally: + pyramid.paster.get_config_loader = old_loader + + def test_it(self): + app = DummyApp() + loader = DummyLoader(app=app) + result = self._callFUT( + '/foo/bar/myapp.ini', 'myapp', options={'a': 'b'}, + _loader=loader) + self.assertEqual(loader.uri.path, '/foo/bar/myapp.ini') + self.assertEqual(len(loader.calls), 1) + self.assertEqual(loader.calls[0]['op'], 'app') + self.assertEqual(loader.calls[0]['name'], 'myapp') + self.assertEqual(loader.calls[0]['defaults'], {'a': 'b'}) + self.assertEqual(result, app) + + def test_it_with_dummyapp_requiring_options(self): + options = {'bar': 'baz'} + app = self._callFUT( + os.path.join(here, 'fixtures', 'dummy.ini'), + 'myapp', options=options) + self.assertEqual(app.settings['foo'], 'baz') + +class Test_get_appsettings(unittest.TestCase): + def _callFUT(self, config_file, section_name, options=None, _loader=None): + import pyramid.paster + old_loader = pyramid.paster.get_config_loader + try: + if _loader is not None: + pyramid.paster.get_config_loader = _loader + return pyramid.paster.get_appsettings(config_file, section_name, + options=options) + finally: + pyramid.paster.get_config_loader = old_loader + + def test_it(self): + values = {'a': 1} + loader = DummyLoader(app_settings=values) + result = self._callFUT( + '/foo/bar/myapp.ini', 'myapp', options={'a': 'b'}, + _loader=loader) + self.assertEqual(loader.uri.path, '/foo/bar/myapp.ini') + self.assertEqual(len(loader.calls), 1) + self.assertEqual(loader.calls[0]['op'], 'app_settings') + self.assertEqual(loader.calls[0]['name'], 'myapp') + self.assertEqual(loader.calls[0]['defaults'], {'a': 'b'}) + self.assertEqual(result, values) + + def test_it_with_dummyapp_requiring_options(self): + options = {'bar': 'baz'} + result = self._callFUT( + os.path.join(here, 'fixtures', 'dummy.ini'), + 'myapp', options=options) + self.assertEqual(result['foo'], 'baz') + +class Test_setup_logging(unittest.TestCase): + def _callFUT(self, config_file, global_conf=None, _loader=None): + import pyramid.paster + old_loader = pyramid.paster.get_config_loader + try: + if _loader is not None: + pyramid.paster.get_config_loader = _loader + return pyramid.paster.setup_logging(config_file, global_conf) + finally: + pyramid.paster.get_config_loader = old_loader + + def test_it_no_global_conf(self): + loader = DummyLoader() + self._callFUT('/abc.ini', _loader=loader) + self.assertEqual(loader.uri.path, '/abc.ini') + self.assertEqual(len(loader.calls), 1) + self.assertEqual(loader.calls[0]['op'], 'logging') + self.assertEqual(loader.calls[0]['defaults'], None) + + def test_it_global_conf_empty(self): + loader = DummyLoader() + self._callFUT('/abc.ini', global_conf={}, _loader=loader) + self.assertEqual(loader.uri.path, '/abc.ini') + self.assertEqual(len(loader.calls), 1) + self.assertEqual(loader.calls[0]['op'], 'logging') + self.assertEqual(loader.calls[0]['defaults'], {}) + + def test_it_global_conf_not_empty(self): + loader = DummyLoader() + self._callFUT('/abc.ini', global_conf={'key': 'val'}, _loader=loader) + self.assertEqual(loader.uri.path, '/abc.ini') + self.assertEqual(len(loader.calls), 1) + self.assertEqual(loader.calls[0]['op'], 'logging') + self.assertEqual(loader.calls[0]['defaults'], {'key': 'val'}) + +class Test_bootstrap(unittest.TestCase): + def _callFUT(self, config_uri, request=None): + from pyramid.paster import bootstrap + return bootstrap(config_uri, request) + + def setUp(self): + import pyramid.paster + self.original_get_app = pyramid.paster.get_app + self.original_prepare = pyramid.paster.prepare + self.app = app = DummyApp() + self.root = root = Dummy() + + class DummyGetApp(object): + def __call__(self, *a, **kw): + self.a = a + self.kw = kw + return app + self.get_app = pyramid.paster.get_app = DummyGetApp() + + class DummyPrepare(object): + def __call__(self, *a, **kw): + self.a = a + self.kw = kw + return {'root':root, 'closer':lambda: None} + self.getroot = pyramid.paster.prepare = DummyPrepare() + + def tearDown(self): + import pyramid.paster + pyramid.paster.get_app = self.original_get_app + pyramid.paster.prepare = self.original_prepare + + def test_it_request_with_registry(self): + request = DummyRequest({}) + request.registry = dummy_registry + result = self._callFUT('/foo/bar/myapp.ini', request) + self.assertEqual(result['app'], self.app) + self.assertEqual(result['root'], self.root) + self.assertTrue('closer' in result) + +class Dummy: + pass + +class DummyRegistry(object): + settings = {} + +dummy_registry = DummyRegistry() + +class DummyApp: + def __init__(self): + self.registry = dummy_registry + +def make_dummyapp(global_conf, **settings): + app = DummyApp() + app.settings = settings + app.global_conf = global_conf + return app + +class DummyRequest: + application_url = 'http://example.com:5432' + script_name = '' + def __init__(self, environ): + self.environ = environ + self.matchdict = {} diff --git a/tests/test_path.py b/tests/test_path.py new file mode 100644 index 000000000..563ece6d6 --- /dev/null +++ b/tests/test_path.py @@ -0,0 +1,576 @@ +import unittest +import os +from pyramid.compat import PY2 + +here = os.path.abspath(os.path.dirname(__file__)) + +class TestCallerPath(unittest.TestCase): + def tearDown(self): + from pyramid.tests import test_path + if hasattr(test_path, '__abspath__'): + del test_path.__abspath__ + + def _callFUT(self, path, level=2): + from pyramid.path import caller_path + return caller_path(path, level) + + def test_isabs(self): + result = self._callFUT('/a/b/c') + self.assertEqual(result, '/a/b/c') + + def test_pkgrelative(self): + import os + result = self._callFUT('a/b/c') + self.assertEqual(result, os.path.join(here, 'a/b/c')) + + def test_memoization_has_abspath(self): + import os + from pyramid.tests import test_path + test_path.__abspath__ = '/foo/bar' + result = self._callFUT('a/b/c') + self.assertEqual(result, os.path.join('/foo/bar', 'a/b/c')) + + def test_memoization_success(self): + import os + from pyramid.tests import test_path + result = self._callFUT('a/b/c') + self.assertEqual(result, os.path.join(here, 'a/b/c')) + self.assertEqual(test_path.__abspath__, here) + +class TestCallerModule(unittest.TestCase): + def _callFUT(self, *arg, **kw): + from pyramid.path import caller_module + return caller_module(*arg, **kw) + + def test_it_level_1(self): + from pyramid.tests import test_path + result = self._callFUT(1) + self.assertEqual(result, test_path) + + def test_it_level_2(self): + from pyramid.tests import test_path + result = self._callFUT(2) + self.assertEqual(result, test_path) + + def test_it_level_3(self): + from pyramid.tests import test_path + result = self._callFUT(3) + self.assertNotEqual(result, test_path) + + def test_it_no___name__(self): + class DummyFrame(object): + f_globals = {} + class DummySys(object): + def _getframe(self, level): + return DummyFrame() + modules = {'__main__':'main'} + dummy_sys = DummySys() + result = self._callFUT(3, sys=dummy_sys) + self.assertEqual(result, 'main') + + +class TestCallerPackage(unittest.TestCase): + def _callFUT(self, *arg, **kw): + from pyramid.path import caller_package + return caller_package(*arg, **kw) + + def test_it_level_1(self): + from pyramid import tests + result = self._callFUT(1) + self.assertEqual(result, tests) + + def test_it_level_2(self): + from pyramid import tests + result = self._callFUT(2) + self.assertEqual(result, tests) + + def test_it_level_3(self): + import unittest + result = self._callFUT(3) + self.assertEqual(result, unittest) + + def test_it_package(self): + import pyramid.tests + def dummy_caller_module(*arg): + return pyramid.tests + result = self._callFUT(1, caller_module=dummy_caller_module) + self.assertEqual(result, pyramid.tests) + +class TestPackagePath(unittest.TestCase): + def _callFUT(self, package): + from pyramid.path import package_path + return package_path(package) + + def test_it_package(self): + from pyramid import tests + package = DummyPackageOrModule(tests) + result = self._callFUT(package) + self.assertEqual(result, package.package_path) + + def test_it_module(self): + from pyramid.tests import test_path + module = DummyPackageOrModule(test_path) + result = self._callFUT(module) + self.assertEqual(result, module.package_path) + + def test_memoization_success(self): + from pyramid.tests import test_path + module = DummyPackageOrModule(test_path) + self._callFUT(module) + self.assertEqual(module.__abspath__, module.package_path) + + def test_memoization_fail(self): + from pyramid.tests import test_path + module = DummyPackageOrModule(test_path, raise_exc=TypeError) + result = self._callFUT(module) + self.assertFalse(hasattr(module, '__abspath__')) + self.assertEqual(result, module.package_path) + +class TestPackageOf(unittest.TestCase): + def _callFUT(self, package): + from pyramid.path import package_of + return package_of(package) + + def test_it_package(self): + from pyramid import tests + package = DummyPackageOrModule(tests) + result = self._callFUT(package) + self.assertEqual(result, tests) + + def test_it_module(self): + import pyramid.tests.test_path + from pyramid import tests + package = DummyPackageOrModule(pyramid.tests.test_path) + result = self._callFUT(package) + self.assertEqual(result, tests) + +class TestPackageName(unittest.TestCase): + def _callFUT(self, package): + from pyramid.path import package_name + return package_name(package) + + def test_it_package(self): + from pyramid import tests + package = DummyPackageOrModule(tests) + result = self._callFUT(package) + self.assertEqual(result, 'pyramid.tests') + + def test_it_namespace_package(self): + from pyramid import tests + package = DummyNamespacePackage(tests) + result = self._callFUT(package) + self.assertEqual(result, 'pyramid.tests') + + def test_it_module(self): + from pyramid.tests import test_path + module = DummyPackageOrModule(test_path) + result = self._callFUT(module) + self.assertEqual(result, 'pyramid.tests') + + def test_it_None(self): + result = self._callFUT(None) + self.assertEqual(result, '__main__') + + def test_it_main(self): + import __main__ + result = self._callFUT(__main__) + self.assertEqual(result, '__main__') + +class TestResolver(unittest.TestCase): + def _getTargetClass(self): + from pyramid.path import Resolver + return Resolver + + def _makeOne(self, package): + return self._getTargetClass()(package) + + def test_get_package_caller_package(self): + import pyramid.tests + from pyramid.path import CALLER_PACKAGE + self.assertEqual(self._makeOne(CALLER_PACKAGE).get_package(), + pyramid.tests) + + def test_get_package_name_caller_package(self): + from pyramid.path import CALLER_PACKAGE + self.assertEqual(self._makeOne(CALLER_PACKAGE).get_package_name(), + 'pyramid.tests') + + def test_get_package_string(self): + import pyramid.tests + self.assertEqual(self._makeOne('pyramid.tests').get_package(), + pyramid.tests) + + def test_get_package_name_string(self): + self.assertEqual(self._makeOne('pyramid.tests').get_package_name(), + 'pyramid.tests') + +class TestAssetResolver(unittest.TestCase): + def _getTargetClass(self): + from pyramid.path import AssetResolver + return AssetResolver + + def _makeOne(self, package='pyramid.tests'): + return self._getTargetClass()(package) + + def test_ctor_as_package(self): + import sys + tests = sys.modules['pyramid.tests'] + inst = self._makeOne(tests) + self.assertEqual(inst.package, tests) + + def test_ctor_as_str(self): + import sys + tests = sys.modules['pyramid.tests'] + inst = self._makeOne('pyramid.tests') + self.assertEqual(inst.package, tests) + + def test_resolve_abspath(self): + from pyramid.path import FSAssetDescriptor + inst = self._makeOne(None) + r = inst.resolve(os.path.join(here, 'test_asset.py')) + self.assertEqual(r.__class__, FSAssetDescriptor) + self.assertTrue(r.exists()) + + def test_resolve_absspec(self): + from pyramid.path import PkgResourcesAssetDescriptor + inst = self._makeOne(None) + r = inst.resolve('pyramid.tests:test_asset.py') + self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) + self.assertTrue(r.exists()) + + def test_resolve_relspec_with_pkg(self): + from pyramid.path import PkgResourcesAssetDescriptor + inst = self._makeOne('pyramid.tests') + r = inst.resolve('test_asset.py') + self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) + self.assertTrue(r.exists()) + + def test_resolve_relspec_no_package(self): + inst = self._makeOne(None) + self.assertRaises(ValueError, inst.resolve, 'test_asset.py') + + def test_resolve_relspec_caller_package(self): + from pyramid.path import PkgResourcesAssetDescriptor + from pyramid.path import CALLER_PACKAGE + inst = self._makeOne(CALLER_PACKAGE) + r = inst.resolve('test_asset.py') + self.assertEqual(r.__class__, PkgResourcesAssetDescriptor) + self.assertTrue(r.exists()) + +class TestPkgResourcesAssetDescriptor(unittest.TestCase): + def _getTargetClass(self): + from pyramid.path import PkgResourcesAssetDescriptor + return PkgResourcesAssetDescriptor + + def _makeOne(self, pkg='pyramid.tests', path='test_asset.py'): + return self._getTargetClass()(pkg, path) + + def test_class_conforms_to_IAssetDescriptor(self): + from pyramid.interfaces import IAssetDescriptor + from zope.interface.verify import verifyClass + verifyClass(IAssetDescriptor, self._getTargetClass()) + + def test_instance_conforms_to_IAssetDescriptor(self): + from pyramid.interfaces import IAssetDescriptor + from zope.interface.verify import verifyObject + verifyObject(IAssetDescriptor, self._makeOne()) + + def test_absspec(self): + inst = self._makeOne() + self.assertEqual(inst.absspec(), 'pyramid.tests:test_asset.py') + + def test_abspath(self): + inst = self._makeOne() + self.assertEqual(inst.abspath(), os.path.join(here, 'test_asset.py')) + + def test_stream(self): + inst = self._makeOne() + inst.pkg_resources = DummyPkgResource() + inst.pkg_resources.resource_stream = lambda x, y: '%s:%s' % (x, y) + s = inst.stream() + self.assertEqual(s, + '%s:%s' % ('pyramid.tests', 'test_asset.py')) + + def test_isdir(self): + inst = self._makeOne() + inst.pkg_resources = DummyPkgResource() + inst.pkg_resources.resource_isdir = lambda x, y: '%s:%s' % (x, y) + self.assertEqual(inst.isdir(), + '%s:%s' % ('pyramid.tests', 'test_asset.py')) + + def test_listdir(self): + inst = self._makeOne() + inst.pkg_resources = DummyPkgResource() + inst.pkg_resources.resource_listdir = lambda x, y: '%s:%s' % (x, y) + self.assertEqual(inst.listdir(), + '%s:%s' % ('pyramid.tests', 'test_asset.py')) + + def test_exists(self): + inst = self._makeOne() + inst.pkg_resources = DummyPkgResource() + inst.pkg_resources.resource_exists = lambda x, y: '%s:%s' % (x, y) + self.assertEqual(inst.exists(), + '%s:%s' % ('pyramid.tests', 'test_asset.py')) + +class TestFSAssetDescriptor(unittest.TestCase): + def _getTargetClass(self): + from pyramid.path import FSAssetDescriptor + return FSAssetDescriptor + + def _makeOne(self, path=os.path.join(here, 'test_asset.py')): + return self._getTargetClass()(path) + + def test_class_conforms_to_IAssetDescriptor(self): + from pyramid.interfaces import IAssetDescriptor + from zope.interface.verify import verifyClass + verifyClass(IAssetDescriptor, self._getTargetClass()) + + def test_instance_conforms_to_IAssetDescriptor(self): + from pyramid.interfaces import IAssetDescriptor + from zope.interface.verify import verifyObject + verifyObject(IAssetDescriptor, self._makeOne()) + + def test_absspec(self): + inst = self._makeOne() + self.assertRaises(NotImplementedError, inst.absspec) + + def test_abspath(self): + inst = self._makeOne() + self.assertEqual(inst.abspath(), os.path.join(here, 'test_asset.py')) + + def test_stream(self): + inst = self._makeOne() + s = inst.stream() + val = s.read() + s.close() + self.assertTrue(b'asset' in val) + + def test_isdir_False(self): + inst = self._makeOne() + self.assertFalse(inst.isdir()) + + def test_isdir_True(self): + inst = self._makeOne(here) + self.assertTrue(inst.isdir()) + + def test_listdir(self): + inst = self._makeOne(here) + self.assertTrue(inst.listdir()) + + def test_exists(self): + inst = self._makeOne() + self.assertTrue(inst.exists()) + +class TestDottedNameResolver(unittest.TestCase): + def _makeOne(self, package=None): + from pyramid.path import DottedNameResolver + return DottedNameResolver(package) + + def config_exc(self, func, *arg, **kw): + try: + func(*arg, **kw) + except ValueError as e: + return e + else: + raise AssertionError('Invalid not raised') # pragma: no cover + + def test_zope_dottedname_style_resolve_builtin(self): + typ = self._makeOne() + if PY2: + result = typ._zope_dottedname_style('__builtin__.str', None) + else: + result = typ._zope_dottedname_style('builtins.str', None) + self.assertEqual(result, str) + + def test_zope_dottedname_style_resolve_absolute(self): + typ = self._makeOne() + result = typ._zope_dottedname_style( + 'pyramid.tests.test_path.TestDottedNameResolver', None) + self.assertEqual(result, self.__class__) + + def test_zope_dottedname_style_irrresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ._zope_dottedname_style, + 'pyramid.test_path.nonexisting_name', None) + + def test__zope_dottedname_style_resolve_relative(self): + import pyramid.tests + typ = self._makeOne() + result = typ._zope_dottedname_style( + '.test_path.TestDottedNameResolver', pyramid.tests) + self.assertEqual(result, self.__class__) + + def test__zope_dottedname_style_resolve_relative_leading_dots(self): + import pyramid.tests.test_path + typ = self._makeOne() + result = typ._zope_dottedname_style( + '..tests.test_path.TestDottedNameResolver', pyramid.tests) + self.assertEqual(result, self.__class__) + + def test__zope_dottedname_style_resolve_relative_is_dot(self): + import pyramid.tests + typ = self._makeOne() + result = typ._zope_dottedname_style('.', pyramid.tests) + self.assertEqual(result, pyramid.tests) + + def test__zope_dottedname_style_irresolveable_relative_is_dot(self): + typ = self._makeOne() + e = self.config_exc(typ._zope_dottedname_style, '.', None) + self.assertEqual( + e.args[0], + "relative name '.' irresolveable without package") + + def test_zope_dottedname_style_resolve_relative_nocurrentpackage(self): + typ = self._makeOne() + e = self.config_exc(typ._zope_dottedname_style, '.whatever', None) + self.assertEqual( + e.args[0], + "relative name '.whatever' irresolveable without package") + + def test_zope_dottedname_style_irrresolveable_relative(self): + import pyramid.tests + typ = self._makeOne() + self.assertRaises(ImportError, typ._zope_dottedname_style, + '.notexisting', pyramid.tests) + + def test__zope_dottedname_style_resolveable_relative(self): + import pyramid + typ = self._makeOne() + result = typ._zope_dottedname_style('.tests', pyramid) + from pyramid import tests + self.assertEqual(result, tests) + + def test__zope_dottedname_style_irresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises( + ImportError, + typ._zope_dottedname_style, 'pyramid.fudge.bar', None) + + def test__zope_dottedname_style_resolveable_absolute(self): + typ = self._makeOne() + result = typ._zope_dottedname_style( + 'pyramid.tests.test_path.TestDottedNameResolver', None) + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_resolve_absolute(self): + typ = self._makeOne() + result = typ._pkg_resources_style( + 'pyramid.tests.test_path:TestDottedNameResolver', None) + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_irrresolveable_absolute(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ._pkg_resources_style, + 'pyramid.tests:nonexisting', None) + + def test__pkg_resources_style_resolve_relative(self): + import pyramid.tests + typ = self._makeOne() + result = typ._pkg_resources_style( + '.test_path:TestDottedNameResolver', pyramid.tests) + self.assertEqual(result, self.__class__) + + def test__pkg_resources_style_resolve_relative_is_dot(self): + import pyramid.tests + typ = self._makeOne() + result = typ._pkg_resources_style('.', pyramid.tests) + self.assertEqual(result, pyramid.tests) + + def test__pkg_resources_style_resolve_relative_nocurrentpackage(self): + typ = self._makeOne() + self.assertRaises(ValueError, typ._pkg_resources_style, + '.whatever', None) + + def test__pkg_resources_style_irrresolveable_relative(self): + import pyramid + typ = self._makeOne() + self.assertRaises(ImportError, typ._pkg_resources_style, + ':notexisting', pyramid) + + def test_resolve_not_a_string(self): + typ = self._makeOne() + e = self.config_exc(typ.resolve, None) + self.assertEqual(e.args[0], 'None is not a string') + + def test_resolve_using_pkgresources_style(self): + typ = self._makeOne() + result = typ.resolve( + 'pyramid.tests.test_path:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test_resolve_using_zope_dottedname_style(self): + typ = self._makeOne() + result = typ.resolve( + 'pyramid.tests.test_path:TestDottedNameResolver') + self.assertEqual(result, self.__class__) + + def test_resolve_missing_raises(self): + typ = self._makeOne() + self.assertRaises(ImportError, typ.resolve, 'cant.be.found') + + def test_resolve_caller_package(self): + from pyramid.path import CALLER_PACKAGE + typ = self._makeOne(CALLER_PACKAGE) + self.assertEqual(typ.resolve('.test_path.TestDottedNameResolver'), + self.__class__) + + def test_maybe_resolve_caller_package(self): + from pyramid.path import CALLER_PACKAGE + typ = self._makeOne(CALLER_PACKAGE) + self.assertEqual(typ.maybe_resolve('.test_path.TestDottedNameResolver'), + self.__class__) + + def test_ctor_string_module_resolveable(self): + import pyramid.tests + typ = self._makeOne('pyramid.tests.test_path') + self.assertEqual(typ.package, pyramid.tests) + + def test_ctor_string_package_resolveable(self): + import pyramid.tests + typ = self._makeOne('pyramid.tests') + self.assertEqual(typ.package, pyramid.tests) + + def test_ctor_string_irresolveable(self): + self.assertRaises(ValueError, self._makeOne, 'cant.be.found') + + def test_ctor_module(self): + import pyramid.tests + import pyramid.tests.test_path + typ = self._makeOne(pyramid.tests.test_path) + self.assertEqual(typ.package, pyramid.tests) + + def test_ctor_package(self): + import pyramid.tests + typ = self._makeOne(pyramid.tests) + self.assertEqual(typ.package, pyramid.tests) + + def test_ctor_None(self): + typ = self._makeOne(None) + self.assertEqual(typ.package, None) + +class DummyPkgResource(object): + pass + +class DummyPackageOrModule: + def __init__(self, real_package_or_module, raise_exc=None): + self.__dict__['raise_exc'] = raise_exc + self.__dict__['__name__'] = real_package_or_module.__name__ + import os + self.__dict__['package_path'] = os.path.dirname( + os.path.abspath(real_package_or_module.__file__)) + self.__dict__['__file__'] = real_package_or_module.__file__ + + def __setattr__(self, key, val): + if self.raise_exc is not None: + raise self.raise_exc + self.__dict__[key] = val + +class DummyNamespacePackage: + """Has no __file__ attribute. + """ + + def __init__(self, real_package_or_module): + self.__name__ = real_package_or_module.__name__ + import os + self.package_path = os.path.dirname( + os.path.abspath(real_package_or_module.__file__)) diff --git a/tests/test_predicates.py b/tests/test_predicates.py new file mode 100644 index 000000000..da0b44708 --- /dev/null +++ b/tests/test_predicates.py @@ -0,0 +1,556 @@ +import unittest + +from pyramid import testing + +from pyramid.compat import text_ + +class TestXHRPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import XHRPredicate + return XHRPredicate(val, None) + + def test___call___true(self): + inst = self._makeOne(True) + request = Dummy() + request.is_xhr = True + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(True) + request = Dummy() + request.is_xhr = False + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(True) + self.assertEqual(inst.text(), 'xhr = True') + + def test_phash(self): + inst = self._makeOne(True) + self.assertEqual(inst.phash(), 'xhr = True') + +class TestRequestMethodPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import RequestMethodPredicate + return RequestMethodPredicate(val, None) + + def test_ctor_get_but_no_head(self): + inst = self._makeOne('GET') + self.assertEqual(inst.val, ('GET', 'HEAD')) + + def test___call___true_single(self): + inst = self._makeOne('GET') + request = Dummy() + request.method = 'GET' + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_multi(self): + inst = self._makeOne(('GET','HEAD')) + request = Dummy() + request.method = 'GET' + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(('GET','HEAD')) + request = Dummy() + request.method = 'POST' + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(('HEAD','GET')) + self.assertEqual(inst.text(), 'request_method = GET,HEAD') + + def test_phash(self): + inst = self._makeOne(('HEAD','GET')) + self.assertEqual(inst.phash(), 'request_method = GET,HEAD') + +class TestPathInfoPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import PathInfoPredicate + return PathInfoPredicate(val, None) + + def test_ctor_compilefail(self): + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, self._makeOne, '\\') + + def test___call___true(self): + inst = self._makeOne(r'/\d{2}') + request = Dummy() + request.upath_info = text_('/12') + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne(r'/\d{2}') + request = Dummy() + request.upath_info = text_('/n12') + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne('/') + self.assertEqual(inst.text(), 'path_info = /') + + def test_phash(self): + inst = self._makeOne('/') + self.assertEqual(inst.phash(), 'path_info = /') + +class TestRequestParamPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import RequestParamPredicate + return RequestParamPredicate(val, None) + + def test___call___true_exists(self): + inst = self._makeOne('abc') + request = Dummy() + request.params = {'abc':1} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withval(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.params = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_multi(self): + inst = self._makeOne(('abc', '=def =2= ')) + request = Dummy() + request.params = {'abc':'1', '=def': '2='} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false_multi(self): + inst = self._makeOne(('abc=3', 'def =2 ')) + request = Dummy() + request.params = {'abc':'3', 'def': '1'} + result = inst(None, request) + self.assertFalse(result) + + def test___call___false(self): + inst = self._makeOne('abc') + request = Dummy() + request.params = {} + result = inst(None, request) + self.assertFalse(result) + + def test_text_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.text(), 'request_param abc') + + def test_text_exists_equal_sign(self): + inst = self._makeOne('=abc') + self.assertEqual(inst.text(), 'request_param =abc') + + def test_text_withval(self): + inst = self._makeOne('abc= 1') + self.assertEqual(inst.text(), 'request_param abc=1') + + def test_text_multi(self): + inst = self._makeOne(('abc= 1', 'def')) + self.assertEqual(inst.text(), 'request_param abc=1,def') + + def test_text_multi_equal_sign(self): + inst = self._makeOne(('abc= 1', '=def= 2')) + self.assertEqual(inst.text(), 'request_param =def=2,abc=1') + + def test_phash_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.phash(), 'request_param abc') + + def test_phash_exists_equal_sign(self): + inst = self._makeOne('=abc') + self.assertEqual(inst.phash(), 'request_param =abc') + + def test_phash_withval(self): + inst = self._makeOne('abc= 1') + self.assertEqual(inst.phash(), "request_param abc=1") + +class TestMatchParamPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import MatchParamPredicate + return MatchParamPredicate(val, None) + + def test___call___true_single(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + + def test___call___true_multi(self): + inst = self._makeOne(('abc=1', 'def=2')) + request = Dummy() + request.matchdict = {'abc':'1', 'def':'2'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = {} + result = inst(None, request) + self.assertFalse(result) + + def test___call___matchdict_is_None(self): + inst = self._makeOne('abc=1') + request = Dummy() + request.matchdict = None + result = inst(None, request) + self.assertFalse(result) + + def test_text(self): + inst = self._makeOne(('def= 1', 'abc =2')) + self.assertEqual(inst.text(), 'match_param abc=2,def=1') + + def test_phash(self): + inst = self._makeOne(('def= 1', 'abc =2')) + self.assertEqual(inst.phash(), 'match_param abc=2,def=1') + +class TestCustomPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import CustomPredicate + return CustomPredicate(val, None) + + def test___call___true(self): + def func(context, request): + self.assertEqual(context, None) + self.assertEqual(request, None) + return True + inst = self._makeOne(func) + result = inst(None, None) + self.assertTrue(result) + + def test___call___false(self): + def func(context, request): + self.assertEqual(context, None) + self.assertEqual(request, None) + return False + inst = self._makeOne(func) + result = inst(None, None) + self.assertFalse(result) + + def test_text_func_has___text__(self): + pred = predicate() + pred.__text__ = 'text' + inst = self._makeOne(pred) + self.assertEqual(inst.text(), 'text') + + def test_text_func_repr(self): + pred = predicate() + inst = self._makeOne(pred) + self.assertEqual(inst.text(), 'custom predicate: object predicate') + + def test_phash(self): + pred = predicate() + inst = self._makeOne(pred) + self.assertEqual(inst.phash(), 'custom:1') + +class TestTraversePredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import TraversePredicate + return TraversePredicate(val, None) + + def test___call__traverse_has_remainder_already(self): + inst = self._makeOne('/1/:a/:b') + info = {'traverse':'abc'} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'traverse':'abc'}) + + def test___call__traverse_matches(self): + inst = self._makeOne('/1/:a/:b') + info = {'match':{'a':'a', 'b':'b'}} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual(info, {'match': + {'a':'a', 'b':'b', 'traverse':('1', 'a', 'b')}}) + + def test___call__traverse_matches_with_highorder_chars(self): + inst = self._makeOne(text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8')) + info = {'match':{'x':text_(b'Qu\xc3\xa9bec', 'utf-8')}} + request = Dummy() + result = inst(info, request) + self.assertEqual(result, True) + self.assertEqual( + info['match']['traverse'], + (text_(b'La Pe\xc3\xb1a', 'utf-8'), + text_(b'Qu\xc3\xa9bec', 'utf-8')) + ) + + def test_text(self): + inst = self._makeOne('/abc') + self.assertEqual(inst.text(), 'traverse matchdict pseudo-predicate') + + def test_phash(self): + inst = self._makeOne('/abc') + self.assertEqual(inst.phash(), '') + +class Test_CheckCSRFTokenPredicate(unittest.TestCase): + def _makeOne(self, val, config): + from pyramid.predicates import CheckCSRFTokenPredicate + return CheckCSRFTokenPredicate(val, config) + + def test_text(self): + inst = self._makeOne(True, None) + self.assertEqual(inst.text(), 'check_csrf = True') + + def test_phash(self): + inst = self._makeOne(True, None) + self.assertEqual(inst.phash(), 'check_csrf = True') + + def test_it_call_val_True(self): + inst = self._makeOne(True, None) + request = Dummy() + def check_csrf_token(req, val, raises=True): + self.assertEqual(req, request) + self.assertEqual(val, 'csrf_token') + self.assertEqual(raises, False) + return True + inst.check_csrf_token = check_csrf_token + result = inst(None, request) + self.assertEqual(result, True) + + def test_it_call_val_str(self): + inst = self._makeOne('abc', None) + request = Dummy() + def check_csrf_token(req, val, raises=True): + self.assertEqual(req, request) + self.assertEqual(val, 'abc') + self.assertEqual(raises, False) + return True + inst.check_csrf_token = check_csrf_token + result = inst(None, request) + self.assertEqual(result, True) + + def test_it_call_val_False(self): + inst = self._makeOne(False, None) + request = Dummy() + result = inst(None, request) + self.assertEqual(result, True) + +class TestHeaderPredicate(unittest.TestCase): + def _makeOne(self, val): + from pyramid.predicates import HeaderPredicate + return HeaderPredicate(val, None) + + def test___call___true_exists(self): + inst = self._makeOne('abc') + request = Dummy() + request.headers = {'abc':1} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withval(self): + inst = self._makeOne('abc:1') + request = Dummy() + request.headers = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___true_withregex(self): + inst = self._makeOne(r'abc:\d+') + request = Dummy() + request.headers = {'abc':'1'} + result = inst(None, request) + self.assertTrue(result) + + def test___call___false_withregex(self): + inst = self._makeOne(r'abc:\d+') + request = Dummy() + request.headers = {'abc':'a'} + result = inst(None, request) + self.assertFalse(result) + + def test___call___false(self): + inst = self._makeOne('abc') + request = Dummy() + request.headers = {} + result = inst(None, request) + self.assertFalse(result) + + def test_text_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.text(), 'header abc') + + def test_text_withval(self): + inst = self._makeOne('abc:1') + self.assertEqual(inst.text(), 'header abc=1') + + def test_text_withregex(self): + inst = self._makeOne(r'abc:\d+') + self.assertEqual(inst.text(), r'header abc=\d+') + + def test_phash_exists(self): + inst = self._makeOne('abc') + self.assertEqual(inst.phash(), 'header abc') + + def test_phash_withval(self): + inst = self._makeOne('abc:1') + self.assertEqual(inst.phash(), "header abc=1") + + def test_phash_withregex(self): + inst = self._makeOne(r'abc:\d+') + self.assertEqual(inst.phash(), r'header abc=\d+') + +class Test_PhysicalPathPredicate(unittest.TestCase): + def _makeOne(self, val, config): + from pyramid.predicates import PhysicalPathPredicate + return PhysicalPathPredicate(val, config) + + def test_text(self): + inst = self._makeOne('/', None) + self.assertEqual(inst.text(), "physical_path = ('',)") + + def test_phash(self): + inst = self._makeOne('/', None) + self.assertEqual(inst.phash(), "physical_path = ('',)") + + def test_it_call_val_tuple_True(self): + inst = self._makeOne(('', 'abc'), None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_val_list_True(self): + inst = self._makeOne(['', 'abc'], None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_val_str_True(self): + inst = self._makeOne('/abc', None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertTrue(inst(context, None)) + + def test_it_call_False(self): + inst = self._makeOne('/', None) + root = Dummy() + root.__name__ = '' + root.__parent__ = None + context = Dummy() + context.__name__ = 'abc' + context.__parent__ = root + self.assertFalse(inst(context, None)) + + def test_it_call_context_has_no_name(self): + inst = self._makeOne('/', None) + context = Dummy() + self.assertFalse(inst(context, None)) + +class Test_EffectivePrincipalsPredicate(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, val, config): + from pyramid.predicates import EffectivePrincipalsPredicate + return EffectivePrincipalsPredicate(val, config) + + def test_text(self): + inst = self._makeOne(('verna', 'fred'), None) + self.assertEqual(inst.text(), + "effective_principals = ['fred', 'verna']") + + def test_text_noniter(self): + inst = self._makeOne('verna', None) + self.assertEqual(inst.text(), + "effective_principals = ['verna']") + + def test_phash(self): + inst = self._makeOne(('verna', 'fred'), None) + self.assertEqual(inst.phash(), + "effective_principals = ['fred', 'verna']") + + def test_it_call_no_authentication_policy(self): + request = testing.DummyRequest() + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertFalse(inst(context, request)) + + def test_it_call_authentication_policy_provides_superset(self): + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertTrue(inst(context, request)) + + def test_it_call_authentication_policy_provides_superset_implicit(self): + from pyramid.security import Authenticated + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred', groupids=('verna', 'bambi')) + inst = self._makeOne(Authenticated, None) + context = Dummy() + self.assertTrue(inst(context, request)) + + def test_it_call_authentication_policy_doesnt_provide_superset(self): + request = testing.DummyRequest() + self.config.testing_securitypolicy('fred') + inst = self._makeOne(('verna', 'fred'), None) + context = Dummy() + self.assertFalse(inst(context, request)) + + +class TestNotted(unittest.TestCase): + def _makeOne(self, predicate): + from pyramid.predicates import Notted + return Notted(predicate) + + def test_it_with_phash_val(self): + pred = DummyPredicate('val') + inst = self._makeOne(pred) + self.assertEqual(inst.text(), '!val') + self.assertEqual(inst.phash(), '!val') + self.assertEqual(inst(None, None), False) + + def test_it_without_phash_val(self): + pred = DummyPredicate('') + inst = self._makeOne(pred) + self.assertEqual(inst.text(), '') + self.assertEqual(inst.phash(), '') + self.assertEqual(inst(None, None), True) + +class predicate(object): + def __repr__(self): + return 'predicate' + def __hash__(self): + return 1 + +class Dummy(object): + pass + +class DummyPredicate(object): + def __init__(self, result): + self.result = result + + def text(self): + return self.result + + phash = text + + def __call__(self, context, request): + return True diff --git a/tests/test_registry.py b/tests/test_registry.py new file mode 100644 index 000000000..aa44b5408 --- /dev/null +++ b/tests/test_registry.py @@ -0,0 +1,401 @@ +import unittest + +class TestRegistry(unittest.TestCase): + def _getTargetClass(self): + from pyramid.registry import Registry + return Registry + + def _makeOne(self, *args, **kw): + return self._getTargetClass()(*args, **kw) + + def test___nonzero__(self): + registry = self._makeOne() + self.assertEqual(registry.__nonzero__(), True) + + def test__lock(self): + registry = self._makeOne() + self.assertTrue(registry._lock) + + def test_clear_view_cache_lookup(self): + registry = self._makeOne() + registry._view_lookup_cache[1] = 2 + registry._clear_view_lookup_cache() + self.assertEqual(registry._view_lookup_cache, {}) + + def test_package_name(self): + package_name = 'testing' + registry = self._makeOne(package_name) + self.assertEqual(registry.package_name, package_name) + + def test_default_package_name(self): + registry = self._makeOne() + self.assertEqual(registry.package_name, 'pyramid.tests') + + def test_registerHandler_and_notify(self): + registry = self._makeOne() + self.assertEqual(registry.has_listeners, False) + L = [] + def f(event): + L.append(event) + registry.registerHandler(f, [IDummyEvent]) + self.assertEqual(registry.has_listeners, True) + event = DummyEvent() + registry.notify(event) + self.assertEqual(L, [event]) + + def test_registerSubscriptionAdapter(self): + registry = self._makeOne() + self.assertEqual(registry.has_listeners, False) + from zope.interface import Interface + registry.registerSubscriptionAdapter(DummyEvent, + [IDummyEvent], Interface) + self.assertEqual(registry.has_listeners, True) + + def test__get_settings(self): + registry = self._makeOne() + registry._settings = 'foo' + self.assertEqual(registry.settings, 'foo') + + def test__set_settings(self): + registry = self._makeOne() + registry.settings = 'foo' + self.assertEqual(registry._settings, 'foo') + + def test_init_forwards_args(self): + from zope.interface import Interface + from zope.interface.registry import Components + dummy = object() + c = Components() + c.registerUtility(dummy, Interface) + registry = self._makeOne('foo', (c,)) + self.assertEqual(registry.__name__, 'foo') + self.assertEqual(registry.getUtility(Interface), dummy) + + def test_init_forwards_kw(self): + from zope.interface import Interface + from zope.interface.registry import Components + dummy = object() + c = Components() + c.registerUtility(dummy, Interface) + registry = self._makeOne(bases=(c,)) + self.assertEqual(registry.getUtility(Interface), dummy) + +class TestIntrospector(unittest.TestCase): + def _getTargetClass(slf): + from pyramid.registry import Introspector + return Introspector + + def _makeOne(self): + return self._getTargetClass()() + + def test_conformance(self): + from zope.interface.verify import verifyClass + from zope.interface.verify import verifyObject + from pyramid.interfaces import IIntrospector + verifyClass(IIntrospector, self._getTargetClass()) + verifyObject(IIntrospector, self._makeOne()) + + def test_add(self): + inst = self._makeOne() + intr = DummyIntrospectable() + inst.add(intr) + self.assertEqual(intr.order, 0) + category = {'discriminator':intr, 'discriminator_hash':intr} + self.assertEqual(inst._categories, {'category':category}) + + def test_get_success(self): + inst = self._makeOne() + intr = DummyIntrospectable() + inst.add(intr) + self.assertEqual(inst.get('category', 'discriminator'), intr) + + def test_get_success_byhash(self): + inst = self._makeOne() + intr = DummyIntrospectable() + inst.add(intr) + self.assertEqual(inst.get('category', 'discriminator_hash'), intr) + + def test_get_fail(self): + inst = self._makeOne() + intr = DummyIntrospectable() + inst.add(intr) + self.assertEqual(inst.get('category', 'wontexist', 'foo'), 'foo') + + def test_get_category(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr2) + inst.add(intr) + expected = [ + {'introspectable':intr2, 'related':[]}, + {'introspectable':intr, 'related':[]}, + ] + self.assertEqual(inst.get_category('category'), expected) + + def test_get_category_returns_default_on_miss(self): + inst = self._makeOne() + self.assertEqual(inst.get_category('category', '123'), '123') + + def test_get_category_with_sortkey(self): + import operator + inst = self._makeOne() + intr = DummyIntrospectable() + intr.foo = 2 + intr2 = DummyIntrospectable() + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + intr2.foo = 1 + inst.add(intr) + inst.add(intr2) + expected = [ + {'introspectable':intr2, 'related':[]}, + {'introspectable':intr, 'related':[]}, + ] + self.assertEqual( + inst.get_category('category', sort_key=operator.attrgetter('foo')), + expected) + + def test_categorized(self): + import operator + inst = self._makeOne() + intr = DummyIntrospectable() + intr.foo = 2 + intr2 = DummyIntrospectable() + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + intr2.foo = 1 + inst.add(intr) + inst.add(intr2) + expected = [('category', [ + {'introspectable':intr2, 'related':[]}, + {'introspectable':intr, 'related':[]}, + ])] + self.assertEqual( + inst.categorized(sort_key=operator.attrgetter('foo')), expected) + + def test_categories(self): + inst = self._makeOne() + inst._categories['a'] = 1 + inst._categories['b'] = 2 + self.assertEqual(list(inst.categories()), ['a', 'b']) + + def test_remove(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.category_name = 'category2' + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr) + inst.add(intr2) + inst.relate(('category', 'discriminator'), + ('category2', 'discriminator2')) + inst.remove('category', 'discriminator') + self.assertEqual(inst._categories, + {'category': + {}, + 'category2': + {'discriminator2': intr2, + 'discriminator2_hash': intr2} + }) + self.assertEqual(inst._refs.get(intr), None) + self.assertEqual(inst._refs[intr2], []) + + def test_remove_fail(self): + inst = self._makeOne() + self.assertEqual(inst.remove('a', 'b'), None) + + def test_relate(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.category_name = 'category2' + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr) + inst.add(intr2) + inst.relate(('category', 'discriminator'), + ('category2', 'discriminator2')) + self.assertEqual(inst._categories, + {'category': + {'discriminator':intr, + 'discriminator_hash':intr}, + 'category2': + {'discriminator2': intr2, + 'discriminator2_hash': intr2} + }) + self.assertEqual(inst._refs[intr], [intr2]) + self.assertEqual(inst._refs[intr2], [intr]) + + def test_relate_fail(self): + inst = self._makeOne() + intr = DummyIntrospectable() + inst.add(intr) + self.assertRaises( + KeyError, + inst.relate, + ('category', 'discriminator'), + ('category2', 'discriminator2') + ) + + def test_unrelate(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.category_name = 'category2' + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr) + inst.add(intr2) + inst.relate(('category', 'discriminator'), + ('category2', 'discriminator2')) + inst.unrelate(('category', 'discriminator'), + ('category2', 'discriminator2')) + self.assertEqual(inst._categories, + {'category': + {'discriminator':intr, + 'discriminator_hash':intr}, + 'category2': + {'discriminator2': intr2, + 'discriminator2_hash': intr2} + }) + self.assertEqual(inst._refs[intr], []) + self.assertEqual(inst._refs[intr2], []) + + def test_related(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.category_name = 'category2' + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr) + inst.add(intr2) + inst.relate(('category', 'discriminator'), + ('category2', 'discriminator2')) + self.assertEqual(inst.related(intr), [intr2]) + + def test_related_fail(self): + inst = self._makeOne() + intr = DummyIntrospectable() + intr2 = DummyIntrospectable() + intr2.category_name = 'category2' + intr2.discriminator = 'discriminator2' + intr2.discriminator_hash = 'discriminator2_hash' + inst.add(intr) + inst.add(intr2) + inst.relate(('category', 'discriminator'), + ('category2', 'discriminator2')) + del inst._categories['category'] + self.assertRaises(KeyError, inst.related, intr) + +class TestIntrospectable(unittest.TestCase): + def _getTargetClass(slf): + from pyramid.registry import Introspectable + return Introspectable + + def _makeOne(self, *arg, **kw): + return self._getTargetClass()(*arg, **kw) + + def _makeOnePopulated(self): + return self._makeOne('category', 'discrim', 'title', 'type') + + def test_conformance(self): + from zope.interface.verify import verifyClass + from zope.interface.verify import verifyObject + from pyramid.interfaces import IIntrospectable + verifyClass(IIntrospectable, self._getTargetClass()) + verifyObject(IIntrospectable, self._makeOnePopulated()) + + def test_relate(self): + inst = self._makeOnePopulated() + inst.relate('a', 'b') + self.assertEqual(inst._relations, [(True, 'a', 'b')]) + + def test_unrelate(self): + inst = self._makeOnePopulated() + inst.unrelate('a', 'b') + self.assertEqual(inst._relations, [(False, 'a', 'b')]) + + def test_discriminator_hash(self): + inst = self._makeOnePopulated() + self.assertEqual(inst.discriminator_hash, hash(inst.discriminator)) + + def test___hash__(self): + inst = self._makeOnePopulated() + self.assertEqual(hash(inst), + hash((inst.category_name,) + (inst.discriminator,))) + + def test___repr__(self): + inst = self._makeOnePopulated() + self.assertEqual( + repr(inst), + "") + + def test___nonzero__(self): + inst = self._makeOnePopulated() + self.assertEqual(inst.__nonzero__(), True) + + def test___bool__(self): + inst = self._makeOnePopulated() + self.assertEqual(inst.__bool__(), True) + + def test_register(self): + introspector = DummyIntrospector() + action_info = object() + inst = self._makeOnePopulated() + inst._relations.append((True, 'category1', 'discrim1')) + inst._relations.append((False, 'category2', 'discrim2')) + inst.register(introspector, action_info) + self.assertEqual(inst.action_info, action_info) + self.assertEqual(introspector.intrs, [inst]) + self.assertEqual(introspector.relations, + [(('category', 'discrim'), ('category1', 'discrim1'))]) + self.assertEqual(introspector.unrelations, + [(('category', 'discrim'), ('category2', 'discrim2'))]) + +class DummyIntrospector(object): + def __init__(self): + self.intrs = [] + self.relations = [] + self.unrelations = [] + + def add(self, intr): + self.intrs.append(intr) + + def relate(self, *pairs): + self.relations.append(pairs) + + def unrelate(self, *pairs): + self.unrelations.append(pairs) + +class DummyModule: + __path__ = "foo" + __name__ = "dummy" + __file__ = '' + +class DummyIntrospectable(object): + category_name = 'category' + discriminator = 'discriminator' + title = 'title' + type_name = 'type' + order = None + action_info = None + discriminator_hash = 'discriminator_hash' + + def __hash__(self): + return hash((self.category_name,) + (self.discriminator,)) + + +from zope.interface import Interface +from zope.interface import implementer +class IDummyEvent(Interface): + pass + +@implementer(IDummyEvent) +class DummyEvent(object): + pass + diff --git a/tests/test_renderers.py b/tests/test_renderers.py new file mode 100644 index 000000000..a2f7bf8c2 --- /dev/null +++ b/tests/test_renderers.py @@ -0,0 +1,705 @@ +import unittest + +from pyramid.testing import cleanUp +from pyramid import testing +from pyramid.compat import text_ + +class TestJSON(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, **kw): + from pyramid.renderers import JSON + return JSON(**kw) + + def test_it(self): + renderer = self._makeOne()(None) + result = renderer({'a':1}, {}) + self.assertEqual(result, '{"a": 1}') + + def test_with_request_content_type_notset(self): + request = testing.DummyRequest() + renderer = self._makeOne()(None) + renderer({'a':1}, {'request':request}) + self.assertEqual(request.response.content_type, 'application/json') + + def test_with_request_content_type_set(self): + request = testing.DummyRequest() + request.response.content_type = 'text/mishmash' + renderer = self._makeOne()(None) + renderer({'a':1}, {'request':request}) + self.assertEqual(request.response.content_type, 'text/mishmash') + + def test_with_custom_adapter(self): + request = testing.DummyRequest() + from datetime import datetime + def adapter(obj, req): + self.assertEqual(req, request) + return obj.isoformat() + now = datetime.utcnow() + renderer = self._makeOne() + renderer.add_adapter(datetime, adapter) + result = renderer(None)({'a':now}, {'request':request}) + self.assertEqual(result, '{"a": "%s"}' % now.isoformat()) + + def test_with_custom_adapter2(self): + request = testing.DummyRequest() + from datetime import datetime + def adapter(obj, req): + self.assertEqual(req, request) + return obj.isoformat() + now = datetime.utcnow() + renderer = self._makeOne(adapters=((datetime, adapter),)) + result = renderer(None)({'a':now}, {'request':request}) + self.assertEqual(result, '{"a": "%s"}' % now.isoformat()) + + def test_with_custom_serializer(self): + class Serializer(object): + def __call__(self, obj, **kw): + self.obj = obj + self.kw = kw + return 'foo' + serializer = Serializer() + renderer = self._makeOne(serializer=serializer, baz=5) + obj = {'a':'b'} + result = renderer(None)(obj, {}) + self.assertEqual(result, 'foo') + self.assertEqual(serializer.obj, obj) + self.assertEqual(serializer.kw['baz'], 5) + self.assertTrue('default' in serializer.kw) + + def test_with_object_adapter(self): + request = testing.DummyRequest() + outerself = self + class MyObject(object): + def __init__(self, x): + self.x = x + def __json__(self, req): + outerself.assertEqual(req, request) + return {'x': self.x} + + objects = [MyObject(1), MyObject(2)] + renderer = self._makeOne()(None) + result = renderer(objects, {'request':request}) + self.assertEqual(result, '[{"x": 1}, {"x": 2}]') + + def test_with_object_adapter_no___json__(self): + class MyObject(object): + def __init__(self, x): + self.x = x + objects = [MyObject(1), MyObject(2)] + renderer = self._makeOne()(None) + self.assertRaises(TypeError, renderer, objects, {}) + +class Test_string_renderer_factory(unittest.TestCase): + def _callFUT(self, name): + from pyramid.renderers import string_renderer_factory + return string_renderer_factory(name) + + def test_it_unicode(self): + renderer = self._callFUT(None) + value = text_('La Pe\xc3\xb1a', 'utf-8') + result = renderer(value, {}) + self.assertEqual(result, value) + + def test_it_str(self): + renderer = self._callFUT(None) + value = 'La Pe\xc3\xb1a' + result = renderer(value, {}) + self.assertEqual(result, value) + + def test_it_other(self): + renderer = self._callFUT(None) + value = None + result = renderer(value, {}) + self.assertEqual(result, 'None') + + def test_with_request_content_type_notset(self): + request = testing.DummyRequest() + renderer = self._callFUT(None) + renderer('', {'request':request}) + self.assertEqual(request.response.content_type, 'text/plain') + + def test_with_request_content_type_set(self): + request = testing.DummyRequest() + request.response.content_type = 'text/mishmash' + renderer = self._callFUT(None) + renderer('', {'request':request}) + self.assertEqual(request.response.content_type, 'text/mishmash') + + +class TestRendererHelper(unittest.TestCase): + def setUp(self): + self.config = cleanUp() + + def tearDown(self): + cleanUp() + + def _makeOne(self, *arg, **kw): + from pyramid.renderers import RendererHelper + return RendererHelper(*arg, **kw) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IRendererInfo + helper = self._makeOne() + verifyObject(IRendererInfo, helper) + + def test_settings_registry_settings_is_None(self): + class Dummy(object): + settings = None + helper = self._makeOne(registry=Dummy) + self.assertEqual(helper.settings, {}) + + def test_settings_registry_name_is_None(self): + class Dummy(object): + settings = None + helper = self._makeOne(registry=Dummy) + self.assertEqual(helper.name, None) + self.assertEqual(helper.type, '') + + def test_settings_registry_settings_is_not_None(self): + class Dummy(object): + settings = {'a':1} + helper = self._makeOne(registry=Dummy) + self.assertEqual(helper.settings, {'a':1}) + + def _registerRendererFactory(self): + from pyramid.interfaces import IRendererFactory + def renderer(*arg): + def respond(*arg): + return arg + renderer.respond = respond + return respond + self.config.registry.registerUtility(renderer, IRendererFactory, + name='.foo') + return renderer + + def _registerResponseFactory(self): + from pyramid.interfaces import IResponseFactory + class ResponseFactory(object): + pass + + self.config.registry.registerUtility( + lambda r: ResponseFactory(), IResponseFactory + ) + + def test_render_to_response(self): + self._registerRendererFactory() + self._registerResponseFactory() + request = Dummy() + helper = self._makeOne('loo.foo') + response = helper.render_to_response('values', {}, + request=request) + self.assertEqual(response.app_iter[0], 'values') + self.assertEqual(response.app_iter[1], {}) + + def test_get_renderer(self): + factory = self._registerRendererFactory() + helper = self._makeOne('loo.foo') + self.assertEqual(helper.get_renderer(), factory.respond) + + def test_render_view(self): + import pyramid.csrf + self._registerRendererFactory() + self._registerResponseFactory() + request = Dummy() + helper = self._makeOne('loo.foo') + view = 'view' + context = 'context' + request = testing.DummyRequest() + response = 'response' + response = helper.render_view(request, response, view, context) + get_csrf = response.app_iter[1].pop('get_csrf_token') + self.assertEqual(get_csrf.args, (request, )) + self.assertEqual(get_csrf.func, pyramid.csrf.get_csrf_token) + self.assertEqual(response.app_iter[0], 'response') + self.assertEqual(response.app_iter[1], + {'renderer_info': helper, + 'renderer_name': 'loo.foo', + 'request': request, + 'context': 'context', + 'view': 'view', + 'req': request,} + ) + + def test_render_explicit_registry(self): + factory = self._registerRendererFactory() + class DummyRegistry(object): + def __init__(self): + self.responses = [factory, lambda *arg: {}, None] + def queryUtility(self, iface, name=None): + self.queried = True + return self.responses.pop(0) + def notify(self, event): + self.event = event + reg = DummyRegistry() + helper = self._makeOne('loo.foo', registry=reg) + result = helper.render('value', {}) + self.assertEqual(result[0], 'value') + self.assertEqual(result[1], {}) + self.assertTrue(reg.queried) + self.assertEqual(reg.event, {}) + self.assertEqual(reg.event.__class__.__name__, 'BeforeRender') + + def test_render_system_values_is_None(self): + import pyramid.csrf + self._registerRendererFactory() + request = Dummy() + context = Dummy() + request.context = context + helper = self._makeOne('loo.foo') + result = helper.render('values', None, request=request) + get_csrf = result[1].pop('get_csrf_token') + self.assertEqual(get_csrf.args, (request, )) + self.assertEqual(get_csrf.func, pyramid.csrf.get_csrf_token) + system = {'request':request, + 'context':context, + 'renderer_name':'loo.foo', + 'view':None, + 'renderer_info':helper, + 'req':request, + } + self.assertEqual(result[0], 'values') + self.assertEqual(result[1], system) + + def test__make_response_request_is_None(self): + request = None + helper = self._makeOne('loo.foo') + response = helper._make_response('abc', request) + self.assertEqual(response.body, b'abc') + + def test__make_response_request_is_None_response_factory_exists(self): + self._registerResponseFactory() + request = None + helper = self._makeOne('loo.foo') + response = helper._make_response(b'abc', request) + self.assertEqual(response.__class__.__name__, 'ResponseFactory') + self.assertEqual(response.body, b'abc') + + def test__make_response_result_is_unicode(self): + from pyramid.response import Response + request = testing.DummyRequest() + request.response = Response() + helper = self._makeOne('loo.foo') + la = text_('/La Pe\xc3\xb1a', 'utf-8') + response = helper._make_response(la, request) + self.assertEqual(response.body, la.encode('utf-8')) + + def test__make_response_result_is_str(self): + from pyramid.response import Response + request = testing.DummyRequest() + request.response = Response() + helper = self._makeOne('loo.foo') + la = text_('/La Pe\xc3\xb1a', 'utf-8') + response = helper._make_response(la.encode('utf-8'), request) + self.assertEqual(response.body, la.encode('utf-8')) + + def test__make_response_result_is_iterable(self): + from pyramid.response import Response + request = testing.DummyRequest() + request.response = Response() + helper = self._makeOne('loo.foo') + la = text_('/La Pe\xc3\xb1a', 'utf-8') + response = helper._make_response([la.encode('utf-8')], request) + self.assertEqual(response.body, la.encode('utf-8')) + + def test__make_response_result_is_other(self): + self._registerResponseFactory() + request = None + helper = self._makeOne('loo.foo') + result = object() + response = helper._make_response(result, request) + self.assertEqual(response.body, result) + + def test__make_response_result_is_None_no_body(self): + from pyramid.response import Response + request = testing.DummyRequest() + request.response = Response() + helper = self._makeOne('loo.foo') + response = helper._make_response(None, request) + self.assertEqual(response.body, b'') + + def test__make_response_result_is_None_existing_body_not_molested(self): + from pyramid.response import Response + request = testing.DummyRequest() + response = Response() + response.body = b'abc' + request.response = response + helper = self._makeOne('loo.foo') + response = helper._make_response(None, request) + self.assertEqual(response.body, b'abc') + + def test_with_alternate_response_factory(self): + from pyramid.interfaces import IResponseFactory + class ResponseFactory(object): + def __init__(self): + pass + self.config.registry.registerUtility( + lambda r: ResponseFactory(), IResponseFactory + ) + request = testing.DummyRequest() + helper = self._makeOne('loo.foo') + response = helper._make_response(b'abc', request) + self.assertEqual(response.__class__, ResponseFactory) + self.assertEqual(response.body, b'abc') + + def test__make_response_with_real_request(self): + # functional + from pyramid.request import Request + request = Request({}) + request.registry = self.config.registry + request.response.status = '406 You Lose' + helper = self._makeOne('loo.foo') + response = helper._make_response('abc', request) + self.assertEqual(response.status, '406 You Lose') + self.assertEqual(response.body, b'abc') + + def test_clone_noargs(self): + helper = self._makeOne('name', 'package', 'registry') + cloned_helper = helper.clone() + self.assertEqual(cloned_helper.name, 'name') + self.assertEqual(cloned_helper.package, 'package') + self.assertEqual(cloned_helper.registry, 'registry') + self.assertFalse(helper is cloned_helper) + + def test_clone_allargs(self): + helper = self._makeOne('name', 'package', 'registry') + cloned_helper = helper.clone(name='name2', package='package2', + registry='registry2') + self.assertEqual(cloned_helper.name, 'name2') + self.assertEqual(cloned_helper.package, 'package2') + self.assertEqual(cloned_helper.registry, 'registry2') + self.assertFalse(helper is cloned_helper) + + def test_renderer_absolute_file(self): + registry = self.config.registry + settings = {} + registry.settings = settings + from pyramid.interfaces import IRendererFactory + import os + here = os.path.dirname(os.path.abspath(__file__)) + fixture = os.path.join(here, 'fixtures/minimal.pt') + def factory(info, **kw): + return info + self.config.registry.registerUtility( + factory, IRendererFactory, name='.pt') + result = self._makeOne(fixture).renderer + self.assertEqual(result.registry, registry) + self.assertEqual(result.type, '.pt') + self.assertEqual(result.package, None) + self.assertEqual(result.name, fixture) + self.assertEqual(result.settings, settings) + + def test_renderer_with_package(self): + import pyramid + registry = self.config.registry + settings = {} + registry.settings = settings + from pyramid.interfaces import IRendererFactory + import os + here = os.path.dirname(os.path.abspath(__file__)) + fixture = os.path.join(here, 'fixtures/minimal.pt') + def factory(info, **kw): + return info + self.config.registry.registerUtility( + factory, IRendererFactory, name='.pt') + result = self._makeOne(fixture, pyramid).renderer + self.assertEqual(result.registry, registry) + self.assertEqual(result.type, '.pt') + self.assertEqual(result.package, pyramid) + self.assertEqual(result.name, fixture) + self.assertEqual(result.settings, settings) + + def test_renderer_missing(self): + inst = self._makeOne('foo') + self.assertRaises(ValueError, getattr, inst, 'renderer') + +class TestNullRendererHelper(unittest.TestCase): + def setUp(self): + self.config = cleanUp() + + def tearDown(self): + cleanUp() + + def _makeOne(self, *arg, **kw): + from pyramid.renderers import NullRendererHelper + return NullRendererHelper(*arg, **kw) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IRendererInfo + helper = self._makeOne() + verifyObject(IRendererInfo, helper) + + def test_render_view(self): + helper = self._makeOne() + self.assertEqual(helper.render_view(None, True, None, None), True) + + def test_render(self): + helper = self._makeOne() + self.assertEqual(helper.render(True, None, None), True) + + def test_render_to_response(self): + helper = self._makeOne() + self.assertEqual(helper.render_to_response(True, None, None), True) + + def test_clone(self): + helper = self._makeOne() + self.assertTrue(helper.clone() is helper) + +class Test_render(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, renderer_name, value, request=None, package=None): + from pyramid.renderers import render + return render(renderer_name, value, request=request, package=package) + + def _registerRenderer(self): + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + renderer.string_response = 'abc' + return renderer + + def test_it_no_request(self): + renderer = self._registerRenderer() + result = self._callFUT('abc/def.pt', dict(a=1)) + self.assertEqual(result, 'abc') + renderer.assert_(a=1) + renderer.assert_(request=None) + + def test_it_with_request(self): + renderer = self._registerRenderer() + request = testing.DummyRequest() + result = self._callFUT('abc/def.pt', + dict(a=1), request=request) + self.assertEqual(result, 'abc') + renderer.assert_(a=1) + renderer.assert_(request=request) + + def test_it_with_package(self): + import pyramid.tests + renderer = self._registerRenderer() + request = testing.DummyRequest() + result = self._callFUT('abc/def.pt', dict(a=1), request=request, + package=pyramid.tests) + self.assertEqual(result, 'abc') + renderer.assert_(a=1) + renderer.assert_(request=request) + + def test_response_preserved(self): + request = testing.DummyRequest() + response = object() # should error if mutated + request.response = response + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertEqual(request.response, response) + + def test_no_response_to_preserve(self): + from pyramid.decorator import reify + class DummyRequestWithClassResponse(object): + _response = DummyResponse() + _response.content_type = None + _response.default_content_type = None + @reify + def response(self): + return self._response + request = DummyRequestWithClassResponse() + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result, '{"a": 1}') + self.assertFalse('response' in request.__dict__) + +class Test_render_to_response(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, renderer_name, value, request=None, package=None, + response=None): + from pyramid.renderers import render_to_response + return render_to_response(renderer_name, value, request=request, + package=package, response=response) + + def test_it_no_request(self): + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + renderer.string_response = 'abc' + response = self._callFUT('abc/def.pt', dict(a=1)) + self.assertEqual(response.body, b'abc') + renderer.assert_(a=1) + renderer.assert_(request=None) + + def test_it_with_request(self): + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + renderer.string_response = 'abc' + request = testing.DummyRequest() + response = self._callFUT('abc/def.pt', + dict(a=1), request=request) + self.assertEqual(response.body, b'abc') + renderer.assert_(a=1) + renderer.assert_(request=request) + + def test_it_with_package(self): + import pyramid.tests + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + renderer.string_response = 'abc' + request = testing.DummyRequest() + response = self._callFUT('abc/def.pt', dict(a=1), request=request, + package=pyramid.tests) + self.assertEqual(response.body, b'abc') + renderer.assert_(a=1) + renderer.assert_(request=request) + + def test_response_preserved(self): + request = testing.DummyRequest() + response = object() # should error if mutated + request.response = response + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result.body, b'{"a": 1}') + self.assertNotEqual(request.response, result) + self.assertEqual(request.response, response) + + def test_no_response_to_preserve(self): + from pyramid.decorator import reify + class DummyRequestWithClassResponse(object): + _response = DummyResponse() + _response.content_type = None + _response.default_content_type = None + @reify + def response(self): + return self._response + request = DummyRequestWithClassResponse() + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request) + self.assertEqual(result.body, b'{"a": 1}') + self.assertFalse('response' in request.__dict__) + + def test_custom_response_object(self): + class DummyRequestWithClassResponse(object): + pass + request = DummyRequestWithClassResponse() + response = DummyResponse() + # use a json renderer, which will mutate the response + result = self._callFUT('json', dict(a=1), request=request, + response=response) + self.assertTrue(result is response) + self.assertEqual(result.body, b'{"a": 1}') + self.assertFalse('response' in request.__dict__) + +class Test_get_renderer(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, renderer_name, **kw): + from pyramid.renderers import get_renderer + return get_renderer(renderer_name, **kw) + + def test_it_no_package(self): + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + result = self._callFUT('abc/def.pt') + self.assertEqual(result, renderer) + + def test_it_with_package(self): + import pyramid.tests + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + result = self._callFUT('abc/def.pt', package=pyramid.tests) + self.assertEqual(result, renderer) + + def test_it_with_registry(self): + renderer = self.config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + result = self._callFUT('abc/def.pt', registry=self.config.registry) + self.assertEqual(result, renderer) + + def test_it_with_isolated_registry(self): + from pyramid.config import Configurator + isolated_config = Configurator() + renderer = isolated_config.testing_add_renderer( + 'pyramid.tests:abc/def.pt') + result = self._callFUT('abc/def.pt', registry=isolated_config.registry) + self.assertEqual(result, renderer) + +class TestJSONP(unittest.TestCase): + def _makeOne(self, param_name='callback'): + from pyramid.renderers import JSONP + return JSONP(param_name) + + def test_render_to_jsonp(self): + renderer_factory = self._makeOne() + renderer = renderer_factory(None) + request = testing.DummyRequest() + request.GET['callback'] = 'callback' + result = renderer({'a':'1'}, {'request':request}) + self.assertEqual(result, '/**/callback({"a": "1"});') + self.assertEqual(request.response.content_type, + 'application/javascript') + + def test_render_to_jsonp_with_dot(self): + renderer_factory = self._makeOne() + renderer = renderer_factory(None) + request = testing.DummyRequest() + request.GET['callback'] = 'angular.callbacks._0' + result = renderer({'a':'1'}, {'request':request}) + self.assertEqual(result, '/**/angular.callbacks._0({"a": "1"});') + self.assertEqual(request.response.content_type, + 'application/javascript') + + def test_render_to_json(self): + renderer_factory = self._makeOne() + renderer = renderer_factory(None) + request = testing.DummyRequest() + result = renderer({'a':'1'}, {'request':request}) + self.assertEqual(result, '{"a": "1"}') + self.assertEqual(request.response.content_type, + 'application/json') + + def test_render_without_request(self): + renderer_factory = self._makeOne() + renderer = renderer_factory(None) + result = renderer({'a':'1'}, {}) + self.assertEqual(result, '{"a": "1"}') + + def test_render_to_jsonp_invalid_callback(self): + from pyramid.httpexceptions import HTTPBadRequest + renderer_factory = self._makeOne() + renderer = renderer_factory(None) + request = testing.DummyRequest() + request.GET['callback'] = '78mycallback' + self.assertRaises(HTTPBadRequest, renderer, {'a':'1'}, {'request':request}) + + +class Dummy: + pass + +class DummyResponse: + status = '200 OK' + default_content_type = 'text/html' + content_type = default_content_type + headerlist = () + app_iter = () + body = b'' + + # compat for renderer that will set unicode on py3 + def _set_text(self, val): # pragma: no cover + self.body = val.encode('utf8') + text = property(fset=_set_text) + diff --git a/tests/test_request.py b/tests/test_request.py new file mode 100644 index 000000000..c79c84d63 --- /dev/null +++ b/tests/test_request.py @@ -0,0 +1,588 @@ +from collections import deque +import unittest +from pyramid import testing + +from pyramid.compat import ( + PY2, + text_, + bytes_, + native_, + ) +from pyramid.security import ( + AuthenticationAPIMixin, + AuthorizationAPIMixin, + ) + +class TestRequest(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _getTargetClass(self): + from pyramid.request import Request + return Request + + def _makeOne(self, environ=None): + if environ is None: + environ = {} + return self._getTargetClass()(environ) + + def _registerResourceURL(self): + from pyramid.interfaces import IResourceURL + from zope.interface import Interface + class DummyResourceURL(object): + def __init__(self, context, request): + self.physical_path = '/context/' + self.virtual_path = '/context/' + self.config.registry.registerAdapter( + DummyResourceURL, (Interface, Interface), + IResourceURL) + + def test_class_conforms_to_IRequest(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import IRequest + verifyClass(IRequest, self._getTargetClass()) + + def test_instance_conforms_to_IRequest(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import IRequest + verifyObject(IRequest, self._makeOne()) + + def test_ResponseClass_is_pyramid_Response(self): + from pyramid.response import Response + cls = self._getTargetClass() + self.assertEqual(cls.ResponseClass, Response) + + def test_implements_security_apis(self): + apis = (AuthenticationAPIMixin, AuthorizationAPIMixin) + r = self._makeOne() + self.assertTrue(isinstance(r, apis)) + + def test_charset_defaults_to_utf8(self): + r = self._makeOne({'PATH_INFO':'/'}) + self.assertEqual(r.charset, 'UTF-8') + + def test_exception_defaults_to_None(self): + r = self._makeOne({'PATH_INFO':'/'}) + self.assertEqual(r.exception, None) + + def test_matchdict_defaults_to_None(self): + r = self._makeOne({'PATH_INFO':'/'}) + self.assertEqual(r.matchdict, None) + + def test_matched_route_defaults_to_None(self): + r = self._makeOne({'PATH_INFO':'/'}) + self.assertEqual(r.matched_route, None) + + def test_params_decoded_from_utf_8_by_default(self): + environ = { + 'PATH_INFO':'/', + 'QUERY_STRING':'la=La%20Pe%C3%B1a' + } + request = self._makeOne(environ) + request.charset = None + self.assertEqual(request.GET['la'], text_(b'La Pe\xf1a')) + + def test_tmpl_context(self): + from pyramid.request import TemplateContext + inst = self._makeOne() + result = inst.tmpl_context + self.assertEqual(result.__class__, TemplateContext) + + def test_session_configured(self): + from pyramid.interfaces import ISessionFactory + inst = self._makeOne() + def factory(request): + return 'orangejuice' + self.config.registry.registerUtility(factory, ISessionFactory) + inst.registry = self.config.registry + self.assertEqual(inst.session, 'orangejuice') + self.assertEqual(inst.__dict__['session'], 'orangejuice') + + def test_session_not_configured(self): + inst = self._makeOne() + inst.registry = self.config.registry + self.assertRaises(AttributeError, getattr, inst, 'session') + + def test_setattr_and_getattr_dotnotation(self): + inst = self._makeOne() + inst.foo = 1 + self.assertEqual(inst.foo, 1) + + def test_setattr_and_getattr(self): + environ = {} + inst = self._makeOne(environ) + setattr(inst, 'bar', 1) + self.assertEqual(getattr(inst, 'bar'), 1) + self.assertEqual(environ, {}) # make sure we're not using adhoc attrs + + def test_add_response_callback(self): + inst = self._makeOne() + self.assertEqual(len(inst.response_callbacks), 0) + def callback(request, response): + """ """ + inst.add_response_callback(callback) + self.assertEqual(list(inst.response_callbacks), [callback]) + inst.add_response_callback(callback) + self.assertEqual(list(inst.response_callbacks), [callback, callback]) + + def test__process_response_callbacks(self): + inst = self._makeOne() + def callback1(request, response): + request.called1 = True + response.called1 = True + def callback2(request, response): + request.called2 = True + response.called2 = True + inst.add_response_callback(callback1) + inst.add_response_callback(callback2) + response = DummyResponse() + inst._process_response_callbacks(response) + self.assertEqual(inst.called1, True) + self.assertEqual(inst.called2, True) + self.assertEqual(response.called1, True) + self.assertEqual(response.called2, True) + self.assertEqual(len(inst.response_callbacks), 0) + + def test__process_response_callback_adding_response_callback(self): + """ + When a response callback adds another callback, that new callback should still be called. + + See https://github.com/Pylons/pyramid/pull/1373 + """ + inst = self._makeOne() + def callback1(request, response): + request.called1 = True + response.called1 = True + request.add_response_callback(callback2) + def callback2(request, response): + request.called2 = True + response.called2 = True + inst.add_response_callback(callback1) + response = DummyResponse() + inst._process_response_callbacks(response) + self.assertEqual(inst.called1, True) + self.assertEqual(inst.called2, True) + self.assertEqual(response.called1, True) + self.assertEqual(response.called2, True) + self.assertEqual(len(inst.response_callbacks), 0) + + def test_add_finished_callback(self): + inst = self._makeOne() + self.assertEqual(len(inst.finished_callbacks), 0) + def callback(request): + """ """ + inst.add_finished_callback(callback) + self.assertEqual(list(inst.finished_callbacks), [callback]) + inst.add_finished_callback(callback) + self.assertEqual(list(inst.finished_callbacks), [callback, callback]) + + def test__process_finished_callbacks(self): + inst = self._makeOne() + def callback1(request): + request.called1 = True + def callback2(request): + request.called2 = True + inst.add_finished_callback(callback1) + inst.add_finished_callback(callback2) + inst._process_finished_callbacks() + self.assertEqual(inst.called1, True) + self.assertEqual(inst.called2, True) + self.assertEqual(len(inst.finished_callbacks), 0) + + def test_resource_url(self): + self._registerResourceURL() + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + 'wsgi.url_scheme':'http', + } + inst = self._makeOne(environ) + root = DummyContext() + result = inst.resource_url(root) + self.assertEqual(result, 'http://example.com/context/') + + def test_route_url(self): + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'la=La%20Pe%C3%B1a', + 'wsgi.url_scheme':'http', + } + from pyramid.interfaces import IRoutesMapper + inst = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + self.config.registry.registerUtility(mapper, IRoutesMapper) + result = inst.route_url('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=text_("foo")) + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + + def test_route_path(self): + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'la=La%20Pe%C3%B1a', + 'wsgi.url_scheme':'http', + } + from pyramid.interfaces import IRoutesMapper + inst = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + self.config.registry.registerUtility(mapper, IRoutesMapper) + result = inst.route_path('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=text_("foo")) + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + + def test_static_url(self): + from pyramid.interfaces import IStaticURLInfo + environ = { + 'PATH_INFO':'/', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'5432', + 'QUERY_STRING':'', + 'wsgi.url_scheme':'http', + } + request = self._makeOne(environ) + info = DummyStaticURLInfo('abc') + self.config.registry.registerUtility(info, IStaticURLInfo) + result = request.static_url('pyramid.tests:static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, {}) ) + + def test_is_response_false(self): + request = self._makeOne() + request.registry = self.config.registry + self.assertEqual(request.is_response('abc'), False) + + def test_is_response_true_ob_is_pyramid_response(self): + from pyramid.response import Response + r = Response('hello') + request = self._makeOne() + request.registry = self.config.registry + self.assertEqual(request.is_response(r), True) + + def test_is_response_false_adapter_is_not_self(self): + from pyramid.interfaces import IResponse + request = self._makeOne() + request.registry = self.config.registry + def adapter(ob): + return object() + class Foo(object): + pass + foo = Foo() + request.registry.registerAdapter(adapter, (Foo,), IResponse) + self.assertEqual(request.is_response(foo), False) + + def test_is_response_adapter_true(self): + from pyramid.interfaces import IResponse + request = self._makeOne() + request.registry = self.config.registry + class Foo(object): + pass + foo = Foo() + def adapter(ob): + return ob + request.registry.registerAdapter(adapter, (Foo,), IResponse) + self.assertEqual(request.is_response(foo), True) + + def test_json_body_invalid_json(self): + request = self._makeOne({'REQUEST_METHOD':'POST'}) + request.body = b'{' + self.assertRaises(ValueError, getattr, request, 'json_body') + + def test_json_body_valid_json(self): + request = self._makeOne({'REQUEST_METHOD':'POST'}) + request.body = b'{"a":1}' + self.assertEqual(request.json_body, {'a':1}) + + def test_json_body_alternate_charset(self): + import json + request = self._makeOne({'REQUEST_METHOD':'POST'}) + inp = text_( + b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', + 'utf-8' + ) + if PY2: + body = json.dumps({'a':inp}).decode('utf-8').encode('utf-16') + else: + body = bytes(json.dumps({'a':inp}), 'utf-16') + request.body = body + request.content_type = 'application/json; charset=utf-16' + self.assertEqual(request.json_body, {'a':inp}) + + def test_json_body_GET_request(self): + request = self._makeOne({'REQUEST_METHOD':'GET'}) + self.assertRaises(ValueError, getattr, request, 'json_body') + + def test_set_property(self): + request = self._makeOne() + opts = [2, 1] + def connect(obj): + return opts.pop() + request.set_property(connect, name='db') + self.assertEqual(1, request.db) + self.assertEqual(2, request.db) + + def test_set_property_reify(self): + request = self._makeOne() + opts = [2, 1] + def connect(obj): + return opts.pop() + request.set_property(connect, name='db', reify=True) + self.assertEqual(1, request.db) + self.assertEqual(1, request.db) + +class Test_route_request_iface(unittest.TestCase): + def _callFUT(self, name): + from pyramid.request import route_request_iface + return route_request_iface(name) + + def test_it(self): + iface = self._callFUT('routename') + self.assertEqual(iface.__name__, 'routename_IRequest') + self.assertTrue(hasattr(iface, 'combined')) + self.assertEqual(iface.combined.__name__, 'routename_combined_IRequest') + + def test_it_routename_with_spaces(self): + # see https://github.com/Pylons/pyramid/issues/232 + iface = self._callFUT('routename with spaces') + self.assertEqual(iface.__name__, 'routename with spaces_IRequest') + self.assertTrue(hasattr(iface, 'combined')) + self.assertEqual(iface.combined.__name__, + 'routename with spaces_combined_IRequest') + + +class Test_add_global_response_headers(unittest.TestCase): + def _callFUT(self, request, headerlist): + from pyramid.request import add_global_response_headers + return add_global_response_headers(request, headerlist) + + def test_it(self): + request = DummyRequest() + response = DummyResponse() + self._callFUT(request, [('c', 1)]) + self.assertEqual(len(request.response_callbacks), 1) + request.response_callbacks[0](None, response) + self.assertEqual(response.headerlist, [('c', 1)] ) + +class Test_call_app_with_subpath_as_path_info(unittest.TestCase): + def _callFUT(self, request, app): + from pyramid.request import call_app_with_subpath_as_path_info + return call_app_with_subpath_as_path_info(request, app) + + def test_it_all_request_and_environment_data_missing(self): + request = DummyRequest({}) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '') + self.assertEqual(request.environ['PATH_INFO'], '/') + + def test_it_with_subpath_and_path_info(self): + request = DummyRequest({'PATH_INFO':'/hello'}) + request.subpath = ('hello',) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '') + self.assertEqual(request.environ['PATH_INFO'], '/hello') + + def test_it_with_subpath_and_path_info_path_info_endswith_slash(self): + request = DummyRequest({'PATH_INFO':'/hello/'}) + request.subpath = ('hello',) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '') + self.assertEqual(request.environ['PATH_INFO'], '/hello/') + + def test_it_with_subpath_and_path_info_extra_script_name(self): + request = DummyRequest({'PATH_INFO':'/hello', 'SCRIPT_NAME':'/script'}) + request.subpath = ('hello',) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '/script') + self.assertEqual(request.environ['PATH_INFO'], '/hello') + + def test_it_with_extra_slashes_in_path_info(self): + request = DummyRequest({'PATH_INFO':'//hello/', + 'SCRIPT_NAME':'/script'}) + request.subpath = ('hello',) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '/script') + self.assertEqual(request.environ['PATH_INFO'], '/hello/') + + def test_subpath_path_info_and_script_name_have_utf8(self): + encoded = native_(text_(b'La Pe\xc3\xb1a')) + decoded = text_(bytes_(encoded), 'utf-8') + request = DummyRequest({'PATH_INFO':'/' + encoded, + 'SCRIPT_NAME':'/' + encoded}) + request.subpath = (decoded, ) + response = self._callFUT(request, 'app') + self.assertTrue(request.copied) + self.assertEqual(response, 'app') + self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) + self.assertEqual(request.environ['PATH_INFO'], '/' + encoded) + +class Test_apply_request_extensions(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, request, extensions=None): + from pyramid.request import apply_request_extensions + return apply_request_extensions(request, extensions=extensions) + + def test_it_with_registry(self): + from pyramid.interfaces import IRequestExtensions + extensions = Dummy() + extensions.methods = {'foo': lambda x, y: y} + extensions.descriptors = {'bar': property(lambda x: 'bar')} + self.config.registry.registerUtility(extensions, IRequestExtensions) + request = DummyRequest() + request.registry = self.config.registry + self._callFUT(request) + self.assertEqual(request.bar, 'bar') + self.assertEqual(request.foo('abc'), 'abc') + + def test_it_override_extensions(self): + from pyramid.interfaces import IRequestExtensions + ignore = Dummy() + ignore.methods = {'x': lambda x, y, z: 'asdf'} + ignore.descriptors = {'bar': property(lambda x: 'asdf')} + self.config.registry.registerUtility(ignore, IRequestExtensions) + request = DummyRequest() + request.registry = self.config.registry + + extensions = Dummy() + extensions.methods = {'foo': lambda x, y: y} + extensions.descriptors = {'bar': property(lambda x: 'bar')} + self._callFUT(request, extensions=extensions) + self.assertRaises(AttributeError, lambda: request.x) + self.assertEqual(request.bar, 'bar') + self.assertEqual(request.foo('abc'), 'abc') + +class Dummy(object): + pass + +class Test_subclassing_Request(unittest.TestCase): + def test_subclass(self): + from pyramid.interfaces import IRequest + from pyramid.request import Request + + class RequestSub(Request): + pass + + self.assertTrue(hasattr(Request, '__provides__')) + self.assertTrue(hasattr(Request, '__implemented__')) + self.assertTrue(hasattr(Request, '__providedBy__')) + self.assertFalse(hasattr(RequestSub, '__provides__')) + self.assertTrue(hasattr(RequestSub, '__providedBy__')) + self.assertTrue(hasattr(RequestSub, '__implemented__')) + + self.assertTrue(IRequest.implementedBy(RequestSub)) + # The call to implementedBy will add __provides__ to the class + self.assertTrue(hasattr(RequestSub, '__provides__')) + + + def test_subclass_with_implementer(self): + from pyramid.interfaces import IRequest + from pyramid.request import Request + from pyramid.util import InstancePropertyHelper + from zope.interface import implementer + + @implementer(IRequest) + class RequestSub(Request): + pass + + self.assertTrue(hasattr(Request, '__provides__')) + self.assertTrue(hasattr(Request, '__implemented__')) + self.assertTrue(hasattr(Request, '__providedBy__')) + self.assertTrue(hasattr(RequestSub, '__provides__')) + self.assertTrue(hasattr(RequestSub, '__providedBy__')) + self.assertTrue(hasattr(RequestSub, '__implemented__')) + + req = RequestSub({}) + helper = InstancePropertyHelper() + helper.apply_properties(req, {'b': 'b'}) + + self.assertTrue(IRequest.providedBy(req)) + self.assertTrue(IRequest.implementedBy(RequestSub)) + + def test_subclass_mutate_before_providedBy(self): + from pyramid.interfaces import IRequest + from pyramid.request import Request + from pyramid.util import InstancePropertyHelper + + class RequestSub(Request): + pass + + req = RequestSub({}) + helper = InstancePropertyHelper() + helper.apply_properties(req, {'b': 'b'}) + + self.assertTrue(IRequest.providedBy(req)) + self.assertTrue(IRequest.implementedBy(RequestSub)) + + +class DummyRequest(object): + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + + def add_response_callback(self, callback): + self.response_callbacks = [callback] + + def get_response(self, app): + return app + + def copy(self): + self.copied = True + return self + +class DummyResponse: + def __init__(self): + self.headerlist = [] + + +class DummyContext: + pass + +class DummyRoutesMapper: + raise_exc = None + def __init__(self, route=None, raise_exc=False): + self.route = route + + def get_route(self, route_name): + return self.route + +class DummyRoute: + pregenerator = None + def __init__(self, result='/1/2/3'): + self.result = result + + def generate(self, kw): + self.kw = kw + return self.result + +class DummyStaticURLInfo: + def __init__(self, result): + self.result = result + + def generate(self, path, request, **kw): + self.args = path, request, kw + return self.result diff --git a/tests/test_response.py b/tests/test_response.py new file mode 100644 index 000000000..53e3ce17a --- /dev/null +++ b/tests/test_response.py @@ -0,0 +1,214 @@ +import io +import mimetypes +import os +import unittest +from pyramid import testing + +class TestResponse(unittest.TestCase): + def _getTargetClass(self): + from pyramid.response import Response + return Response + + def test_implements_IResponse(self): + from pyramid.interfaces import IResponse + cls = self._getTargetClass() + self.assertTrue(IResponse.implementedBy(cls)) + + def test_provides_IResponse(self): + from pyramid.interfaces import IResponse + inst = self._getTargetClass()() + self.assertTrue(IResponse.providedBy(inst)) + +class TestFileResponse(unittest.TestCase): + def _makeOne(self, file, **kw): + from pyramid.response import FileResponse + return FileResponse(file, **kw) + + def _getPath(self, suffix='txt'): + here = os.path.dirname(__file__) + return os.path.join(here, 'fixtures', 'minimal.%s' % (suffix,)) + + def test_with_image_content_type(self): + path = self._getPath('jpg') + r = self._makeOne(path, content_type='image/jpeg') + self.assertEqual(r.content_type, 'image/jpeg') + self.assertEqual(r.headers['content-type'], 'image/jpeg') + path = self._getPath() + r.app_iter.close() + + def test_with_xml_content_type(self): + path = self._getPath('xml') + r = self._makeOne(path, content_type='application/xml') + self.assertEqual(r.content_type, 'application/xml') + self.assertEqual(r.headers['content-type'], + 'application/xml; charset=UTF-8') + r.app_iter.close() + + def test_with_pdf_content_type(self): + path = self._getPath('xml') + r = self._makeOne(path, content_type='application/pdf') + self.assertEqual(r.content_type, 'application/pdf') + self.assertEqual(r.headers['content-type'], 'application/pdf') + r.app_iter.close() + + def test_without_content_type(self): + for suffix in ('txt', 'xml', 'pdf'): + path = self._getPath(suffix) + r = self._makeOne(path) + self.assertEqual(r.headers['content-type'].split(';')[0], + mimetypes.guess_type(path, strict=False)[0]) + r.app_iter.close() + + def test_python_277_bug_15207(self): + # python 2.7.7 on windows has a bug where its mimetypes.guess_type + # function returns Unicode for the content_type, unlike any previous + # version of Python. See https://github.com/Pylons/pyramid/issues/1360 + # for more information. + from pyramid.compat import text_ + import mimetypes as old_mimetypes + from pyramid import response + class FakeMimetypesModule(object): + def guess_type(self, *arg, **kw): + return text_('foo/bar'), None + fake_mimetypes = FakeMimetypesModule() + try: + response.mimetypes = fake_mimetypes + path = self._getPath('xml') + r = self._makeOne(path) + self.assertEqual(r.content_type, 'foo/bar') + self.assertEqual(type(r.content_type), str) + finally: + response.mimetypes = old_mimetypes + +class TestFileIter(unittest.TestCase): + def _makeOne(self, file, block_size): + from pyramid.response import FileIter + return FileIter(file, block_size) + + def test___iter__(self): + f = io.BytesIO(b'abc') + inst = self._makeOne(f, 1) + self.assertEqual(inst.__iter__(), inst) + + def test_iteration(self): + data = b'abcdef' + f = io.BytesIO(b'abcdef') + inst = self._makeOne(f, 1) + r = b'' + for x in inst: + self.assertEqual(len(x), 1) + r+=x + self.assertEqual(r, data) + + def test_close(self): + f = io.BytesIO(b'abc') + inst = self._makeOne(f, 1) + inst.close() + self.assertTrue(f.closed) + +class Test_patch_mimetypes(unittest.TestCase): + def _callFUT(self, module): + from pyramid.response import init_mimetypes + return init_mimetypes(module) + + def test_has_init(self): + class DummyMimetypes(object): + def init(self): + self.initted = True + module = DummyMimetypes() + result = self._callFUT(module) + self.assertEqual(result, True) + self.assertEqual(module.initted, True) + + def test_missing_init(self): + class DummyMimetypes(object): + pass + module = DummyMimetypes() + result = self._callFUT(module) + self.assertEqual(result, False) + + +class TestResponseAdapter(unittest.TestCase): + def setUp(self): + registry = Dummy() + self.config = testing.setUp(registry=registry) + + def tearDown(self): + self.config.end() + + def _makeOne(self, *types_or_ifaces, **kw): + from pyramid.response import response_adapter + return response_adapter(*types_or_ifaces, **kw) + + def test_register_single(self): + from zope.interface import Interface + class IFoo(Interface): pass + dec = self._makeOne(IFoo) + def foo(): pass + config = DummyConfigurator() + scanner = Dummy() + scanner.config = config + dec.register(scanner, None, foo) + self.assertEqual(config.adapters, [(foo, IFoo)]) + + def test_register_multi(self): + from zope.interface import Interface + class IFoo(Interface): pass + class IBar(Interface): pass + dec = self._makeOne(IFoo, IBar) + def foo(): pass + config = DummyConfigurator() + scanner = Dummy() + scanner.config = config + dec.register(scanner, None, foo) + self.assertEqual(config.adapters, [(foo, IFoo), (foo, IBar)]) + + def test___call__(self): + from zope.interface import Interface + class IFoo(Interface): pass + dec = self._makeOne(IFoo) + dummy_venusian = DummyVenusian() + dec.venusian = dummy_venusian + def foo(): pass + dec(foo) + self.assertEqual(dummy_venusian.attached, + [(foo, dec.register, 'pyramid', 1)]) + + def test___call___with_venusian_args(self): + from zope.interface import Interface + class IFoo(Interface): pass + dec = self._makeOne(IFoo, _category='foo', _depth=1) + dummy_venusian = DummyVenusian() + dec.venusian = dummy_venusian + def foo(): pass + dec(foo) + self.assertEqual(dummy_venusian.attached, + [(foo, dec.register, 'foo', 2)]) + + +class TestGetResponseFactory(unittest.TestCase): + def test_get_factory(self): + from pyramid.registry import Registry + from pyramid.response import Response, _get_response_factory + + registry = Registry() + response = _get_response_factory(registry)(None) + self.assertTrue(isinstance(response, Response)) + + +class Dummy(object): + pass + +class DummyConfigurator(object): + def __init__(self): + self.adapters = [] + + def add_response_adapter(self, wrapped, type_or_iface): + self.adapters.append((wrapped, type_or_iface)) + +class DummyVenusian(object): + def __init__(self): + self.attached = [] + + def attach(self, wrapped, fn, category=None, depth=None): + self.attached.append((wrapped, fn, category, depth)) diff --git a/tests/test_router.py b/tests/test_router.py new file mode 100644 index 000000000..6097018f0 --- /dev/null +++ b/tests/test_router.py @@ -0,0 +1,1410 @@ +import unittest + +from pyramid import testing + +class TestRouter(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + self.registry = self.config.registry + + def tearDown(self): + testing.tearDown() + + def _registerRouteRequest(self, name): + from pyramid.interfaces import IRouteRequest + from pyramid.request import route_request_iface + iface = route_request_iface(name) + self.registry.registerUtility(iface, IRouteRequest, name=name) + return iface + + def _connectRoute(self, name, path, factory=None): + from pyramid.interfaces import IRoutesMapper + from pyramid.urldispatch import RoutesMapper + mapper = self.registry.queryUtility(IRoutesMapper) + if mapper is None: + mapper = RoutesMapper() + self.registry.registerUtility(mapper, IRoutesMapper) + return mapper.connect(name, path, factory) + + def _registerLogger(self): + from pyramid.interfaces import IDebugLogger + logger = DummyLogger() + self.registry.registerUtility(logger, IDebugLogger) + return logger + + def _registerSettings(self, **kw): + settings = {'debug_authorization':False, + 'debug_notfound':False, + 'debug_routematch':False} + settings.update(kw) + self.registry.settings = settings + + def _registerTraverserFactory(self, context, view_name='', subpath=None, + traversed=None, virtual_root=None, + virtual_root_path=None, raise_error=None, + **kw): + from pyramid.interfaces import ITraverser + + if virtual_root is None: + virtual_root = context + if subpath is None: + subpath = [] + if traversed is None: + traversed = [] + if virtual_root_path is None: + virtual_root_path = [] + + class DummyTraverserFactory: + def __init__(self, root): + self.root = root + + def __call__(self, request): + if raise_error: + raise raise_error + values = {'root':self.root, + 'context':context, + 'view_name':view_name, + 'subpath':subpath, + 'traversed':traversed, + 'virtual_root':virtual_root, + 'virtual_root_path':virtual_root_path} + kw.update(values) + return kw + + self.registry.registerAdapter(DummyTraverserFactory, (None,), + ITraverser, name='') + + def _registerView(self, app, name, classifier, req_iface, ctx_iface): + from pyramid.interfaces import IView + self.registry.registerAdapter( + app, (classifier, req_iface, ctx_iface), IView, name) + + def _registerEventListener(self, iface): + L = [] + def listener(event): + L.append(event) + self.registry.registerHandler(listener, (iface,)) + return L + + def _registerRootFactory(self, val): + rootfactory = DummyRootFactory(val) + from pyramid.interfaces import IRootFactory + self.registry.registerUtility(rootfactory, IRootFactory) + return rootfactory + + def _getTargetClass(self): + from pyramid.router import Router + return Router + + def _makeOne(self): + klass = self._getTargetClass() + return klass(self.registry) + + def _makeEnviron(self, **extras): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'localhost', + 'SERVER_PORT':'8080', + 'REQUEST_METHOD':'GET', + 'PATH_INFO':'/', + } + environ.update(extras) + return environ + + def test_ctor_registry_has_no_settings(self): + self.registry.settings = None + router = self._makeOne() + self.assertEqual(router.debug_notfound, False) + self.assertEqual(router.debug_routematch, False) + self.assertFalse('debug_notfound' in router.__dict__) + self.assertFalse('debug_routematch' in router.__dict__) + + def test_root_policy(self): + context = DummyContext() + self._registerTraverserFactory(context) + rootfactory = self._registerRootFactory('abc') + router = self._makeOne() + self.assertEqual(router.root_policy, rootfactory) + + def test_request_factory(self): + from pyramid.interfaces import IRequestFactory + class DummyRequestFactory(object): + pass + self.registry.registerUtility(DummyRequestFactory, IRequestFactory) + router = self._makeOne() + self.assertEqual(router.request_factory, DummyRequestFactory) + + def test_tween_factories(self): + from pyramid.interfaces import ITweens + from pyramid.config.tweens import Tweens + from pyramid.response import Response + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IResponse + tweens = Tweens() + self.registry.registerUtility(tweens, ITweens) + L = [] + def tween_factory1(handler, registry): + L.append((handler, registry)) + def wrapper(request): + request.environ['handled'].append('one') + return handler(request) + wrapper.name = 'one' + wrapper.child = handler + return wrapper + def tween_factory2(handler, registry): + L.append((handler, registry)) + def wrapper(request): + request.environ['handled'] = ['two'] + return handler(request) + wrapper.name = 'two' + wrapper.child = handler + return wrapper + tweens.add_implicit('one', tween_factory1) + tweens.add_implicit('two', tween_factory2) + router = self._makeOne() + self.assertEqual(router.handle_request.name, 'two') + self.assertEqual(router.handle_request.child.name, 'one') + self.assertEqual(router.handle_request.child.child.__name__, + 'handle_request') + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron() + view = DummyView('abc') + self._registerView(self.config.derive_view(view), '', + IViewClassifier, None, None) + start_response = DummyStartResponse() + def make_response(s): + return Response(s) + router.registry.registerAdapter(make_response, (str,), IResponse) + app_iter = router(environ, start_response) + self.assertEqual(app_iter, [b'abc']) + self.assertEqual(start_response.status, '200 OK') + self.assertEqual(environ['handled'], ['two', 'one']) + + def test_call_traverser_default(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + logger = self._registerLogger() + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue('/' in why.args[0], why) + self.assertFalse('debug_notfound' in why.args[0]) + self.assertEqual(len(logger.messages), 0) + + def test_traverser_raises_notfound_class(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, raise_error=HTTPNotFound) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(HTTPNotFound, router, environ, start_response) + + def test_traverser_raises_notfound_instance(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, raise_error=HTTPNotFound('foo')) + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue('foo' in why.args[0], why) + + def test_traverser_raises_forbidden_class(self): + from pyramid.httpexceptions import HTTPForbidden + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, raise_error=HTTPForbidden) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(HTTPForbidden, router, environ, start_response) + + def test_traverser_raises_forbidden_instance(self): + from pyramid.httpexceptions import HTTPForbidden + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, + raise_error=HTTPForbidden('foo')) + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPForbidden, router, environ, start_response) + self.assertTrue('foo' in why.args[0], why) + + def test_call_no_view_registered_no_isettings(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context) + logger = self._registerLogger() + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue('/' in why.args[0], why) + self.assertFalse('debug_notfound' in why.args[0]) + self.assertEqual(len(logger.messages), 0) + + def test_call_no_view_registered_debug_notfound_false(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context) + logger = self._registerLogger() + self._registerSettings(debug_notfound=False) + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue('/' in why.args[0], why) + self.assertFalse('debug_notfound' in why.args[0]) + self.assertEqual(len(logger.messages), 0) + + def test_call_no_view_registered_debug_notfound_true(self): + from pyramid.httpexceptions import HTTPNotFound + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context) + self._registerSettings(debug_notfound=True) + logger = self._registerLogger() + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue( + "debug_notfound of url http://localhost:8080/; " in why.args[0]) + self.assertTrue("view_name: '', subpath: []" in why.args[0]) + self.assertTrue('http://localhost:8080' in why.args[0], why) + + self.assertEqual(len(logger.messages), 1) + message = logger.messages[0] + self.assertTrue('of url http://localhost:8080' in message) + self.assertTrue("path_info: " in message) + self.assertTrue('DummyContext' in message) + self.assertTrue("view_name: ''" in message) + self.assertTrue("subpath: []" in message) + + def test_call_view_returns_non_iresponse(self): + from pyramid.interfaces import IViewClassifier + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron() + view = DummyView('abc') + self._registerView(self.config.derive_view(view), '', IViewClassifier, + None, None) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(ValueError, router, environ, start_response) + + def test_call_view_returns_adapted_response(self): + from pyramid.response import Response + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IResponse + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron() + view = DummyView('abc') + self._registerView(self.config.derive_view(view), '', + IViewClassifier, None, None) + router = self._makeOne() + start_response = DummyStartResponse() + def make_response(s): + return Response(s) + router.registry.registerAdapter(make_response, (str,), IResponse) + app_iter = router(environ, start_response) + self.assertEqual(app_iter, [b'abc']) + self.assertEqual(start_response.status, '200 OK') + + def test_call_with_request_extensions(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequestExtensions + from pyramid.interfaces import IRequest + from pyramid.request import Request + from pyramid.util import InstancePropertyHelper + context = DummyContext() + self._registerTraverserFactory(context) + class Extensions(object): + def __init__(self): + self.methods = {} + self.descriptors = {} + extensions = Extensions() + ext_method = lambda r: 'bar' + name, fn = InstancePropertyHelper.make_property(ext_method, name='foo') + extensions.descriptors[name] = fn + request = Request.blank('/') + request.request_iface = IRequest + request.registry = self.registry + def request_factory(environ): + return request + self.registry.registerUtility(extensions, IRequestExtensions) + environ = self._makeEnviron() + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + self._registerView(self.config.derive_view(view), '', + IViewClassifier, None, None) + router = self._makeOne() + router.request_factory = request_factory + start_response = DummyStartResponse() + router(environ, start_response) + self.assertEqual(view.request.foo, 'bar') + + def test_call_view_registered_nonspecific_default_path(self): + from pyramid.interfaces import IViewClassifier + context = DummyContext() + self._registerTraverserFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron() + self._registerView(self.config.derive_view(view), '', + IViewClassifier, None, None) + self._registerRootFactory(context) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['Hello world']) + self.assertEqual(start_response.headers, ()) + self.assertEqual(start_response.status, '200 OK') + request = view.request + self.assertEqual(request.view_name, '') + self.assertEqual(request.subpath, []) + self.assertEqual(request.context, context) + self.assertEqual(request.root, context) + + def test_call_view_registered_nonspecific_nondefault_path_and_subpath(self): + from pyramid.interfaces import IViewClassifier + context = DummyContext() + self._registerTraverserFactory(context, view_name='foo', + subpath=['bar'], + traversed=['context']) + self._registerRootFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron() + self._registerView(view, 'foo', IViewClassifier, None, None) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['Hello world']) + self.assertEqual(start_response.headers, ()) + self.assertEqual(start_response.status, '200 OK') + request = view.request + self.assertEqual(request.view_name, 'foo') + self.assertEqual(request.subpath, ['bar']) + self.assertEqual(request.context, context) + self.assertEqual(request.root, context) + + def test_call_view_registered_specific_success(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context) + self._registerRootFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['Hello world']) + self.assertEqual(start_response.headers, ()) + self.assertEqual(start_response.status, '200 OK') + request = view.request + self.assertEqual(request.view_name, '') + self.assertEqual(request.subpath, []) + self.assertEqual(request.context, context) + self.assertEqual(request.root, context) + + def test_call_view_registered_specific_fail(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from pyramid.httpexceptions import HTTPNotFound + from pyramid.interfaces import IViewClassifier + class IContext(Interface): + pass + class INotContext(Interface): + pass + from pyramid.interfaces import IRequest + context = DummyContext() + directlyProvides(context, INotContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + view = DummyView(response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(HTTPNotFound, router, environ, start_response) + + def test_call_view_raises_forbidden(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from pyramid.httpexceptions import HTTPForbidden + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + view = DummyView(response, + raise_exception=HTTPForbidden("unauthorized")) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPForbidden, router, environ, start_response) + self.assertEqual(why.args[0], 'unauthorized') + + def test_call_view_raises_notfound(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.httpexceptions import HTTPNotFound + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + view = DummyView(response, raise_exception=HTTPNotFound("notfound")) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertEqual(why.args[0], 'notfound') + + def test_call_view_raises_response_cleared(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from pyramid.interfaces import IExceptionViewClassifier + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + def view(context, request): + request.response.a = 1 + raise KeyError + def exc_view(context, request): + self.assertFalse(hasattr(request.response, 'a')) + request.response.body = b'OK' + return request.response + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + self._registerView(exc_view, '', IExceptionViewClassifier, + IRequest, KeyError) + router = self._makeOne() + start_response = DummyStartResponse() + itera = router(environ, start_response) + self.assertEqual(itera, [b'OK']) + + def test_call_request_has_response_callbacks(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse('200 OK') + def view(context, request): + def callback(request, response): + response.called_back = True + request.add_response_callback(callback) + return response + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + router(environ, start_response) + self.assertEqual(response.called_back, True) + + def test_call_request_has_finished_callbacks_when_view_succeeds(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse('200 OK') + def view(context, request): + def callback(request): + request.environ['called_back'] = True + request.add_finished_callback(callback) + return response + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + router(environ, start_response) + self.assertEqual(environ['called_back'], True) + + def test_call_request_has_finished_callbacks_when_view_raises(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + def view(context, request): + def callback(request): + request.environ['called_back'] = True + request.add_finished_callback(callback) + raise NotImplementedError + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, IContext) + router = self._makeOne() + start_response = DummyStartResponse() + exc_raised(NotImplementedError, router, environ, start_response) + self.assertEqual(environ['called_back'], True) + + def test_call_request_factory_raises(self): + # making sure finally doesnt barf when a request cannot be created + environ = self._makeEnviron() + router = self._makeOne() + def dummy_request_factory(environ): + raise NotImplementedError + router.request_factory = dummy_request_factory + start_response = DummyStartResponse() + exc_raised(NotImplementedError, router, environ, start_response) + + def test_call_eventsends(self): + from pyramid.interfaces import INewRequest + from pyramid.interfaces import INewResponse + from pyramid.interfaces import IBeforeTraversal + from pyramid.interfaces import IContextFound + from pyramid.interfaces import IViewClassifier + context = DummyContext() + self._registerTraverserFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, None, None) + request_events = self._registerEventListener(INewRequest) + beforetraversal_events = self._registerEventListener(IBeforeTraversal) + context_found_events = self._registerEventListener(IContextFound) + response_events = self._registerEventListener(INewResponse) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(len(request_events), 1) + self.assertEqual(request_events[0].request.environ, environ) + self.assertEqual(len(beforetraversal_events), 1) + self.assertEqual(beforetraversal_events[0].request.environ, environ) + self.assertEqual(len(context_found_events), 1) + self.assertEqual(context_found_events[0].request.environ, environ) + self.assertEqual(context_found_events[0].request.context, context) + self.assertEqual(len(response_events), 1) + self.assertEqual(response_events[0].response, response) + self.assertEqual(response_events[0].request.context, context) + self.assertEqual(result, response.app_iter) + + def test_call_newrequest_evllist_exc_can_be_caught_by_exceptionview(self): + from pyramid.interfaces import INewRequest + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron() + def listener(event): + raise KeyError + self.registry.registerHandler(listener, (INewRequest,)) + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + exception_view = DummyView(exception_response) + environ = self._makeEnviron() + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, KeyError) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, exception_response.app_iter) + + def test_call_route_matches_and_has_factory(self): + from pyramid.interfaces import IViewClassifier + logger = self._registerLogger() + self._registerSettings(debug_routematch=True) + self._registerRouteRequest('foo') + root = object() + def factory(request): + return root + route = self._connectRoute('foo', 'archives/:action/:article', factory) + route.predicates = [DummyPredicate()] + context = DummyContext() + self._registerTraverserFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + self._registerView(view, '', IViewClassifier, None, None) + self._registerRootFactory(context) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['Hello world']) + self.assertEqual(start_response.headers, ()) + self.assertEqual(start_response.status, '200 OK') + request = view.request + self.assertEqual(request.view_name, '') + self.assertEqual(request.subpath, []) + self.assertEqual(request.context, context) + self.assertEqual(request.root, root) + matchdict = {'action':'action1', 'article':'article1'} + self.assertEqual(request.matchdict, matchdict) + self.assertEqual(request.matched_route.name, 'foo') + self.assertEqual(len(logger.messages), 1) + self.assertTrue( + logger.messages[0].startswith( + "route matched for url http://localhost:8080" + "/archives/action1/article1; " + "route_name: 'foo', " + "path_info: ") + ) + self.assertTrue( + "predicates: 'predicate'" in logger.messages[0] + ) + + def test_call_route_match_miss_debug_routematch(self): + from pyramid.httpexceptions import HTTPNotFound + logger = self._registerLogger() + self._registerSettings(debug_routematch=True) + self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article') + context = DummyContext() + self._registerTraverserFactory(context) + environ = self._makeEnviron(PATH_INFO='/wontmatch') + self._registerRootFactory(context) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(HTTPNotFound, router, environ, start_response) + + self.assertEqual(len(logger.messages), 1) + self.assertEqual( + logger.messages[0], + 'no route matched for url http://localhost:8080/wontmatch') + + def test_call_route_matches_doesnt_overwrite_subscriber_iface(self): + from pyramid.interfaces import INewRequest + from pyramid.interfaces import IViewClassifier + from zope.interface import alsoProvides + from zope.interface import Interface + self._registerRouteRequest('foo') + class IFoo(Interface): + pass + def listener(event): + alsoProvides(event.request, IFoo) + self.registry.registerHandler(listener, (INewRequest,)) + root = object() + def factory(request): + return root + self._connectRoute('foo', 'archives/:action/:article', factory) + context = DummyContext() + self._registerTraverserFactory(context) + response = DummyResponse() + response.app_iter = ['Hello world'] + view = DummyView(response) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + self._registerView(view, '', IViewClassifier, None, None) + self._registerRootFactory(context) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['Hello world']) + self.assertEqual(start_response.headers, ()) + self.assertEqual(start_response.status, '200 OK') + request = view.request + self.assertEqual(request.view_name, '') + self.assertEqual(request.subpath, []) + self.assertEqual(request.context, context) + self.assertEqual(request.root, root) + matchdict = {'action':'action1', 'article':'article1'} + self.assertEqual(request.matchdict, matchdict) + self.assertEqual(request.matched_route.name, 'foo') + self.assertTrue(IFoo.providedBy(request)) + + def test_root_factory_raises_notfound(self): + from pyramid.interfaces import IRootFactory + from pyramid.httpexceptions import HTTPNotFound + from zope.interface import Interface + from zope.interface import directlyProvides + def rootfactory(request): + raise HTTPNotFound('from root factory') + self.registry.registerUtility(rootfactory, IRootFactory) + class IContext(Interface): + pass + context = DummyContext() + directlyProvides(context, IContext) + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPNotFound, router, environ, start_response) + self.assertTrue('from root factory' in why.args[0]) + + def test_root_factory_raises_forbidden(self): + from pyramid.interfaces import IRootFactory + from pyramid.httpexceptions import HTTPForbidden + from zope.interface import Interface + from zope.interface import directlyProvides + def rootfactory(request): + raise HTTPForbidden('from root factory') + self.registry.registerUtility(rootfactory, IRootFactory) + class IContext(Interface): + pass + context = DummyContext() + directlyProvides(context, IContext) + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + why = exc_raised(HTTPForbidden, router, environ, start_response) + self.assertTrue('from root factory' in why.args[0]) + + def test_root_factory_exception_propagating(self): + from pyramid.interfaces import IRootFactory + from zope.interface import Interface + from zope.interface import directlyProvides + def rootfactory(request): + raise RuntimeError() + self.registry.registerUtility(rootfactory, IRootFactory) + class IContext(Interface): + pass + context = DummyContext() + directlyProvides(context, IContext) + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(RuntimeError, router, environ, start_response) + + def test_traverser_exception_propagating(self): + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, raise_error=RuntimeError()) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(RuntimeError, router, environ, start_response) + + def test_call_view_exception_propagating(self): + from zope.interface import Interface + from zope.interface import directlyProvides + class IContext(Interface): + pass + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequestFactory + from pyramid.interfaces import IExceptionViewClassifier + def rfactory(environ): + return request + self.registry.registerUtility(rfactory, IRequestFactory) + from pyramid.request import Request + request = Request.blank('/') + context = DummyContext() + directlyProvides(context, IContext) + self._registerTraverserFactory(context, subpath=['']) + response = DummyResponse() + response.app_iter = ['OK'] + error = RuntimeError() + view = DummyView(response, raise_exception=error) + environ = self._makeEnviron() + def exception_view(context, request): + self.assertEqual(request.exc_info[0], RuntimeError) + return response + self._registerView(view, '', IViewClassifier, IRequest, IContext) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ['OK']) + # exc_info and exception should still be around on the request after + # the excview tween has run (see + # https://github.com/Pylons/pyramid/issues/1223) + self.assertEqual(request.exception, error) + self.assertEqual(request.exc_info[:2], (RuntimeError, error,)) + + def test_call_view_raises_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + response = DummyResponse() + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + view = DummyView(response, raise_exception=RuntimeError) + def exception_view(context, request): + self.assertEqual(request.exception.__class__, RuntimeError) + return exception_response + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, None) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_call_view_raises_super_exception_sub_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class SuperException(Exception): + pass + class SubException(SuperException): + pass + response = DummyResponse() + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + view = DummyView(response, raise_exception=SuperException) + exception_view = DummyView(exception_response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, None) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, SubException) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(SuperException, router, environ, start_response) + + def test_call_view_raises_sub_exception_super_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class SuperException(Exception): + pass + class SubException(SuperException): + pass + response = DummyResponse() + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + view = DummyView(response, raise_exception=SubException) + exception_view = DummyView(exception_response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, None) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, SuperException) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_call_view_raises_exception_another_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class MyException(Exception): + pass + class AnotherException(Exception): + pass + response = DummyResponse() + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + view = DummyView(response, raise_exception=MyException) + exception_view = DummyView(exception_response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, None) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, AnotherException) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(MyException, router, environ, start_response) + + def test_root_factory_raises_exception_view(self): + from pyramid.interfaces import IRootFactory + from pyramid.interfaces import IRequest + from pyramid.interfaces import IExceptionViewClassifier + def rootfactory(request): + raise RuntimeError() + self.registry.registerUtility(rootfactory, IRootFactory) + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + exception_view = DummyView(exception_response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + app_iter = router(environ, start_response) + self.assertEqual(app_iter, ["Hello, world"]) + + def test_traverser_raises_exception_view(self): + from pyramid.interfaces import IRequest + from pyramid.interfaces import IExceptionViewClassifier + environ = self._makeEnviron() + context = DummyContext() + self._registerTraverserFactory(context, raise_error=RuntimeError()) + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + exception_view = DummyView(exception_response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + router = self._makeOne() + start_response = DummyStartResponse() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_exception_view_returns_non_iresponse(self): + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + environ = self._makeEnviron() + response = DummyResponse() + view = DummyView(response, raise_exception=RuntimeError) + + self._registerView(self.config.derive_view(view), '', + IViewClassifier, IRequest, None) + exception_view = DummyView(None) + self._registerView(self.config.derive_view(exception_view), '', + IExceptionViewClassifier, + IRequest, RuntimeError) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(ValueError, router, environ, start_response) + + def test_call_route_raises_route_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=RuntimeError) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + req_iface, RuntimeError) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_call_view_raises_exception_route_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=RuntimeError) + self._registerView(view, '', IViewClassifier, IRequest, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + req_iface, RuntimeError) + environ = self._makeEnviron() + start_response = DummyStartResponse() + router = self._makeOne() + self.assertRaises(RuntimeError, router, environ, start_response) + + def test_call_route_raises_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=RuntimeError) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_call_route_raises_super_exception_sub_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class SuperException(Exception): + pass + class SubException(SuperException): + pass + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=SuperException) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, SubException) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + self.assertRaises(SuperException, router, environ, start_response) + + def test_call_route_raises_sub_exception_super_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class SuperException(Exception): + pass + class SubException(SuperException): + pass + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=SubException) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, SuperException) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_call_route_raises_exception_another_exception_view(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class MyException(Exception): + pass + class AnotherException(Exception): + pass + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=MyException) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, AnotherException) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + self.assertRaises(MyException, router, environ, start_response) + + def test_call_route_raises_exception_view_specializing(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=RuntimeError) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + IRequest, RuntimeError) + response_spec = DummyResponse() + response_spec.app_iter = ["Hello, special world"] + exception_view_spec = DummyView(response_spec) + self._registerView(exception_view_spec, '', IExceptionViewClassifier, + req_iface, RuntimeError) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, special world"]) + + def test_call_route_raises_exception_view_another_route(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + req_iface = self._registerRouteRequest('foo') + another_req_iface = self._registerRouteRequest('bar') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=RuntimeError) + self._registerView(view, '', IViewClassifier, req_iface, None) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view = DummyView(response) + self._registerView(exception_view, '', IExceptionViewClassifier, + another_req_iface, RuntimeError) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + self.assertRaises(RuntimeError, router, environ, start_response) + + def test_call_view_raises_exception_view_route(self): + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + req_iface = self._registerRouteRequest('foo') + response = DummyResponse() + exception_response = DummyResponse() + exception_response.app_iter = ["Hello, world"] + view = DummyView(response, raise_exception=RuntimeError) + exception_view = DummyView(exception_response) + environ = self._makeEnviron() + self._registerView(view, '', IViewClassifier, IRequest, None) + self._registerView(exception_view, '', IExceptionViewClassifier, + req_iface, RuntimeError) + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(RuntimeError, router, environ, start_response) + + def test_call_view_raises_predicate_mismatch(self): + from pyramid.exceptions import PredicateMismatch + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequest + view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) + self._registerView(view, '', IViewClassifier, IRequest, None) + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(PredicateMismatch, router, environ, start_response) + + def test_call_view_predicate_mismatch_doesnt_hide_views(self): + from pyramid.exceptions import PredicateMismatch + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequest, IResponse + from pyramid.response import Response + class BaseContext: + pass + class DummyContext(BaseContext): + pass + context = DummyContext() + self._registerTraverserFactory(context) + view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) + self._registerView(view, '', IViewClassifier, IRequest, + DummyContext) + good_view = DummyView('abc') + self._registerView(self.config.derive_view(good_view), + '', IViewClassifier, IRequest, BaseContext) + router = self._makeOne() + def make_response(s): + return Response(s) + router.registry.registerAdapter(make_response, (str,), IResponse) + environ = self._makeEnviron() + start_response = DummyStartResponse() + app_iter = router(environ, start_response) + self.assertEqual(app_iter, [b'abc']) + + def test_call_view_multiple_predicate_mismatches_dont_hide_views(self): + from pyramid.exceptions import PredicateMismatch + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequest, IResponse + from pyramid.response import Response + from zope.interface import Interface, implementer + class IBaseContext(Interface): + pass + class IContext(IBaseContext): + pass + @implementer(IContext) + class DummyContext: + pass + context = DummyContext() + self._registerTraverserFactory(context) + view1 = DummyView(DummyResponse(), raise_exception=PredicateMismatch) + self._registerView(view1, '', IViewClassifier, IRequest, + DummyContext) + view2 = DummyView(DummyResponse(), raise_exception=PredicateMismatch) + self._registerView(view2, '', IViewClassifier, IRequest, + IContext) + good_view = DummyView('abc') + self._registerView(self.config.derive_view(good_view), + '', IViewClassifier, IRequest, IBaseContext) + router = self._makeOne() + def make_response(s): + return Response(s) + router.registry.registerAdapter(make_response, (str,), IResponse) + environ = self._makeEnviron() + start_response = DummyStartResponse() + app_iter = router(environ, start_response) + self.assertEqual(app_iter, [b'abc']) + + def test_call_view_predicate_mismatch_doesnt_find_unrelated_views(self): + from pyramid.exceptions import PredicateMismatch + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IRequest + from zope.interface import Interface, implementer + class IContext(Interface): + pass + class IOtherContext(Interface): + pass + @implementer(IContext) + class DummyContext: + pass + context = DummyContext() + self._registerTraverserFactory(context) + view = DummyView(DummyResponse(), raise_exception=PredicateMismatch) + self._registerView(view, '', IViewClassifier, IRequest, + DummyContext) + please_dont_call_me_view = DummyView('abc') + self._registerView(self.config.derive_view(please_dont_call_me_view), + '', IViewClassifier, IRequest, IOtherContext) + router = self._makeOne() + environ = self._makeEnviron() + router = self._makeOne() + start_response = DummyStartResponse() + self.assertRaises(PredicateMismatch, router, environ, start_response) + + def test_custom_execution_policy(self): + from pyramid.interfaces import IExecutionPolicy + from pyramid.request import Request + from pyramid.response import Response + registry = self.config.registry + def dummy_policy(environ, router): + return Response(status=200, body=b'foo') + registry.registerUtility(dummy_policy, IExecutionPolicy) + router = self._makeOne() + resp = Request.blank('/').get_response(router) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.body, b'foo') + + def test_execution_policy_handles_exception(self): + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IExceptionViewClassifier + from pyramid.interfaces import IRequest + class Exception1(Exception): + pass + class Exception2(Exception): + pass + req_iface = self._registerRouteRequest('foo') + self._connectRoute('foo', 'archives/:action/:article', None) + view = DummyView(DummyResponse(), raise_exception=Exception1) + self._registerView(view, '', IViewClassifier, req_iface, None) + exception_view1 = DummyView(DummyResponse(), + raise_exception=Exception2) + self._registerView(exception_view1, '', IExceptionViewClassifier, + IRequest, Exception1) + response = DummyResponse() + response.app_iter = ["Hello, world"] + exception_view2 = DummyView(response) + self._registerView(exception_view2, '', IExceptionViewClassifier, + IRequest, Exception2) + environ = self._makeEnviron(PATH_INFO='/archives/action1/article1') + start_response = DummyStartResponse() + router = self._makeOne() + result = router(environ, start_response) + self.assertEqual(result, ["Hello, world"]) + + def test_request_context_with_statement(self): + from pyramid.threadlocal import get_current_request + from pyramid.interfaces import IExecutionPolicy + from pyramid.request import Request + from pyramid.response import Response + registry = self.config.registry + result = [] + def dummy_policy(environ, router): + with router.request_context(environ): + result.append(get_current_request()) + result.append(get_current_request()) + return Response(status=200, body=b'foo') + registry.registerUtility(dummy_policy, IExecutionPolicy) + router = self._makeOne() + resp = Request.blank('/test_path').get_response(router) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.body, b'foo') + self.assertEqual(result[0].path_info, '/test_path') + self.assertEqual(result[1], None) + + def test_request_context_manually(self): + from pyramid.threadlocal import get_current_request + from pyramid.interfaces import IExecutionPolicy + from pyramid.request import Request + from pyramid.response import Response + registry = self.config.registry + result = [] + def dummy_policy(environ, router): + ctx = router.request_context(environ) + ctx.begin() + result.append(get_current_request()) + ctx.end() + result.append(get_current_request()) + return Response(status=200, body=b'foo') + registry.registerUtility(dummy_policy, IExecutionPolicy) + router = self._makeOne() + resp = Request.blank('/test_path').get_response(router) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.body, b'foo') + self.assertEqual(result[0].path_info, '/test_path') + self.assertEqual(result[1], None) + +class DummyPredicate(object): + def __call__(self, info, request): + return True + def text(self): + return 'predicate' + +class DummyContext: + pass + +class DummyView: + def __init__(self, response, raise_exception=None): + self.response = response + self.raise_exception = raise_exception + + def __call__(self, context, request): + self.context = context + self.request = request + if self.raise_exception is not None: + raise self.raise_exception + return self.response + +class DummyRootFactory: + def __init__(self, root): + self.root = root + + def __call__(self, environ): + return self.root + +class DummyStartResponse: + status = () + headers = () + def __call__(self, status, headers): + self.status = status + self.headers = headers + +from pyramid.interfaces import IResponse +from zope.interface import implementer + +@implementer(IResponse) +class DummyResponse(object): + headerlist = () + app_iter = () + environ = None + def __init__(self, status='200 OK'): + self.status = status + + def __call__(self, environ, start_response): + self.environ = environ + start_response(self.status, self.headerlist) + return self.app_iter + +class DummyAuthenticationPolicy: + pass + +class DummyLogger: + def __init__(self): + self.messages = [] + def info(self, msg): + self.messages.append(msg) + warn = info + debug = info + +def exc_raised(exc, func, *arg, **kw): + try: + func(*arg, **kw) + except exc as e: + return e + else: + raise AssertionError('%s not raised' % exc) # pragma: no cover + + diff --git a/tests/test_scaffolds/__init__.py b/tests/test_scaffolds/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/tests/test_scaffolds/__init__.py @@ -0,0 +1 @@ +# package diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/.badfile b/tests/test_scaffolds/fixture_scaffold/+package+/.badfile new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl b/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl new file mode 100644 index 000000000..d763b2435 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/__init__.py_tmpl @@ -0,0 +1,12 @@ +from pyramid.config import Configurator +from {{package}}.resources import Root + +def main(global_config, **settings): + """ This function returns a Pyramid WSGI application. + """ + config = Configurator(root_factory=Root, settings=settings) + config.add_view('{{package}}.views.my_view', + context='{{package}}:resources.Root', + renderer='{{package}}:templates/mytemplate.pt') + config.add_static_view('static', '{{package}}:static', cache_max_age=3600) + return config.make_wsgi_app() diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/resources.py b/tests/test_scaffolds/fixture_scaffold/+package+/resources.py new file mode 100644 index 000000000..3d811895c --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/resources.py @@ -0,0 +1,3 @@ +class Root(object): + def __init__(self, request): + self.request = request diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico b/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico new file mode 100644 index 000000000..71f837c9e Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/favicon.ico differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png b/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png new file mode 100644 index 000000000..1fbc873da Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/footerbg.png differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png b/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png new file mode 100644 index 000000000..0596f2020 Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/headerbg.png differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css b/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css new file mode 100644 index 000000000..b7c8493d8 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/static/ie6.css @@ -0,0 +1,8 @@ +* html img, +* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none", +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')", +this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''), +this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')", +this.runtimeStyle.backgroundImage = "none")),this.pngSet=true) +);} +#wrap{display:table;height:100%} diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png b/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png new file mode 100644 index 000000000..2369cfb7d Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/middlebg.png differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css b/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css new file mode 100644 index 000000000..c54499ddd --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/static/pylons.css @@ -0,0 +1,65 @@ +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */ +vertical-align:baseline;background:transparent;} +body{line-height:1;} +ol,ul{list-style:none;} +blockquote,q{quotes:none;} +blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;} +:focus{outline:0;} +ins{text-decoration:none;} +del{text-decoration:line-through;} +table{border-collapse:collapse;border-spacing:0;} +sub{vertical-align:sub;font-size:smaller;line-height:normal;} +sup{vertical-align:super;font-size:smaller;line-height:normal;} +ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;} +ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;} +li{display:list-item;} +ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;} +ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;} +ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;} +.hidden{display:none;} +p{line-height:1.5em;} +h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;} +h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;} +h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;} +h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;} +html,body{width:100%;height:100%;} +body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;} +a{color:#1b61d6;text-decoration:none;} +a:hover{color:#e88f00;text-decoration:underline;} +body h1, +body h2, +body h3, +body h4, +body h5, +body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;} +#wrap{min-height:100%;} +#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;} +#header{background:#000000;top:0;font-size:14px;} +#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;} +.header,.footer{width:750px;margin-right:auto;margin-left:auto;} +.wrapper{width:100%} +#top,#top-small,#bottom{width:100%;} +#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;} +#bottom{color:#222;background-color:#ffffff;} +.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;} +.top{padding-top:40px;} +.top-small{padding-top:10px;} +#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;} +.app-welcome{margin-top:25px;} +.app-name{color:#000000;font-weight:bold;} +.bottom{padding-top:50px;} +#left{width:350px;float:left;padding-right:25px;} +#right{width:350px;float:right;padding-left:25px;} +.align-left{text-align:left;} +.align-right{text-align:right;} +.align-center{text-align:center;} +ul.links{margin:0;padding:0;} +ul.links li{list-style-type:none;font-size:14px;} +form{border-style:none;} +fieldset{border-style:none;} +input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;} +input[type=text],input[type=password]{width:205px;} +input[type=submit]{background-color:#ddd;font-weight:bold;} +/*Opera Fix*/ +body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;} diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png b/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png new file mode 100644 index 000000000..a5bc0ade7 Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid-small.png differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png b/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png new file mode 100644 index 000000000..347e05549 Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/pyramid.png differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif b/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif new file mode 100644 index 000000000..0341802e5 Binary files /dev/null and b/tests/test_scaffolds/fixture_scaffold/+package+/static/transparent.gif differ diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl b/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl new file mode 100644 index 000000000..f4d98ec29 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/templates/mytemplate.pt_tmpl @@ -0,0 +1,76 @@ + + + + The Pyramid Web Framework + + + + + + + + + + +
+
+
+
pyramid
+
+
+
+
+

+ Welcome to ${project}, an application generated by
+ the Pyramid Web Framework. +

+
+
+
+
+
+

Search documentation

+
+ + +
+
+ +
+
+
+ + + diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl b/tests/test_scaffolds/fixture_scaffold/+package+/test_no_content.py_tmpl new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl b/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl new file mode 100644 index 000000000..1627bf015 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/tests.py_tmpl @@ -0,0 +1,16 @@ +import unittest + +from pyramid import testing + +class ViewTests(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_my_view(self): + from {{package}}.views import my_view + request = testing.DummyRequest() + info = my_view(request) + self.assertEqual(info['project'], '{{project}}') diff --git a/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl b/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl new file mode 100644 index 000000000..12ed8832d --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/+package+/views.py_tmpl @@ -0,0 +1,2 @@ +def my_view(request): + return {'project':'{{project}}'} diff --git a/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl b/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl new file mode 100644 index 000000000..35a34f332 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/CHANGES.txt_tmpl @@ -0,0 +1,4 @@ +0.0 +--- + +- Initial version diff --git a/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl b/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl new file mode 100644 index 000000000..0ff6eb7a0 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/MANIFEST.in_tmpl @@ -0,0 +1,2 @@ +include *.txt *.ini *.cfg *.rst +recursive-include {{package}} *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml diff --git a/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl b/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl new file mode 100644 index 000000000..40f98d14a --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/README.txt_tmpl @@ -0,0 +1 @@ +{{project}} README diff --git a/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl b/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl new file mode 100644 index 000000000..01c504f99 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/development.ini_tmpl @@ -0,0 +1,45 @@ +[app:main] +use = egg:{{project}} + +pyramid.reload_templates = true +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = true +pyramid.default_locale_name = en +pyramid.includes = pyramid_debugtoolbar + +[server:main] +use = egg:pyramid#wsgiref +listen = *:6543 + +# Begin logging configuration + +[loggers] +keys = root, {{package_logger}} + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = INFO +handlers = console + +[logger_{{package_logger}}] +level = DEBUG +handlers = +qualname = {{package}} + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl b/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl new file mode 100644 index 000000000..becd3aa76 --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/production.ini_tmpl @@ -0,0 +1,44 @@ +[app:main] +use = egg:{{project}} + +pyramid.reload_templates = false +pyramid.debug_authorization = false +pyramid.debug_notfound = false +pyramid.debug_routematch = false +pyramid.debug_templates = false +pyramid.default_locale_name = en + +[server:main] +use = egg:pyramid#wsgiref +listen = *:6543 + +# Begin logging configuration + +[loggers] +keys = root, {{package_logger}} + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console + +[logger_{{package_logger}}] +level = WARN +handlers = +qualname = {{package}} + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s + +# End logging configuration diff --git a/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl b/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl new file mode 100644 index 000000000..ee9fd5fda --- /dev/null +++ b/tests/test_scaffolds/fixture_scaffold/setup.py_tmpl @@ -0,0 +1,38 @@ +import os + +from setuptools import setup, find_packages + +here = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(here, 'README.txt')) as f: + README = f.read() +with open(os.path.join(here, 'CHANGES.txt')) as f: + CHANGES = f.read() + +requires = ['pyramid', 'pyramid_debugtoolbar'] + +setup(name='{{project}}', + version='0.0', + description='{{project}}', + long_description=README + '\n\n' + CHANGES, + classifiers=[ + "Programming Language :: Python", + "Framework :: Pylons", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application", + ], + author='', + author_email='', + url='', + keywords='web pyramid pylons', + packages=find_packages(), + include_package_data=True, + zip_safe=False, + install_requires=requires, + tests_require=requires, + test_suite="{{package}}", + entry_points = """\ + [paste.app_factory] + main = {{package}}:main + """, + ) + diff --git a/tests/test_scaffolds/test_copydir.py b/tests/test_scaffolds/test_copydir.py new file mode 100644 index 000000000..1e92b3c36 --- /dev/null +++ b/tests/test_scaffolds/test_copydir.py @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- +import unittest +import os +import pkg_resources + +class Test_copy_dir(unittest.TestCase): + def setUp(self): + import tempfile + from pyramid.compat import NativeIO + self.dirname = tempfile.mkdtemp() + self.out = NativeIO() + self.fixturetuple = ('pyramid.tests.test_scaffolds', + 'fixture_scaffold') + + def tearDown(self): + import shutil + shutil.rmtree(self.dirname, ignore_errors=True) + self.out.close() + + def _callFUT(self, *arg, **kw): + kw['out_'] = self.out + from pyramid.scaffolds.copydir import copy_dir + return copy_dir(*arg, **kw) + + def test_copy_source_as_pkg_resource(self): + vars = {'package':'mypackage'} + self._callFUT(self.fixturetuple, + self.dirname, + vars, + 1, False, + template_renderer=dummy_template_renderer) + result = self.out.getvalue() + self.assertTrue('Creating' in result) + self.assertTrue( + 'Copying fixture_scaffold/+package+/__init__.py_tmpl to' in result) + source = pkg_resources.resource_filename( + 'pyramid.tests.test_scaffolds', + 'fixture_scaffold/+package+/__init__.py_tmpl') + target = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(target, 'r') as f: + tcontent = f.read() + with open(source, 'r') as f: + scontent = f.read() + self.assertEqual(scontent, tcontent) + + def test_copy_source_as_dirname(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 1, False, + template_renderer=dummy_template_renderer) + result = self.out.getvalue() + self.assertTrue('Creating' in result) + self.assertTrue('Copying __init__.py_tmpl to' in result) + source = pkg_resources.resource_filename( + 'pyramid.tests.test_scaffolds', + 'fixture_scaffold/+package+/__init__.py_tmpl') + target = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(target, 'r') as f: + tcontent = f.read() + with open(source, 'r') as f: + scontent = f.read() + self.assertEqual(scontent, tcontent) + + def test_content_is_same_message(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 2, False, + template_renderer=dummy_template_renderer) + self._callFUT(source, + self.dirname, + vars, + 2, False, + template_renderer=dummy_template_renderer) + result = self.out.getvalue() + self.assertTrue('%s already exists (same content)' % \ + os.path.join(self.dirname, 'mypackage', '__init__.py') in result) + + def test_direxists_message(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + # if not os.path.exists(self.dirname): + # os.mkdir(self.dirname) + self._callFUT(source, + self.dirname, + vars, + 2, False, + template_renderer=dummy_template_renderer) + result = self.out.getvalue() + self.assertTrue('Directory %s exists' % self.dirname in result, result) + + def test_overwrite_false(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=False, + template_renderer=dummy_template_renderer) + # toplevel file + toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(toplevel, 'w') as f: + f.write('These are the words you are looking for.') + # sub directory file + sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') + with open(sub, 'w') as f: + f.write('These are the words you are looking for.') + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=False, + template_renderer=dummy_template_renderer) + with open(toplevel, 'r') as f: + tcontent = f.read() + self.assertEqual('These are the words you are looking for.', tcontent) + with open(sub, 'r') as f: + tcontent = f.read() + self.assertEqual('These are the words you are looking for.', tcontent) + + def test_overwrite_true(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=True, + template_renderer=dummy_template_renderer) + # toplevel file + toplevel = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(toplevel, 'w') as f: + f.write('These are not the words you are looking for.') + # sub directory file + sub = os.path.join(self.dirname, 'mypackage', 'templates', 'mytemplate.pt') + with open(sub, 'w') as f: + f.write('These are not the words you are looking for.') + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=True, + template_renderer=dummy_template_renderer) + with open(toplevel, 'r') as f: + tcontent = f.read() + self.assertNotEqual('These are not the words you are looking for.', tcontent) + with open(sub, 'r') as f: + tcontent = f.read() + self.assertNotEqual('These are not the words you are looking for.', tcontent) + + def test_detect_SkipTemplate(self): + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + def dummy_template_renderer(*args, **kwargs): + from pyramid.scaffolds.copydir import SkipTemplate + raise SkipTemplate + self._callFUT(source, + self.dirname, + vars, + 1, False, + template_renderer=dummy_template_renderer) + + def test_query_interactive(self): + from pyramid.scaffolds import copydir + vars = {'package':'mypackage'} + source = pkg_resources.resource_filename(*self.fixturetuple) + self._callFUT(source, + self.dirname, + vars, + 1, False, + overwrite=False, + template_renderer=dummy_template_renderer) + target = os.path.join(self.dirname, 'mypackage', '__init__.py') + with open(target, 'w') as f: + f.write('These are not the words you are looking for.') + # We need query_interactive to return False in order to force + # execution of a branch + original_code_object = copydir.query_interactive + copydir.query_interactive = lambda *args, **kwargs: False + self._callFUT(source, + self.dirname, + vars, + 1, False, + interactive=True, + overwrite=False, + template_renderer=dummy_template_renderer) + copydir.query_interactive = original_code_object + +class Test_raise_SkipTemplate(unittest.TestCase): + + def _callFUT(self, *arg, **kw): + from pyramid.scaffolds.copydir import skip_template + return skip_template(*arg, **kw) + + def test_raise_SkipTemplate(self): + from pyramid.scaffolds.copydir import SkipTemplate + self.assertRaises(SkipTemplate, + self._callFUT, True, "exc-message") + +class Test_makedirs(unittest.TestCase): + + def _callFUT(self, *arg, **kw): + from pyramid.scaffolds.copydir import makedirs + return makedirs(*arg, **kw) + + def test_makedirs_parent_dir(self): + import shutil + import tempfile + tmpdir = tempfile.mkdtemp() + target = os.path.join(tmpdir, 'nonexistent_subdir') + self._callFUT(target, 2, None) + shutil.rmtree(tmpdir) + + def test_makedirs_no_parent_dir(self): + import shutil + import tempfile + tmpdir = tempfile.mkdtemp() + target = os.path.join(tmpdir, 'nonexistent_subdir', 'non2') + self._callFUT(target, 2, None) + shutil.rmtree(tmpdir) + +class Test_support_functions(unittest.TestCase): + + def _call_html_quote(self, *arg, **kw): + from pyramid.scaffolds.copydir import html_quote + return html_quote(*arg, **kw) + + def _call_url_quote(self, *arg, **kw): + from pyramid.scaffolds.copydir import url_quote + return url_quote(*arg, **kw) + + def _call_test(self, *arg, **kw): + from pyramid.scaffolds.copydir import test + return test(*arg, **kw) + + def test_html_quote(self): + import string + s = None + self.assertEqual(self._call_html_quote(s), '') + s = string.ascii_letters + self.assertEqual(self._call_html_quote(s), s) + s = "Λεμεσός" + self.assertEqual(self._call_url_quote(s), + "%CE%9B%CE%B5%CE%BC%CE%B5%CF%83%CF%8C%CF%82") + + def test_url_quote(self): + import string + s = None + self.assertEqual(self._call_url_quote(s), '') + s = string.ascii_letters + self.assertEqual(self._call_url_quote(s), s) + s = "Λεμεσός" + self.assertEqual(self._call_url_quote(s), + "%CE%9B%CE%B5%CE%BC%CE%B5%CF%83%CF%8C%CF%82") + + def test_test(self): + conf = True + true_cond = "faked" + self.assertEqual(self._call_test( + conf, true_cond, false_cond=None), "faked") + conf = False + self.assertEqual(self._call_test( + conf, true_cond, false_cond="alsofaked"), "alsofaked") + + +class Test_should_skip_file(unittest.TestCase): + + def _callFUT(self, *arg, **kw): + from pyramid.scaffolds.copydir import should_skip_file + return should_skip_file(*arg, **kw) + + def test_should_skip_dot_hidden_file(self): + self.assertEqual( + self._callFUT('.a_filename'), + 'Skipping hidden file %(filename)s') + + def test_should_skip_backup_file(self): + for name in ('a_filename~', 'a_filename.bak'): + self.assertEqual( + self._callFUT(name), + 'Skipping backup file %(filename)s') + + def test_should_skip_bytecompiled_file(self): + for name in ('afilename.pyc', 'afilename.pyo'): + extension = os.path.splitext(name)[1] + self.assertEqual( + self._callFUT(name), + 'Skipping %s file ' % extension + '%(filename)s') + + def test_should_skip_jython_class_file(self): + self.assertEqual( + self._callFUT('afilename$py.class'), + 'Skipping $py.class file %(filename)s') + + def test_should_skip_version_control_directory(self): + for name in ('CVS', '_darcs'): + self.assertEqual( + self._callFUT(name), + 'Skipping version control directory %(filename)s') + + def test_valid_file_is_not_skipped(self): + self.assertEqual( + self._callFUT('a_filename'), None) + +class RawInputMockObject( object ): + count = 0 + def __init__( self, fake_input ): + self.input= fake_input + self.count = 0 + def __call__( self, prompt ): + # Don't cycle endlessly. + self.count += 1 + if self.count > 1: + return 'y' + else: + return self.input + +class Test_query_interactive(unittest.TestCase): + + def setUp(self): + import tempfile + from pyramid.compat import NativeIO + self.dirname = tempfile.mkdtemp() + self.out = NativeIO() + self.fixturetuple = ('pyramid.tests.test_scaffolds', + 'fixture_scaffold') + self.src_content = """\ +These are not the droids +that you are looking for.""" + self.dest_content = """\ +These are the droids for +whom you are looking; +now you have found them.""" + self.src_fn = os.path.join(self.dirname, 'mypackage', '__init__.py') + self.dest_fn = os.path.join(self.dirname, 'mypackage', '__init__.py') + # query_interactive is only normally executed when the destination + # is discovered to be already occupied by existing files, so ... + # create the required occupancy. + from pyramid.scaffolds.copydir import copy_dir + copy_dir(self.fixturetuple, + self.dirname, + {'package':'mypackage'}, + 0, False, + template_renderer=dummy_template_renderer) + + def tearDown(self): + import shutil + shutil.rmtree(self.dirname, ignore_errors=True) + self.out.close() + + def _callFUT(self, *arg, **kw): + from pyramid.scaffolds.copydir import query_interactive + return query_interactive(*arg, **kw) + + def test_query_interactive_0y(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("y") + self._callFUT(self.src_fn, self.dest_fn, + self.src_content, self.dest_content, + simulate=False, + out_=self.out) + self.assertTrue("Replace" in self.out.getvalue()) + + def test_query_interactive_1n(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("n") + self._callFUT(self.src_fn, self.dest_fn, + self.src_content, + '\n'.join(self.dest_content.split('\n')[:-1]), + simulate=False, + out_=self.out) + self.assertTrue("Replace" in self.out.getvalue()) + + def test_query_interactive_2b(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("b") + with open(os.path.join( + self.dirname, 'mypackage', '__init__.py.bak'), 'w') as fp: + fp.write("") + fp.close() + self._callFUT(self.src_fn, self.dest_fn, + self.dest_content, self.src_content, + simulate=False, + out_=self.out) + self.assertTrue("Backing up" in self.out.getvalue()) + + def test_query_interactive_3d(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("d") + self._callFUT(self.src_fn, self.dest_fn, + self.dest_content, self.src_content, + simulate=False, + out_=self.out) + output = self.out.getvalue() + # The useful text in self.out gets wiped out on the second + # call to raw_input, otherwise the test could be made + # more usefully precise... + # print("3d", output) + # self.assertTrue("@@" in output, output) + self.assertTrue("Replace" in output) + + def test_query_interactive_4dc(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("dc") + self._callFUT(self.src_fn, self.dest_fn, + self.dest_content, self.src_content, + simulate=False, + out_=self.out) + output = self.out.getvalue() + # The useful text in self.out gets wiped out on the second + # call to raw_input, otherwise, the test could be made + # more usefully precise... + # print("4dc", output) + # self.assertTrue("***" in output, output) + self.assertTrue("Replace" in output) + + def test_query_interactive_5allbad(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("all z") + self._callFUT(self.src_fn, self.dest_fn, + self.src_content, self.dest_content, + simulate=False, + out_=self.out) + output = self.out.getvalue() + # The useful text in self.out gets wiped out on the second + # call to raw_input, otherwise the test could be made + # more usefully precise... + # print("5allbad", output) + # self.assertTrue("Responses" in output, output) + self.assertTrue("Replace" in output) + + def test_query_interactive_6all(self): + from pyramid.scaffolds import copydir + copydir.input_ = RawInputMockObject("all b") + self._callFUT(self.src_fn, self.dest_fn, + self.src_content, self.dest_content, + simulate=False, + out_=self.out) + output = self.out.getvalue() + # The useful text in self.out gets wiped out on the second + # call to raw_input, otherwise the test could be made + # more usefully precise... + # print("6all", output) + # self.assertTrue("Responses" in output, output) + self.assertTrue("Replace" in output) + +def dummy_template_renderer(content, v, filename=None): + return content + diff --git a/tests/test_scaffolds/test_init.py b/tests/test_scaffolds/test_init.py new file mode 100644 index 000000000..f4d1b287a --- /dev/null +++ b/tests/test_scaffolds/test_init.py @@ -0,0 +1,21 @@ +import unittest + +class TestPyramidTemplate(unittest.TestCase): + def _makeOne(self): + from pyramid.scaffolds import PyramidTemplate + return PyramidTemplate('name') + + def test_pre(self): + inst = self._makeOne() + vars = {'package':'one'} + inst.pre('command', 'output dir', vars) + self.assertTrue(vars['random_string']) + self.assertEqual(vars['package_logger'], 'one') + + def test_pre_root(self): + inst = self._makeOne() + vars = {'package':'root'} + inst.pre('command', 'output dir', vars) + self.assertTrue(vars['random_string']) + self.assertEqual(vars['package_logger'], 'app') + diff --git a/tests/test_scaffolds/test_template.py b/tests/test_scaffolds/test_template.py new file mode 100644 index 000000000..98f2daf73 --- /dev/null +++ b/tests/test_scaffolds/test_template.py @@ -0,0 +1,155 @@ +import unittest + +from pyramid.compat import bytes_ + +class TestTemplate(unittest.TestCase): + def _makeOne(self, name='whatever'): + from pyramid.scaffolds.template import Template + return Template(name) + + def test_render_template_success(self): + inst = self._makeOne() + result = inst.render_template('{{a}} {{b}}', {'a':'1', 'b':'2'}) + self.assertEqual(result, bytes_('1 2')) + + def test_render_template_expr_failure(self): + inst = self._makeOne() + self.assertRaises(AttributeError, inst.render_template, + '{{a.foo}}', {'a':'1', 'b':'2'}) + + def test_render_template_expr_success(self): + inst = self._makeOne() + result = inst.render_template('{{a.lower()}}', {'a':'A'}) + self.assertEqual(result, b'a') + + def test_render_template_expr_success_via_pipe(self): + inst = self._makeOne() + result = inst.render_template('{{b|c|a.lower()}}', {'a':'A'}) + self.assertEqual(result, b'a') + + def test_render_template_expr_success_via_pipe2(self): + inst = self._makeOne() + result = inst.render_template('{{b|a.lower()|c}}', {'a':'A'}) + self.assertEqual(result, b'a') + + def test_render_template_expr_value_is_None(self): + inst = self._makeOne() + result = inst.render_template('{{a}}', {'a':None}) + self.assertEqual(result, b'') + + def test_render_template_with_escaped_double_braces(self): + inst = self._makeOne() + result = inst.render_template('{{a}} {{b}} \{\{a\}\} \{\{c\}\}', {'a':'1', 'b':'2'}) + self.assertEqual(result, bytes_('1 2 {{a}} {{c}}')) + + def test_render_template_with_breaking_escaped_braces(self): + inst = self._makeOne() + result = inst.render_template('{{a}} {{b}} \{\{a\} \{b\}\}', {'a':'1', 'b':'2'}) + self.assertEqual(result, bytes_('1 2 \{\{a\} \{b\}\}')) + + def test_render_template_with_escaped_single_braces(self): + inst = self._makeOne() + result = inst.render_template('{{a}} {{b}} \{a\} \{b', {'a':'1', 'b':'2'}) + self.assertEqual(result, bytes_('1 2 \{a\} \{b')) + + def test_module_dir(self): + import sys + import pkg_resources + package = sys.modules['pyramid.scaffolds.template'] + path = pkg_resources.resource_filename(package.__name__, '') + inst = self._makeOne() + result = inst.module_dir() + self.assertEqual(result, path) + + def test_template_dir__template_dir_is_None(self): + inst = self._makeOne() + self.assertRaises(AssertionError, inst.template_dir) + + def test_template_dir__template_dir_is_tuple(self): + inst = self._makeOne() + inst._template_dir = ('a', 'b') + self.assertEqual(inst.template_dir(), ('a', 'b')) + + def test_template_dir__template_dir_is_not_None(self): + import os + import sys + import pkg_resources + package = sys.modules['pyramid.scaffolds.template'] + path = pkg_resources.resource_filename(package.__name__, '') + inst = self._makeOne() + inst._template_dir ='foo' + result = inst.template_dir() + self.assertEqual(result, os.path.join(path, 'foo')) + + def test_write_files_path_exists(self): + import os + import sys + import pkg_resources + package = sys.modules['pyramid.scaffolds.template'] + path = pkg_resources.resource_filename(package.__name__, '') + inst = self._makeOne() + inst._template_dir = 'foo' + inst.exists = lambda *arg: True + copydir = DummyCopydir() + inst.copydir = copydir + command = DummyCommand() + inst.write_files(command, 'output dir', {'a':1}) + self.assertEqual(copydir.template_dir, os.path.join(path, 'foo')) + self.assertEqual(copydir.output_dir, 'output dir') + self.assertEqual(copydir.vars, {'a':1}) + self.assertEqual(copydir.kw, + {'template_renderer':inst.render_template, + 'indent':1, + 'verbosity':1, + 'simulate':False, + 'overwrite':False, + 'interactive':False, + }) + + def test_write_files_path_missing(self): + L = [] + inst = self._makeOne() + inst._template_dir = 'foo' + inst.exists = lambda *arg: False + inst.out = lambda *arg: None + inst.makedirs = lambda dir: L.append(dir) + copydir = DummyCopydir() + inst.copydir = copydir + command = DummyCommand() + inst.write_files(command, 'output dir', {'a':1}) + self.assertEqual(L, ['output dir']) + + def test_run(self): + L = [] + inst = self._makeOne() + inst._template_dir = 'foo' + inst.exists = lambda *arg: False + inst.out = lambda *arg: None + inst.makedirs = lambda dir: L.append(dir) + copydir = DummyCopydir() + inst.copydir = copydir + command = DummyCommand() + inst.run(command, 'output dir', {'a':1}) + self.assertEqual(L, ['output dir']) + + def test_check_vars(self): + inst = self._makeOne() + self.assertRaises(RuntimeError, inst.check_vars, 'one', 'two') + +class DummyCopydir(object): + def copy_dir(self, template_dir, output_dir, vars, **kw): + self.template_dir = template_dir + self.output_dir = output_dir + self.vars = vars + self.kw = kw + +class DummyArgs(object): + simulate = False + overwrite = False + interactive = False + +class DummyCommand(object): + args = DummyArgs() + verbosity = 1 + + diff --git a/tests/test_scripting.py b/tests/test_scripting.py new file mode 100644 index 000000000..ed88bb470 --- /dev/null +++ b/tests/test_scripting.py @@ -0,0 +1,221 @@ +import unittest + +class Test_get_root(unittest.TestCase): + def _callFUT(self, app, request=None): + from pyramid.scripting import get_root + return get_root(app, request) + + def _makeRegistry(self): + return DummyRegistry([DummyFactory]) + + def setUp(self): + from pyramid.threadlocal import manager + self.manager = manager + self.default = manager.get() + + def test_it_norequest(self): + registry = self._makeRegistry() + app = DummyApp(registry=registry) + root, closer = self._callFUT(app) + self.assertEqual(dummy_root, root) + pushed = self.manager.get() + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'].registry, registry) + self.assertEqual(pushed['request'].environ['path'], '/') + closer() + self.assertEqual(self.default, self.manager.get()) + + def test_it_withrequest(self): + registry = self._makeRegistry() + app = DummyApp(registry=registry) + request = DummyRequest({}) + root, closer = self._callFUT(app, request) + self.assertEqual(dummy_root, root) + pushed = self.manager.get() + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'], request) + self.assertEqual(pushed['request'].registry, registry) + closer() + self.assertEqual(self.default, self.manager.get()) + +class Test_prepare(unittest.TestCase): + def _callFUT(self, request=None, registry=None): + from pyramid.scripting import prepare + return prepare(request, registry) + + def _makeRegistry(self, L=None): + if L is None: + L = [None, DummyFactory] + return DummyRegistry(L) + + def setUp(self): + from pyramid.threadlocal import manager + self.manager = manager + self.default = manager.get() + + def test_it_no_valid_apps(self): + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, self._callFUT) + + def test_it_norequest(self): + registry = self._makeRegistry([DummyFactory, None, DummyFactory]) + info = self._callFUT(registry=registry) + root, closer, request = info['root'], info['closer'], info['request'] + pushed = self.manager.get() + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'].registry, registry) + self.assertEqual(root.a, (pushed['request'],)) + closer() + self.assertEqual(self.default, self.manager.get()) + self.assertEqual(request.context, root) + + def test_it_withrequest_hasregistry(self): + request = DummyRequest({}) + registry = request.registry = self._makeRegistry() + info = self._callFUT(request=request) + root, closer, request = info['root'], info['closer'], info['request'] + pushed = self.manager.get() + self.assertEqual(pushed['request'], request) + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'].registry, registry) + self.assertEqual(root.a, (request,)) + closer() + self.assertEqual(self.default, self.manager.get()) + self.assertEqual(request.context, root) + self.assertEqual(request.registry, registry) + + def test_it_withrequest_noregistry(self): + request = DummyRequest({}) + registry = self._makeRegistry() + info = self._callFUT(request=request, registry=registry) + root, closer, request = info['root'], info['closer'], info['request'] + closer() + self.assertEqual(request.context, root) + # should be set by prepare + self.assertEqual(request.registry, registry) + + def test_it_with_request_and_registry(self): + request = DummyRequest({}) + registry = request.registry = self._makeRegistry() + info = self._callFUT(request=request, registry=registry) + root, closer, root = info['root'], info['closer'], info['root'] + pushed = self.manager.get() + self.assertEqual(pushed['request'], request) + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'].registry, registry) + self.assertEqual(root.a, (request,)) + closer() + self.assertEqual(self.default, self.manager.get()) + self.assertEqual(request.context, root) + + def test_it_with_request_context_already_set(self): + request = DummyRequest({}) + context = Dummy() + request.context = context + registry = request.registry = self._makeRegistry() + info = self._callFUT(request=request, registry=registry) + root, closer, root = info['root'], info['closer'], info['root'] + closer() + self.assertEqual(request.context, context) + + def test_it_with_extensions(self): + from pyramid.util import InstancePropertyHelper + exts = DummyExtensions() + ext_method = lambda r: 'bar' + name, fn = InstancePropertyHelper.make_property(ext_method, 'foo') + exts.descriptors[name] = fn + request = DummyRequest({}) + registry = request.registry = self._makeRegistry([exts, DummyFactory]) + info = self._callFUT(request=request, registry=registry) + self.assertEqual(request.foo, 'bar') + root, closer = info['root'], info['closer'] + closer() + + def test_it_is_a_context_manager(self): + request = DummyRequest({}) + registry = request.registry = self._makeRegistry() + closer_called = [False] + with self._callFUT(request=request) as info: + root, request = info['root'], info['request'] + pushed = self.manager.get() + self.assertEqual(pushed['request'], request) + self.assertEqual(pushed['registry'], registry) + self.assertEqual(pushed['request'].registry, registry) + self.assertEqual(root.a, (request,)) + orig_closer = info['closer'] + def closer(): + orig_closer() + closer_called[0] = True + info['closer'] = closer + self.assertTrue(closer_called[0]) + self.assertEqual(self.default, self.manager.get()) + self.assertEqual(request.context, root) + self.assertEqual(request.registry, registry) + +class Test__make_request(unittest.TestCase): + def _callFUT(self, path='/', registry=None): + from pyramid.scripting import _make_request + return _make_request(path, registry) + + def _makeRegistry(self): + return DummyRegistry([DummyFactory]) + + def test_it_with_registry(self): + registry = self._makeRegistry() + request = self._callFUT('/', registry) + self.assertEqual(request.environ['path'], '/') + self.assertEqual(request.registry, registry) + + def test_it_with_no_registry(self): + from pyramid.config import global_registries + registry = self._makeRegistry() + global_registries.add(registry) + try: + request = self._callFUT('/hello') + self.assertEqual(request.environ['path'], '/hello') + self.assertEqual(request.registry, registry) + finally: + global_registries.empty() + +class Dummy: + pass + +dummy_root = Dummy() + +class DummyFactory(object): + @classmethod + def blank(cls, path): + req = DummyRequest({'path': path}) + return req + + def __init__(self, *a, **kw): + self.a = a + self.kw = kw + +class DummyRegistry(object): + def __init__(self, utilities): + self.utilities = utilities + + def queryUtility(self, iface, default=None): # pragma: no cover + if self.utilities: + return self.utilities.pop(0) + return default + +class DummyApp: + def __init__(self, registry=None): + if registry: + self.registry = registry + + def root_factory(self, environ): + return dummy_root + +class DummyRequest(object): + matchdict = None + matched_route = None + def __init__(self, environ): + self.environ = environ + +class DummyExtensions: + def __init__(self): + self.descriptors = {} + self.methods = {} diff --git a/tests/test_scripts/__init__.py b/tests/test_scripts/__init__.py new file mode 100644 index 000000000..5bb534f79 --- /dev/null +++ b/tests/test_scripts/__init__.py @@ -0,0 +1 @@ +# package diff --git a/tests/test_scripts/dummy.py b/tests/test_scripts/dummy.py new file mode 100644 index 000000000..f1ef403f8 --- /dev/null +++ b/tests/test_scripts/dummy.py @@ -0,0 +1,190 @@ +class DummyTweens(object): + def __init__(self, implicit, explicit): + self._implicit = implicit + self.explicit = explicit + self.name_to_alias = {} + def implicit(self): + return self._implicit + +class Dummy: + pass + +dummy_root = Dummy() + +class DummyRegistry(object): + settings = {} + def queryUtility(self, iface, default=None, name=''): + return default + +dummy_registry = DummyRegistry() + +class DummyShell(object): + env = {} + help = '' + called = False + dummy_attr = 1 + + def __call__(self, env, help): + self.env = env + self.help = help + self.called = True + self.env['request'].dummy_attr = self.dummy_attr + +class DummyInteractor: + def __call__(self, banner, local): + self.banner = banner + self.local = local + +class DummyApp: + def __init__(self): + self.registry = dummy_registry + +class DummyMapper(object): + def __init__(self, *routes): + self.routes = routes + + def get_routes(self, include_static=False): + return self.routes + +class DummyRoute(object): + def __init__(self, name, pattern, factory=None, + matchdict=None, predicate=None): + self.name = name + self.path = pattern + self.pattern = pattern + self.factory = factory + self.matchdict = matchdict + self.predicates = [] + if predicate is not None: + self.predicates = [predicate] + + def match(self, route): + return self.matchdict + +class DummyRequest: + application_url = 'http://example.com:5432' + script_name = '' + def __init__(self, environ): + self.environ = environ + self.matchdict = {} + +class DummyView(object): + def __init__(self, **attrs): + self.__request_attrs__ = attrs + + def view(context, request): pass + +from zope.interface import implementer +from pyramid.interfaces import IMultiView +@implementer(IMultiView) +class DummyMultiView(object): + + def __init__(self, *views, **attrs): + self.views = [(None, view, None) for view in views] + self.__request_attrs__ = attrs + +class DummyCloser(object): + def __call__(self): + self.called = True + +class DummyBootstrap(object): + def __init__(self, app=None, registry=None, request=None, root=None, + root_factory=None, closer=None): + self.app = app or DummyApp() + if registry is None: + registry = DummyRegistry() + self.registry = registry + if request is None: + request = DummyRequest({}) + self.request = request + if root is None: + root = Dummy() + self.root = root + if root_factory is None: + root_factory = Dummy() + self.root_factory = root_factory + if closer is None: + closer = DummyCloser() + self.closer = closer + + def __call__(self, *a, **kw): + self.a = a + self.kw = kw + registry = kw.get('registry', self.registry) + request = kw.get('request', self.request) + request.registry = registry + return { + 'app': self.app, + 'registry': registry, + 'request': request, + 'root': self.root, + 'root_factory': self.root_factory, + 'closer': self.closer, + } + + +class DummyEntryPoint(object): + def __init__(self, name, module): + self.name = name + self.module = module + + def load(self): + return self.module + + +class DummyPkgResources(object): + def __init__(self, entry_point_values): + self.entry_points = [] + + for name, module in entry_point_values.items(): + self.entry_points.append(DummyEntryPoint(name, module)) + + def iter_entry_points(self, name): + return self.entry_points + + +class dummy_setup_logging(object): + def __call__(self, config_uri, global_conf): + self.config_uri = config_uri + self.defaults = global_conf + + +class DummyLoader(object): + def __init__(self, settings=None, app_settings=None, app=None, server=None): + if not settings: + settings = {} + if not app_settings: + app_settings = {} + self.settings = settings + self.app_settings = app_settings + self.app = app + self.server = server + self.calls = [] + + def __call__(self, uri): + import plaster + self.uri = plaster.parse_uri(uri) + return self + + def add_call(self, op, name, defaults): + self.calls.append({'op': op, 'name': name, 'defaults': defaults}) + + def get_settings(self, name=None, defaults=None): + self.add_call('settings', name, defaults) + return self.settings.get(name, {}) + + def get_wsgi_app(self, name=None, defaults=None): + self.add_call('app', name, defaults) + return self.app + + def get_wsgi_app_settings(self, name=None, defaults=None): + self.add_call('app_settings', name, defaults) + return self.app_settings + + def get_wsgi_server(self, name=None, defaults=None): + self.add_call('server', name, defaults) + return self.server + + def setup_logging(self, defaults): + self.add_call('logging', None, defaults) + self.defaults = defaults diff --git a/tests/test_scripts/pystartup.txt b/tests/test_scripts/pystartup.txt new file mode 100644 index 000000000..c62c4ca74 --- /dev/null +++ b/tests/test_scripts/pystartup.txt @@ -0,0 +1,3 @@ +# this file has a .txt extension to avoid coverage reports +# since it is not imported but rather the contents are read and exec'd +foo = 1 diff --git a/tests/test_scripts/test_common.py b/tests/test_scripts/test_common.py new file mode 100644 index 000000000..60741db92 --- /dev/null +++ b/tests/test_scripts/test_common.py @@ -0,0 +1,13 @@ +import unittest + +class TestParseVars(unittest.TestCase): + def test_parse_vars_good(self): + from pyramid.scripts.common import parse_vars + vars = ['a=1', 'b=2'] + result = parse_vars(vars) + self.assertEqual(result, {'a': '1', 'b': '2'}) + + def test_parse_vars_bad(self): + from pyramid.scripts.common import parse_vars + vars = ['a'] + self.assertRaises(ValueError, parse_vars, vars) diff --git a/tests/test_scripts/test_pcreate.py b/tests/test_scripts/test_pcreate.py new file mode 100644 index 000000000..0286614ce --- /dev/null +++ b/tests/test_scripts/test_pcreate.py @@ -0,0 +1,309 @@ +import unittest + + +class TestPCreateCommand(unittest.TestCase): + def setUp(self): + from pyramid.compat import NativeIO + self.out_ = NativeIO() + + def out(self, msg): + self.out_.write(msg) + + def _getTargetClass(self): + from pyramid.scripts.pcreate import PCreateCommand + return PCreateCommand + + def _makeOne(self, *args, **kw): + effargs = ['pcreate'] + effargs.extend(args) + tgt_class = kw.pop('target_class', self._getTargetClass()) + cmd = tgt_class(effargs, **kw) + cmd.out = self.out + return cmd + + def test_run_show_scaffolds_exist(self): + cmd = self._makeOne('-l') + result = cmd.run() + self.assertEqual(result, 0) + out = self.out_.getvalue() + self.assertTrue(out.count('Available scaffolds')) + + def test_run_show_scaffolds_none_exist(self): + cmd = self._makeOne('-l') + cmd.scaffolds = [] + result = cmd.run() + self.assertEqual(result, 0) + out = self.out_.getvalue() + self.assertTrue(out.count('No scaffolds available')) + + def test_run_no_scaffold_no_args(self): + cmd = self._makeOne(quiet=True) + result = cmd.run() + self.assertEqual(result, 2) + + def test_run_no_scaffold_name(self): + cmd = self._makeOne('dummy') + result = cmd.run() + self.assertEqual(result, 2) + out = self.out_.getvalue() + self.assertTrue(out.count( + 'You must provide at least one scaffold name')) + + def test_no_project_name(self): + cmd = self._makeOne('-s', 'dummy') + result = cmd.run() + self.assertEqual(result, 2) + out = self.out_.getvalue() + self.assertTrue(out.count('You must provide a project name')) + + def test_unknown_scaffold_name(self): + cmd = self._makeOne('-s', 'dummyXX', 'distro') + result = cmd.run() + self.assertEqual(result, 2) + out = self.out_.getvalue() + self.assertTrue(out.count('Unavailable scaffolds')) + + def test_known_scaffold_single_rendered(self): + import os + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + def test_scaffold_with_package_name(self): + import os + cmd = self._makeOne('-s', 'dummy', '--package-name', 'dummy_package', + 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'dummy_package', + 'package': 'dummy_package', 'pyramid_version': '0.1', + 'pyramid_docs_branch':'0.1-branch'}) + + + def test_scaffold_with_hyphen_in_project_name(self): + import os + cmd = self._makeOne('-s', 'dummy', 'Distro-') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro-')) + ) + self.assertEqual( + scaffold.vars, + {'project': 'Distro-', 'egg': 'Distro_', 'package': 'distro_', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + def test_known_scaffold_absolute_path(self): + import os + path = os.path.abspath('Distro') + cmd = self._makeOne('-s', 'dummy', path) + cmd.pyramid_dist = DummyDist("0.1") + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + def test_known_scaffold_multiple_rendered(self): + import os + cmd = self._makeOne('-s', 'dummy1', '-s', 'dummy2', 'Distro') + scaffold1 = DummyScaffold('dummy1') + scaffold2 = DummyScaffold('dummy2') + cmd.scaffolds = [scaffold1, scaffold2] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold1.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) + self.assertEqual( + scaffold1.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + self.assertEqual( + scaffold2.output_dir, + os.path.normpath(os.path.join(os.getcwd(), 'Distro')) + ) + self.assertEqual( + scaffold2.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + def test_known_scaffold_with_path_as_project_target_rendered(self): + import os + cmd = self._makeOne('-s', 'dummy', '/tmp/foo/Distro/') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.output_dir, + os.path.normpath(os.path.join(os.getcwd(), '/tmp/foo/Distro')) + ) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + + def test_scaffold_with_prod_pyramid_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.2") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.2', 'pyramid_docs_branch':'0.2-branch'}) + + def test_scaffold_with_prod_pyramid_long_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.2.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.2.1', 'pyramid_docs_branch':'0.2-branch'}) + + def test_scaffold_with_prod_pyramid_unparsable_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("abc") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': 'abc', 'pyramid_docs_branch':'latest'}) + + def test_scaffold_with_dev_pyramid_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.12dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.12dev', + 'pyramid_docs_branch': 'master'}) + + def test_scaffold_with_dev_pyramid_long_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.10.1dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.10.1dev', + 'pyramid_docs_branch': 'master'}) + + def test_confirm_override_conflicting_name(self): + from pyramid.scripts.pcreate import PCreateCommand + class YahInputPCreateCommand(PCreateCommand): + def confirm_bad_name(self, pkg_name): + return True + cmd = self._makeOne('-s', 'dummy', 'Unittest', target_class=YahInputPCreateCommand) + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.10.1dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Unittest', 'egg': 'Unittest', 'package': 'unittest', + 'pyramid_version': '0.10.1dev', + 'pyramid_docs_branch': 'master'}) + + def test_force_override_conflicting_name(self): + cmd = self._makeOne('-s', 'dummy', 'Unittest', '--ignore-conflicting-name') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.10.1dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Unittest', 'egg': 'Unittest', 'package': 'unittest', + 'pyramid_version': '0.10.1dev', + 'pyramid_docs_branch': 'master'}) + + def test_force_override_site_name(self): + from pyramid.scripts.pcreate import PCreateCommand + class NayInputPCreateCommand(PCreateCommand): + def confirm_bad_name(self, pkg_name): + return False + cmd = self._makeOne('-s', 'dummy', 'Site', target_class=NayInputPCreateCommand) + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.10.1dev") + result = cmd.run() + self.assertEqual(result, 2) + + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.pcreate import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['pcreate']) + self.assertEqual(result, 2) + +class DummyScaffold(object): + def __init__(self, name): + self.name = name + + def run(self, command, output_dir, vars): + self.command = command + self.output_dir = output_dir + self.vars = vars + +class DummyDist(object): + def __init__(self, version): + self.version = version diff --git a/tests/test_scripts/test_pdistreport.py b/tests/test_scripts/test_pdistreport.py new file mode 100644 index 000000000..e229667c5 --- /dev/null +++ b/tests/test_scripts/test_pdistreport.py @@ -0,0 +1,73 @@ +import unittest + +class TestPDistReportCommand(unittest.TestCase): + def _callFUT(self, **kw): + argv = [] + from pyramid.scripts.pdistreport import main + return main(argv, **kw) + + def test_no_dists(self): + def platform(): + return 'myplatform' + pkg_resources = DummyPkgResources() + L = [] + def out(*args): + L.extend(args) + result = self._callFUT(pkg_resources=pkg_resources, platform=platform, + out=out) + self.assertEqual(result, None) + self.assertEqual( + L, + ['Pyramid version:', '1', + 'Platform:', 'myplatform', + 'Packages:'] + ) + + def test_with_dists(self): + def platform(): + return 'myplatform' + working_set = (DummyDistribution('abc'), DummyDistribution('def')) + pkg_resources = DummyPkgResources(working_set) + L = [] + def out(*args): + L.extend(args) + result = self._callFUT(pkg_resources=pkg_resources, platform=platform, + out=out) + self.assertEqual(result, None) + self.assertEqual( + L, + ['Pyramid version:', + '1', + 'Platform:', + 'myplatform', + 'Packages:', + ' ', + 'abc', + '1', + ' ', + '/projects/abc', + ' ', + 'def', + '1', + ' ', + '/projects/def'] + ) + +class DummyPkgResources(object): + def __init__(self, working_set=()): + self.working_set = working_set + + def get_distribution(self, name): + return Version('1') + +class Version(object): + def __init__(self, version): + self.version = version + +class DummyDistribution(object): + def __init__(self, name): + self.project_name = name + self.version = '1' + self.location = '/projects/%s' % name + + diff --git a/tests/test_scripts/test_prequest.py b/tests/test_scripts/test_prequest.py new file mode 100644 index 000000000..75d5cc198 --- /dev/null +++ b/tests/test_scripts/test_prequest.py @@ -0,0 +1,214 @@ +import unittest +from pyramid.tests.test_scripts import dummy + +class TestPRequestCommand(unittest.TestCase): + def _getTargetClass(self): + from pyramid.scripts.prequest import PRequestCommand + return PRequestCommand + + def _makeOne(self, argv, headers=None): + cmd = self._getTargetClass()(argv) + + def helloworld(environ, start_request): + self._environ = environ + self._path_info = environ['PATH_INFO'] + start_request('200 OK', headers or []) + return [b'abc'] + self.loader = dummy.DummyLoader(app=helloworld) + self._out = [] + cmd._get_config_loader = self.loader + cmd.out = self.out + return cmd + + def out(self, msg): + self._out.append(msg) + + def test_command_not_enough_args(self): + command = self._makeOne([]) + command.run() + self.assertEqual(self._out, ['You must provide at least two arguments']) + + def test_command_two_args(self): + command = self._makeOne(['', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._path_info, '/') + self.assertEqual(self.loader.uri.path, 'development.ini') + self.assertEqual(self.loader.calls[0]['op'], 'logging') + self.assertEqual(self.loader.calls[1]['op'], 'app') + self.assertEqual(self.loader.calls[1]['name'], None) + self.assertEqual(self._out, ['abc']) + + def test_command_path_doesnt_start_with_slash(self): + command = self._makeOne(['', 'development.ini', 'abc'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._path_info, '/abc') + self.assertEqual(self.loader.uri.path, 'development.ini') + self.assertEqual(self._out, ['abc']) + + def test_command_has_bad_config_header(self): + command = self._makeOne( + ['', '--header=name','development.ini', '/']) + command.run() + self.assertEqual( + self._out[0], + ("Bad --header=name option, value must be in the form " + "'name:value'")) + + def test_command_has_good_header_var(self): + command = self._makeOne( + ['', '--header=name:value','development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._environ['HTTP_NAME'], 'value') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_w_basic_auth(self): + command = self._makeOne( + ['', '--login=user:password', + '--header=name:value','development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._environ['HTTP_NAME'], 'value') + self.assertEqual(self._environ['HTTP_AUTHORIZATION'], + 'Basic dXNlcjpwYXNzd29yZA==') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_has_content_type_header_var(self): + command = self._makeOne( + ['', '--header=content-type:app/foo','development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._environ['CONTENT_TYPE'], 'app/foo') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_has_multiple_header_vars(self): + command = self._makeOne( + ['', + '--header=name:value', + '--header=name2:value2', + 'development.ini', + '/'], + [('Content-Type', 'text/html; charset=UTF-8')] + ) + command.run() + self.assertEqual(self._environ['HTTP_NAME'], 'value') + self.assertEqual(self._environ['HTTP_NAME2'], 'value2') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_get(self): + command = self._makeOne(['', '--method=GET', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'GET') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_post(self): + from pyramid.compat import NativeIO + command = self._makeOne(['', '--method=POST', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + stdin = NativeIO() + command.stdin = stdin + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'POST') + self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') + self.assertEqual(self._environ['wsgi.input'], stdin) + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_put(self): + from pyramid.compat import NativeIO + command = self._makeOne(['', '--method=PUT', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + stdin = NativeIO() + command.stdin = stdin + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'PUT') + self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') + self.assertEqual(self._environ['wsgi.input'], stdin) + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_patch(self): + from pyramid.compat import NativeIO + command = self._makeOne(['', '--method=PATCH', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + stdin = NativeIO() + command.stdin = stdin + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'PATCH') + self.assertEqual(self._environ['CONTENT_LENGTH'], '-1') + self.assertEqual(self._environ['wsgi.input'], stdin) + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_propfind(self): + from pyramid.compat import NativeIO + command = self._makeOne(['', '--method=PROPFIND', 'development.ini', + '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + stdin = NativeIO() + command.stdin = stdin + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'PROPFIND') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_method_options(self): + from pyramid.compat import NativeIO + command = self._makeOne(['', '--method=OPTIONS', 'development.ini', + '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + stdin = NativeIO() + command.stdin = stdin + command.run() + self.assertEqual(self._environ['REQUEST_METHOD'], 'OPTIONS') + self.assertEqual(self._path_info, '/') + self.assertEqual(self._out, ['abc']) + + def test_command_with_query_string(self): + command = self._makeOne(['', 'development.ini', '/abc?a=1&b=2&c'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._environ['QUERY_STRING'], 'a=1&b=2&c') + self.assertEqual(self._path_info, '/abc') + self.assertEqual(self._out, ['abc']) + + def test_command_display_headers(self): + command = self._makeOne( + ['', '--display-headers', 'development.ini', '/'], + [('Content-Type', 'text/html; charset=UTF-8')]) + command.run() + self.assertEqual(self._path_info, '/') + self.assertEqual( + self._out, + ['200 OK', 'Content-Type: text/html; charset=UTF-8', 'abc']) + + def test_command_response_has_no_charset(self): + command = self._makeOne(['', '--method=GET', 'development.ini', '/'], + headers=[('Content-Type', 'image/jpeg')]) + command.run() + self.assertEqual(self._path_info, '/') + + self.assertEqual(self._out, [b'abc']) + + def test_command_method_configures_logging(self): + command = self._makeOne(['', 'development.ini', '/']) + command.run() + self.assertEqual(self.loader.calls[0]['op'], 'logging') + + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.prequest import main + return main(argv, True) + + def test_it(self): + result = self._callFUT(['prequest']) + self.assertEqual(result, 2) diff --git a/tests/test_scripts/test_proutes.py b/tests/test_scripts/test_proutes.py new file mode 100644 index 000000000..fab5e163e --- /dev/null +++ b/tests/test_scripts/test_proutes.py @@ -0,0 +1,792 @@ +import os +import unittest +from pyramid.tests.test_scripts import dummy + + +class DummyIntrospector(object): + def __init__(self): + self.relations = {} + self.introspectables = {} + + def get(self, name, discrim): + pass + + +class TestPRoutesCommand(unittest.TestCase): + def _getTargetClass(self): + from pyramid.scripts.proutes import PRoutesCommand + return PRoutesCommand + + def _makeOne(self): + cmd = self._getTargetClass()([]) + cmd.bootstrap = dummy.DummyBootstrap() + cmd.get_config_loader = dummy.DummyLoader() + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + + return cmd + + def _makeRegistry(self): + from pyramid.registry import Registry + registry = Registry() + registry.introspector = DummyIntrospector() + return registry + + def _makeConfig(self, *arg, **kw): + from pyramid.config import Configurator + config = Configurator(*arg, **kw) + return config + + def test_good_args(self): + cmd = self._getTargetClass()([]) + cmd.bootstrap = dummy.DummyBootstrap() + cmd.get_config_loader = dummy.DummyLoader() + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + cmd.args.config_args = ('a=1',) + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + cmd._get_mapper = lambda *arg: mapper + registry = self._makeRegistry() + cmd.bootstrap = dummy.DummyBootstrap(registry=registry) + L = [] + cmd.out = lambda msg: L.append(msg) + cmd.run() + self.assertTrue('' in ''.join(L)) + + def test_bad_args(self): + cmd = self._getTargetClass()([]) + cmd.bootstrap = dummy.DummyBootstrap() + cmd.get_config_loader = dummy.DummyLoader() + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + cmd.args.config_vars = ('a',) + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + cmd._get_mapper = lambda *arg: mapper + + self.assertRaises(ValueError, cmd.run) + + def test_no_routes(self): + command = self._makeOne() + mapper = dummy.DummyMapper() + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L, []) + + def test_no_mapper(self): + command = self._makeOne() + command._get_mapper = lambda *arg:None + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L, []) + + def test_single_route_no_route_registered(self): + command = self._makeOne() + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + registry = self._makeRegistry() + command.bootstrap = dummy.DummyBootstrap(registry=registry) + + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + self.assertEqual(L[-1].split(), ['a', '/a', '', '*']) + + def test_route_with_no_slash_prefix(self): + command = self._makeOne() + route = dummy.DummyRoute('a', 'a') + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + registry = self._makeRegistry() + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + self.assertEqual(L[-1].split(), ['a', '/a', '', '*']) + + def test_single_route_no_views_registered(self): + from zope.interface import Interface + from pyramid.interfaces import IRouteRequest + registry = self._makeRegistry() + + def view():pass + class IMyRoute(Interface): + pass + registry.registerUtility(IMyRoute, IRouteRequest, name='a') + command = self._makeOne() + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + self.assertEqual(L[-1].split()[:3], ['a', '/a', '']) + + def test_single_route_one_view_registered(self): + from zope.interface import Interface + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + registry = self._makeRegistry() + + def view():pass + class IMyRoute(Interface): + pass + registry.registerAdapter(view, + (IViewClassifier, IMyRoute, Interface), + IView, '') + registry.registerUtility(IMyRoute, IRouteRequest, name='a') + command = self._makeOne() + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split()[:3] + self.assertEqual( + compare_to, + ['a', '/a', 'pyramid.tests.test_scripts.test_proutes.view'] + ) + + def test_one_route_with_long_name_one_view_registered(self): + from zope.interface import Interface + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + registry = self._makeRegistry() + + def view():pass + + class IMyRoute(Interface): + pass + + registry.registerAdapter( + view, + (IViewClassifier, IMyRoute, Interface), + IView, '' + ) + + registry.registerUtility(IMyRoute, IRouteRequest, + name='very_long_name_123') + + command = self._makeOne() + route = dummy.DummyRoute( + 'very_long_name_123', + '/and_very_long_pattern_as_well' + ) + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split()[:3] + self.assertEqual( + compare_to, + ['very_long_name_123', + '/and_very_long_pattern_as_well', + 'pyramid.tests.test_scripts.test_proutes.view'] + ) + + def test_class_view(self): + from pyramid.renderers import null_renderer as nr + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=dummy.DummyView, + attr='view', + renderer=nr, + request_method='POST' + ) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + 'pyramid.tests.test_scripts.dummy.DummyView.view', 'POST' + ] + self.assertEqual(compare_to, expected) + + def test_single_route_one_view_registered_with_factory(self): + from zope.interface import Interface + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + registry = self._makeRegistry() + + def view():pass + class IMyRoot(Interface): + pass + class IMyRoute(Interface): + pass + registry.registerAdapter(view, + (IViewClassifier, IMyRoute, IMyRoot), + IView, '') + registry.registerUtility(IMyRoute, IRouteRequest, name='a') + command = self._makeOne() + def factory(request): pass + route = dummy.DummyRoute('a', '/a', factory=factory) + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + self.assertEqual(L[-1].split()[:3], ['a', '/a', '']) + + def test_single_route_multiview_registered(self): + from zope.interface import Interface + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + + registry = self._makeRegistry() + + def view(): pass + + class IMyRoute(Interface): + pass + + multiview1 = dummy.DummyMultiView( + view, context='context', + view_name='a1' + ) + + registry.registerAdapter( + multiview1, + (IViewClassifier, IMyRoute, Interface), + IMultiView, '' + ) + registry.registerUtility(IMyRoute, IRouteRequest, name='a') + command = self._makeOne() + route = dummy.DummyRoute('a', '/a') + mapper = dummy.DummyMapper(route) + command._get_mapper = lambda *arg: mapper + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split()[:3] + view_module = 'pyramid.tests.test_scripts.dummy' + view_str = '' + ] + self.assertEqual(compare_to, expected) + + def test_route_static_views(self): + from pyramid.renderers import null_renderer as nr + config = self._makeConfig(autocommit=True) + config.add_static_view('static', 'static', cache_max_age=3600) + path2 = os.path.normpath('/var/www/static') + config.add_static_view(name='static2', path=path2) + config.add_static_view( + name='pyramid_scaffold', + path='pyramid:scaffolds/starter/+package+/static' + ) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 5) + + expected = [ + ['__static/', '/static/*subpath', + 'pyramid.tests.test_scripts:static/', '*'], + ['__static2/', '/static2/*subpath', path2 + os.sep, '*'], + ['__pyramid_scaffold/', '/pyramid_scaffold/*subpath', + 'pyramid:scaffolds/starter/+package+/static/', '*'], + ] + + for index, line in enumerate(L[2:]): + data = line.split() + self.assertEqual(data, expected[index]) + + def test_route_no_view(self): + from pyramid.renderers import null_renderer as nr + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b', request_method='POST') + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + '', + 'POST', + ] + self.assertEqual(compare_to, expected) + + def test_route_as_wsgiapp(self): + from pyramid.wsgi import wsgiapp2 + + config1 = self._makeConfig(autocommit=True) + def view1(context, request): return 'view1' + config1.add_route('foo', '/a/b', request_method='POST') + config1.add_view(view=view1, route_name='foo') + + config2 = self._makeConfig(autocommit=True) + config2.add_route('foo', '/a/b', request_method='POST') + config2.add_view( + wsgiapp2(config1.make_wsgi_app()), + route_name='foo', + ) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config2.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + '', + 'POST', + ] + self.assertEqual(compare_to, expected) + + def test_route_is_get_view_request_method_not_post(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b', request_method='GET') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + 'pyramid.tests.test_scripts.test_proutes.view1', + 'GET' + ] + self.assertEqual(compare_to, expected) + + def test_view_request_method_not_post(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + 'pyramid.tests.test_scripts.test_proutes.view1', + '!POST,*' + ] + self.assertEqual(compare_to, expected) + + def test_view_glob(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + def view2(context, request): return 'view2' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + config.add_route('bar', '/b/a') + config.add_view( + route_name='bar', + view=view2, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + command.args.glob = '*foo*' + + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', '/a/b', + 'pyramid.tests.test_scripts.test_proutes.view1', + '!POST,*' + ] + self.assertEqual(compare_to, expected) + + def test_good_format(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + command.args.glob = '*foo*' + command.args.format = 'method,name' + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = ['!POST,*', 'foo'] + + self.assertEqual(compare_to, expected) + self.assertEqual(L[0].split(), ['Method', 'Name']) + + def test_bad_format(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + command.args.glob = '*foo*' + command.args.format = 'predicates,name,pattern' + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + expected = ( + "You provided invalid formats ['predicates'], " + "Available formats are ['name', 'pattern', 'view', 'method']" + ) + result = command.run() + self.assertEqual(result, 2) + self.assertEqual(L[0], expected) + + def test_config_format_ini_newlines(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + command.get_config_loader = dummy.DummyLoader( + {'proutes': {'format': 'method\nname'}}) + + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = ['!POST,*', 'foo'] + + self.assertEqual(compare_to, expected) + self.assertEqual(L[0].split(), ['Method', 'Name']) + + def test_config_format_ini_spaces(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + command.get_config_loader = dummy.DummyLoader( + {'proutes': {'format': 'method name'}}) + + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = ['!POST,*', 'foo'] + + self.assertEqual(compare_to, expected) + self.assertEqual(L[0].split(), ['Method', 'Name']) + + def test_config_format_ini_commas(self): + from pyramid.renderers import null_renderer as nr + from pyramid.config import not_ + + def view1(context, request): return 'view1' + + config = self._makeConfig(autocommit=True) + config.add_route('foo', '/a/b') + config.add_view( + route_name='foo', + view=view1, + renderer=nr, + request_method=not_('POST') + ) + + command = self._makeOne() + + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + command.get_config_loader = dummy.DummyLoader( + {'proutes': {'format': 'method,name'}}) + + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = ['!POST,*', 'foo'] + + self.assertEqual(compare_to, expected) + self.assertEqual(L[0].split(), ['Method', 'Name']) + + def test_static_routes_included_in_list(self): + from pyramid.renderers import null_renderer as nr + + config = self._makeConfig(autocommit=True) + config.add_route('foo', 'http://example.com/bar.aspx', static=True) + + command = self._makeOne() + L = [] + command.out = L.append + command.bootstrap = dummy.DummyBootstrap(registry=config.registry) + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(len(L), 3) + compare_to = L[-1].split() + expected = [ + 'foo', 'http://example.com/bar.aspx', + '', '*', + ] + self.assertEqual(compare_to, expected) + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.proutes import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['proutes']) + self.assertEqual(result, 2) diff --git a/tests/test_scripts/test_pserve.py b/tests/test_scripts/test_pserve.py new file mode 100644 index 000000000..485cf38cb --- /dev/null +++ b/tests/test_scripts/test_pserve.py @@ -0,0 +1,131 @@ +import os +import unittest +from pyramid.tests.test_scripts import dummy + + +here = os.path.abspath(os.path.dirname(__file__)) + + +class TestPServeCommand(unittest.TestCase): + def setUp(self): + from pyramid.compat import NativeIO + self.out_ = NativeIO() + + def out(self, msg): + self.out_.write(msg) + + def _getTargetClass(self): + from pyramid.scripts.pserve import PServeCommand + return PServeCommand + + def _makeOne(self, *args): + effargs = ['pserve'] + effargs.extend(args) + cmd = self._getTargetClass()(effargs) + cmd.out = self.out + self.loader = dummy.DummyLoader() + cmd._get_config_loader = self.loader + return cmd + + def test_run_no_args(self): + inst = self._makeOne() + result = inst.run() + self.assertEqual(result, 2) + self.assertEqual(self.out_.getvalue(), 'You must give a config file') + + def test_parse_vars_good(self): + inst = self._makeOne('development.ini', 'a=1', 'b=2') + app = dummy.DummyApp() + + def get_app(name, global_conf): + app.name = name + app.global_conf = global_conf + return app + self.loader.get_wsgi_app = get_app + self.loader.server = lambda x: x + + inst.run() + self.assertEqual(app.global_conf, {'a': '1', 'b': '2'}) + + def test_parse_vars_bad(self): + inst = self._makeOne('development.ini', 'a') + self.assertRaises(ValueError, inst.run) + + def test_config_file_finds_watch_files(self): + inst = self._makeOne('development.ini') + loader = self.loader('/base/path.ini') + loader.settings = {'pserve': { + 'watch_files': 'foo\n/baz\npyramid.tests.test_scripts:*.py', + }} + inst.pserve_file_config(loader, global_conf={'a': '1'}) + self.assertEqual(loader.calls[0]['defaults'], { + 'a': '1', + }) + self.assertEqual(inst.watch_files, set([ + os.path.abspath('/base/foo'), + os.path.abspath('/baz'), + os.path.abspath(os.path.join(here, '*.py')), + ])) + + def test_config_file_finds_open_url(self): + inst = self._makeOne('development.ini') + loader = self.loader('/base/path.ini') + loader.settings = {'pserve': { + 'open_url': 'http://127.0.0.1:8080/', + }} + inst.pserve_file_config(loader, global_conf={'a': '1'}) + self.assertEqual(loader.calls[0]['defaults'], { + 'a': '1', + }) + self.assertEqual(inst.open_url, 'http://127.0.0.1:8080/') + + def test_guess_server_url(self): + inst = self._makeOne('development.ini') + loader = self.loader('/base/path.ini') + loader.settings = {'server:foo': { + 'port': '8080', + }} + url = inst.guess_server_url(loader, 'foo', global_conf={'a': '1'}) + self.assertEqual(loader.calls[0]['defaults'], { + 'a': '1', + }) + self.assertEqual(url, 'http://127.0.0.1:8080') + + def test_reload_call_hupper_with_correct_args(self): + from pyramid.scripts import pserve + + class AttrDict(dict): + def __init__(self, *args, **kwargs): + super(AttrDict, self).__init__(*args, **kwargs) + self.__dict__ = self + + def dummy_start_reloader(*args, **kwargs): + dummy_start_reloader.args = args + dummy_start_reloader.kwargs = kwargs + + orig_hupper = pserve.hupper + try: + pserve.hupper = AttrDict(is_active=lambda: False, + start_reloader=dummy_start_reloader) + + inst = self._makeOne('--reload', 'development.ini') + inst.run() + finally: + pserve.hupper = orig_hupper + + self.assertEquals(dummy_start_reloader.args, ('pyramid.scripts.pserve.main',)) + self.assertEquals(dummy_start_reloader.kwargs, { + 'reload_interval': 1, + 'verbose': 1, + 'worker_kwargs': {'argv': ['pserve', '--reload', 'development.ini'], + 'quiet': False}}) + + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.pserve import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['pserve']) + self.assertEqual(result, 2) diff --git a/tests/test_scripts/test_pshell.py b/tests/test_scripts/test_pshell.py new file mode 100644 index 000000000..df664bea9 --- /dev/null +++ b/tests/test_scripts/test_pshell.py @@ -0,0 +1,398 @@ +import os +import unittest +from pyramid.tests.test_scripts import dummy + + +class TestPShellCommand(unittest.TestCase): + def _getTargetClass(self): + from pyramid.scripts.pshell import PShellCommand + return PShellCommand + + def _makeOne(self, patch_bootstrap=True, patch_loader=True, + patch_args=True, patch_options=True): + cmd = self._getTargetClass()([]) + + if patch_bootstrap: + self.bootstrap = dummy.DummyBootstrap() + cmd.bootstrap = self.bootstrap + if patch_loader: + self.loader = dummy.DummyLoader() + cmd.get_config_loader = self.loader + if patch_args: + class Args(object): pass + self.args = Args() + self.args.config_uri = '/foo/bar/myapp.ini#myapp' + cmd.args.config_uri = self.args.config_uri + if patch_options: + class Options(object): pass + self.options = Options() + self.options.python_shell = '' + self.options.setup = None + self.options.list = None + cmd.options = self.options + + # default to None to prevent side-effects from running tests in + # unknown environments + cmd.pystartup = None + return cmd + + def _makeEntryPoints(self, command, shells): + command.pkg_resources = dummy.DummyPkgResources(shells) + + def test_command_loads_default_shell(self): + command = self._makeOne() + shell = dummy.DummyShell() + self._makeEntryPoints(command, {}) + + command.default_runner = shell + command.run() + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':self.bootstrap.root, + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_errors_with_unknown_shell(self): + command = self._makeOne() + out_calls = [] + + def out(msg): + out_calls.append(msg) + + command.out = out + + shell = dummy.DummyShell() + + self._makeEntryPoints(command, {}) + + command.default_runner = shell + command.args.python_shell = 'unknown_python_shell' + result = command.run() + self.assertEqual(result, 1) + self.assertEqual( + out_calls, ['could not find a shell named "unknown_python_shell"'] + ) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertTrue(self.bootstrap.closer.called) + + def test_command_loads_ipython(self): + command = self._makeOne() + shell = dummy.DummyShell() + bad_shell = dummy.DummyShell() + self._makeEntryPoints( + command, + { + 'ipython': shell, + 'bpython': bad_shell, + } + ) + + command.args.python_shell = 'ipython' + + command.run() + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':self.bootstrap.root, + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_shell_entry_points(self): + command = self._makeOne() + dshell = dummy.DummyShell() + + self._makeEntryPoints( + command, + { + 'ipython': dshell, + 'bpython': dshell, + } + ) + + command.default_runner = None + shell = command.make_shell() + self.assertEqual(shell, dshell) + + def test_shell_override(self): + command = self._makeOne() + ipshell = dummy.DummyShell() + bpshell = dummy.DummyShell() + dshell = dummy.DummyShell() + + self._makeEntryPoints(command, {}) + + command.default_runner = dshell + + shell = command.make_shell() + self.assertEqual(shell, dshell) + + command.args.python_shell = 'ipython' + self.assertRaises(ValueError, command.make_shell) + + self._makeEntryPoints( + command, + { + 'ipython': ipshell, + 'bpython': bpshell, + 'python': dshell, + } + ) + + command.args.python_shell = 'ipython' + shell = command.make_shell() + self.assertEqual(shell, ipshell) + + command.args.python_shell = 'bpython' + shell = command.make_shell() + self.assertEqual(shell, bpshell) + + command.args.python_shell = 'python' + shell = command.make_shell() + self.assertEqual(shell, dshell) + + def test_shell_ordering(self): + command = self._makeOne() + ipshell = dummy.DummyShell() + bpshell = dummy.DummyShell() + dshell = dummy.DummyShell() + + self._makeEntryPoints( + command, + { + 'ipython': ipshell, + 'bpython': bpshell, + 'python': dshell, + } + ) + + command.default_runner = dshell + + command.preferred_shells = ['ipython', 'bpython'] + shell = command.make_shell() + self.assertEqual(shell, ipshell) + + command.preferred_shells = ['bpython', 'python'] + shell = command.make_shell() + self.assertEqual(shell, bpshell) + + command.preferred_shells = ['python', 'ipython'] + shell = command.make_shell() + self.assertEqual(shell, dshell) + + def test_command_loads_custom_items(self): + command = self._makeOne() + model = dummy.Dummy() + user = dummy.Dummy() + self.loader.settings = {'pshell': {'m': model, 'User': user}} + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':self.bootstrap.root, + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'm':model, + 'User': user, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_setup(self): + command = self._makeOne() + def setup(env): + env['a'] = 1 + env['root'] = 'root override' + env['none'] = None + self.loader.settings = {'pshell': {'setup': setup}} + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':'root override', + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'a':1, + 'none': None, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_setup_generator(self): + command = self._makeOne() + did_resume_after_yield = {} + def setup(env): + env['a'] = 1 + env['root'] = 'root override' + env['none'] = None + request = env['request'] + yield + did_resume_after_yield['result'] = True + self.assertEqual(request.dummy_attr, 1) + self.loader.settings = {'pshell': {'setup': setup}} + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':'root override', + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'a':1, + 'none': None, + }) + self.assertTrue(did_resume_after_yield['result']) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_default_shell_option(self): + command = self._makeOne() + ipshell = dummy.DummyShell() + dshell = dummy.DummyShell() + self._makeEntryPoints( + command, + { + 'ipython': ipshell, + 'python': dshell, + } + ) + self.loader.settings = {'pshell': { + 'default_shell': 'bpython python\nipython'}} + command.run() + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertTrue(dshell.called) + + def test_command_loads_check_variable_override_order(self): + command = self._makeOne() + model = dummy.Dummy() + def setup(env): + env['a'] = 1 + env['m'] = 'model override' + env['root'] = 'root override' + self.loader.settings = {'pshell': {'setup': setup, 'm': model}} + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':'root override', + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'a':1, 'm':'model override', + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_loads_setup_from_options(self): + command = self._makeOne() + def setup(env): + env['a'] = 1 + env['root'] = 'root override' + model = dummy.Dummy() + self.loader.settings = {'pshell': {'setup': 'abc', 'm': model}} + command.args.setup = setup + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':'root override', + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'a':1, 'm':model, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_custom_section_override(self): + command = self._makeOne() + dummy_ = dummy.Dummy() + self.loader.settings = {'pshell': { + 'app': dummy_, 'root': dummy_, 'registry': dummy_, + 'request': dummy_}} + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':dummy_, 'root':dummy_, 'registry':dummy_, 'request':dummy_, + 'root_factory':self.bootstrap.root_factory, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_command_loads_pythonstartup(self): + command = self._makeOne() + command.pystartup = ( + os.path.abspath( + os.path.join( + os.path.dirname(__file__), + 'pystartup.txt'))) + shell = dummy.DummyShell() + command.run(shell) + self.assertEqual(self.bootstrap.a[0], '/foo/bar/myapp.ini#myapp') + self.assertEqual(shell.env, { + 'app':self.bootstrap.app, 'root':self.bootstrap.root, + 'registry':self.bootstrap.registry, + 'request':self.bootstrap.request, + 'root_factory':self.bootstrap.root_factory, + 'foo':1, + }) + self.assertTrue(self.bootstrap.closer.called) + self.assertTrue(shell.help) + + def test_list_shells(self): + command = self._makeOne() + + dshell = dummy.DummyShell() + out_calls = [] + + def out(msg): + out_calls.append(msg) + + command.out = out + + self._makeEntryPoints( + command, + { + 'ipython': dshell, + 'python': dshell, + } + ) + + command.args.list = True + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(out_calls, [ + 'Available shells:', + ' ipython', + ' python', + ]) + + +class Test_python_shell_runner(unittest.TestCase): + def _callFUT(self, env, help, interact): + from pyramid.scripts.pshell import python_shell_runner + return python_shell_runner(env, help, interact=interact) + + def test_it(self): + interact = dummy.DummyInteractor() + self._callFUT({'foo': 'bar'}, 'a help message', interact) + self.assertEqual(interact.local, {'foo': 'bar'}) + self.assertTrue('a help message' in interact.banner) + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.pshell import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['pshell']) + self.assertEqual(result, 2) diff --git a/tests/test_scripts/test_ptweens.py b/tests/test_scripts/test_ptweens.py new file mode 100644 index 000000000..6907b858d --- /dev/null +++ b/tests/test_scripts/test_ptweens.py @@ -0,0 +1,62 @@ +import unittest +from pyramid.tests.test_scripts import dummy + +class TestPTweensCommand(unittest.TestCase): + def _getTargetClass(self): + from pyramid.scripts.ptweens import PTweensCommand + return PTweensCommand + + def _makeOne(self): + cmd = self._getTargetClass()([]) + cmd.bootstrap = dummy.DummyBootstrap() + cmd.setup_logging = dummy.dummy_setup_logging() + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + return cmd + + def test_command_no_tweens(self): + command = self._makeOne() + command._get_tweens = lambda *arg: None + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L, []) + + def test_command_implicit_tweens_only(self): + command = self._makeOne() + tweens = dummy.DummyTweens([('name', 'item')], None) + command._get_tweens = lambda *arg: tweens + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual( + L[0], + '"pyramid.tweens" config value NOT set (implicitly ordered tweens ' + 'used)') + + def test_command_implicit_and_explicit_tweens(self): + command = self._makeOne() + tweens = dummy.DummyTweens([('name', 'item')], [('name2', 'item2')]) + command._get_tweens = lambda *arg: tweens + L = [] + command.out = L.append + result = command.run() + self.assertEqual(result, 0) + self.assertEqual( + L[0], + '"pyramid.tweens" config value set (explicitly ordered tweens used)') + + def test__get_tweens(self): + command = self._makeOne() + registry = dummy.DummyRegistry() + self.assertEqual(command._get_tweens(registry), None) + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.ptweens import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['ptweens']) + self.assertEqual(result, 2) diff --git a/tests/test_scripts/test_pviews.py b/tests/test_scripts/test_pviews.py new file mode 100644 index 000000000..6ec9defbd --- /dev/null +++ b/tests/test_scripts/test_pviews.py @@ -0,0 +1,501 @@ +import unittest +from pyramid.tests.test_scripts import dummy + +class TestPViewsCommand(unittest.TestCase): + def _getTargetClass(self): + from pyramid.scripts.pviews import PViewsCommand + return PViewsCommand + + def _makeOne(self, registry=None): + cmd = self._getTargetClass()([]) + cmd.bootstrap = dummy.DummyBootstrap(registry=registry) + cmd.setup_logging = dummy.dummy_setup_logging() + cmd.args.config_uri = '/foo/bar/myapp.ini#myapp' + return cmd + + def _makeRequest(self, url, registry): + from pyramid.request import Request + request = Request.blank('/a') + request.registry = registry + return request + + def _register_mapper(self, registry, routes): + from pyramid.interfaces import IRoutesMapper + mapper = dummy.DummyMapper(*routes) + registry.registerUtility(mapper, IRoutesMapper) + + def test__find_view_no_match(self): + from pyramid.registry import Registry + registry = Registry() + self._register_mapper(registry, []) + command = self._makeOne(registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertEqual(result, None) + + def test__find_view_no_match_multiview_registered(self): + from zope.interface import implementer + from zope.interface import providedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + from pyramid.traversal import DefaultRootFactory + from pyramid.registry import Registry + registry = Registry() + @implementer(IMultiView) + class View1(object): + pass + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + root = DefaultRootFactory(request) + root_iface = providedBy(root) + registry.registerAdapter(View1(), + (IViewClassifier, IRequest, root_iface), + IMultiView) + self._register_mapper(registry, []) + command = self._makeOne(registry=registry) + request = self._makeRequest('/x', registry) + result = command._find_view(request) + self.assertEqual(result, None) + + def test__find_view_traversal(self): + from zope.interface import providedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + from pyramid.traversal import DefaultRootFactory + from pyramid.registry import Registry + registry = Registry() + def view1(): pass + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + root = DefaultRootFactory(request) + root_iface = providedBy(root) + registry.registerAdapter(view1, + (IViewClassifier, IRequest, root_iface), + IView, name='a') + self._register_mapper(registry, []) + command = self._makeOne(registry=registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertEqual(result, view1) + + def test__find_view_traversal_multiview(self): + from zope.interface import implementer + from zope.interface import providedBy + from pyramid.interfaces import IRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IMultiView + from pyramid.traversal import DefaultRootFactory + from pyramid.registry import Registry + registry = Registry() + @implementer(IMultiView) + class View1(object): + pass + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + root = DefaultRootFactory(request) + root_iface = providedBy(root) + view = View1() + registry.registerAdapter(view, + (IViewClassifier, IRequest, root_iface), + IMultiView, name='a') + self._register_mapper(registry, []) + command = self._makeOne(registry=registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertEqual(result, view) + + def test__find_view_route_no_multiview(self): + from zope.interface import Interface + from zope.interface import implementer + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + from pyramid.registry import Registry + registry = Registry() + def view():pass + class IMyRoot(Interface): + pass + class IMyRoute(Interface): + pass + registry.registerAdapter(view, + (IViewClassifier, IMyRoute, IMyRoot), + IView, '') + registry.registerUtility(IMyRoute, IRouteRequest, name='a') + @implementer(IMyRoot) + class Factory(object): + def __init__(self, request): + pass + routes = [dummy.DummyRoute('a', '/a', factory=Factory, matchdict={}), + dummy.DummyRoute('b', '/b', factory=Factory)] + self._register_mapper(registry, routes) + command = self._makeOne(registry=registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertEqual(result, view) + + def test__find_view_route_multiview_no_view_registered(self): + from zope.interface import Interface + from zope.interface import implementer + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IRootFactory + from pyramid.registry import Registry + registry = Registry() + def view1():pass + def view2():pass + class IMyRoot(Interface): + pass + class IMyRoute1(Interface): + pass + class IMyRoute2(Interface): + pass + registry.registerUtility(IMyRoute1, IRouteRequest, name='a') + registry.registerUtility(IMyRoute2, IRouteRequest, name='b') + @implementer(IMyRoot) + class Factory(object): + def __init__(self, request): + pass + registry.registerUtility(Factory, IRootFactory) + routes = [dummy.DummyRoute('a', '/a', matchdict={}), + dummy.DummyRoute('b', '/a', matchdict={})] + self._register_mapper(registry, routes) + command = self._makeOne(registry=registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertTrue(IMultiView.providedBy(result)) + + def test__find_view_route_multiview(self): + from zope.interface import Interface + from zope.interface import implementer + from pyramid.interfaces import IRouteRequest + from pyramid.interfaces import IViewClassifier + from pyramid.interfaces import IView + from pyramid.interfaces import IMultiView + from pyramid.interfaces import IRootFactory + from pyramid.registry import Registry + registry = Registry() + def view1():pass + def view2():pass + class IMyRoot(Interface): + pass + class IMyRoute1(Interface): + pass + class IMyRoute2(Interface): + pass + registry.registerAdapter(view1, + (IViewClassifier, IMyRoute1, IMyRoot), + IView, '') + registry.registerAdapter(view2, + (IViewClassifier, IMyRoute2, IMyRoot), + IView, '') + registry.registerUtility(IMyRoute1, IRouteRequest, name='a') + registry.registerUtility(IMyRoute2, IRouteRequest, name='b') + @implementer(IMyRoot) + class Factory(object): + def __init__(self, request): + pass + registry.registerUtility(Factory, IRootFactory) + routes = [dummy.DummyRoute('a', '/a', matchdict={}), + dummy.DummyRoute('b', '/a', matchdict={})] + self._register_mapper(registry, routes) + command = self._makeOne(registry=registry) + request = self._makeRequest('/a', registry) + result = command._find_view(request) + self.assertTrue(IMultiView.providedBy(result)) + self.assertEqual(len(result.views), 2) + self.assertTrue((None, view1, None) in result.views) + self.assertTrue((None, view2, None) in result.views) + + def test__find_multi_routes_all_match(self): + command = self._makeOne() + def factory(request): pass + routes = [dummy.DummyRoute('a', '/a', factory=factory, matchdict={}), + dummy.DummyRoute('b', '/a', factory=factory, matchdict={})] + mapper = dummy.DummyMapper(*routes) + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + result = command._find_multi_routes(mapper, request) + self.assertEqual(result, [{'match':{}, 'route':routes[0]}, + {'match':{}, 'route':routes[1]}]) + + def test__find_multi_routes_some_match(self): + command = self._makeOne() + def factory(request): pass + routes = [dummy.DummyRoute('a', '/a', factory=factory), + dummy.DummyRoute('b', '/a', factory=factory, matchdict={})] + mapper = dummy.DummyMapper(*routes) + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + result = command._find_multi_routes(mapper, request) + self.assertEqual(result, [{'match':{}, 'route':routes[1]}]) + + def test__find_multi_routes_none_match(self): + command = self._makeOne() + def factory(request): pass + routes = [dummy.DummyRoute('a', '/a', factory=factory), + dummy.DummyRoute('b', '/a', factory=factory)] + mapper = dummy.DummyMapper(*routes) + request = dummy.DummyRequest({'PATH_INFO':'/a'}) + result = command._find_multi_routes(mapper, request) + self.assertEqual(result, []) + + def test_views_command_not_found(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + command._find_view = lambda arg1: None + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' Not found.') + + def test_views_command_not_found_url_starts_without_slash(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + command._find_view = lambda arg1: None + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = 'a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' Not found.') + + def test_views_command_single_view_traversal(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + view = dummy.DummyView(context='context', view_name='a') + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.DummyView') + + def test_views_command_single_view_function_traversal(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + def view(): pass + view.__request_attrs__ = {'context': 'context', 'view_name': 'a'} + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.test_pviews.view') + + def test_views_command_single_view_traversal_with_permission(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + view = dummy.DummyView(context='context', view_name='a') + view.__permission__ = 'test' + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.DummyView') + self.assertEqual(L[9], ' required permission = test') + + def test_views_command_single_view_traversal_with_predicates(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + def predicate(): pass + predicate.text = lambda *arg: "predicate = x" + view = dummy.DummyView(context='context', view_name='a') + view.__predicates__ = [predicate] + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.DummyView') + self.assertEqual(L[9], ' view predicates (predicate = x)') + + def test_views_command_single_view_route(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + route = dummy.DummyRoute('a', '/a', matchdict={}) + view = dummy.DummyView(context='context', view_name='a', + matched_route=route, subpath='') + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[6], ' Route:') + self.assertEqual(L[8], ' route name: a') + self.assertEqual(L[9], ' route pattern: /a') + self.assertEqual(L[10], ' route path: /a') + self.assertEqual(L[11], ' subpath: ') + self.assertEqual(L[15], + ' pyramid.tests.test_scripts.dummy.DummyView') + + def test_views_command_multi_view_nested(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + view1 = dummy.DummyView(context='context', view_name='a1') + view1.__name__ = 'view1' + view1.__view_attr__ = 'call' + multiview1 = dummy.DummyMultiView(view1, context='context', + view_name='a1') + multiview2 = dummy.DummyMultiView(multiview1, context='context', + view_name='a') + command._find_view = lambda arg1: multiview2 + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.DummyMultiView') + self.assertEqual(L[12], + ' pyramid.tests.test_scripts.dummy.view1.call') + + def test_views_command_single_view_route_with_route_predicates(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + def predicate(): pass + predicate.text = lambda *arg: "predicate = x" + route = dummy.DummyRoute('a', '/a', matchdict={}, predicate=predicate) + view = dummy.DummyView(context='context', view_name='a', + matched_route=route, subpath='') + command._find_view = lambda arg1: view + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[6], ' Route:') + self.assertEqual(L[8], ' route name: a') + self.assertEqual(L[9], ' route pattern: /a') + self.assertEqual(L[10], ' route path: /a') + self.assertEqual(L[11], ' subpath: ') + self.assertEqual(L[12], ' route predicates (predicate = x)') + self.assertEqual(L[16], + ' pyramid.tests.test_scripts.dummy.DummyView') + + def test_views_command_multiview(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + view = dummy.DummyView(context='context') + view.__name__ = 'view' + view.__view_attr__ = 'call' + multiview = dummy.DummyMultiView(view, context='context', view_name='a') + command._find_view = lambda arg1: multiview + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.view.call') + + def test_views_command_multiview_with_permission(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + view = dummy.DummyView(context='context') + view.__name__ = 'view' + view.__view_attr__ = 'call' + view.__permission__ = 'test' + multiview = dummy.DummyMultiView(view, context='context', view_name='a') + command._find_view = lambda arg1: multiview + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.view.call') + self.assertEqual(L[9], ' required permission = test') + + def test_views_command_multiview_with_predicates(self): + from pyramid.registry import Registry + registry = Registry() + command = self._makeOne(registry=registry) + L = [] + command.out = L.append + def predicate(): pass + predicate.text = lambda *arg: "predicate = x" + view = dummy.DummyView(context='context') + view.__name__ = 'view' + view.__view_attr__ = 'call' + view.__predicates__ = [predicate] + multiview = dummy.DummyMultiView(view, context='context', view_name='a') + command._find_view = lambda arg1: multiview + command.args.config_uri = '/foo/bar/myapp.ini#myapp' + command.args.url = '/a' + result = command.run() + self.assertEqual(result, 0) + self.assertEqual(L[1], 'URL = /a') + self.assertEqual(L[3], ' context: context') + self.assertEqual(L[4], ' view name: a') + self.assertEqual(L[8], + ' pyramid.tests.test_scripts.dummy.view.call') + self.assertEqual(L[9], ' view predicates (predicate = x)') + +class Test_main(unittest.TestCase): + def _callFUT(self, argv): + from pyramid.scripts.pviews import main + return main(argv, quiet=True) + + def test_it(self): + result = self._callFUT(['pviews']) + self.assertEqual(result, 2) diff --git a/tests/test_security.py b/tests/test_security.py new file mode 100644 index 000000000..e5399ecdf --- /dev/null +++ b/tests/test_security.py @@ -0,0 +1,549 @@ +import unittest + +from pyramid import testing + +class TestAllPermissionsList(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _getTargetClass(self): + from pyramid.security import AllPermissionsList + return AllPermissionsList + + def _makeOne(self): + return self._getTargetClass()() + + def test_equality_w_self(self): + thing = self._makeOne() + self.assertTrue(thing.__eq__(thing)) + + def test_equality_w_other_instances_of_class(self): + thing = self._makeOne() + other = self._makeOne() + self.assertTrue(thing.__eq__(other)) + + def test_equality_miss(self): + thing = self._makeOne() + other = object() + self.assertFalse(thing.__eq__(other)) + + def test_contains_w_string(self): + thing = self._makeOne() + self.assertTrue('anything' in thing) + + def test_contains_w_object(self): + thing = self._makeOne() + self.assertTrue(object() in thing) + + def test_iterable(self): + thing = self._makeOne() + self.assertEqual(list(thing), []) + + def test_singleton(self): + from pyramid.security import ALL_PERMISSIONS + self.assertEqual(ALL_PERMISSIONS.__class__, self._getTargetClass()) + +class TestAllowed(unittest.TestCase): + def _getTargetClass(self): + from pyramid.security import Allowed + return Allowed + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_it(self): + allowed = self._makeOne('hello') + self.assertEqual(allowed.msg, 'hello') + self.assertEqual(allowed, True) + self.assertTrue(allowed) + self.assertEqual(str(allowed), 'hello') + self.assertTrue('" in repr(allowed)) + +class TestDenied(unittest.TestCase): + def _getTargetClass(self): + from pyramid.security import Denied + return Denied + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_it(self): + denied = self._makeOne('hello') + self.assertEqual(denied.msg, 'hello') + self.assertEqual(denied, False) + self.assertFalse(denied) + self.assertEqual(str(denied), 'hello') + self.assertTrue('" in repr(denied)) + +class TestACLAllowed(unittest.TestCase): + def _getTargetClass(self): + from pyramid.security import ACLAllowed + return ACLAllowed + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_it(self): + from pyramid.security import Allowed + msg = ("ACLAllowed permission 'permission' via ACE 'ace' in ACL 'acl' " + "on context 'ctx' for principals 'principals'") + allowed = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') + self.assertIsInstance(allowed, Allowed) + self.assertTrue(msg in allowed.msg) + self.assertEqual(allowed, True) + self.assertTrue(allowed) + self.assertEqual(str(allowed), msg) + self.assertTrue('" % msg in repr(allowed)) + +class TestACLDenied(unittest.TestCase): + def _getTargetClass(self): + from pyramid.security import ACLDenied + return ACLDenied + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def test_it(self): + from pyramid.security import Denied + msg = ("ACLDenied permission 'permission' via ACE 'ace' in ACL 'acl' " + "on context 'ctx' for principals 'principals'") + denied = self._makeOne('ace', 'acl', 'permission', 'principals', 'ctx') + self.assertIsInstance(denied, Denied) + self.assertTrue(msg in denied.msg) + self.assertEqual(denied, False) + self.assertFalse(denied) + self.assertEqual(str(denied), msg) + self.assertTrue('" % msg in repr(denied)) + +class TestPrincipalsAllowedByPermission(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, *arg): + from pyramid.security import principals_allowed_by_permission + return principals_allowed_by_permission(*arg) + + def test_no_authorization_policy(self): + from pyramid.security import Everyone + context = DummyContext() + result = self._callFUT(context, 'view') + self.assertEqual(result, [Everyone]) + + def test_with_authorization_policy(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + _registerAuthorizationPolicy(registry, 'yo') + context = DummyContext() + result = self._callFUT(context, 'view') + self.assertEqual(result, 'yo') + +class TestRemember(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, *arg, **kwarg): + from pyramid.security import remember + return remember(*arg, **kwarg) + + def test_no_authentication_policy(self): + request = _makeRequest() + result = self._callFUT(request, 'me') + self.assertEqual(result, []) + + def test_with_authentication_policy(self): + request = _makeRequest() + registry = request.registry + _registerAuthenticationPolicy(registry, 'yo') + result = self._callFUT(request, 'me') + self.assertEqual(result, [('X-Pyramid-Test', 'me')]) + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = _makeRequest() + del request.registry + _registerAuthenticationPolicy(registry, 'yo') + result = self._callFUT(request, 'me') + self.assertEqual(result, [('X-Pyramid-Test', 'me')]) + + def test_with_missing_arg(self): + request = _makeRequest() + registry = request.registry + _registerAuthenticationPolicy(registry, 'yo') + self.assertRaises(TypeError, lambda: self._callFUT(request)) + +class TestForget(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, *arg): + from pyramid.security import forget + return forget(*arg) + + def test_no_authentication_policy(self): + request = _makeRequest() + result = self._callFUT(request) + self.assertEqual(result, []) + + def test_with_authentication_policy(self): + request = _makeRequest() + _registerAuthenticationPolicy(request.registry, 'yo') + result = self._callFUT(request) + self.assertEqual(result, [('X-Pyramid-Test', 'logout')]) + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = _makeRequest() + del request.registry + _registerAuthenticationPolicy(registry, 'yo') + result = self._callFUT(request) + self.assertEqual(result, [('X-Pyramid-Test', 'logout')]) + +class TestViewExecutionPermitted(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self, *arg, **kw): + from pyramid.security import view_execution_permitted + return view_execution_permitted(*arg, **kw) + + def _registerSecuredView(self, view_name, allow=True): + from pyramid.threadlocal import get_current_registry + from zope.interface import Interface + from pyramid.interfaces import ISecuredView + from pyramid.interfaces import IViewClassifier + class Checker(object): + def __permitted__(self, context, request): + self.context = context + self.request = request + return allow + checker = Checker() + reg = get_current_registry() + reg.registerAdapter(checker, (IViewClassifier, Interface, Interface), + ISecuredView, view_name) + return checker + + def test_no_permission(self): + from zope.interface import Interface + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ISettings + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + settings = dict(debug_authorization=True) + reg = get_current_registry() + reg.registerUtility(settings, ISettings) + context = DummyContext() + request = testing.DummyRequest({}) + class DummyView(object): + pass + view = DummyView() + reg.registerAdapter(view, (IViewClassifier, Interface, Interface), + IView, '') + result = self._callFUT(context, request, '') + msg = result.msg + self.assertTrue("Allowed: view name '' in context" in msg) + self.assertTrue('(no permission defined)' in msg) + self.assertEqual(result, True) + + def test_no_view_registered(self): + from pyramid.threadlocal import get_current_registry + from pyramid.interfaces import ISettings + settings = dict(debug_authorization=True) + reg = get_current_registry() + reg.registerUtility(settings, ISettings) + context = DummyContext() + request = testing.DummyRequest({}) + self.assertRaises(TypeError, self._callFUT, context, request, '') + + def test_with_permission(self): + from zope.interface import Interface + from zope.interface import directlyProvides + from pyramid.interfaces import IRequest + class IContext(Interface): + pass + context = DummyContext() + directlyProvides(context, IContext) + self._registerSecuredView('', True) + request = testing.DummyRequest({}) + directlyProvides(request, IRequest) + result = self._callFUT(context, request, '') + self.assertTrue(result) + +class TestAuthenticatedUserId(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_backward_compat_delegates_to_mixin(self): + from zope.deprecation import __show__ + try: + __show__.off() + request = _makeFakeRequest() + from pyramid.security import authenticated_userid + self.assertEqual( + authenticated_userid(request), + 'authenticated_userid' + ) + finally: + __show__.on() + + def test_no_authentication_policy(self): + request = _makeRequest() + self.assertEqual(request.authenticated_userid, None) + + def test_with_authentication_policy(self): + request = _makeRequest() + _registerAuthenticationPolicy(request.registry, 'yo') + self.assertEqual(request.authenticated_userid, 'yo') + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = _makeRequest() + del request.registry + _registerAuthenticationPolicy(registry, 'yo') + self.assertEqual(request.authenticated_userid, 'yo') + +class TestUnAuthenticatedUserId(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_backward_compat_delegates_to_mixin(self): + from zope.deprecation import __show__ + try: + __show__.off() + request = _makeFakeRequest() + from pyramid.security import unauthenticated_userid + self.assertEqual( + unauthenticated_userid(request), + 'unauthenticated_userid', + ) + finally: + __show__.on() + + def test_no_authentication_policy(self): + request = _makeRequest() + self.assertEqual(request.unauthenticated_userid, None) + + def test_with_authentication_policy(self): + request = _makeRequest() + _registerAuthenticationPolicy(request.registry, 'yo') + self.assertEqual(request.unauthenticated_userid, 'yo') + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = _makeRequest() + del request.registry + _registerAuthenticationPolicy(registry, 'yo') + self.assertEqual(request.unauthenticated_userid, 'yo') + +class TestEffectivePrincipals(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def test_backward_compat_delegates_to_mixin(self): + request = _makeFakeRequest() + from zope.deprecation import __show__ + try: + __show__.off() + from pyramid.security import effective_principals + self.assertEqual( + effective_principals(request), + 'effective_principals' + ) + finally: + __show__.on() + + def test_no_authentication_policy(self): + from pyramid.security import Everyone + request = _makeRequest() + self.assertEqual(request.effective_principals, [Everyone]) + + def test_with_authentication_policy(self): + request = _makeRequest() + _registerAuthenticationPolicy(request.registry, 'yo') + self.assertEqual(request.effective_principals, 'yo') + + def test_with_authentication_policy_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = _makeRequest() + del request.registry + _registerAuthenticationPolicy(registry, 'yo') + self.assertEqual(request.effective_principals, 'yo') + +class TestHasPermission(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self): + from pyramid.security import AuthorizationAPIMixin + from pyramid.registry import Registry + mixin = AuthorizationAPIMixin() + mixin.registry = Registry() + mixin.context = object() + return mixin + + def test_delegates_to_mixin(self): + from zope.deprecation import __show__ + try: + __show__.off() + mixin = self._makeOne() + from pyramid.security import has_permission + self.called_has_permission = False + + def mocked_has_permission(*args, **kw): + self.called_has_permission = True + + mixin.has_permission = mocked_has_permission + has_permission('view', object(), mixin) + self.assertTrue(self.called_has_permission) + finally: + __show__.on() + + def test_no_authentication_policy(self): + request = self._makeOne() + result = request.has_permission('view') + self.assertTrue(result) + self.assertEqual(result.msg, 'No authentication policy in use.') + + def test_with_no_authorization_policy(self): + request = self._makeOne() + _registerAuthenticationPolicy(request.registry, None) + self.assertRaises(ValueError, + request.has_permission, 'view', context=None) + + def test_with_authn_and_authz_policies_registered(self): + request = self._makeOne() + _registerAuthenticationPolicy(request.registry, None) + _registerAuthorizationPolicy(request.registry, 'yo') + self.assertEqual(request.has_permission('view', context=None), 'yo') + + def test_with_no_reg_on_request(self): + from pyramid.threadlocal import get_current_registry + registry = get_current_registry() + request = self._makeOne() + del request.registry + _registerAuthenticationPolicy(registry, None) + _registerAuthorizationPolicy(registry, 'yo') + self.assertEqual(request.has_permission('view'), 'yo') + + def test_with_no_context_passed(self): + request = self._makeOne() + self.assertTrue(request.has_permission('view')) + + def test_with_no_context_passed_or_on_request(self): + request = self._makeOne() + del request.context + self.assertRaises(AttributeError, request.has_permission, 'view') + +_TEST_HEADER = 'X-Pyramid-Test' + +class DummyContext: + def __init__(self, *arg, **kw): + self.__dict__.update(kw) + +class DummyAuthenticationPolicy: + def __init__(self, result): + self.result = result + + def effective_principals(self, request): + return self.result + + def unauthenticated_userid(self, request): + return self.result + + def authenticated_userid(self, request): + return self.result + + def remember(self, request, userid, **kw): + headers = [(_TEST_HEADER, userid)] + self._header_remembered = headers[0] + return headers + + def forget(self, request): + headers = [(_TEST_HEADER, 'logout')] + self._header_forgotten = headers[0] + return headers + +class DummyAuthorizationPolicy: + def __init__(self, result): + self.result = result + + def permits(self, context, principals, permission): + return self.result + + def principals_allowed_by_permission(self, context, permission): + return self.result + +def _registerAuthenticationPolicy(reg, result): + from pyramid.interfaces import IAuthenticationPolicy + policy = DummyAuthenticationPolicy(result) + reg.registerUtility(policy, IAuthenticationPolicy) + return policy + +def _registerAuthorizationPolicy(reg, result): + from pyramid.interfaces import IAuthorizationPolicy + policy = DummyAuthorizationPolicy(result) + reg.registerUtility(policy, IAuthorizationPolicy) + return policy + +def _makeRequest(): + from pyramid.registry import Registry + request = testing.DummyRequest(environ={}) + request.registry = Registry() + request.context = object() + return request + +def _makeFakeRequest(): + class FakeRequest(testing.DummyRequest): + @property + def authenticated_userid(req): + return 'authenticated_userid' + + @property + def unauthenticated_userid(req): + return 'unauthenticated_userid' + + @property + def effective_principals(req): + return 'effective_principals' + + return FakeRequest({}) + diff --git a/tests/test_session.py b/tests/test_session.py new file mode 100644 index 000000000..3585ed635 --- /dev/null +++ b/tests/test_session.py @@ -0,0 +1,754 @@ +import base64 +import json +import unittest +from pyramid import testing +from pyramid.compat import pickle + +class SharedCookieSessionTests(object): + + def test_ctor_no_cookie(self): + request = testing.DummyRequest() + session = self._makeOne(request) + self.assertEqual(dict(session), {}) + + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import ISession + request = testing.DummyRequest() + session = self._makeOne(request) + verifyObject(ISession, session) + + def test_ctor_with_cookie_still_valid(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request) + self.assertEqual(dict(session), {'state':1}) + + def test_ctor_with_cookie_expired(self): + request = testing.DummyRequest() + cookieval = self._serialize((0, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request) + self.assertEqual(dict(session), {}) + + def test_ctor_with_bad_cookie_cannot_deserialize(self): + request = testing.DummyRequest() + request.cookies['session'] = 'abc' + session = self._makeOne(request) + self.assertEqual(dict(session), {}) + + def test_ctor_with_bad_cookie_not_tuple(self): + request = testing.DummyRequest() + cookieval = self._serialize('abc') + request.cookies['session'] = cookieval + session = self._makeOne(request) + self.assertEqual(dict(session), {}) + + def test_timeout(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time() - 5, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, timeout=1) + self.assertEqual(dict(session), {}) + + def test_timeout_never(self): + import time + request = testing.DummyRequest() + LONG_TIME = 31536000 + cookieval = self._serialize((time.time() + LONG_TIME, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, timeout=None) + self.assertEqual(dict(session), {'state': 1}) + + def test_timeout_str(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time() - 5, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, timeout='1') + self.assertEqual(dict(session), {}) + + def test_timeout_invalid(self): + request = testing.DummyRequest() + self.assertRaises(ValueError, self._makeOne, request, timeout='Invalid value') + + def test_changed(self): + request = testing.DummyRequest() + session = self._makeOne(request) + self.assertEqual(session.changed(), None) + self.assertTrue(session._dirty) + + def test_invalidate(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session['a'] = 1 + self.assertEqual(session.invalidate(), None) + self.assertFalse('a' in session) + + def test_reissue_triggered(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request) + self.assertEqual(session['state'], 1) + self.assertTrue(session._dirty) + + def test__set_cookie_on_exception(self): + request = testing.DummyRequest() + request.exception = True + session = self._makeOne(request) + session._cookie_on_exception = False + response = DummyResponse() + self.assertEqual(session._set_cookie(response), False) + + def test__set_cookie_on_exception_no_request_exception(self): + import webob + request = testing.DummyRequest() + request.exception = None + session = self._makeOne(request) + session._cookie_on_exception = False + response = webob.Response() + self.assertEqual(session._set_cookie(response), True) + self.assertEqual(response.headerlist[-1][0], 'Set-Cookie') + + def test__set_cookie_cookieval_too_long(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session['abc'] = 'x'*100000 + response = DummyResponse() + self.assertRaises(ValueError, session._set_cookie, response) + + def test__set_cookie_real_webob_response(self): + import webob + request = testing.DummyRequest() + session = self._makeOne(request) + session['abc'] = 'x' + response = webob.Response() + self.assertEqual(session._set_cookie(response), True) + self.assertEqual(response.headerlist[-1][0], 'Set-Cookie') + + def test__set_cookie_options(self): + from pyramid.response import Response + request = testing.DummyRequest() + request.exception = None + session = self._makeOne(request, + cookie_name='abc', + path='/foo', + domain='localhost', + secure=True, + httponly=True, + ) + session['abc'] = 'x' + response = Response() + self.assertEqual(session._set_cookie(response), True) + cookieval = response.headerlist[-1][1] + val, domain, path, secure, httponly, samesite = [x.strip() for x in + cookieval.split(';')] + self.assertTrue(val.startswith('abc=')) + self.assertEqual(domain, 'Domain=localhost') + self.assertEqual(path, 'Path=/foo') + self.assertEqual(secure, 'secure') + self.assertEqual(httponly, 'HttpOnly') + self.assertEqual(samesite, 'SameSite=Lax') + + def test_flash_default(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session.flash('msg1') + session.flash('msg2') + self.assertEqual(session['_f_'], ['msg1', 'msg2']) + + def test_flash_allow_duplicate_false(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session.flash('msg1') + session.flash('msg1', allow_duplicate=False) + self.assertEqual(session['_f_'], ['msg1']) + + def test_flash_allow_duplicate_true_and_msg_not_in_storage(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session.flash('msg1', allow_duplicate=True) + self.assertEqual(session['_f_'], ['msg1']) + + def test_flash_allow_duplicate_false_and_msg_not_in_storage(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session.flash('msg1', allow_duplicate=False) + self.assertEqual(session['_f_'], ['msg1']) + + def test_flash_mixed(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session.flash('warn1', 'warn') + session.flash('warn2', 'warn') + session.flash('err1', 'error') + session.flash('err2', 'error') + self.assertEqual(session['_f_warn'], ['warn1', 'warn2']) + + def test_pop_flash_default_queue(self): + request = testing.DummyRequest() + session = self._makeOne(request) + queue = ['one', 'two'] + session['_f_'] = queue + result = session.pop_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), None) + + def test_pop_flash_nodefault_queue(self): + request = testing.DummyRequest() + session = self._makeOne(request) + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.pop_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), None) + + def test_peek_flash_default_queue(self): + request = testing.DummyRequest() + session = self._makeOne(request) + queue = ['one', 'two'] + session['_f_'] = queue + result = session.peek_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), queue) + + def test_peek_flash_nodefault_queue(self): + request = testing.DummyRequest() + session = self._makeOne(request) + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.peek_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), queue) + + def test_new_csrf_token(self): + request = testing.DummyRequest() + session = self._makeOne(request) + token = session.new_csrf_token() + self.assertEqual(token, session['_csrft_']) + + def test_get_csrf_token(self): + request = testing.DummyRequest() + session = self._makeOne(request) + session['_csrft_'] = 'token' + token = session.get_csrf_token() + self.assertEqual(token, 'token') + self.assertTrue('_csrft_' in session) + + def test_get_csrf_token_new(self): + request = testing.DummyRequest() + session = self._makeOne(request) + token = session.get_csrf_token() + self.assertTrue(token) + self.assertTrue('_csrft_' in session) + + def test_no_set_cookie_with_exception(self): + import webob + request = testing.DummyRequest() + request.exception = True + session = self._makeOne(request, set_on_exception=False) + session['a'] = 1 + callbacks = request.response_callbacks + self.assertEqual(len(callbacks), 1) + response = webob.Response() + result = callbacks[0](request, response) + self.assertEqual(result, None) + self.assertFalse('Set-Cookie' in dict(response.headerlist)) + + def test_set_cookie_with_exception(self): + import webob + request = testing.DummyRequest() + request.exception = True + session = self._makeOne(request) + session['a'] = 1 + callbacks = request.response_callbacks + self.assertEqual(len(callbacks), 1) + response = webob.Response() + result = callbacks[0](request, response) + self.assertEqual(result, None) + self.assertTrue('Set-Cookie' in dict(response.headerlist)) + + def test_cookie_is_set(self): + import webob + request = testing.DummyRequest() + session = self._makeOne(request) + session['a'] = 1 + callbacks = request.response_callbacks + self.assertEqual(len(callbacks), 1) + response = webob.Response() + result = callbacks[0](request, response) + self.assertEqual(result, None) + self.assertTrue('Set-Cookie' in dict(response.headerlist)) + +class TestBaseCookieSession(SharedCookieSessionTests, unittest.TestCase): + def _makeOne(self, request, **kw): + from pyramid.session import BaseCookieSessionFactory + serializer = DummySerializer() + return BaseCookieSessionFactory(serializer, **kw)(request) + + def _serialize(self, value): + return base64.b64encode(json.dumps(value).encode('utf-8')) + + def test_reissue_not_triggered(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time=1) + self.assertEqual(session['state'], 1) + self.assertFalse(session._dirty) + + def test_reissue_never(self): + request = testing.DummyRequest() + cookieval = self._serialize((0, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time=None, timeout=None) + self.assertEqual(session['state'], 1) + self.assertFalse(session._dirty) + + def test_reissue_str_triggered(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time='0') + self.assertEqual(session['state'], 1) + self.assertTrue(session._dirty) + + def test_reissue_invalid(self): + request = testing.DummyRequest() + self.assertRaises(ValueError, self._makeOne, request, reissue_time='invalid value') + + def test_cookie_max_age_invalid(self): + request = testing.DummyRequest() + self.assertRaises(ValueError, self._makeOne, request, max_age='invalid value') + +class TestSignedCookieSession(SharedCookieSessionTests, unittest.TestCase): + def _makeOne(self, request, **kw): + from pyramid.session import SignedCookieSessionFactory + kw.setdefault('secret', 'secret') + return SignedCookieSessionFactory(**kw)(request) + + def _serialize(self, value, salt=b'pyramid.session.', hashalg='sha512'): + import base64 + import hashlib + import hmac + import pickle + + digestmod = lambda: hashlib.new(hashalg) + cstruct = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) + sig = hmac.new(salt + b'secret', cstruct, digestmod).digest() + return base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') + + def test_reissue_not_triggered(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time=1) + self.assertEqual(session['state'], 1) + self.assertFalse(session._dirty) + + def test_reissue_never(self): + request = testing.DummyRequest() + cookieval = self._serialize((0, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time=None, timeout=None) + self.assertEqual(session['state'], 1) + self.assertFalse(session._dirty) + + def test_reissue_str_triggered(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time() - 2, 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, reissue_time='0') + self.assertEqual(session['state'], 1) + self.assertTrue(session._dirty) + + def test_reissue_invalid(self): + request = testing.DummyRequest() + self.assertRaises(ValueError, self._makeOne, request, reissue_time='invalid value') + + def test_cookie_max_age_invalid(self): + request = testing.DummyRequest() + self.assertRaises(ValueError, self._makeOne, request, max_age='invalid value') + + def test_custom_salt(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1}), salt=b'f.') + request.cookies['session'] = cookieval + session = self._makeOne(request, salt=b'f.') + self.assertEqual(session['state'], 1) + + def test_salt_mismatch(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1}), salt=b'f.') + request.cookies['session'] = cookieval + session = self._makeOne(request, salt=b'g.') + self.assertEqual(session, {}) + + def test_custom_hashalg(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1}), + hashalg='sha1') + request.cookies['session'] = cookieval + session = self._makeOne(request, hashalg='sha1') + self.assertEqual(session['state'], 1) + + def test_hashalg_mismatch(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1}), + hashalg='sha1') + request.cookies['session'] = cookieval + session = self._makeOne(request, hashalg='sha256') + self.assertEqual(session, {}) + + def test_secret_mismatch(self): + import time + request = testing.DummyRequest() + cookieval = self._serialize((time.time(), 0, {'state': 1})) + request.cookies['session'] = cookieval + session = self._makeOne(request, secret='evilsecret') + self.assertEqual(session, {}) + + def test_custom_serializer(self): + import base64 + from hashlib import sha512 + import hmac + import time + request = testing.DummyRequest() + serializer = DummySerializer() + cstruct = serializer.dumps((time.time(), 0, {'state': 1})) + sig = hmac.new(b'pyramid.session.secret', cstruct, sha512).digest() + cookieval = base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') + request.cookies['session'] = cookieval + session = self._makeOne(request, serializer=serializer) + self.assertEqual(session['state'], 1) + + def test_invalid_data_size(self): + from hashlib import sha512 + import base64 + request = testing.DummyRequest() + num_bytes = sha512().digest_size - 1 + cookieval = base64.b64encode(b' ' * num_bytes) + request.cookies['session'] = cookieval + session = self._makeOne(request) + self.assertEqual(session, {}) + + def test_very_long_key(self): + verylongkey = b'a' * 1024 + import webob + request = testing.DummyRequest() + session = self._makeOne(request, secret=verylongkey) + session['a'] = 1 + callbacks = request.response_callbacks + self.assertEqual(len(callbacks), 1) + response = webob.Response() + + try: + result = callbacks[0](request, response) + except TypeError: # pragma: no cover + self.fail('HMAC failed to initialize due to key length.') + + self.assertEqual(result, None) + self.assertTrue('Set-Cookie' in dict(response.headerlist)) + + def test_bad_pickle(self): + import base64 + import hashlib + import hmac + + digestmod = lambda: hashlib.new('sha512') + # generated from dumping an object that cannot be found anymore, eg: + # class Foo: pass + # print(pickle.dumps(Foo())) + cstruct = b'(i__main__\nFoo\np0\n(dp1\nb.' + sig = hmac.new(b'pyramid.session.secret', cstruct, digestmod).digest() + cookieval = base64.urlsafe_b64encode(sig + cstruct).rstrip(b'=') + + request = testing.DummyRequest() + request.cookies['session'] = cookieval + session = self._makeOne(request, secret='secret') + self.assertEqual(session, {}) + +class TestUnencryptedCookieSession(SharedCookieSessionTests, unittest.TestCase): + def setUp(self): + super(TestUnencryptedCookieSession, self).setUp() + from zope.deprecation import __show__ + __show__.off() + + def tearDown(self): + super(TestUnencryptedCookieSession, self).tearDown() + from zope.deprecation import __show__ + __show__.on() + + def _makeOne(self, request, **kw): + from pyramid.session import UnencryptedCookieSessionFactoryConfig + self._rename_cookie_var(kw, 'path', 'cookie_path') + self._rename_cookie_var(kw, 'domain', 'cookie_domain') + self._rename_cookie_var(kw, 'secure', 'cookie_secure') + self._rename_cookie_var(kw, 'httponly', 'cookie_httponly') + self._rename_cookie_var(kw, 'set_on_exception', 'cookie_on_exception') + return UnencryptedCookieSessionFactoryConfig('secret', **kw)(request) + + def _rename_cookie_var(self, kw, src, dest): + if src in kw: + kw.setdefault(dest, kw.pop(src)) + + def _serialize(self, value): + from pyramid.compat import bytes_ + from pyramid.session import signed_serialize + return bytes_(signed_serialize(value, 'secret')) + + def test_serialize_option(self): + from pyramid.response import Response + secret = 'secret' + request = testing.DummyRequest() + session = self._makeOne(request, + signed_serialize=dummy_signed_serialize) + session['key'] = 'value' + response = Response() + self.assertEqual(session._set_cookie(response), True) + cookie = response.headerlist[-1][1] + expected_cookieval = dummy_signed_serialize( + (session.accessed, session.created, {'key': 'value'}), secret) + response = Response() + response.set_cookie('session', expected_cookieval, samesite='Lax') + expected_cookie = response.headerlist[-1][1] + self.assertEqual(cookie, expected_cookie) + + def test_deserialize_option(self): + import time + secret = 'secret' + request = testing.DummyRequest() + accessed = time.time() + state = {'key': 'value'} + cookieval = dummy_signed_serialize((accessed, accessed, state), secret) + request.cookies['session'] = cookieval + session = self._makeOne(request, + signed_deserialize=dummy_signed_deserialize) + self.assertEqual(dict(session), state) + +def dummy_signed_serialize(data, secret): + import base64 + from pyramid.compat import pickle, bytes_ + pickled = pickle.dumps(data) + return base64.b64encode(bytes_(secret)) + base64.b64encode(pickled) + +def dummy_signed_deserialize(serialized, secret): + import base64 + from pyramid.compat import pickle, bytes_ + serialized_data = base64.b64decode( + serialized[len(base64.b64encode(bytes_(secret))):]) + return pickle.loads(serialized_data) + +class Test_manage_accessed(unittest.TestCase): + def _makeOne(self, wrapped): + from pyramid.session import manage_accessed + return manage_accessed(wrapped) + + def test_accessed_set(self): + request = testing.DummyRequest() + session = DummySessionFactory(request) + session.renewed = 0 + wrapper = self._makeOne(session.__class__.get) + wrapper(session, 'a') + self.assertNotEqual(session.accessed, None) + self.assertTrue(session._dirty) + + def test_accessed_without_renew(self): + import time + request = testing.DummyRequest() + session = DummySessionFactory(request) + session._reissue_time = 5 + session.renewed = time.time() + wrapper = self._makeOne(session.__class__.get) + wrapper(session, 'a') + self.assertNotEqual(session.accessed, None) + self.assertFalse(session._dirty) + + def test_already_dirty(self): + request = testing.DummyRequest() + session = DummySessionFactory(request) + session.renewed = 0 + session._dirty = True + session['a'] = 1 + wrapper = self._makeOne(session.__class__.get) + self.assertEqual(wrapper.__doc__, session.get.__doc__) + result = wrapper(session, 'a') + self.assertEqual(result, 1) + callbacks = request.response_callbacks + if callbacks is not None: self.assertEqual(len(callbacks), 0) + +class Test_manage_changed(unittest.TestCase): + def _makeOne(self, wrapped): + from pyramid.session import manage_changed + return manage_changed(wrapped) + + def test_it(self): + request = testing.DummyRequest() + session = DummySessionFactory(request) + wrapper = self._makeOne(session.__class__.__setitem__) + wrapper(session, 'a', 1) + self.assertNotEqual(session.accessed, None) + self.assertTrue(session._dirty) + +def serialize(data, secret): + import hmac + import base64 + from hashlib import sha1 + from pyramid.compat import bytes_ + from pyramid.compat import native_ + from pyramid.compat import pickle + pickled = pickle.dumps(data, pickle.HIGHEST_PROTOCOL) + sig = hmac.new(bytes_(secret, 'utf-8'), pickled, sha1).hexdigest() + return sig + native_(base64.b64encode(pickled)) + +class Test_signed_serialize(unittest.TestCase): + def _callFUT(self, data, secret): + from pyramid.session import signed_serialize + return signed_serialize(data, secret) + + def test_it(self): + expected = serialize('123', 'secret') + result = self._callFUT('123', 'secret') + self.assertEqual(result, expected) + + def test_it_with_highorder_secret(self): + secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') + expected = serialize('123', secret) + result = self._callFUT('123', secret) + self.assertEqual(result, expected) + + def test_it_with_latin1_secret(self): + secret = b'La Pe\xc3\xb1a' + expected = serialize('123', secret) + result = self._callFUT('123', secret.decode('latin-1')) + self.assertEqual(result, expected) + +class Test_signed_deserialize(unittest.TestCase): + def _callFUT(self, serialized, secret, hmac=None): + if hmac is None: + import hmac + from pyramid.session import signed_deserialize + return signed_deserialize(serialized, secret, hmac=hmac) + + def test_it(self): + serialized = serialize('123', 'secret') + result = self._callFUT(serialized, 'secret') + self.assertEqual(result, '123') + + def test_invalid_bits(self): + serialized = serialize('123', 'secret') + self.assertRaises(ValueError, self._callFUT, serialized, 'seekrit') + + def test_invalid_len(self): + class hmac(object): + def new(self, *arg): + return self + def hexdigest(self): + return '1234' + serialized = serialize('123', 'secret123') + self.assertRaises(ValueError, self._callFUT, serialized, 'secret', + hmac=hmac()) + + def test_it_bad_encoding(self): + serialized = 'bad' + serialize('123', 'secret') + self.assertRaises(ValueError, self._callFUT, serialized, 'secret') + + def test_it_with_highorder_secret(self): + secret = b'\xce\xb1\xce\xb2\xce\xb3\xce\xb4'.decode('utf-8') + serialized = serialize('123', secret) + result = self._callFUT(serialized, secret) + self.assertEqual(result, '123') + + # bwcompat with pyramid <= 1.5b1 where latin1 is the default + def test_it_with_latin1_secret(self): + secret = b'La Pe\xc3\xb1a' + serialized = serialize('123', secret) + result = self._callFUT(serialized, secret.decode('latin-1')) + self.assertEqual(result, '123') + + +class TestPickleSerializer(unittest.TestCase): + def _makeOne(self): + from pyramid.session import PickleSerializer + return PickleSerializer() + + def test_loads(self): + # generated from dumping Dummy() using protocol=2 + cstruct = b'\x80\x02cpyramid.tests.test_session\nDummy\nq\x00)\x81q\x01.' + serializer = self._makeOne() + result = serializer.loads(cstruct) + self.assertIsInstance(result, Dummy) + + def test_loads_raises_ValueError_on_invalid_data(self): + cstruct = b'not pickled' + serializer = self._makeOne() + self.assertRaises(ValueError, serializer.loads, cstruct) + + def test_loads_raises_ValueError_on_bad_import(self): + # generated from dumping an object that cannot be found anymore, eg: + # class Foo: pass + # print(pickle.dumps(Foo())) + cstruct = b'(i__main__\nFoo\np0\n(dp1\nb.' + serializer = self._makeOne() + self.assertRaises(ValueError, serializer.loads, cstruct) + + def test_dumps(self): + obj = Dummy() + serializer = self._makeOne() + result = serializer.dumps(obj) + expected_result = pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL) + self.assertEqual(result, expected_result) + self.assertIsInstance(result, bytes) + + +class Dummy(object): + pass + + +class DummySerializer(object): + def dumps(self, value): + return base64.b64encode(json.dumps(value).encode('utf-8')) + + def loads(self, value): + try: + return json.loads(base64.b64decode(value).decode('utf-8')) + + # base64.b64decode raises a TypeError on py2 instead of a ValueError + # and a ValueError is required for the session to handle it properly + except TypeError: + raise ValueError + +class DummySessionFactory(dict): + _dirty = False + _cookie_name = 'session' + _cookie_max_age = None + _cookie_path = '/' + _cookie_domain = None + _cookie_secure = False + _cookie_httponly = False + _timeout = 1200 + _reissue_time = 0 + + def __init__(self, request): + self.request = request + dict.__init__(self, {}) + + def changed(self): + self._dirty = True + +class DummyResponse(object): + def __init__(self): + self.headerlist = [] diff --git a/tests/test_settings.py b/tests/test_settings.py new file mode 100644 index 000000000..a586cb6fd --- /dev/null +++ b/tests/test_settings.py @@ -0,0 +1,80 @@ +import unittest + +class Test_asbool(unittest.TestCase): + def _callFUT(self, s): + from pyramid.settings import asbool + return asbool(s) + + def test_s_is_None(self): + result = self._callFUT(None) + self.assertEqual(result, False) + + def test_s_is_True(self): + result = self._callFUT(True) + self.assertEqual(result, True) + + def test_s_is_False(self): + result = self._callFUT(False) + self.assertEqual(result, False) + + def test_s_is_true(self): + result = self._callFUT('True') + self.assertEqual(result, True) + + def test_s_is_false(self): + result = self._callFUT('False') + self.assertEqual(result, False) + + def test_s_is_yes(self): + result = self._callFUT('yes') + self.assertEqual(result, True) + + def test_s_is_on(self): + result = self._callFUT('on') + self.assertEqual(result, True) + + def test_s_is_1(self): + result = self._callFUT(1) + self.assertEqual(result, True) + +class Test_aslist_cronly(unittest.TestCase): + def _callFUT(self, val): + from pyramid.settings import aslist_cronly + return aslist_cronly(val) + + def test_with_list(self): + result = self._callFUT(['abc', 'def']) + self.assertEqual(result, ['abc', 'def']) + + def test_with_string(self): + result = self._callFUT('abc def') + self.assertEqual(result, ['abc def']) + + def test_with_string_crsep(self): + result = self._callFUT(' abc\n def') + self.assertEqual(result, ['abc', 'def']) + +class Test_aslist(unittest.TestCase): + def _callFUT(self, val, **kw): + from pyramid.settings import aslist + return aslist(val, **kw) + + def test_with_list(self): + result = self._callFUT(['abc', 'def']) + self.assertEqual(list(result), ['abc', 'def']) + + def test_with_string(self): + result = self._callFUT('abc def') + self.assertEqual(result, ['abc', 'def']) + + def test_with_string_crsep(self): + result = self._callFUT(' abc\n def') + self.assertEqual(result, ['abc', 'def']) + + def test_with_string_crsep_spacesep(self): + result = self._callFUT(' abc\n def ghi') + self.assertEqual(result, ['abc', 'def', 'ghi']) + + def test_with_string_crsep_spacesep_no_flatten(self): + result = self._callFUT(' abc\n def ghi ', flatten=False) + self.assertEqual(result, ['abc', 'def ghi']) diff --git a/tests/test_static.py b/tests/test_static.py new file mode 100644 index 000000000..f76cc5067 --- /dev/null +++ b/tests/test_static.py @@ -0,0 +1,477 @@ +import datetime +import os.path +import unittest + +here = os.path.dirname(__file__) + +# 5 years from now (more or less) +fiveyrsfuture = datetime.datetime.utcnow() + datetime.timedelta(5*365) + +class Test_static_view_use_subpath_False(unittest.TestCase): + def _getTargetClass(self): + from pyramid.static import static_view + return static_view + + def _makeOne(self, *arg, **kw): + return self._getTargetClass()(*arg, **kw) + + def _makeRequest(self, kw=None): + from pyramid.request import Request + environ = { + 'wsgi.url_scheme':'http', + 'wsgi.version':(1,0), + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'6543', + 'PATH_INFO':'/', + 'SCRIPT_NAME':'', + 'REQUEST_METHOD':'GET', + } + if kw is not None: + environ.update(kw) + return Request(environ=environ) + + def test_ctor_defaultargs(self): + inst = self._makeOne('package:resource_name') + self.assertEqual(inst.package_name, 'package') + self.assertEqual(inst.docroot, 'resource_name') + self.assertEqual(inst.cache_max_age, 3600) + self.assertEqual(inst.index, 'index.html') + + def test_call_adds_slash_path_info_empty(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':''}) + context = DummyContext() + from pyramid.httpexceptions import HTTPMovedPermanently + self.assertRaises(HTTPMovedPermanently, inst, context, request) + + def test_path_info_slash_means_index_html(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + + def test_oob_singledot(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/./index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertEqual(response.status, '200 OK') + self.assertTrue(b'static' in response.body) + + def test_oob_emptyelement(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'//index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertEqual(response.status, '200 OK') + self.assertTrue(b'static' in response.body) + + def test_oob_dotdotslash(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/subdir/../../minimal.pt'}) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_dotdotslash_encoded(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest( + {'PATH_INFO':'/subdir/%2E%2E%2F%2E%2E/minimal.pt'}) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_os_sep(self): + import os + inst = self._makeOne('pyramid.tests:fixtures/static') + dds = '..' + os.sep + request = self._makeRequest({'PATH_INFO':'/subdir/%s%sminimal.pt' % + (dds, dds)}) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_resource_doesnt_exist(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/notthere'}) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_resource_isdir(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/subdir/'}) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'subdir' in response.body) + + def test_resource_is_file(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + + def test_resource_is_file_with_wsgi_file_wrapper(self): + from pyramid.response import _BLOCK_SIZE + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/index.html'}) + class _Wrapper(object): + def __init__(self, file, block_size=None): + self.file = file + self.block_size = block_size + request.environ['wsgi.file_wrapper'] = _Wrapper + context = DummyContext() + response = inst(context, request) + app_iter = response.app_iter + self.assertTrue(isinstance(app_iter, _Wrapper)) + self.assertTrue(b'static' in app_iter.file.read()) + self.assertEqual(app_iter.block_size, _BLOCK_SIZE) + app_iter.file.close() + + def test_resource_is_file_with_cache_max_age(self): + inst = self._makeOne('pyramid.tests:fixtures/static', cache_max_age=600) + request = self._makeRequest({'PATH_INFO':'/index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + self.assertEqual(len(response.headerlist), 5) + header_names = [ x[0] for x in response.headerlist ] + header_names.sort() + self.assertEqual(header_names, + ['Cache-Control', 'Content-Length', 'Content-Type', + 'Expires', 'Last-Modified']) + + def test_resource_is_file_with_no_cache_max_age(self): + inst = self._makeOne('pyramid.tests:fixtures/static', + cache_max_age=None) + request = self._makeRequest({'PATH_INFO':'/index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + self.assertEqual(len(response.headerlist), 3) + header_names = [ x[0] for x in response.headerlist ] + header_names.sort() + self.assertEqual( + header_names, + ['Content-Length', 'Content-Type', 'Last-Modified']) + + def test_resource_notmodified(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/index.html'}) + request.if_modified_since = fiveyrsfuture + context = DummyContext() + response = inst(context, request) + start_response = DummyStartResponse() + app_iter = response(request.environ, start_response) + try: + self.assertEqual(start_response.status, '304 Not Modified') + self.assertEqual(list(app_iter), []) + finally: + app_iter.close() + + def test_not_found(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/notthere.html'}) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_gz_resource_no_content_encoding(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/arcs.svg.tgz'}) + context = DummyContext() + response = inst(context, request) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'application/x-tar') + self.assertEqual(response.content_encoding, None) + response.app_iter.close() + + def test_resource_no_content_encoding(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':'/index.html'}) + context = DummyContext() + response = inst(context, request) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.content_type, 'text/html') + self.assertEqual(response.content_encoding, None) + response.app_iter.close() + +class Test_static_view_use_subpath_True(unittest.TestCase): + def _getTargetClass(self): + from pyramid.static import static_view + return static_view + + def _makeOne(self, *arg, **kw): + kw['use_subpath'] = True + return self._getTargetClass()(*arg, **kw) + + def _makeRequest(self, kw=None): + from pyramid.request import Request + environ = { + 'wsgi.url_scheme':'http', + 'wsgi.version':(1,0), + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'6543', + 'PATH_INFO':'/', + 'SCRIPT_NAME':'', + 'REQUEST_METHOD':'GET', + } + if kw is not None: + environ.update(kw) + return Request(environ=environ) + + def test_ctor_defaultargs(self): + inst = self._makeOne('package:resource_name') + self.assertEqual(inst.package_name, 'package') + self.assertEqual(inst.docroot, 'resource_name') + self.assertEqual(inst.cache_max_age, 3600) + self.assertEqual(inst.index, 'index.html') + + def test_call_adds_slash_path_info_empty(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest({'PATH_INFO':''}) + request.subpath = () + context = DummyContext() + from pyramid.httpexceptions import HTTPMovedPermanently + self.assertRaises(HTTPMovedPermanently, inst, context, request) + + def test_path_info_slash_means_index_html(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = () + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + + def test_oob_singledot(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('.', 'index.html') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_emptyelement(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('', 'index.html') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_dotdotslash(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('subdir', '..', '..', 'minimal.pt') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_dotdotslash_encoded(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('subdir', '%2E%2E', '%2E%2E', 'minimal.pt') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_oob_os_sep(self): + import os + inst = self._makeOne('pyramid.tests:fixtures/static') + dds = '..' + os.sep + request = self._makeRequest() + request.subpath = ('subdir', dds, dds, 'minimal.pt') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_resource_doesnt_exist(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('notthere,') + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + + def test_resource_isdir(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('subdir',) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'subdir' in response.body) + + def test_resource_is_file(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('index.html',) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + + def test_resource_is_file_with_cache_max_age(self): + inst = self._makeOne('pyramid.tests:fixtures/static', cache_max_age=600) + request = self._makeRequest() + request.subpath = ('index.html',) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + self.assertEqual(len(response.headerlist), 5) + header_names = [ x[0] for x in response.headerlist ] + header_names.sort() + self.assertEqual(header_names, + ['Cache-Control', 'Content-Length', 'Content-Type', + 'Expires', 'Last-Modified']) + + def test_resource_is_file_with_no_cache_max_age(self): + inst = self._makeOne('pyramid.tests:fixtures/static', + cache_max_age=None) + request = self._makeRequest() + request.subpath = ('index.html',) + context = DummyContext() + response = inst(context, request) + self.assertTrue(b'static' in response.body) + self.assertEqual(len(response.headerlist), 3) + header_names = [ x[0] for x in response.headerlist ] + header_names.sort() + self.assertEqual( + header_names, + ['Content-Length', 'Content-Type', 'Last-Modified']) + + def test_resource_notmodified(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.if_modified_since = fiveyrsfuture + request.subpath = ('index.html',) + context = DummyContext() + response = inst(context, request) + start_response = DummyStartResponse() + app_iter = response(request.environ, start_response) + try: + self.assertEqual(start_response.status, '304 Not Modified') + self.assertEqual(list(app_iter), []) + finally: + app_iter.close() + + def test_not_found(self): + inst = self._makeOne('pyramid.tests:fixtures/static') + request = self._makeRequest() + request.subpath = ('notthere.html',) + context = DummyContext() + from pyramid.httpexceptions import HTTPNotFound + self.assertRaises(HTTPNotFound, inst, context, request) + +class TestQueryStringConstantCacheBuster(unittest.TestCase): + + def _makeOne(self, param=None): + from pyramid.static import QueryStringConstantCacheBuster as cls + if param: + inst = cls('foo', param) + else: + inst = cls('foo') + return inst + + def test_token(self): + fut = self._makeOne().tokenize + self.assertEqual(fut(None, 'whatever', None), 'foo') + + def test_it(self): + fut = self._makeOne() + self.assertEqual( + fut('foo', 'bar', {}), + ('bar', {'_query': {'x': 'foo'}})) + + def test_change_param(self): + fut = self._makeOne('y') + self.assertEqual( + fut('foo', 'bar', {}), + ('bar', {'_query': {'y': 'foo'}})) + + def test_query_is_already_tuples(self): + fut = self._makeOne() + self.assertEqual( + fut('foo', 'bar', {'_query': [('a', 'b')]}), + ('bar', {'_query': (('a', 'b'), ('x', 'foo'))})) + + def test_query_is_tuple_of_tuples(self): + fut = self._makeOne() + self.assertEqual( + fut('foo', 'bar', {'_query': (('a', 'b'),)}), + ('bar', {'_query': (('a', 'b'), ('x', 'foo'))})) + +class TestManifestCacheBuster(unittest.TestCase): + + def _makeOne(self, path, **kw): + from pyramid.static import ManifestCacheBuster as cls + return cls(path, **kw) + + def test_it(self): + manifest_path = os.path.join(here, 'fixtures', 'manifest.json') + fut = self._makeOne(manifest_path) + self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-test.css', {})) + + def test_it_with_relspec(self): + fut = self._makeOne('fixtures/manifest.json') + self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-test.css', {})) + + def test_it_with_absspec(self): + fut = self._makeOne('pyramid.tests:fixtures/manifest.json') + self.assertEqual(fut('foo', 'bar', {}), ('bar', {})) + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-test.css', {})) + + def test_reload(self): + manifest_path = os.path.join(here, 'fixtures', 'manifest.json') + new_manifest_path = os.path.join(here, 'fixtures', 'manifest2.json') + inst = self._makeOne('foo', reload=True) + inst.getmtime = lambda *args, **kwargs: 0 + fut = inst + + # test without a valid manifest + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main.css', {})) + + # swap to a real manifest, setting mtime to 0 + inst.manifest_path = manifest_path + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-test.css', {})) + + # ensure switching the path doesn't change the result + inst.manifest_path = new_manifest_path + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-test.css', {})) + + # update mtime, should cause a reload + inst.getmtime = lambda *args, **kwargs: 1 + self.assertEqual( + fut('foo', 'css/main.css', {}), + ('css/main-678b7c80.css', {})) + + def test_invalid_manifest(self): + self.assertRaises(IOError, lambda: self._makeOne('foo')) + + def test_invalid_manifest_with_reload(self): + inst = self._makeOne('foo', reload=True) + self.assertEqual(inst.manifest, {}) + +class DummyContext: + pass + +class DummyStartResponse: + status = () + headers = () + def __call__(self, status, headers): + self.status = status + self.headers = headers diff --git a/tests/test_testing.py b/tests/test_testing.py new file mode 100644 index 000000000..86c219988 --- /dev/null +++ b/tests/test_testing.py @@ -0,0 +1,689 @@ +import unittest +from zope.component import getSiteManager +from pyramid import testing + +class TestDummyRootFactory(unittest.TestCase): + def _makeOne(self, environ): + from pyramid.testing import DummyRootFactory + return DummyRootFactory(environ) + + def test_it(self): + environ = {'bfg.routes.matchdict':{'a':1}} + factory = self._makeOne(environ) + self.assertEqual(factory.a, 1) + +class TestDummySecurityPolicy(unittest.TestCase): + def _getTargetClass(self): + from pyramid.testing import DummySecurityPolicy + return DummySecurityPolicy + + def _makeOne(self, userid=None, groupids=(), permissive=True): + klass = self._getTargetClass() + return klass(userid, groupids, permissive) + + def test_authenticated_userid(self): + policy = self._makeOne('user') + self.assertEqual(policy.authenticated_userid(None), 'user') + + def test_unauthenticated_userid(self): + policy = self._makeOne('user') + self.assertEqual(policy.unauthenticated_userid(None), 'user') + + def test_effective_principals_userid(self): + policy = self._makeOne('user', ('group1',)) + from pyramid.security import Everyone + from pyramid.security import Authenticated + self.assertEqual(policy.effective_principals(None), + [Everyone, Authenticated, 'user', 'group1']) + + def test_effective_principals_nouserid(self): + policy = self._makeOne() + from pyramid.security import Everyone + self.assertEqual(policy.effective_principals(None), [Everyone]) + + def test_permits(self): + policy = self._makeOne() + self.assertEqual(policy.permits(None, None, None), True) + + def test_principals_allowed_by_permission(self): + policy = self._makeOne('user', ('group1',)) + from pyramid.security import Everyone + from pyramid.security import Authenticated + result = policy.principals_allowed_by_permission(None, None) + self.assertEqual(result, [Everyone, Authenticated, 'user', 'group1']) + + def test_forget(self): + policy = self._makeOne() + self.assertEqual(policy.forget(None), []) + + def test_remember(self): + policy = self._makeOne() + self.assertEqual(policy.remember(None, None), []) + + + +class TestDummyResource(unittest.TestCase): + def _getTargetClass(self): + from pyramid.testing import DummyResource + return DummyResource + + def _makeOne(self, name=None, parent=None, **kw): + klass = self._getTargetClass() + return klass(name, parent, **kw) + + def test__setitem__and__getitem__and__delitem__and__contains__and_get(self): + class Dummy: + pass + dummy = Dummy() + resource = self._makeOne() + resource['abc'] = dummy + self.assertEqual(dummy.__name__, 'abc') + self.assertEqual(dummy.__parent__, resource) + self.assertEqual(resource['abc'], dummy) + self.assertEqual(resource.get('abc'), dummy) + self.assertRaises(KeyError, resource.__getitem__, 'none') + self.assertTrue('abc' in resource) + del resource['abc'] + self.assertFalse('abc' in resource) + self.assertEqual(resource.get('abc', 'foo'), 'foo') + self.assertEqual(resource.get('abc'), None) + + def test_extra_params(self): + resource = self._makeOne(foo=1) + self.assertEqual(resource.foo, 1) + + def test_clone(self): + resource = self._makeOne('name', 'parent', foo=1, bar=2) + clone = resource.clone('name2', 'parent2', bar=1) + self.assertEqual(clone.bar, 1) + self.assertEqual(clone.__name__, 'name2') + self.assertEqual(clone.__parent__, 'parent2') + self.assertEqual(clone.foo, 1) + + def test_keys_items_values_len(self): + class Dummy: + pass + resource = self._makeOne() + resource['abc'] = Dummy() + resource['def'] = Dummy() + L = list + self.assertEqual(L(resource.values()), L(resource.subs.values())) + self.assertEqual(L(resource.items()), L(resource.subs.items())) + self.assertEqual(L(resource.keys()), L(resource.subs.keys())) + self.assertEqual(len(resource), 2) + + def test_nonzero(self): + resource = self._makeOne() + self.assertEqual(resource.__nonzero__(), True) + + def test_bool(self): + resource = self._makeOne() + self.assertEqual(resource.__bool__(), True) + + def test_ctor_with__provides__(self): + resource = self._makeOne(__provides__=IDummy) + self.assertTrue(IDummy.providedBy(resource)) + +class TestDummyRequest(unittest.TestCase): + def _getTargetClass(self): + from pyramid.testing import DummyRequest + return DummyRequest + + def _makeOne(self, *arg, **kw): + return self._getTargetClass()(*arg, **kw) + + def test_params(self): + request = self._makeOne(params = {'say':'Hello'}, + environ = {'PATH_INFO':'/foo'}, + headers = {'X-Foo':'YUP'}, + ) + self.assertEqual(request.params['say'], 'Hello') + self.assertEqual(request.GET['say'], 'Hello') + self.assertEqual(request.POST['say'], 'Hello') + self.assertEqual(request.headers['X-Foo'], 'YUP') + self.assertEqual(request.environ['PATH_INFO'], '/foo') + + def test_defaults(self): + from pyramid.threadlocal import get_current_registry + from pyramid.testing import DummySession + request = self._makeOne() + self.assertEqual(request.method, 'GET') + self.assertEqual(request.application_url, 'http://example.com') + self.assertEqual(request.host_url, 'http://example.com') + self.assertEqual(request.path_url, 'http://example.com') + self.assertEqual(request.url, 'http://example.com') + self.assertEqual(request.host, 'example.com:80') + self.assertEqual(request.content_length, 0) + self.assertEqual(request.environ.get('PATH_INFO'), None) + self.assertEqual(request.headers.get('X-Foo'), None) + self.assertEqual(request.params.get('foo'), None) + self.assertEqual(request.GET.get('foo'), None) + self.assertEqual(request.POST.get('foo'), None) + self.assertEqual(request.cookies.get('type'), None) + self.assertEqual(request.path, '/') + self.assertEqual(request.path_info, '/') + self.assertEqual(request.script_name, '') + self.assertEqual(request.path_qs, '') + self.assertEqual(request.view_name, '') + self.assertEqual(request.subpath, ()) + self.assertEqual(request.context, None) + self.assertEqual(request.root, None) + self.assertEqual(request.virtual_root, None) + self.assertEqual(request.virtual_root_path, ()) + self.assertEqual(request.registry, get_current_registry()) + self.assertEqual(request.session.__class__, DummySession) + + def test_params_explicit(self): + request = self._makeOne(params = {'foo':'bar'}) + self.assertEqual(request.params['foo'], 'bar') + self.assertEqual(request.GET['foo'], 'bar') + self.assertEqual(request.POST['foo'], 'bar') + + def test_environ_explicit(self): + request = self._makeOne(environ = {'PATH_INFO':'/foo'}) + self.assertEqual(request.environ['PATH_INFO'], '/foo') + + def test_headers_explicit(self): + request = self._makeOne(headers = {'X-Foo':'YUP'}) + self.assertEqual(request.headers['X-Foo'], 'YUP') + + def test_path_explicit(self): + request = self._makeOne(path = '/abc') + self.assertEqual(request.path, '/abc') + + def test_cookies_explicit(self): + request = self._makeOne(cookies = {'type': 'gingersnap'}) + self.assertEqual(request.cookies['type'], 'gingersnap') + + def test_post_explicit(self): + POST = {'foo': 'bar', 'baz': 'qux'} + request = self._makeOne(post=POST) + self.assertEqual(request.method, 'POST') + self.assertEqual(request.POST, POST) + # N.B.: Unlike a normal request, passing 'post' should *not* put + # explict POST data into params: doing so masks a possible + # XSS bug in the app. Tests for apps which don't care about + # the distinction should just use 'params'. + self.assertEqual(request.params, {}) + + def test_post_empty_shadows_params(self): + request = self._makeOne(params={'foo': 'bar'}, post={}) + self.assertEqual(request.method, 'POST') + self.assertEqual(request.params.get('foo'), 'bar') + self.assertEqual(request.POST.get('foo'), None) + + def test_kwargs(self): + request = self._makeOne(water = 1) + self.assertEqual(request.water, 1) + + def test_add_response_callback(self): + request = self._makeOne() + request.add_response_callback(1) + self.assertEqual(list(request.response_callbacks), [1]) + + def test_registry_is_config_registry_when_setup_is_called_after_ctor(self): + # see https://github.com/Pylons/pyramid/issues/165 + from pyramid.registry import Registry + from pyramid.config import Configurator + request = self._makeOne() + try: + registry = Registry('this_test') + config = Configurator(registry=registry) + config.begin() + self.assertTrue(request.registry is registry) + finally: + config.end() + + def test_set_registry(self): + request = self._makeOne() + request.registry = 'abc' + self.assertEqual(request.registry, 'abc') + + def test_del_registry(self): + # see https://github.com/Pylons/pyramid/issues/165 + from pyramid.registry import Registry + from pyramid.config import Configurator + request = self._makeOne() + request.registry = 'abc' + self.assertEqual(request.registry, 'abc') + del request.registry + try: + registry = Registry('this_test') + config = Configurator(registry=registry) + config.begin() + self.assertTrue(request.registry is registry) + finally: + config.end() + + def test_response_with_responsefactory(self): + from pyramid.registry import Registry + from pyramid.interfaces import IResponseFactory + registry = Registry('this_test') + class ResponseFactory(object): + pass + registry.registerUtility( + lambda r: ResponseFactory(), IResponseFactory + ) + request = self._makeOne() + request.registry = registry + resp = request.response + self.assertEqual(resp.__class__, ResponseFactory) + self.assertTrue(request.response is resp) # reified + + def test_response_without_responsefactory(self): + from pyramid.registry import Registry + from pyramid.response import Response + registry = Registry('this_test') + request = self._makeOne() + request.registry = registry + resp = request.response + self.assertEqual(resp.__class__, Response) + self.assertTrue(request.response is resp) # reified + + +class TestDummyTemplateRenderer(unittest.TestCase): + def _getTargetClass(self, ): + from pyramid.testing import DummyTemplateRenderer + return DummyTemplateRenderer + + def _makeOne(self, string_response=''): + return self._getTargetClass()(string_response=string_response) + + def test_implementation(self): + renderer = self._makeOne() + impl = renderer.implementation() + impl(a=1, b=2) + self.assertEqual(renderer._implementation._received['a'], 1) + self.assertEqual(renderer._implementation._received['b'], 2) + + def test_getattr(self): + renderer = self._makeOne() + renderer({'a':1}) + self.assertEqual(renderer.a, 1) + self.assertRaises(AttributeError, renderer.__getattr__, 'b') + + def test_assert_(self): + renderer = self._makeOne() + renderer({'a':1, 'b':2}) + self.assertRaises(AssertionError, renderer.assert_, c=1) + self.assertRaises(AssertionError, renderer.assert_, b=3) + self.assertTrue(renderer.assert_(a=1, b=2)) + + def test_nondefault_string_response(self): + renderer = self._makeOne('abc') + result = renderer({'a':1, 'b':2}) + self.assertEqual(result, 'abc') + +class Test_setUp(unittest.TestCase): + def _callFUT(self, **kw): + from pyramid.testing import setUp + return setUp(**kw) + + def tearDown(self): + from pyramid.threadlocal import manager + manager.clear() + getSiteManager.reset() + + def _assertSMHook(self, hook): + result = getSiteManager.sethook(None) + self.assertEqual(result, hook) + + def test_it_defaults(self): + from pyramid.threadlocal import manager + from pyramid.threadlocal import get_current_registry + from pyramid.registry import Registry + old = True + manager.push(old) + config = self._callFUT() + current = manager.get() + self.assertFalse(current is old) + self.assertEqual(config.registry, current['registry']) + self.assertEqual(current['registry'].__class__, Registry) + self.assertEqual(current['request'], None) + self.assertEqual(config.package.__name__, 'pyramid.tests') + self._assertSMHook(get_current_registry) + + def test_it_with_registry(self): + from pyramid.registry import Registry + from pyramid.threadlocal import manager + registry = Registry() + self._callFUT(registry=registry) + current = manager.get() + self.assertEqual(current['registry'], registry) + + def test_it_with_request(self): + from pyramid.threadlocal import manager + request = object() + self._callFUT(request=request) + current = manager.get() + self.assertEqual(current['request'], request) + + def test_it_with_package(self): + config = self._callFUT(package='pyramid') + self.assertEqual(config.package.__name__, 'pyramid') + + def test_it_with_hook_zca_false(self): + from pyramid.registry import Registry + registry = Registry() + self._callFUT(registry=registry, hook_zca=False) + sm = getSiteManager() + self.assertFalse(sm is registry) + + def test_it_with_settings_passed_explicit_registry(self): + from pyramid.registry import Registry + registry = Registry() + self._callFUT(registry=registry, hook_zca=False, settings=dict(a=1)) + self.assertEqual(registry.settings['a'], 1) + + def test_it_with_settings_passed_implicit_registry(self): + config = self._callFUT(hook_zca=False, settings=dict(a=1)) + self.assertEqual(config.registry.settings['a'], 1) + +class Test_cleanUp(Test_setUp): + def _callFUT(self, *arg, **kw): + from pyramid.testing import cleanUp + return cleanUp(*arg, **kw) + +class Test_tearDown(unittest.TestCase): + def _callFUT(self, **kw): + from pyramid.testing import tearDown + return tearDown(**kw) + + def tearDown(self): + from pyramid.threadlocal import manager + manager.clear() + getSiteManager.reset() + + def _assertSMHook(self, hook): + result = getSiteManager.sethook(None) + self.assertEqual(result, hook) + + def _setSMHook(self, hook): + getSiteManager.sethook(hook) + + def test_defaults(self): + from pyramid.threadlocal import manager + registry = DummyRegistry() + old = {'registry':registry} + hook = lambda *arg: None + try: + self._setSMHook(hook) + manager.push(old) + self._callFUT() + current = manager.get() + self.assertNotEqual(current, old) + self.assertEqual(registry.inited, 2) + finally: + result = getSiteManager.sethook(None) + self.assertNotEqual(result, hook) + + def test_registry_cannot_be_inited(self): + from pyramid.threadlocal import manager + registry = DummyRegistry() + def raiseit(name): + raise TypeError + registry.__init__ = raiseit + old = {'registry':registry} + try: + manager.push(old) + self._callFUT() # doesn't blow up + current = manager.get() + self.assertNotEqual(current, old) + self.assertEqual(registry.inited, 1) + finally: + manager.clear() + + def test_unhook_zc_false(self): + hook = lambda *arg: None + try: + self._setSMHook(hook) + self._callFUT(unhook_zca=False) + finally: + self._assertSMHook(hook) + +class TestDummyRendererFactory(unittest.TestCase): + def _makeOne(self, name, factory): + from pyramid.testing import DummyRendererFactory + return DummyRendererFactory(name, factory) + + def test_add_no_colon(self): + f = self._makeOne('name', None) + f.add('spec', 'renderer') + self.assertEqual(f.renderers['spec'], 'renderer') + + def test_add_with_colon(self): + f = self._makeOne('name', None) + f.add('spec:spec2', 'renderer') + self.assertEqual(f.renderers['spec:spec2'], 'renderer') + self.assertEqual(f.renderers['spec2'], 'renderer') + + def test_call(self): + f = self._makeOne('name', None) + f.renderers['spec'] = 'renderer' + info = DummyRendererInfo({'name':'spec'}) + self.assertEqual(f(info), 'renderer') + + def test_call2(self): + f = self._makeOne('name', None) + f.renderers['spec'] = 'renderer' + info = DummyRendererInfo({'name':'spec:spec'}) + self.assertEqual(f(info), 'renderer') + + def test_call3(self): + def factory(spec): + return 'renderer' + f = self._makeOne('name', factory) + info = DummyRendererInfo({'name':'spec'}) + self.assertEqual(f(info), 'renderer') + + def test_call_miss(self): + f = self._makeOne('name', None) + info = DummyRendererInfo({'name':'spec'}) + self.assertRaises(KeyError, f, info) + +class TestMockTemplate(unittest.TestCase): + def _makeOne(self, response): + from pyramid.testing import MockTemplate + return MockTemplate(response) + + def test_getattr(self): + template = self._makeOne(None) + self.assertEqual(template.foo, template) + + def test_getitem(self): + template = self._makeOne(None) + self.assertEqual(template['foo'], template) + + def test_call(self): + template = self._makeOne('123') + self.assertEqual(template(), '123') + +class Test_skip_on(unittest.TestCase): + def setUp(self): + from pyramid.testing import skip_on + self.os_name = skip_on.os_name + skip_on.os_name = 'wrong' + + def tearDown(self): + from pyramid.testing import skip_on + skip_on.os_name = self.os_name + + def _callFUT(self, *platforms): + from pyramid.testing import skip_on + return skip_on(*platforms) + + def test_wrong_platform(self): + def foo(): return True + decorated = self._callFUT('wrong')(foo) + self.assertEqual(decorated(), None) + + def test_ok_platform(self): + def foo(): return True + decorated = self._callFUT('ok')(foo) + self.assertEqual(decorated(), True) + +class TestDummySession(unittest.TestCase): + def _makeOne(self): + from pyramid.testing import DummySession + return DummySession() + + @testing.skip_on('pypy') # see https://github.com/Pylons/pyramid/issues/3237 + def test_instance_conforms(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import ISession + session = self._makeOne() + verifyObject(ISession, session) + + def test_changed(self): + session = self._makeOne() + self.assertEqual(session.changed(), None) + + def test_invalidate(self): + session = self._makeOne() + session['a'] = 1 + self.assertEqual(session.invalidate(), None) + self.assertFalse('a' in session) + + def test_flash_default(self): + session = self._makeOne() + session.flash('msg1') + session.flash('msg2') + self.assertEqual(session['_f_'], ['msg1', 'msg2']) + + def test_flash_mixed(self): + session = self._makeOne() + session.flash('warn1', 'warn') + session.flash('warn2', 'warn') + session.flash('err1', 'error') + session.flash('err2', 'error') + self.assertEqual(session['_f_warn'], ['warn1', 'warn2']) + + def test_pop_flash_default_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_'] = queue + result = session.pop_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), None) + + def test_pop_flash_nodefault_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.pop_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), None) + + def test_peek_flash_default_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_'] = queue + result = session.peek_flash() + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_'), queue) + + def test_peek_flash_nodefault_queue(self): + session = self._makeOne() + queue = ['one', 'two'] + session['_f_error'] = queue + result = session.peek_flash('error') + self.assertEqual(result, queue) + self.assertEqual(session.get('_f_error'), queue) + + def test_new_csrf_token(self): + session = self._makeOne() + token = session.new_csrf_token() + self.assertEqual(token, session['_csrft_']) + + def test_get_csrf_token(self): + session = self._makeOne() + session['_csrft_'] = 'token' + token = session.get_csrf_token() + self.assertEqual(token, 'token') + self.assertTrue('_csrft_' in session) + + def test_get_csrf_token_generates_token(self): + session = self._makeOne() + token = session.get_csrf_token() + self.assertNotEqual(token, None) + self.assertTrue(len(token) >= 1) + +from zope.interface import Interface +from zope.interface import implementer + +class IDummy(Interface): + pass + +@implementer(IDummy) +class DummyEvent: + pass + +class DummyFactory: + def __init__(self, environ): + """ """ + +class DummyRegistry(object): + inited = 0 + __name__ = 'name' + def __init__(self, name=''): + self.inited = self.inited + 1 + +class DummyRendererInfo(object): + def __init__(self, kw): + self.__dict__.update(kw) + +class Test_testConfig(unittest.TestCase): + + def _setUp(self, **kw): + self._log.append(('setUp', kw)) + return 'fake config' + + def _tearDown(self, **kw): + self._log.append(('tearDown', kw)) + + def setUp(self): + from pyramid import testing + self._log = [] + self._orig_setUp = testing.setUp + testing.setUp = self._setUp + self._orig_tearDown = testing.tearDown + testing.tearDown = self._tearDown + + def tearDown(self): + from pyramid import testing + testing.setUp = self._orig_setUp + testing.tearDown = self._orig_tearDown + + def _callFUT(self, inner, **kw): + from pyramid.testing import testConfig + with testConfig(**kw) as config: + inner(config) + + def test_ok_calls(self): + self.assertEqual(self._log, []) + def inner(config): + self.assertEqual(self._log, + [('setUp', + {'autocommit': True, + 'hook_zca': True, + 'registry': None, + 'request': None, + 'settings': None})]) + self._log.pop() + self._callFUT(inner) + self.assertEqual(self._log, + [('tearDown', {'unhook_zca': True})]) + + def test_teardown_called_on_exception(self): + class TestException(Exception): + pass + def inner(config): + self._log = [] + raise TestException('oops') + self.assertRaises(TestException, self._callFUT, inner) + self.assertEqual(self._log[0][0], 'tearDown') + + def test_ok_get_config(self): + def inner(config): + self.assertEqual(config, 'fake config') + self._callFUT(inner) diff --git a/tests/test_threadlocal.py b/tests/test_threadlocal.py new file mode 100644 index 000000000..088156507 --- /dev/null +++ b/tests/test_threadlocal.py @@ -0,0 +1,95 @@ +from pyramid import testing +import unittest + +class TestThreadLocalManager(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _getTargetClass(self): + from pyramid.threadlocal import ThreadLocalManager + return ThreadLocalManager + + def _makeOne(self, default=lambda *x: 1): + return self._getTargetClass()(default) + + def test_init(self): + local = self._makeOne() + self.assertEqual(local.stack, []) + self.assertEqual(local.get(), 1) + + def test_default(self): + def thedefault(): + return '123' + local = self._makeOne(thedefault) + self.assertEqual(local.stack, []) + self.assertEqual(local.get(), '123') + + def test_push_and_pop(self): + local = self._makeOne() + local.push(True) + self.assertEqual(local.get(), True) + self.assertEqual(local.pop(), True) + self.assertEqual(local.pop(), None) + self.assertEqual(local.get(), 1) + + def test_set_get_and_clear(self): + local = self._makeOne() + local.set(None) + self.assertEqual(local.stack, [None]) + self.assertEqual(local.get(), None) + local.clear() + self.assertEqual(local.get(), 1) + local.clear() + self.assertEqual(local.get(), 1) + + +class TestGetCurrentRequest(unittest.TestCase): + def _callFUT(self): + from pyramid.threadlocal import get_current_request + return get_current_request() + + def test_it_None(self): + request = self._callFUT() + self.assertEqual(request, None) + + def test_it(self): + from pyramid.threadlocal import manager + request = object() + try: + manager.push({'request':request}) + self.assertEqual(self._callFUT(), request) + finally: + manager.pop() + self.assertEqual(self._callFUT(), None) + +class GetCurrentRegistryTests(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _callFUT(self): + from pyramid.threadlocal import get_current_registry + return get_current_registry() + + def test_it(self): + from pyramid.threadlocal import manager + try: + manager.push({'registry':123}) + self.assertEqual(self._callFUT(), 123) + finally: + manager.pop() + +class GetCurrentRegistryWithoutTestingRegistry(unittest.TestCase): + def _callFUT(self): + from pyramid.threadlocal import get_current_registry + return get_current_registry() + + def test_it(self): + from pyramid.registry import global_registry + self.assertEqual(self._callFUT(), global_registry) + diff --git a/tests/test_traversal.py b/tests/test_traversal.py new file mode 100644 index 000000000..437fe46df --- /dev/null +++ b/tests/test_traversal.py @@ -0,0 +1,1221 @@ +# -*- coding: utf-8 -*- +import unittest + +from pyramid.testing import cleanUp + +from pyramid.compat import ( + text_, + native_, + text_type, + url_quote, + PY2, + ) + +class TraversalPathTests(unittest.TestCase): + def _callFUT(self, path): + from pyramid.traversal import traversal_path + return traversal_path(path) + + def test_utf8(self): + la = b'La Pe\xc3\xb1a' + encoded = url_quote(la) + decoded = text_(la, 'utf-8') + path = '/'.join([encoded, encoded]) + result = self._callFUT(path) + self.assertEqual(result, (decoded, decoded)) + + def test_utf16(self): + from pyramid.exceptions import URLDecodeError + la = text_(b'La Pe\xc3\xb1a', 'utf-8').encode('utf-16') + encoded = url_quote(la) + path = '/'.join([encoded, encoded]) + self.assertRaises(URLDecodeError, self._callFUT, path) + + def test_unicode_highorder_chars(self): + path = text_('/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') + self.assertEqual(self._callFUT(path), + (text_('\u6d41\u884c\u8d8b\u52bf', 'unicode_escape'),)) + + def test_element_urllquoted(self): + self.assertEqual(self._callFUT('/foo/space%20thing/bar'), + (text_('foo'), text_('space thing'), text_('bar'))) + + def test_unicode_undecodeable_to_ascii(self): + path = text_(b'/La Pe\xc3\xb1a', 'utf-8') + self.assertRaises(UnicodeEncodeError, self._callFUT, path) + +class TraversalPathInfoTests(unittest.TestCase): + def _callFUT(self, path): + from pyramid.traversal import traversal_path_info + return traversal_path_info(path) + + def test_path_startswith_endswith(self): + self.assertEqual(self._callFUT('/foo/'), (text_('foo'),)) + + def test_empty_elements(self): + self.assertEqual(self._callFUT('foo///'), (text_('foo'),)) + + def test_onedot(self): + self.assertEqual(self._callFUT('foo/./bar'), + (text_('foo'), text_('bar'))) + + def test_twodots(self): + self.assertEqual(self._callFUT('foo/../bar'), (text_('bar'),)) + + def test_twodots_at_start(self): + self.assertEqual(self._callFUT('../../bar'), (text_('bar'),)) + + def test_segments_are_unicode(self): + result = self._callFUT('/foo/bar') + self.assertEqual(type(result[0]), text_type) + self.assertEqual(type(result[1]), text_type) + + def test_same_value_returned_if_cached(self): + result1 = self._callFUT('/foo/bar') + result2 = self._callFUT('/foo/bar') + self.assertEqual(result1, (text_('foo'), text_('bar'))) + self.assertEqual(result2, (text_('foo'), text_('bar'))) + + def test_unicode_simple(self): + path = text_('/abc') + self.assertEqual(self._callFUT(path), (text_('abc'),)) + + def test_highorder(self): + la = b'La Pe\xc3\xb1a' + latin1 = native_(la) + result = self._callFUT(latin1) + self.assertEqual(result, (text_(la, 'utf-8'),)) + + def test_highorder_undecodeable(self): + from pyramid.exceptions import URLDecodeError + la = text_(b'La Pe\xc3\xb1a', 'utf-8') + notlatin1 = native_(la) + self.assertRaises(URLDecodeError, self._callFUT, notlatin1) + +class ResourceTreeTraverserTests(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _getTargetClass(self): + from pyramid.traversal import ResourceTreeTraverser + return ResourceTreeTraverser + + def _makeOne(self, *arg, **kw): + klass = self._getTargetClass() + return klass(*arg, **kw) + + def _getEnviron(self, **kw): + environ = {} + environ.update(kw) + return environ + + def test_class_conforms_to_ITraverser(self): + from zope.interface.verify import verifyClass + from pyramid.interfaces import ITraverser + verifyClass(ITraverser, self._getTargetClass()) + + def test_instance_conforms_to_ITraverser(self): + from zope.interface.verify import verifyObject + from pyramid.interfaces import ITraverser + context = DummyContext() + verifyObject(ITraverser, self._makeOne(context)) + + def test_call_with_empty_pathinfo(self): + policy = self._makeOne(None) + environ = self._getEnviron() + request = DummyRequest(environ, path_info='') + result = policy(request) + self.assertEqual(result['context'], None) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_pathinfo_KeyError(self): + policy = self._makeOne(None) + environ = self._getEnviron() + request = DummyRequest(environ, toraise=KeyError) + result = policy(request) + self.assertEqual(result['context'], None) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_pathinfo_highorder(self): + path = text_(b'/Qu\xc3\xa9bec', 'utf-8') + foo = DummyContext(None, path) + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=path) + result = policy(request) + self.assertEqual(result['context'], foo) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (path[1:],)) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_pathel_with_no_getitem(self): + policy = self._makeOne(None) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=text_('/foo/bar')) + result = policy(request) + self.assertEqual(result['context'], None) + self.assertEqual(result['view_name'], 'foo') + self.assertEqual(result['subpath'], ('bar',)) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_withconn_getitem_emptypath_nosubpath(self): + root = DummyContext() + policy = self._makeOne(root) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=text_('')) + result = policy(request) + self.assertEqual(result['context'], root) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_withconn_getitem_withpath_nosubpath(self): + foo = DummyContext() + root = DummyContext(foo) + policy = self._makeOne(root) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=text_('/foo/bar')) + result = policy(request) + self.assertEqual(result['context'], foo) + self.assertEqual(result['view_name'], 'bar') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], (text_('foo'),)) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_withconn_getitem_withpath_withsubpath(self): + foo = DummyContext() + root = DummyContext(foo) + policy = self._makeOne(root) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) + result = policy(request) + self.assertEqual(result['context'], foo) + self.assertEqual(result['view_name'], 'bar') + self.assertEqual(result['subpath'], ('baz', 'buz')) + self.assertEqual(result['traversed'], (text_('foo'),)) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_explicit_viewname(self): + foo = DummyContext() + root = DummyContext(foo) + policy = self._makeOne(root) + environ = self._getEnviron() + request = DummyRequest(environ, path_info=text_('/@@foo')) + result = policy(request) + self.assertEqual(result['context'], root) + self.assertEqual(result['view_name'], 'foo') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_vh_root(self): + environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar') + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + request = DummyRequest(environ, path_info=text_('/baz')) + result = policy(request) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], + (text_('foo'), text_('bar'), text_('baz'))) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], bar) + self.assertEqual(result['virtual_root_path'], + (text_('foo'), text_('bar'))) + + def test_call_with_vh_root2(self): + environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo') + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + request = DummyRequest(environ, path_info=text_('/bar/baz')) + result = policy(request) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], + (text_('foo'), text_('bar'), text_('baz'))) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], foo) + self.assertEqual(result['virtual_root_path'], (text_('foo'),)) + + def test_call_with_vh_root3(self): + environ = self._getEnviron(HTTP_X_VHM_ROOT='/') + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + policy = self._makeOne(root) + request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) + result = policy(request) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], + (text_('foo'), text_('bar'), text_('baz'))) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_vh_root4(self): + environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar/baz') + baz = DummyContext(None, 'baz') + bar = DummyContext(baz, 'bar') + foo = DummyContext(bar, 'foo') + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + request = DummyRequest(environ, path_info=text_('/')) + result = policy(request) + self.assertEqual(result['context'], baz) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], + (text_('foo'), text_('bar'), text_('baz'))) + self.assertEqual(result['root'], root) + self.assertEqual(result['virtual_root'], baz) + self.assertEqual(result['virtual_root_path'], + (text_('foo'), text_('bar'), text_('baz'))) + + def test_call_with_vh_root_path_root(self): + policy = self._makeOne(None) + environ = self._getEnviron(HTTP_X_VHM_ROOT='/') + request = DummyRequest(environ, path_info=text_('/')) + result = policy(request) + self.assertEqual(result['context'], None) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], policy.root) + self.assertEqual(result['virtual_root_path'], ()) + + def test_call_with_vh_root_highorder(self): + path = text_(b'Qu\xc3\xa9bec', 'utf-8') + bar = DummyContext(None, 'bar') + foo = DummyContext(bar, path) + root = DummyContext(foo, 'root') + policy = self._makeOne(root) + if PY2: + vhm_root = b'/Qu\xc3\xa9bec' + else: + vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') + environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) + request = DummyRequest(environ, path_info=text_('/bar')) + result = policy(request) + self.assertEqual(result['context'], bar) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual( + result['traversed'], + (path, text_('bar')) + ) + self.assertEqual(result['root'], policy.root) + self.assertEqual(result['virtual_root'], foo) + self.assertEqual( + result['virtual_root_path'], + (path,) + ) + + def test_path_info_raises_unicodedecodeerror(self): + from pyramid.exceptions import URLDecodeError + foo = DummyContext() + root = DummyContext(foo) + policy = self._makeOne(root) + environ = self._getEnviron() + toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5') + request = DummyRequest(environ, toraise=toraise) + request.matchdict = None + self.assertRaises(URLDecodeError, policy, request) + + def test_withroute_nothingfancy(self): + resource = DummyContext() + traverser = self._makeOne(resource) + request = DummyRequest({}) + request.matchdict = {} + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_with_subpath_string(self): + resource = DummyContext() + traverser = self._makeOne(resource) + matchdict = {'subpath':'/a/b/c'} + request = DummyRequest({}) + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ('a', 'b','c')) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_with_subpath_tuple(self): + resource = DummyContext() + traverser = self._makeOne(resource) + matchdict = {'subpath':('a', 'b', 'c')} + request = DummyRequest({}) + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ('a', 'b','c')) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_and_traverse_string(self): + resource = DummyContext() + traverser = self._makeOne(resource) + matchdict = {'traverse':text_('foo/bar')} + request = DummyRequest({}) + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], 'foo') + self.assertEqual(result['subpath'], ('bar',)) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_and_traverse_tuple(self): + resource = DummyContext() + traverser = self._makeOne(resource) + matchdict = {'traverse':('foo', 'bar')} + request = DummyRequest({}) + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], 'foo') + self.assertEqual(result['subpath'], ('bar',)) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_and_traverse_empty(self): + resource = DummyContext() + traverser = self._makeOne(resource) + matchdict = {'traverse':''} + request = DummyRequest({}) + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], resource) + self.assertEqual(result['view_name'], '') + self.assertEqual(result['subpath'], ()) + self.assertEqual(result['traversed'], ()) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], resource) + self.assertEqual(result['virtual_root_path'], ()) + + def test_withroute_and_traverse_and_vroot(self): + abc = DummyContext() + resource = DummyContext(next=abc) + environ = self._getEnviron(HTTP_X_VHM_ROOT='/abc') + request = DummyRequest(environ) + traverser = self._makeOne(resource) + matchdict = {'traverse':text_('/foo/bar')} + request.matchdict = matchdict + result = traverser(request) + self.assertEqual(result['context'], abc) + self.assertEqual(result['view_name'], 'foo') + self.assertEqual(result['subpath'], ('bar',)) + self.assertEqual(result['traversed'], ('abc', 'foo')) + self.assertEqual(result['root'], resource) + self.assertEqual(result['virtual_root'], abc) + self.assertEqual(result['virtual_root_path'], ('abc',)) + +class FindInterfaceTests(unittest.TestCase): + def _callFUT(self, context, iface): + from pyramid.traversal import find_interface + return find_interface(context, iface) + + def test_it_interface(self): + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + root.__parent__ = None + root.__name__ = 'root' + foo.__parent__ = root + foo.__name__ = 'foo' + bar.__parent__ = foo + bar.__name__ = 'bar' + baz.__parent__ = bar + baz.__name__ = 'baz' + from zope.interface import directlyProvides + from zope.interface import Interface + class IFoo(Interface): + pass + directlyProvides(root, IFoo) + result = self._callFUT(baz, IFoo) + self.assertEqual(result.__name__, 'root') + + def test_it_class(self): + class DummyRoot(object): + def __init__(self, child): + self.child = child + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyRoot(foo) + root.__parent__ = None + root.__name__ = 'root' + foo.__parent__ = root + foo.__name__ = 'foo' + bar.__parent__ = foo + bar.__name__ = 'bar' + baz.__parent__ = bar + baz.__name__ = 'baz' + result = self._callFUT(baz, DummyRoot) + self.assertEqual(result.__name__, 'root') + +class FindRootTests(unittest.TestCase): + def _callFUT(self, context): + from pyramid.traversal import find_root + return find_root(context) + + def test_it(self): + dummy = DummyContext() + baz = DummyContext() + baz.__parent__ = dummy + baz.__name__ = 'baz' + dummy.__parent__ = None + dummy.__name__ = None + result = self._callFUT(baz) + self.assertEqual(result, dummy) + +class FindResourceTests(unittest.TestCase): + def _callFUT(self, context, name): + from pyramid.traversal import find_resource + return find_resource(context, name) + + def _registerTraverser(self, traverser): + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + from pyramid.interfaces import ITraverser + from zope.interface import Interface + reg.registerAdapter(traverser, (Interface,), ITraverser) + + def test_list(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, ['']) + self.assertEqual(result, resource) + self.assertEqual(resource.request.environ['PATH_INFO'], '/') + + def test_generator(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + def foo(): + yield '' + result = self._callFUT(resource, foo()) + self.assertEqual(result, resource) + self.assertEqual(resource.request.environ['PATH_INFO'], '/') + + def test_self_string_found(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, '') + self.assertEqual(result, resource) + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_self_tuple_found(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, ()) + self.assertEqual(result, resource) + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_relative_string_found(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, 'baz') + self.assertEqual(result, baz) + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_relative_tuple_found(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, ('baz',)) + self.assertEqual(result, baz) + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_relative_string_notfound(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':'bar'}) + self._registerTraverser(traverser) + self.assertRaises(KeyError, self._callFUT, resource, 'baz') + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_relative_tuple_notfound(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':'bar'}) + self._registerTraverser(traverser) + self.assertRaises(KeyError, self._callFUT, resource, ('baz',)) + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_absolute_string_found(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, '/') + self.assertEqual(result, root) + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_absolute_tuple_found(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(resource, ('',)) + self.assertEqual(result, root) + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_absolute_string_notfound(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':'fuz'}) + self._registerTraverser(traverser) + self.assertRaises(KeyError, self._callFUT, resource, '/') + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_absolute_tuple_notfound(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':'fuz'}) + self._registerTraverser(traverser) + self.assertRaises(KeyError, self._callFUT, resource, ('',)) + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_absolute_unicode_found(self): + # test for bug wiggy found in wild, traceback stack: + # root = u'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF' + # wiggy's code: section=find_resource(page, root) + # find_resource L76: D = traverse(resource, path) + # traverse L291: return traverser(request) + # __call__ line 568: vpath_tuple = traversal_path(vpath) + # lru_cached line 91: f(*arg) + # traversal_path line 443: path.encode('ascii') + # UnicodeEncodeError: 'ascii' codec can't encode characters in + # position 1-12: ordinal not in range(128) + # + # solution: encode string to ascii in pyramid.traversal.traverse + # before passing it along to webob as path_info + from pyramid.traversal import ResourceTreeTraverser + unprintable = DummyContext() + root = DummyContext(unprintable) + unprintable.__parent__ = root + unprintable.__name__ = text_( + b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8') + root.__parent__ = None + root.__name__ = None + traverser = ResourceTreeTraverser + self._registerTraverser(traverser) + result = self._callFUT( + root, + text_(b'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') + ) + self.assertEqual(result, unprintable) + +class ResourcePathTests(unittest.TestCase): + def _callFUT(self, resource, *elements): + from pyramid.traversal import resource_path + return resource_path(resource, *elements) + + def test_it(self): + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + root.__parent__ = None + root.__name__ = None + foo.__parent__ = root + foo.__name__ = 'foo ' + bar.__parent__ = foo + bar.__name__ = 'bar' + baz.__parent__ = bar + baz.__name__ = 'baz' + result = self._callFUT(baz, 'this/theotherthing', 'that') + self.assertEqual(result, '/foo%20/bar/baz/this%2Ftheotherthing/that') + + def test_root_default(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + result = self._callFUT(root) + self.assertEqual(result, '/') + + def test_root_default_emptystring(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = '' + result = self._callFUT(root) + self.assertEqual(result, '/') + + def test_root_object_nonnull_name_direct(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = 'flubadub' + result = self._callFUT(root) + self.assertEqual(result, 'flubadub') # insane case + + def test_root_object_nonnull_name_indirect(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = 'flubadub' + other = DummyContext() + other.__parent__ = root + other.__name__ = 'barker' + result = self._callFUT(other) + self.assertEqual(result, 'flubadub/barker') # insane case + + def test_nonroot_default(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + other = DummyContext() + other.__parent__ = root + other.__name__ = 'other' + result = self._callFUT(other) + self.assertEqual(result, '/other') + + def test_path_with_None_itermediate_names(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + other = DummyContext() + other.__parent__ = root + other.__name__ = None + other2 = DummyContext() + other2.__parent__ = other + other2.__name__ = 'other2' + result = self._callFUT(other2) + self.assertEqual(result, '//other2') + +class ResourcePathTupleTests(unittest.TestCase): + def _callFUT(self, resource, *elements): + from pyramid.traversal import resource_path_tuple + return resource_path_tuple(resource, *elements) + + def test_it(self): + baz = DummyContext() + bar = DummyContext(baz) + foo = DummyContext(bar) + root = DummyContext(foo) + root.__parent__ = None + root.__name__ = None + foo.__parent__ = root + foo.__name__ = 'foo ' + bar.__parent__ = foo + bar.__name__ = 'bar' + baz.__parent__ = bar + baz.__name__ = 'baz' + result = self._callFUT(baz, 'this/theotherthing', 'that') + self.assertEqual(result, ('','foo ', 'bar', 'baz', 'this/theotherthing', + 'that')) + + def test_root_default(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + result = self._callFUT(root) + self.assertEqual(result, ('',)) + + def test_root_default_emptystring_name(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = '' + other = DummyContext() + other.__parent__ = root + other.__name__ = 'other' + result = self._callFUT(other) + self.assertEqual(result, ('', 'other',)) + + def test_nonroot_default(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + other = DummyContext() + other.__parent__ = root + other.__name__ = 'other' + result = self._callFUT(other) + self.assertEqual(result, ('', 'other')) + + def test_path_with_None_itermediate_names(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + other = DummyContext() + other.__parent__ = root + other.__name__ = None + other2 = DummyContext() + other2.__parent__ = other + other2.__name__ = 'other2' + result = self._callFUT(other2) + self.assertEqual(result, ('', '', 'other2')) + +class QuotePathSegmentTests(unittest.TestCase): + def _callFUT(self, s): + from pyramid.traversal import quote_path_segment + return quote_path_segment(s) + + def test_unicode(self): + la = text_(b'/La Pe\xc3\xb1a', 'utf-8') + result = self._callFUT(la) + self.assertEqual(result, '%2FLa%20Pe%C3%B1a') + + def test_string(self): + s = '/ hello!' + result = self._callFUT(s) + self.assertEqual(result, '%2F%20hello!') + + def test_int(self): + s = 12345 + result = self._callFUT(s) + self.assertEqual(result, '12345') + + def test_long(self): + from pyramid.compat import long + import sys + s = long(sys.maxsize + 1) + result = self._callFUT(s) + expected = str(s) + self.assertEqual(result, expected) + + def test_other(self): + class Foo(object): + def __str__(self): + return 'abc' + s = Foo() + result = self._callFUT(s) + self.assertEqual(result, 'abc') + +class ResourceURLTests(unittest.TestCase): + def _makeOne(self, context, url): + return self._getTargetClass()(context, url) + + def _getTargetClass(self): + from pyramid.traversal import ResourceURL + return ResourceURL + + def test_instance_conforms_to_IResourceURL(self): + from pyramid.interfaces import IResourceURL + from zope.interface.verify import verifyObject + context = DummyContext() + request = DummyRequest() + verifyObject(IResourceURL, self._makeOne(context, request)) + + def test_IResourceURL_attributes_with_vroot(self): + from pyramid.interfaces import VH_ROOT_KEY + root = DummyContext() + root.__parent__ = None + root.__name__ = None + one = DummyContext() + one.__parent__ = root + one.__name__ = 'one' + two = DummyContext() + two.__parent__ = one + two.__name__ = 'two' + environ = {VH_ROOT_KEY:'/one'} + request = DummyRequest(environ) + context_url = self._makeOne(two, request) + self.assertEqual(context_url.physical_path, '/one/two/') + self.assertEqual(context_url.virtual_path, '/two/') + self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) + self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) + + def test_IResourceURL_attributes_vroot_ends_with_slash(self): + from pyramid.interfaces import VH_ROOT_KEY + root = DummyContext() + root.__parent__ = None + root.__name__ = None + one = DummyContext() + one.__parent__ = root + one.__name__ = 'one' + two = DummyContext() + two.__parent__ = one + two.__name__ = 'two' + environ = {VH_ROOT_KEY:'/one/'} + request = DummyRequest(environ) + context_url = self._makeOne(two, request) + self.assertEqual(context_url.physical_path, '/one/two/') + self.assertEqual(context_url.virtual_path, '/two/') + self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) + self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) + + def test_IResourceURL_attributes_no_vroot(self): + root = DummyContext() + root.__parent__ = None + root.__name__ = None + one = DummyContext() + one.__parent__ = root + one.__name__ = 'one' + two = DummyContext() + two.__parent__ = one + two.__name__ = 'two' + environ = {} + request = DummyRequest(environ) + context_url = self._makeOne(two, request) + self.assertEqual(context_url.physical_path, '/one/two/') + self.assertEqual(context_url.virtual_path, '/one/two/') + self.assertEqual(context_url.physical_path_tuple, ('', 'one', 'two','')) + self.assertEqual(context_url.virtual_path_tuple, ('', 'one', 'two', '')) + +class TestVirtualRoot(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, resource, request): + from pyramid.traversal import virtual_root + return virtual_root(resource, request) + + def _registerTraverser(self, traverser): + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + from pyramid.interfaces import ITraverser + from zope.interface import Interface + reg.registerAdapter(traverser, (Interface,), ITraverser) + + def test_virtual_root_no_virtual_root_path(self): + root = DummyContext() + root.__name__ = None + root.__parent__ = None + one = DummyContext() + one.__name__ = 'one' + one.__parent__ = root + request = DummyRequest() + result = self._callFUT(one, request) + self.assertEqual(result, root) + + def test_virtual_root_no_virtual_root_path_with_root_on_request(self): + context = DummyContext() + context.__parent__ = None + request = DummyRequest() + request.root = DummyContext() + result = self._callFUT(context, request) + self.assertEqual(result, request.root) + + def test_virtual_root_with_virtual_root_path(self): + from pyramid.interfaces import VH_ROOT_KEY + root = DummyContext() + root.__parent__ = None + context = DummyContext() + context.__name__ = 'one' + context.__parent__ = root + traversed_to = DummyContext() + environ = {VH_ROOT_KEY:'/one'} + request = DummyRequest(environ) + traverser = make_traverser({'context':traversed_to, 'view_name':''}) + self._registerTraverser(traverser) + result = self._callFUT(context, request) + self.assertEqual(result, traversed_to) + self.assertEqual(root.request.environ['PATH_INFO'], '/one') + + def test_default(self): + context = DummyContext() + request = _makeRequest() + request.environ['PATH_INFO'] = '/' + result = self._callFUT(context, request) + self.assertEqual(result, context) + + def test_default_no_registry_on_request(self): + context = DummyContext() + request = _makeRequest() + del request.registry + request.environ['PATH_INFO'] = '/' + result = self._callFUT(context, request) + self.assertEqual(result, context) + +class TraverseTests(unittest.TestCase): + def setUp(self): + cleanUp() + + def tearDown(self): + cleanUp() + + def _callFUT(self, context, name): + from pyramid.traversal import traverse + return traverse(context, name) + + def _registerTraverser(self, traverser): + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + from pyramid.interfaces import ITraverser + from zope.interface import Interface + reg.registerAdapter(traverser, (Interface,), ITraverser) + + def test_request_has_registry(self): + from pyramid.threadlocal import get_current_registry + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ['']) + self.assertEqual(resource.request.registry, get_current_registry()) + + def test_list(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ['']) + self.assertEqual(resource.request.environ['PATH_INFO'], '/') + + def test_generator(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + def foo(): + yield '' + self._callFUT(resource, foo()) + self.assertEqual(resource.request.environ['PATH_INFO'], '/') + + def test_self_string_found(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, '') + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_self_unicode_found(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, text_('')) + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_self_tuple_found(self): + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ()) + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_relative_string_found(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, 'baz') + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_relative_tuple_found(self): + resource = DummyContext() + baz = DummyContext() + traverser = make_traverser({'context':baz, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ('baz',)) + self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') + + def test_absolute_string_found(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, '/') + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_absolute_tuple_found(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ('',)) + self.assertEqual(root.wascontext, True) + self.assertEqual(root.request.environ['PATH_INFO'], '/') + + def test_empty_sequence(self): + root = DummyContext() + resource = DummyContext() + resource.__parent__ = root + resource.__name__ = 'baz' + traverser = make_traverser({'context':root, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, []) + self.assertEqual(resource.wascontext, True) + self.assertEqual(resource.request.environ['PATH_INFO'], '') + + def test_default_traverser(self): + resource = DummyContext() + result = self._callFUT(resource, '') + self.assertEqual(result['view_name'], '') + self.assertEqual(result['context'], resource) + + def test_requestfactory_overridden(self): + from pyramid.interfaces import IRequestFactory + from pyramid.request import Request + from pyramid.threadlocal import get_current_registry + reg = get_current_registry() + class MyRequest(Request): + pass + reg.registerUtility(MyRequest, IRequestFactory) + resource = DummyContext() + traverser = make_traverser({'context':resource, 'view_name':''}) + self._registerTraverser(traverser) + self._callFUT(resource, ['']) + self.assertEqual(resource.request.__class__, MyRequest) + +class TestDefaultRootFactory(unittest.TestCase): + def _getTargetClass(self): + from pyramid.traversal import DefaultRootFactory + return DefaultRootFactory + + def _makeOne(self, environ): + return self._getTargetClass()(environ) + + def test_it(self): + class DummyRequest(object): + pass + root = self._makeOne(DummyRequest()) + self.assertEqual(root.__parent__, None) + self.assertEqual(root.__name__, None) + +class Test__join_path_tuple(unittest.TestCase): + def _callFUT(self, tup): + from pyramid.traversal import _join_path_tuple + return _join_path_tuple(tup) + + def test_empty_tuple(self): + # tests "or '/'" case + result = self._callFUT(()) + self.assertEqual(result, '/') + + def test_nonempty_tuple(self): + result = self._callFUT(('x',)) + self.assertEqual(result, 'x') + + def test_segments_with_unsafes(self): + safe_segments = tuple(u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=:@") + result = self._callFUT(safe_segments) + self.assertEqual(result, u'/'.join(safe_segments)) + unsafe_segments = tuple(chr(i) for i in range(0x20, 0x80) if not chr(i) in safe_segments) + (u'あ',) + result = self._callFUT(unsafe_segments) + self.assertEqual(result, u'/'.join(''.join('%%%02X' % (ord(c) if isinstance(c, str) else c) for c in unsafe_segment.encode('utf-8')) for unsafe_segment in unsafe_segments)) + + +def make_traverser(result): + class DummyTraverser(object): + def __init__(self, context): + self.context = context + context.wascontext = True + def __call__(self, request): + self.context.request = request + return result + return DummyTraverser + +class DummyContext(object): + __parent__ = None + def __init__(self, next=None, name=None): + self.next = next + self.__name__ = name + + def __getitem__(self, name): + if self.next is None: + raise KeyError(name) + return self.next + + def __repr__(self): + return ''%(self.__name__, id(self)) + +class DummyRequest: + + application_url = 'http://example.com:5432' # app_url never ends with slash + matchdict = None + matched_route = None + + def __init__(self, environ=None, path_info=text_('/'), toraise=None): + if environ is None: + environ = {} + self.environ = environ + self._set_path_info(path_info) + self.toraise = toraise + + def _get_path_info(self): + if self.toraise: + raise self.toraise + return self._path_info + + def _set_path_info(self, v): + self._path_info = v + + path_info = property(_get_path_info, _set_path_info) + + +def _makeRequest(environ=None): + from pyramid.registry import Registry + request = DummyRequest() + request.registry = Registry() + return request diff --git a/tests/test_tweens.py b/tests/test_tweens.py new file mode 100644 index 000000000..2e74ad7cf --- /dev/null +++ b/tests/test_tweens.py @@ -0,0 +1,88 @@ +import unittest +from pyramid import testing + +class Test_excview_tween_factory(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, handler, registry=None): + from pyramid.tweens import excview_tween_factory + if registry is None: + registry = self.config.registry + return excview_tween_factory(handler, registry) + + def test_it_passthrough_no_exception(self): + dummy_response = DummyResponse() + def handler(request): + return dummy_response + tween = self._makeOne(handler) + request = DummyRequest() + result = tween(request) + self.assertTrue(result is dummy_response) + self.assertIsNone(request.exception) + self.assertIsNone(request.exc_info) + + def test_it_catches_notfound(self): + from pyramid.request import Request + from pyramid.httpexceptions import HTTPNotFound + self.config.add_notfound_view(lambda exc, request: exc) + def handler(request): + raise HTTPNotFound + tween = self._makeOne(handler) + request = Request.blank('/') + request.registry = self.config.registry + result = tween(request) + self.assertEqual(result.status, '404 Not Found') + self.assertIsInstance(request.exception, HTTPNotFound) + self.assertEqual(request.exception, request.exc_info[1]) + + def test_it_catches_with_predicate(self): + from pyramid.request import Request + from pyramid.response import Response + def excview(request): + return Response('foo') + self.config.add_view(excview, context=ValueError, request_method='GET') + def handler(request): + raise ValueError + tween = self._makeOne(handler) + request = Request.blank('/') + request.registry = self.config.registry + result = tween(request) + self.assertTrue(b'foo' in result.body) + self.assertIsInstance(request.exception, ValueError) + self.assertEqual(request.exception, request.exc_info[1]) + + def test_it_reraises_on_mismatch(self): + from pyramid.request import Request + def excview(request): pass + self.config.add_view(excview, context=ValueError, request_method='GET') + def handler(request): + raise ValueError + tween = self._makeOne(handler) + request = Request.blank('/') + request.registry = self.config.registry + request.method = 'POST' + self.assertRaises(ValueError, lambda: tween(request)) + self.assertIsNone(request.exception) + self.assertIsNone(request.exc_info) + + def test_it_reraises_on_no_match(self): + from pyramid.request import Request + def handler(request): + raise ValueError + tween = self._makeOne(handler) + request = Request.blank('/') + request.registry = self.config.registry + self.assertRaises(ValueError, lambda: tween(request)) + self.assertIsNone(request.exception) + self.assertIsNone(request.exc_info) + +class DummyRequest: + exception = None + exc_info = None + +class DummyResponse: + pass diff --git a/tests/test_url.py b/tests/test_url.py new file mode 100644 index 000000000..31b3dd571 --- /dev/null +++ b/tests/test_url.py @@ -0,0 +1,1352 @@ +import os +import unittest +import warnings + +from pyramid import testing + +from pyramid.compat import ( + text_, + WIN, + ) + +class TestURLMethodsMixin(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, environ=None): + from pyramid.url import URLMethodsMixin + if environ is None: + environ = {} + class Request(URLMethodsMixin): + application_url = 'http://example.com:5432' + script_name = '' + def __init__(self, environ): + self.environ = environ + request = Request(environ) + request.registry = self.config.registry + return request + + def _registerResourceURL(self, reg): + from pyramid.interfaces import IResourceURL + from zope.interface import Interface + class DummyResourceURL(object): + physical_path = '/context/' + virtual_path = '/context/' + def __init__(self, context, request): pass + reg.registerAdapter(DummyResourceURL, (Interface, Interface), + IResourceURL) + return DummyResourceURL + + def test_resource_url_root_default(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_url(root) + self.assertEqual(result, 'http://example.com:5432/context/') + + def test_resource_url_extra_args(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'this/theotherthing', 'that') + self.assertEqual( + result, + 'http://example.com:5432/context/this%2Ftheotherthing/that') + + def test_resource_url_unicode_in_element_names(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + uc = text_(b'La Pe\xc3\xb1a', 'utf-8') + context = DummyContext() + result = request.resource_url(context, uc) + self.assertEqual(result, + 'http://example.com:5432/context/La%20Pe%C3%B1a') + + def test_resource_url_at_sign_in_element_names(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, '@@myview') + self.assertEqual(result, + 'http://example.com:5432/context/@@myview') + + def test_resource_url_element_names_url_quoted(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a b c') + self.assertEqual(result, 'http://example.com:5432/context/a%20b%20c') + + def test_resource_url_with_query_str(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a', query='(openlayers)') + self.assertEqual(result, + 'http://example.com:5432/context/a?(openlayers)') + + def test_resource_url_with_query_dict(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + uc = text_(b'La Pe\xc3\xb1a', 'utf-8') + result = request.resource_url(context, 'a', query={'a':uc}) + self.assertEqual(result, + 'http://example.com:5432/context/a?a=La+Pe%C3%B1a') + + def test_resource_url_with_query_seq(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + uc = text_(b'La Pe\xc3\xb1a', 'utf-8') + result = request.resource_url(context, 'a', query=[('a', 'hi there'), + ('b', uc)]) + self.assertEqual(result, + 'http://example.com:5432/context/a?a=hi+there&b=La+Pe%C3%B1a') + + def test_resource_url_with_query_empty(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a', query=[]) + self.assertEqual(result, + 'http://example.com:5432/context/a') + + def test_resource_url_with_query_None(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a', query=None) + self.assertEqual(result, + 'http://example.com:5432/context/a') + + def test_resource_url_anchor_is_after_root_when_no_elements(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, anchor='a') + self.assertEqual(result, + 'http://example.com:5432/context/#a') + + def test_resource_url_anchor_is_after_elements_when_no_qs(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a', anchor='b') + self.assertEqual(result, + 'http://example.com:5432/context/a#b') + + def test_resource_url_anchor_is_after_qs_when_qs_is_present(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, 'a', + query={'b':'c'}, anchor='d') + self.assertEqual(result, + 'http://example.com:5432/context/a?b=c#d') + + def test_resource_url_anchor_is_encoded_utf8_if_unicode(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + uc = text_(b'La Pe\xc3\xb1a', 'utf-8') + result = request.resource_url(context, anchor=uc) + self.assertEqual(result, + 'http://example.com:5432/context/#La%20Pe%C3%B1a') + + def test_resource_url_anchor_is_urlencoded_safe(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, anchor=' /#?&+') + self.assertEqual(result, + 'http://example.com:5432/context/#%20/%23?&+') + + def test_resource_url_anchor_is_None(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + context = DummyContext() + result = request.resource_url(context, anchor=None) + self.assertEqual(result, 'http://example.com:5432/context/') + + def test_resource_url_no_IResourceURL_registered(self): + # falls back to ResourceURL + root = DummyContext() + root.__name__ = '' + root.__parent__ = None + request = self._makeOne() + request.environ = {} + result = request.resource_url(root) + self.assertEqual(result, 'http://example.com:5432/') + + def test_resource_url_no_registry_on_request(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + del request.registry + root = DummyContext() + result = request.resource_url(root) + self.assertEqual(result, 'http://example.com:5432/context/') + + def test_resource_url_with_app_url(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_url(root, app_url='http://somewhere.com') + self.assertEqual(result, 'http://somewhere.com/context/') + + def test_resource_url_with_scheme(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_url(root, scheme='https') + self.assertEqual(result, 'https://example.com/context/') + + def test_resource_url_with_host(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_url(root, host='someotherhost.com') + self.assertEqual(result, 'http://someotherhost.com:8080/context/') + + def test_resource_url_with_port(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_url(root, port='8181') + self.assertEqual(result, 'http://example.com:8181/context/') + + def test_resource_url_with_local_url(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + self._registerResourceURL(request.registry) + root = DummyContext() + def resource_url(req, info): + self.assertEqual(req, request) + self.assertEqual(info['virtual_path'], '/context/') + self.assertEqual(info['physical_path'], '/context/') + self.assertEqual(info['app_url'], 'http://example.com:5432') + return 'http://example.com/contextabc/' + root.__resource_url__ = resource_url + result = request.resource_url(root) + self.assertEqual(result, 'http://example.com/contextabc/') + + def test_resource_url_with_route_name_no_remainder_on_adapter(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # no virtual_path_tuple on adapter + adapter.virtual_path = '/a/b/c/' + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, route_name='foo') + self.assertEqual(result, 'http://example.com:5432/1/2/3') + self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) + + def test_resource_url_with_route_name_remainder_on_adapter(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, route_name='foo') + self.assertEqual(result, 'http://example.com:5432/1/2/3') + self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) + + def test_resource_url_with_route_name_and_app_url(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, route_name='foo', app_url='app_url') + self.assertEqual(result, 'app_url/1/2/3') + self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) + + def test_resource_url_with_route_name_and_scheme_host_port_etc(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, route_name='foo', scheme='scheme', + host='host', port='port', query={'a':'1'}, + anchor='anchor') + self.assertEqual(result, 'scheme://host:port/1/2/3?a=1#anchor') + self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) + + def test_resource_url_with_route_name_and_route_kwargs(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url( + root, route_name='foo', route_kw={'a':'1', 'b':'2'}) + self.assertEqual(result, 'http://example.com:5432/1/2/3') + self.assertEqual( + route.kw, + {'traverse': ('', 'a', 'b', 'c', ''), + 'a':'1', + 'b':'2'} + ) + + def test_resource_url_with_route_name_and_elements(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, 'e1', 'e2', route_name='foo') + self.assertEqual(result, 'http://example.com:5432/1/2/3/e1/e2') + self.assertEqual(route.kw, {'traverse': ('', 'a', 'b', 'c', '')}) + + def test_resource_url_with_route_name_and_remainder_name(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'8080', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + adapter = self._registerResourceURL(request.registry) + # virtual_path_tuple on adapter + adapter.virtual_path_tuple = ('', 'a', 'b', 'c', '') + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route) + request.registry.registerUtility(mapper, IRoutesMapper) + root = DummyContext() + result = request.resource_url(root, route_name='foo', + route_remainder_name='fred') + self.assertEqual(result, 'http://example.com:5432/1/2/3') + self.assertEqual(route.kw, {'fred': ('', 'a', 'b', 'c', '')}) + + def test_resource_path(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_path(root) + self.assertEqual(result, '/context/') + + def test_resource_path_kwarg(self): + request = self._makeOne() + self._registerResourceURL(request.registry) + root = DummyContext() + result = request.resource_path(root, anchor='abc') + self.assertEqual(result, '/context/#abc') + + def test_route_url_with_elements(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', 'extra1', 'extra2') + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2') + + def test_route_url_with_elements_path_endswith_slash(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3/')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', 'extra1', 'extra2') + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2') + + def test_route_url_no_elements(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', a=1, b=2, c=3, _query={'a':1}, + _anchor=text_(b"foo")) + self.assertEqual(result, + 'http://example.com:5432/1/2/3?a=1#foo') + + def test_route_url_with_query_None(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', a=1, b=2, c=3, _query=None) + self.assertEqual(result, 'http://example.com:5432/1/2/3') + + def test_route_url_with_anchor_binary(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _anchor=b"La Pe\xc3\xb1a") + + self.assertEqual(result, + 'http://example.com:5432/1/2/3#La%20Pe%C3%B1a') + + def test_route_url_with_anchor_unicode(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + anchor = text_(b'La Pe\xc3\xb1a', 'utf-8') + result = request.route_url('flub', _anchor=anchor) + + self.assertEqual(result, + 'http://example.com:5432/1/2/3#La%20Pe%C3%B1a') + + def test_route_url_with_anchor_None(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _anchor=None) + + self.assertEqual(result, 'http://example.com:5432/1/2/3') + + def test_route_url_with_query(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _query={'q':'1'}) + self.assertEqual(result, + 'http://example.com:5432/1/2/3?q=1') + + def test_route_url_with_query_str(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _query='(openlayers)') + self.assertEqual(result, + 'http://example.com:5432/1/2/3?(openlayers)') + + def test_route_url_with_empty_query(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _query={}) + self.assertEqual(result, + 'http://example.com:5432/1/2/3') + + def test_route_url_with_app_url(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _app_url='http://example2.com') + self.assertEqual(result, + 'http://example2.com/1/2/3') + + def test_route_url_with_host(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'5432', + } + request = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _host='someotherhost.com') + self.assertEqual(result, + 'http://someotherhost.com:5432/1/2/3') + + def test_route_url_with_port(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'5432', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _port='8080') + self.assertEqual(result, + 'http://example.com:8080/1/2/3') + + def test_route_url_with_scheme(self): + from pyramid.interfaces import IRoutesMapper + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_PORT':'5432', + 'SERVER_NAME':'example.com', + } + request = self._makeOne(environ) + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _scheme='https') + self.assertEqual(result, + 'https://example.com/1/2/3') + + def test_route_url_generation_error(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(raise_exc=KeyError) + request.registry.registerUtility(mapper, IRoutesMapper) + mapper.raise_exc = KeyError + self.assertRaises(KeyError, request.route_url, 'flub', request, a=1) + + def test_route_url_generate_doesnt_receive_query_or_anchor(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute(result='') + mapper = DummyRoutesMapper(route=route) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', _query=dict(name='some_name')) + self.assertEqual(route.kw, {}) # shouldnt have anchor/query + self.assertEqual(result, 'http://example.com:5432?name=some_name') + + def test_route_url_with_pregenerator(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute(result='/1/2/3') + def pregenerator(request, elements, kw): + return ('a',), {'_app_url':'http://example2.com'} + route.pregenerator = pregenerator + mapper = DummyRoutesMapper(route=route) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub') + self.assertEqual(result, 'http://example2.com/1/2/3/a') + self.assertEqual(route.kw, {}) # shouldnt have anchor/query + + def test_route_url_with_anchor_app_url_elements_and_query(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute(result='/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', 'element1', + _app_url='http://example2.com', + _anchor='anchor', _query={'q':'1'}) + self.assertEqual(result, + 'http://example2.com/1/2/3/element1?q=1#anchor') + + def test_route_url_integration_with_real_request(self): + # to try to replicate https://github.com/Pylons/pyramid/issues/213 + from pyramid.interfaces import IRoutesMapper + from pyramid.request import Request + request = Request.blank('/') + request.registry = self.config.registry + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_url('flub', 'extra1', 'extra2') + self.assertEqual(result, + 'http://localhost/1/2/3/extra1/extra2') + + + def test_current_route_url_current_request_has_no_route(self): + request = self._makeOne() + self.assertRaises(ValueError, request.current_route_url) + + def test_current_route_url_with_elements_query_and_anchor(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url('extra1', 'extra2', _query={'a':1}, + _anchor=text_(b"foo")) + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + + def test_current_route_url_with_route_name(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url('extra1', 'extra2', _query={'a':1}, + _anchor=text_(b"foo"), + _route_name='bar') + self.assertEqual(result, + 'http://example.com:5432/1/2/3/extra1/extra2?a=1#foo') + + def test_current_route_url_with_request_query(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict([('q', '123')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url() + self.assertEqual(result, + 'http://example.com:5432/1/2/3?q=123') + + def test_current_route_url_with_request_query_duplicate_entries(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict( + [('q', '123'), ('b', '2'), ('b', '2'), ('q', '456')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url() + self.assertEqual(result, + 'http://example.com:5432/1/2/3?q=123&b=2&b=2&q=456') + + def test_current_route_url_with_query_override(self): + from pyramid.interfaces import IRoutesMapper + from webob.multidict import GetDict + request = self._makeOne() + request.GET = GetDict([('q', '123')], {}) + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_url(_query={'a':1}) + self.assertEqual(result, + 'http://example.com:5432/1/2/3?a=1') + + def test_current_route_path(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + route = DummyRoute('/1/2/3') + mapper = DummyRoutesMapper(route=route) + request.matched_route = route + request.matchdict = {} + request.script_name = '/script_name' + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.current_route_path('extra1', 'extra2', _query={'a':1}, + _anchor=text_(b"foo")) + self.assertEqual(result, '/script_name/1/2/3/extra1/extra2?a=1#foo') + + def test_route_path_with_elements(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + request.script_name = '' + result = request.route_path('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=text_(b"foo")) + self.assertEqual(result, '/1/2/3/extra1/extra2?a=1#foo') + + def test_route_path_with_script_name(self): + from pyramid.interfaces import IRoutesMapper + request = self._makeOne() + request.script_name = '/foo' + mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3')) + request.registry.registerUtility(mapper, IRoutesMapper) + result = request.route_path('flub', 'extra1', 'extra2', + a=1, b=2, c=3, _query={'a':1}, + _anchor=text_(b"foo")) + self.assertEqual(result, '/foo/1/2/3/extra1/extra2?a=1#foo') + + def test_static_url_staticurlinfo_notfound(self): + request = self._makeOne() + self.assertRaises(ValueError, request.static_url, 'static/foo.css') + + def test_static_url_abspath(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + info = DummyStaticURLInfo('abc') + registry = request.registry + registry.registerUtility(info, IStaticURLInfo) + abspath = makeabs('static', 'foo.css') + result = request.static_url(abspath) + self.assertEqual(result, 'abc') + self.assertEqual(info.args, (makeabs('static', 'foo.css'), request, {})) + request = self._makeOne() + + def test_static_url_found_rel(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + info = DummyStaticURLInfo('abc') + request.registry.registerUtility(info, IStaticURLInfo) + result = request.static_url('static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, {}) ) + + def test_static_url_abs(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + info = DummyStaticURLInfo('abc') + request.registry.registerUtility(info, IStaticURLInfo) + result = request.static_url('pyramid.tests:static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, {}) ) + + def test_static_url_found_abs_no_registry_on_request(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + registry = request.registry + info = DummyStaticURLInfo('abc') + registry.registerUtility(info, IStaticURLInfo) + del request.registry + result = request.static_url('pyramid.tests:static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, {}) ) + + def test_static_url_abspath_integration_with_staticurlinfo(self): + from pyramid.interfaces import IStaticURLInfo + from pyramid.config.views import StaticURLInfo + info = StaticURLInfo() + here = os.path.abspath(os.path.dirname(__file__)) + info.add(self.config, 'absstatic', here) + request = self._makeOne() + registry = request.registry + registry.registerUtility(info, IStaticURLInfo) + abspath = os.path.join(here, 'test_url.py') + result = request.static_url(abspath) + self.assertEqual(result, + 'http://example.com:5432/absstatic/test_url.py') + + def test_static_url_noscheme_uses_scheme_from_request(self): + from pyramid.interfaces import IStaticURLInfo + from pyramid.config.views import StaticURLInfo + info = StaticURLInfo() + here = os.path.abspath(os.path.dirname(__file__)) + info.add(self.config, '//subdomain.example.com/static', here) + request = self._makeOne({'wsgi.url_scheme': 'https'}) + registry = request.registry + registry.registerUtility(info, IStaticURLInfo) + abspath = os.path.join(here, 'test_url.py') + result = request.static_url(abspath) + self.assertEqual(result, + 'https://subdomain.example.com/static/test_url.py') + + def test_static_path_abspath(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + request.script_name = '/foo' + info = DummyStaticURLInfo('abc') + registry = request.registry + registry.registerUtility(info, IStaticURLInfo) + abspath = makeabs('static', 'foo.css') + result = request.static_path(abspath) + self.assertEqual(result, 'abc') + self.assertEqual(info.args, (makeabs('static', 'foo.css'), request, + {'_app_url':'/foo'}) + ) + + def test_static_path_found_rel(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + request.script_name = '/foo' + info = DummyStaticURLInfo('abc') + request.registry.registerUtility(info, IStaticURLInfo) + result = request.static_path('static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, + {'_app_url':'/foo'}) + ) + + def test_static_path_abs(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + request.script_name = '/foo' + info = DummyStaticURLInfo('abc') + request.registry.registerUtility(info, IStaticURLInfo) + result = request.static_path('pyramid.tests:static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, + {'_app_url':'/foo'}) + ) + + def test_static_path(self): + from pyramid.interfaces import IStaticURLInfo + request = self._makeOne() + request.script_name = '/foo' + info = DummyStaticURLInfo('abc') + request.registry.registerUtility(info, IStaticURLInfo) + result = request.static_path('static/foo.css') + self.assertEqual(result, 'abc') + self.assertEqual(info.args, + ('pyramid.tests:static/foo.css', request, + {'_app_url':'/foo'}) + ) + + def test_partial_application_url_with_http_host_default_port_http(self): + environ = { + 'wsgi.url_scheme':'http', + 'HTTP_HOST':'example.com:80', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'http://example.com') + + def test_partial_application_url_with_http_host_default_port_https(self): + environ = { + 'wsgi.url_scheme':'https', + 'HTTP_HOST':'example.com:443', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'https://example.com') + + def test_partial_application_url_with_http_host_nondefault_port_http(self): + environ = { + 'wsgi.url_scheme':'http', + 'HTTP_HOST':'example.com:8080', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'http://example.com:8080') + + def test_partial_application_url_with_http_host_nondefault_port_https(self): + environ = { + 'wsgi.url_scheme':'https', + 'HTTP_HOST':'example.com:4443', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'https://example.com:4443') + + def test_partial_application_url_with_http_host_no_colon(self): + environ = { + 'wsgi.url_scheme':'http', + 'HTTP_HOST':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'http://example.com') + + def test_partial_application_url_no_http_host(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url() + self.assertEqual(result, 'http://example.com') + + def test_partial_application_replace_port(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url(port=8080) + self.assertEqual(result, 'http://example.com:8080') + + def test_partial_application_replace_scheme_https_special_case(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url(scheme='https') + self.assertEqual(result, 'https://example.com') + + def test_partial_application_replace_scheme_https_special_case_avoid(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url(scheme='https', port='8080') + self.assertEqual(result, 'https://example.com:8080') + + def test_partial_application_replace_scheme_http_special_case(self): + environ = { + 'wsgi.url_scheme':'https', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'8080', + } + request = self._makeOne(environ) + result = request._partial_application_url(scheme='http') + self.assertEqual(result, 'http://example.com') + + def test_partial_application_replace_scheme_http_special_case_avoid(self): + environ = { + 'wsgi.url_scheme':'https', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'8000', + } + request = self._makeOne(environ) + result = request._partial_application_url(scheme='http', port='8080') + self.assertEqual(result, 'http://example.com:8080') + + def test_partial_application_replace_host_no_port(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url(host='someotherhost.com') + self.assertEqual(result, 'http://someotherhost.com') + + def test_partial_application_replace_host_with_port(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'8000', + } + request = self._makeOne(environ) + result = request._partial_application_url(host='someotherhost.com:8080') + self.assertEqual(result, 'http://someotherhost.com:8080') + + def test_partial_application_replace_host_and_port(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url(host='someotherhost.com:8080', + port='8000') + self.assertEqual(result, 'http://someotherhost.com:8000') + + def test_partial_application_replace_host_port_and_scheme(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'80', + } + request = self._makeOne(environ) + result = request._partial_application_url( + host='someotherhost.com:8080', + port='8000', + scheme='https', + ) + self.assertEqual(result, 'https://someotherhost.com:8000') + + def test_partial_application_url_with_custom_script_name(self): + environ = { + 'wsgi.url_scheme':'http', + 'SERVER_NAME':'example.com', + 'SERVER_PORT':'8000', + } + request = self._makeOne(environ) + request.script_name = '/abc' + result = request._partial_application_url() + self.assertEqual(result, 'http://example.com:8000/abc') + +class Test_route_url(unittest.TestCase): + def _callFUT(self, route_name, request, *elements, **kw): + from pyramid.url import route_url + return route_url(route_name, request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def route_url(self, route_name, *elements, **kw): + self.route_name = route_name + self.elements = elements + self.kw = kw + return 'route url' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT('abc', request, 'a', _app_url='') + self.assertEqual(result, 'route url') + self.assertEqual(request.route_name, 'abc') + self.assertEqual(request.elements, ('a',)) + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_route_path(unittest.TestCase): + def _callFUT(self, route_name, request, *elements, **kw): + from pyramid.url import route_path + return route_path(route_name, request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def route_path(self, route_name, *elements, **kw): + self.route_name = route_name + self.elements = elements + self.kw = kw + return 'route path' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT('abc', request, 'a', _app_url='') + self.assertEqual(result, 'route path') + self.assertEqual(request.route_name, 'abc') + self.assertEqual(request.elements, ('a',)) + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_resource_url(unittest.TestCase): + def _callFUT(self, resource, request, *elements, **kw): + from pyramid.url import resource_url + return resource_url(resource, request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def resource_url(self, resource, *elements, **kw): + self.resource = resource + self.elements = elements + self.kw = kw + return 'resource url' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT('abc', request, 'a', _app_url='') + self.assertEqual(result, 'resource url') + self.assertEqual(request.resource, 'abc') + self.assertEqual(request.elements, ('a',)) + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_static_url(unittest.TestCase): + def _callFUT(self, path, request, **kw): + from pyramid.url import static_url + return static_url(path, request, **kw) + + def _makeRequest(self): + class Request(object): + def static_url(self, path, **kw): + self.path = path + self.kw = kw + return 'static url' + return Request() + + def test_it_abs(self): + request = self._makeRequest() + result = self._callFUT('/foo/bar/abc', request, _app_url='') + self.assertEqual(result, 'static url') + self.assertEqual(request.path, '/foo/bar/abc') + self.assertEqual(request.kw, {'_app_url':''}) + + def test_it_absspec(self): + request = self._makeRequest() + result = self._callFUT('foo:abc', request, _anchor='anchor') + self.assertEqual(result, 'static url') + self.assertEqual(request.path, 'foo:abc') + self.assertEqual(request.kw, {'_anchor':'anchor'}) + + def test_it_rel(self): + request = self._makeRequest() + result = self._callFUT('abc', request, _app_url='') + self.assertEqual(result, 'static url') + self.assertEqual(request.path, 'pyramid.tests:abc') + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_static_path(unittest.TestCase): + def _callFUT(self, path, request, **kw): + from pyramid.url import static_path + return static_path(path, request, **kw) + + def _makeRequest(self): + class Request(object): + def static_path(self, path, **kw): + self.path = path + self.kw = kw + return 'static path' + return Request() + + def test_it_abs(self): + request = self._makeRequest() + result = self._callFUT('/foo/bar/abc', request, _anchor='anchor') + self.assertEqual(result, 'static path') + self.assertEqual(request.path, '/foo/bar/abc') + self.assertEqual(request.kw, {'_anchor':'anchor'}) + + def test_it_absspec(self): + request = self._makeRequest() + result = self._callFUT('foo:abc', request, _anchor='anchor') + self.assertEqual(result, 'static path') + self.assertEqual(request.path, 'foo:abc') + self.assertEqual(request.kw, {'_anchor':'anchor'}) + + def test_it_rel(self): + request = self._makeRequest() + result = self._callFUT('abc', request, _app_url='') + self.assertEqual(result, 'static path') + self.assertEqual(request.path, 'pyramid.tests:abc') + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_current_route_url(unittest.TestCase): + def _callFUT(self, request, *elements, **kw): + from pyramid.url import current_route_url + return current_route_url(request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def current_route_url(self, *elements, **kw): + self.elements = elements + self.kw = kw + return 'current route url' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT(request, 'abc', _app_url='') + self.assertEqual(result, 'current route url') + self.assertEqual(request.elements, ('abc',)) + self.assertEqual(request.kw, {'_app_url':''}) + +class Test_current_route_path(unittest.TestCase): + def _callFUT(self, request, *elements, **kw): + from pyramid.url import current_route_path + return current_route_path(request, *elements, **kw) + + def _makeRequest(self): + class Request(object): + def current_route_path(self, *elements, **kw): + self.elements = elements + self.kw = kw + return 'current route path' + return Request() + + def test_it(self): + request = self._makeRequest() + result = self._callFUT(request, 'abc', _anchor='abc') + self.assertEqual(result, 'current route path') + self.assertEqual(request.elements, ('abc',)) + self.assertEqual(request.kw, {'_anchor':'abc'}) + +class Test_external_static_url_integration(unittest.TestCase): + + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeRequest(self): + from pyramid.request import Request + return Request.blank('/') + + def test_generate_external_url(self): + self.config.add_route('acme', 'https://acme.org/path/{foo}') + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'https://acme.org/path/bar') + + def test_generate_external_url_without_scheme(self): + self.config.add_route('acme', '//acme.org/path/{foo}') + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'http://acme.org/path/bar') + + def test_generate_external_url_with_explicit_scheme(self): + self.config.add_route('acme', '//acme.org/path/{foo}') + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar', _scheme='https'), + 'https://acme.org/path/bar') + + def test_generate_external_url_with_explicit_app_url(self): + self.config.add_route('acme', 'http://acme.org/path/{foo}') + request = self._makeRequest() + request.registry = self.config.registry + self.assertRaises(ValueError, + request.route_url, 'acme', foo='bar', _app_url='http://fakeme.com') + + def test_generate_external_url_route_path(self): + self.config.add_route('acme', 'https://acme.org/path/{foo}') + request = self._makeRequest() + request.registry = self.config.registry + self.assertRaises(ValueError, request.route_path, 'acme', foo='bar') + + def test_generate_external_url_with_pregenerator(self): + def pregenerator(request, elements, kw): + kw['_query'] = {'q': 'foo'} + return elements, kw + self.config.add_route('acme', 'https://acme.org/path/{foo}', + pregenerator=pregenerator) + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'https://acme.org/path/bar?q=foo') + + def test_external_url_with_route_prefix(self): + def includeme(config): + config.add_route('acme', '//acme.org/{foo}') + self.config.include(includeme, route_prefix='some_prefix') + request = self._makeRequest() + request.registry = self.config.registry + self.assertEqual( + request.route_url('acme', foo='bar'), + 'http://acme.org/bar') + +class Test_with_route_prefix(unittest.TestCase): + + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeRequest(self, route): + from pyramid.request import Request + return Request.blank(route) + + def test_old_route_is_preserved(self): + self.config.route_prefix = 'old_prefix' + with self.config.route_prefix_context('new_addon'): + assert 'new_addon' in self.config.route_prefix + + assert 'old_prefix' == self.config.route_prefix + + def test_route_prefix_none(self): + self.config.route_prefix = 'old_prefix' + with self.config.route_prefix_context(None): + assert 'old_prefix' == self.config.route_prefix + + assert 'old_prefix' == self.config.route_prefix + + def test_route_prefix_empty(self): + self.config.route_prefix = 'old_prefix' + with self.config.route_prefix_context(''): + assert 'old_prefix' == self.config.route_prefix + + assert 'old_prefix' == self.config.route_prefix + + def test_route_has_prefix(self): + with self.config.route_prefix_context('bar'): + self.config.add_route('acme', '/foo') + request = self._makeRequest('/') + self.assertEqual( + request.route_url('acme'), + 'http://localhost/bar/foo', + ) + + def test_route_does_not_have_prefix(self): + with self.config.route_prefix_context('bar'): + pass + + self.config.add_route('acme', '/foo') + request = self._makeRequest('/') + self.assertEqual( + request.route_url('acme'), + 'http://localhost/foo', + ) + + def test_error_reset_prefix(self): + self.config.route_prefix = 'old_prefix' + + try: + with self.config.route_prefix_context('new_prefix'): + raise RuntimeError + except RuntimeError: + pass + + assert self.config.route_prefix == 'old_prefix' + +class DummyContext(object): + def __init__(self, next=None): + self.next = next + +class DummyRoutesMapper: + raise_exc = None + def __init__(self, route=None, raise_exc=False): + self.route = route + + def get_route(self, route_name): + return self.route + +class DummyRoute: + pregenerator = None + name = 'route' + def __init__(self, result='/1/2/3'): + self.result = result + + def generate(self, kw): + self.kw = kw + return self.result + +class DummyStaticURLInfo: + def __init__(self, result): + self.result = result + + def generate(self, path, request, **kw): + self.args = path, request, kw + return self.result + +def makeabs(*elements): + if WIN: # pragma: no cover + return r'c:\\' + os.path.sep.join(elements) + else: + return os.path.sep + os.path.sep.join(elements) diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py new file mode 100644 index 000000000..06f4ad793 --- /dev/null +++ b/tests/test_urldispatch.py @@ -0,0 +1,539 @@ +import unittest +from pyramid import testing +from pyramid.compat import ( + text_, + PY2, + ) + +class TestRoute(unittest.TestCase): + def _getTargetClass(self): + from pyramid.urldispatch import Route + return Route + + def _makeOne(self, *arg): + return self._getTargetClass()(*arg) + + def test_provides_IRoute(self): + from pyramid.interfaces import IRoute + from zope.interface.verify import verifyObject + verifyObject(IRoute, self._makeOne('name', 'pattern')) + + def test_ctor(self): + import types + route = self._makeOne('name', ':path', 'factory') + self.assertEqual(route.pattern, ':path') + self.assertEqual(route.path, ':path') + self.assertEqual(route.name, 'name') + self.assertEqual(route.factory, 'factory') + self.assertTrue(route.generate.__class__ is types.FunctionType) + self.assertTrue(route.match.__class__ is types.FunctionType) + + def test_ctor_defaults(self): + import types + route = self._makeOne('name', ':path') + self.assertEqual(route.pattern, ':path') + self.assertEqual(route.path, ':path') + self.assertEqual(route.name, 'name') + self.assertEqual(route.factory, None) + self.assertTrue(route.generate.__class__ is types.FunctionType) + self.assertTrue(route.match.__class__ is types.FunctionType) + + def test_match(self): + route = self._makeOne('name', ':path') + self.assertEqual(route.match('/whatever'), {'path':'whatever'}) + + def test_generate(self): + route = self._makeOne('name', ':path') + self.assertEqual(route.generate({'path':'abc'}), '/abc') + +class RoutesMapperTests(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _getRequest(self, **kw): + from pyramid.threadlocal import get_current_registry + environ = {'SERVER_NAME':'localhost', + 'wsgi.url_scheme':'http'} + environ.update(kw) + request = DummyRequest(environ) + reg = get_current_registry() + request.registry = reg + return request + + def _getTargetClass(self): + from pyramid.urldispatch import RoutesMapper + return RoutesMapper + + def _makeOne(self): + klass = self._getTargetClass() + return klass() + + def test_provides_IRoutesMapper(self): + from pyramid.interfaces import IRoutesMapper + from zope.interface.verify import verifyObject + verifyObject(IRoutesMapper, self._makeOne()) + + def test_no_route_matches(self): + mapper = self._makeOne() + request = self._getRequest(PATH_INFO='/') + result = mapper(request) + self.assertEqual(result['match'], None) + self.assertEqual(result['route'], None) + + def test_connect_name_exists_removes_old(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/:article') + mapper.connect('foo', 'archives/:action/:article2') + self.assertEqual(len(mapper.routelist), 1) + self.assertEqual(len(mapper.routes), 1) + self.assertEqual(mapper.routes['foo'].pattern, + 'archives/:action/:article2') + self.assertEqual(mapper.routelist[0].pattern, + 'archives/:action/:article2') + + def test_connect_static(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/:article', static=True) + self.assertEqual(len(mapper.routelist), 0) + self.assertEqual(len(mapper.routes), 1) + self.assertEqual(mapper.routes['foo'].pattern, + 'archives/:action/:article') + + def test_connect_static_overridden(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/:article', static=True) + self.assertEqual(len(mapper.routelist), 0) + self.assertEqual(len(mapper.routes), 1) + self.assertEqual(mapper.routes['foo'].pattern, + 'archives/:action/:article') + mapper.connect('foo', 'archives/:action/:article2') + self.assertEqual(len(mapper.routelist), 1) + self.assertEqual(len(mapper.routes), 1) + self.assertEqual(mapper.routes['foo'].pattern, + 'archives/:action/:article2') + self.assertEqual(mapper.routelist[0].pattern, + 'archives/:action/:article2') + + def test___call__pathinfo_cant_be_decoded(self): + from pyramid.exceptions import URLDecodeError + mapper = self._makeOne() + if PY2: + path_info = b'\xff\xfe\xe6\x00' + else: + path_info = b'\xff\xfe\xe6\x00'.decode('latin-1') + request = self._getRequest(PATH_INFO=path_info) + self.assertRaises(URLDecodeError, mapper, request) + + def test___call__route_matches(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/:article') + request = self._getRequest(PATH_INFO='/archives/action1/article1') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['foo']) + self.assertEqual(result['match']['action'], 'action1') + self.assertEqual(result['match']['article'], 'article1') + + def test___call__route_matches_with_predicates(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/:article', + predicates=[lambda *arg: True]) + request = self._getRequest(PATH_INFO='/archives/action1/article1') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['foo']) + self.assertEqual(result['match']['action'], 'action1') + self.assertEqual(result['match']['article'], 'article1') + + def test___call__route_fails_to_match_with_predicates(self): + mapper = self._makeOne() + mapper.connect('foo', 'archives/:action/article1', + predicates=[lambda *arg: True, lambda *arg: False]) + mapper.connect('bar', 'archives/:action/:article') + request = self._getRequest(PATH_INFO='/archives/action1/article1') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['bar']) + self.assertEqual(result['match']['action'], 'action1') + self.assertEqual(result['match']['article'], 'article1') + + def test___call__custom_predicate_gets_info(self): + mapper = self._makeOne() + def pred(info, request): + self.assertEqual(info['match'], {'action':'action1'}) + self.assertEqual(info['route'], mapper.routes['foo']) + return True + mapper.connect('foo', 'archives/:action/article1', predicates=[pred]) + request = self._getRequest(PATH_INFO='/archives/action1/article1') + mapper(request) + + def test_cc_bug(self): + # "unordered" as reported in IRC by author of + # http://labs.creativecommons.org/2010/01/13/cc-engine-and-web-non-frameworks/ + mapper = self._makeOne() + mapper.connect('rdf', 'licenses/:license_code/:license_version/rdf') + mapper.connect('juri', + 'licenses/:license_code/:license_version/:jurisdiction') + + request = self._getRequest(PATH_INFO='/licenses/1/v2/rdf') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['rdf']) + self.assertEqual(result['match']['license_code'], '1') + self.assertEqual(result['match']['license_version'], 'v2') + + request = self._getRequest(PATH_INFO='/licenses/1/v2/usa') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['juri']) + self.assertEqual(result['match']['license_code'], '1') + self.assertEqual(result['match']['license_version'], 'v2') + self.assertEqual(result['match']['jurisdiction'], 'usa') + + def test___call__root_route_matches(self): + mapper = self._makeOne() + mapper.connect('root', '') + request = self._getRequest(PATH_INFO='/') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + + def test___call__root_route_matches2(self): + mapper = self._makeOne() + mapper.connect('root', '/') + request = self._getRequest(PATH_INFO='/') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + + def test___call__root_route_when_path_info_empty(self): + mapper = self._makeOne() + mapper.connect('root', '/') + request = self._getRequest(PATH_INFO='') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + + def test___call__root_route_when_path_info_notempty(self): + mapper = self._makeOne() + mapper.connect('root', '/') + request = self._getRequest(PATH_INFO='/') + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + + def test___call__no_path_info(self): + mapper = self._makeOne() + mapper.connect('root', '/') + request = self._getRequest() + result = mapper(request) + self.assertEqual(result['route'], mapper.routes['root']) + self.assertEqual(result['match'], {}) + + def test_has_routes(self): + mapper = self._makeOne() + self.assertEqual(mapper.has_routes(), False) + mapper.connect('whatever', 'archives/:action/:article') + self.assertEqual(mapper.has_routes(), True) + + def test_get_routes(self): + from pyramid.urldispatch import Route + mapper = self._makeOne() + self.assertEqual(mapper.get_routes(), []) + mapper.connect('whatever', 'archives/:action/:article') + routes = mapper.get_routes() + self.assertEqual(len(routes), 1) + self.assertEqual(routes[0].__class__, Route) + + def test_get_route_matches(self): + mapper = self._makeOne() + mapper.connect('whatever', 'archives/:action/:article') + result = mapper.get_route('whatever') + self.assertEqual(result.pattern, 'archives/:action/:article') + + def test_get_route_misses(self): + mapper = self._makeOne() + result = mapper.get_route('whatever') + self.assertEqual(result, None) + + def test_generate(self): + mapper = self._makeOne() + def generator(kw): + return 123 + route = DummyRoute(generator) + mapper.routes['abc'] = route + self.assertEqual(mapper.generate('abc', {}), 123) + +class TestCompileRoute(unittest.TestCase): + def _callFUT(self, pattern): + from pyramid.urldispatch import _compile_route + return _compile_route(pattern) + + def test_no_star(self): + matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar') + self.assertEqual(matcher('/foo/baz/biz/buz/bar'), + {'baz':'baz', 'buz':'buz'}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + + def test_with_star(self): + matcher, generator = self._callFUT('/foo/:baz/biz/:buz/bar*traverse') + self.assertEqual(matcher('/foo/baz/biz/buz/bar'), + {'baz':'baz', 'buz':'buz', 'traverse':()}) + self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), + {'baz':'baz', 'buz':'buz', + 'traverse':('everything', 'else', 'here')}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator( + {'baz':1, 'buz':2, 'traverse':'/a/b'}), '/foo/1/biz/2/bar/a/b') + + def test_with_bracket_star(self): + matcher, generator = self._callFUT( + '/foo/{baz}/biz/{buz}/bar{remainder:.*}') + self.assertEqual(matcher('/foo/baz/biz/buz/bar'), + {'baz':'baz', 'buz':'buz', 'remainder':''}) + self.assertEqual(matcher('/foo/baz/biz/buz/bar/everything/else/here'), + {'baz':'baz', 'buz':'buz', + 'remainder':'/everything/else/here'}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator( + {'baz':1, 'buz':2, 'remainder':'/a/b'}), '/foo/1/biz/2/bar/a/b') + + def test_no_beginning_slash(self): + matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar') + self.assertEqual(matcher('/foo/baz/biz/buz/bar'), + {'baz':'baz', 'buz':'buz'}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + + def test_custom_regex(self): + matcher, generator = self._callFUT('foo/{baz}/biz/{buz:[^/\.]+}.{bar}') + self.assertEqual(matcher('/foo/baz/biz/buz.bar'), + {'baz':'baz', 'buz':'buz', 'bar':'bar'}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), + '/foo/1/biz/2.html') + + def test_custom_regex_with_colons(self): + matcher, generator = self._callFUT('foo/{baz}/biz/{buz:(?:[^/\.]+)}.{bar}') + self.assertEqual(matcher('/foo/baz/biz/buz.bar'), + {'baz':'baz', 'buz':'buz', 'bar':'bar'}) + self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) + self.assertEqual(generator({'baz':1, 'buz':2, 'bar': 'html'}), + '/foo/1/biz/2.html') + + def test_mixed_newstyle_oldstyle_pattern_defaults_to_newstyle(self): + # pattern: '\\/foo\\/(?Pabc)\\/biz\\/(?P[^/]+)\\/bar$' + # note presence of :abc in pattern (oldstyle match) + matcher, generator = self._callFUT('foo/{baz:abc}/biz/{buz}/bar') + self.assertEqual(matcher('/foo/abc/biz/buz/bar'), + {'baz':'abc', 'buz':'buz'}) + self.assertEqual(generator({'baz':1, 'buz':2}), '/foo/1/biz/2/bar') + + def test_custom_regex_with_embedded_squigglies(self): + matcher, generator = self._callFUT('/{buz:\d{4}}') + self.assertEqual(matcher('/2001'), {'buz':'2001'}) + self.assertEqual(matcher('/200'), None) + self.assertEqual(generator({'buz':2001}), '/2001') + + def test_custom_regex_with_embedded_squigglies2(self): + matcher, generator = self._callFUT('/{buz:\d{3,4}}') + self.assertEqual(matcher('/2001'), {'buz':'2001'}) + self.assertEqual(matcher('/200'), {'buz':'200'}) + self.assertEqual(matcher('/20'), None) + self.assertEqual(generator({'buz':2001}), '/2001') + + def test_custom_regex_with_embedded_squigglies3(self): + matcher, generator = self._callFUT( + '/{buz:(\d{2}|\d{4})-[a-zA-Z]{3,4}-\d{2}}') + self.assertEqual(matcher('/2001-Nov-15'), {'buz':'2001-Nov-15'}) + self.assertEqual(matcher('/99-June-10'), {'buz':'99-June-10'}) + self.assertEqual(matcher('/2-Nov-15'), None) + self.assertEqual(matcher('/200-Nov-15'), None) + self.assertEqual(matcher('/2001-No-15'), None) + self.assertEqual(generator({'buz':'2001-Nov-15'}), '/2001-Nov-15') + self.assertEqual(generator({'buz':'99-June-10'}), '/99-June-10') + + def test_pattern_with_high_order_literal(self): + pattern = text_(b'/La Pe\xc3\xb1a/{x}', 'utf-8') + matcher, generator = self._callFUT(pattern) + self.assertEqual(matcher(text_(b'/La Pe\xc3\xb1a/x', 'utf-8')), + {'x':'x'}) + self.assertEqual(generator({'x':'1'}), '/La%20Pe%C3%B1a/1') + + def test_pattern_generate_with_high_order_dynamic(self): + pattern = '/{x}' + _, generator = self._callFUT(pattern) + self.assertEqual( + generator({'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}), + '/La%20Pe%C3%B1a') + + def test_docs_sample_generate(self): + # sample from urldispatch.rst + pattern = text_(b'/La Pe\xc3\xb1a/{city}', 'utf-8') + _, generator = self._callFUT(pattern) + self.assertEqual( + generator({'city':text_(b'Qu\xc3\xa9bec', 'utf-8')}), + '/La%20Pe%C3%B1a/Qu%C3%A9bec') + + def test_generate_with_mixedtype_values(self): + pattern = '/{city}/{state}' + _, generator = self._callFUT(pattern) + result = generator( + {'city': text_(b'Qu\xc3\xa9bec', 'utf-8'), + 'state': b'La Pe\xc3\xb1a'} + ) + self.assertEqual(result, '/Qu%C3%A9bec/La%20Pe%C3%B1a') + # should be a native string + self.assertEqual(type(result), str) + + def test_highorder_pattern_utf8(self): + pattern = b'/La Pe\xc3\xb1a/{city}' + self.assertRaises(ValueError, self._callFUT, pattern) + + def test_generate_with_string_remainder_and_unicode_replacement(self): + pattern = text_(b'/abc*remainder', 'utf-8') + _, generator = self._callFUT(pattern) + result = generator( + {'remainder': text_(b'/Qu\xc3\xa9bec/La Pe\xc3\xb1a', 'utf-8')} + ) + self.assertEqual(result, '/abc/Qu%C3%A9bec/La%20Pe%C3%B1a') + # should be a native string + self.assertEqual(type(result), str) + + def test_generate_with_string_remainder_and_nonstring_replacement(self): + pattern = text_(b'/abc/*remainder', 'utf-8') + _, generator = self._callFUT(pattern) + result = generator( + {'remainder': None} + ) + self.assertEqual(result, '/abc/None') + # should be a native string + self.assertEqual(type(result), str) + +class TestCompileRouteFunctional(unittest.TestCase): + def matches(self, pattern, path, expected): + from pyramid.urldispatch import _compile_route + matcher = _compile_route(pattern)[0] + result = matcher(path) + self.assertEqual(result, expected) + + def generates(self, pattern, dict, result): + from pyramid.urldispatch import _compile_route + self.assertEqual(_compile_route(pattern)[1](dict), result) + + def test_matcher_functional_notdynamic(self): + self.matches('/', '', None) + self.matches('', '', None) + self.matches('/', '/foo', None) + self.matches('/foo/', '/foo', None) + self.matches('', '/', {}) + self.matches('/', '/', {}) + + def test_matcher_functional_newstyle(self): + self.matches('/{x}', '', None) + self.matches('/{x}', '/', None) + self.matches('/abc/{def}', '/abc/', None) + self.matches('/{x}', '/a', {'x':'a'}) + self.matches('zzz/{x}', '/zzz/abc', {'x':'abc'}) + self.matches('zzz/{x}*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) + self.matches('zzz/{x}*traverse', '/zzz/abc/def/g', + {'x':'abc', 'traverse':('def', 'g')}) + self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) + self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) + #'/La%20Pe%C3%B1a' + self.matches('{x}', text_(b'/La Pe\xc3\xb1a', 'utf-8'), + {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) + # '/La%20Pe%C3%B1a/x' + self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x'), + {'traverse':(text_(b'La Pe\xc3\xb1a'), 'x')}) + self.matches('/foo/{id}.html', '/foo/bar.html', {'id':'bar'}) + self.matches('/{num:[0-9]+}/*traverse', '/555/abc/def', + {'num':'555', 'traverse':('abc', 'def')}) + self.matches('/{num:[0-9]*}/*traverse', '/555/abc/def', + {'num':'555', 'traverse':('abc', 'def')}) + self.matches('zzz/{_}', '/zzz/abc', {'_':'abc'}) + self.matches('zzz/{_abc}', '/zzz/abc', {'_abc':'abc'}) + self.matches('zzz/{abc_def}', '/zzz/abc', {'abc_def':'abc'}) + + def test_matcher_functional_oldstyle(self): + self.matches('/:x', '', None) + self.matches('/:x', '/', None) + self.matches('/abc/:def', '/abc/', None) + self.matches('/:x', '/a', {'x':'a'}) + self.matches('zzz/:x', '/zzz/abc', {'x':'abc'}) + self.matches('zzz/:x*traverse', '/zzz/abc', {'x':'abc', 'traverse':()}) + self.matches('zzz/:x*traverse', '/zzz/abc/def/g', + {'x':'abc', 'traverse':('def', 'g')}) + self.matches('*traverse', '/zzz/abc', {'traverse':('zzz', 'abc')}) + self.matches('*traverse', '/zzz/ abc', {'traverse':('zzz', ' abc')}) + #'/La%20Pe%C3%B1a' + # pattern, path, expected + self.matches(':x', text_(b'/La Pe\xc3\xb1a', 'utf-8'), + {'x':text_(b'La Pe\xc3\xb1a', 'utf-8')}) + # '/La%20Pe%C3%B1a/x' + self.matches('*traverse', text_(b'/La Pe\xc3\xb1a/x', 'utf-8'), + {'traverse':(text_(b'La Pe\xc3\xb1a', 'utf-8'), 'x')}) + self.matches('/foo/:id.html', '/foo/bar.html', {'id':'bar'}) + self.matches('/foo/:id_html', '/foo/bar_html', {'id_html':'bar_html'}) + self.matches('zzz/:_', '/zzz/abc', {'_':'abc'}) + self.matches('zzz/:_abc', '/zzz/abc', {'_abc':'abc'}) + self.matches('zzz/:abc_def', '/zzz/abc', {'abc_def':'abc'}) + + def test_generator_functional_notdynamic(self): + self.generates('', {}, '/') + self.generates('/', {}, '/') + + def test_generator_functional_newstyle(self): + self.generates('/{x}', {'x':''}, '/') + self.generates('/{x}', {'x':'a'}, '/a') + self.generates('/{x}', {'x':'a/b/c'}, '/a/b/c') + self.generates('/{x}', {'x':':@&+$,'}, '/:@&+$,') + self.generates('zzz/{x}', {'x':'abc'}, '/zzz/abc') + self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':''}, + '/zzz/abc') + self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'}, + '/zzz/abc/def/g') + self.generates('zzz/{x}*traverse', {'x':':@&+$,', 'traverse':'/:@&+$,'}, + '/zzz/:@&+$,/:@&+$,') + self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, + '//La%20Pe%C3%B1a') + self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), + 'y':'/rest/of/path'}, + '//La%20Pe%C3%B1a/rest/of/path') + self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, + '/a/La%20Pe%C3%B1a') + self.generates('/foo/{id}.html', {'id':'bar'}, '/foo/bar.html') + self.generates('/foo/{_}', {'_':'20'}, '/foo/20') + self.generates('/foo/{_abc}', {'_abc':'20'}, '/foo/20') + self.generates('/foo/{abc_def}', {'abc_def':'20'}, '/foo/20') + + def test_generator_functional_oldstyle(self): + self.generates('/:x', {'x':''}, '/') + self.generates('/:x', {'x':'a'}, '/a') + self.generates('zzz/:x', {'x':'abc'}, '/zzz/abc') + self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':''}, + '/zzz/abc') + self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'}, + '/zzz/abc/def/g') + self.generates('/:x', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, + '//La%20Pe%C3%B1a') + self.generates('/:x*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), + 'y':'/rest/of/path'}, + '//La%20Pe%C3%B1a/rest/of/path') + self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, + '/a/La%20Pe%C3%B1a') + self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html') + self.generates('/foo/:_', {'_':'20'}, '/foo/20') + self.generates('/foo/:_abc', {'_abc':'20'}, '/foo/20') + self.generates('/foo/:abc_def', {'abc_def':'20'}, '/foo/20') + +class DummyContext(object): + """ """ + +class DummyRequest(object): + def __init__(self, environ): + self.environ = environ + +class DummyRoute(object): + def __init__(self, generator): + self.generate = generator + diff --git a/tests/test_util.py b/tests/test_util.py new file mode 100644 index 000000000..a76cd2017 --- /dev/null +++ b/tests/test_util.py @@ -0,0 +1,1111 @@ +import unittest +from pyramid.compat import ( + PY2, + text_, + bytes_, + ) + + +class Test_InstancePropertyHelper(unittest.TestCase): + def _makeOne(self): + cls = self._getTargetClass() + return cls() + + def _getTargetClass(self): + from pyramid.util import InstancePropertyHelper + return InstancePropertyHelper + + def test_callable(self): + def worker(obj): + return obj.bar + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker) + foo.bar = 1 + self.assertEqual(1, foo.worker) + foo.bar = 2 + self.assertEqual(2, foo.worker) + + def test_callable_with_name(self): + def worker(obj): + return obj.bar + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker, name='x') + foo.bar = 1 + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + + def test_callable_with_reify(self): + def worker(obj): + return obj.bar + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker, reify=True) + foo.bar = 1 + self.assertEqual(1, foo.worker) + foo.bar = 2 + self.assertEqual(1, foo.worker) + + def test_callable_with_name_reify(self): + def worker(obj): + return obj.bar + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker, name='x') + helper.set_property(foo, worker, name='y', reify=True) + foo.bar = 1 + self.assertEqual(1, foo.y) + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + self.assertEqual(1, foo.y) + + def test_property_without_name(self): + def worker(obj): pass + foo = Dummy() + helper = self._getTargetClass() + self.assertRaises(ValueError, helper.set_property, foo, property(worker)) + + def test_property_with_name(self): + def worker(obj): + return obj.bar + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, property(worker), name='x') + foo.bar = 1 + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + + def test_property_with_reify(self): + def worker(obj): pass + foo = Dummy() + helper = self._getTargetClass() + self.assertRaises(ValueError, helper.set_property, + foo, property(worker), name='x', reify=True) + + def test_override_property(self): + def worker(obj): pass + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker, name='x') + def doit(): + foo.x = 1 + self.assertRaises(AttributeError, doit) + + def test_override_reify(self): + def worker(obj): pass + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, worker, name='x', reify=True) + foo.x = 1 + self.assertEqual(1, foo.x) + foo.x = 2 + self.assertEqual(2, foo.x) + + def test_reset_property(self): + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, lambda _: 1, name='x') + self.assertEqual(1, foo.x) + helper.set_property(foo, lambda _: 2, name='x') + self.assertEqual(2, foo.x) + + def test_reset_reify(self): + """ This is questionable behavior, but may as well get notified + if it changes.""" + foo = Dummy() + helper = self._getTargetClass() + helper.set_property(foo, lambda _: 1, name='x', reify=True) + self.assertEqual(1, foo.x) + helper.set_property(foo, lambda _: 2, name='x', reify=True) + self.assertEqual(1, foo.x) + + def test_make_property(self): + from pyramid.decorator import reify + helper = self._getTargetClass() + name, fn = helper.make_property(lambda x: 1, name='x', reify=True) + self.assertEqual(name, 'x') + self.assertTrue(isinstance(fn, reify)) + + def test_apply_properties_with_iterable(self): + foo = Dummy() + helper = self._getTargetClass() + x = helper.make_property(lambda _: 1, name='x', reify=True) + y = helper.make_property(lambda _: 2, name='y') + helper.apply_properties(foo, [x, y]) + self.assertEqual(1, foo.x) + self.assertEqual(2, foo.y) + + def test_apply_properties_with_dict(self): + foo = Dummy() + helper = self._getTargetClass() + x_name, x_fn = helper.make_property(lambda _: 1, name='x', reify=True) + y_name, y_fn = helper.make_property(lambda _: 2, name='y') + helper.apply_properties(foo, {x_name: x_fn, y_name: y_fn}) + self.assertEqual(1, foo.x) + self.assertEqual(2, foo.y) + + def test_make_property_unicode(self): + from pyramid.compat import text_ + from pyramid.exceptions import ConfigurationError + + cls = self._getTargetClass() + if PY2: + name = text_(b'La Pe\xc3\xb1a', 'utf-8') + else: + name = b'La Pe\xc3\xb1a' + + def make_bad_name(): + cls.make_property(lambda x: 1, name=name, reify=True) + + self.assertRaises(ConfigurationError, make_bad_name) + + def test_add_property(self): + helper = self._makeOne() + helper.add_property(lambda obj: obj.bar, name='x', reify=True) + helper.add_property(lambda obj: obj.bar, name='y') + self.assertEqual(len(helper.properties), 2) + foo = Dummy() + helper.apply(foo) + foo.bar = 1 + self.assertEqual(foo.x, 1) + self.assertEqual(foo.y, 1) + foo.bar = 2 + self.assertEqual(foo.x, 1) + self.assertEqual(foo.y, 2) + + def test_apply_multiple_times(self): + helper = self._makeOne() + helper.add_property(lambda obj: 1, name='x') + foo, bar = Dummy(), Dummy() + helper.apply(foo) + self.assertEqual(foo.x, 1) + helper.add_property(lambda obj: 2, name='x') + helper.apply(bar) + self.assertEqual(foo.x, 1) + self.assertEqual(bar.x, 2) + +class Test_InstancePropertyMixin(unittest.TestCase): + def _makeOne(self): + cls = self._getTargetClass() + + class Foo(cls): + pass + return Foo() + + def _getTargetClass(self): + from pyramid.util import InstancePropertyMixin + return InstancePropertyMixin + + def test_callable(self): + def worker(obj): + return obj.bar + foo = self._makeOne() + foo.set_property(worker) + foo.bar = 1 + self.assertEqual(1, foo.worker) + foo.bar = 2 + self.assertEqual(2, foo.worker) + + def test_callable_with_name(self): + def worker(obj): + return obj.bar + foo = self._makeOne() + foo.set_property(worker, name='x') + foo.bar = 1 + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + + def test_callable_with_reify(self): + def worker(obj): + return obj.bar + foo = self._makeOne() + foo.set_property(worker, reify=True) + foo.bar = 1 + self.assertEqual(1, foo.worker) + foo.bar = 2 + self.assertEqual(1, foo.worker) + + def test_callable_with_name_reify(self): + def worker(obj): + return obj.bar + foo = self._makeOne() + foo.set_property(worker, name='x') + foo.set_property(worker, name='y', reify=True) + foo.bar = 1 + self.assertEqual(1, foo.y) + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + self.assertEqual(1, foo.y) + + def test_property_without_name(self): + def worker(obj): pass + foo = self._makeOne() + self.assertRaises(ValueError, foo.set_property, property(worker)) + + def test_property_with_name(self): + def worker(obj): + return obj.bar + foo = self._makeOne() + foo.set_property(property(worker), name='x') + foo.bar = 1 + self.assertEqual(1, foo.x) + foo.bar = 2 + self.assertEqual(2, foo.x) + + def test_property_with_reify(self): + def worker(obj): pass + foo = self._makeOne() + self.assertRaises(ValueError, foo.set_property, + property(worker), name='x', reify=True) + + def test_override_property(self): + def worker(obj): pass + foo = self._makeOne() + foo.set_property(worker, name='x') + def doit(): + foo.x = 1 + self.assertRaises(AttributeError, doit) + + def test_override_reify(self): + def worker(obj): pass + foo = self._makeOne() + foo.set_property(worker, name='x', reify=True) + foo.x = 1 + self.assertEqual(1, foo.x) + foo.x = 2 + self.assertEqual(2, foo.x) + + def test_reset_property(self): + foo = self._makeOne() + foo.set_property(lambda _: 1, name='x') + self.assertEqual(1, foo.x) + foo.set_property(lambda _: 2, name='x') + self.assertEqual(2, foo.x) + + def test_reset_reify(self): + """ This is questionable behavior, but may as well get notified + if it changes.""" + foo = self._makeOne() + foo.set_property(lambda _: 1, name='x', reify=True) + self.assertEqual(1, foo.x) + foo.set_property(lambda _: 2, name='x', reify=True) + self.assertEqual(1, foo.x) + + def test_new_class_keeps_parent_module_name(self): + foo = self._makeOne() + self.assertEqual(foo.__module__, 'pyramid.tests.test_util') + self.assertEqual(foo.__class__.__module__, 'pyramid.tests.test_util') + foo.set_property(lambda _: 1, name='x', reify=True) + self.assertEqual(foo.__module__, 'pyramid.tests.test_util') + self.assertEqual(foo.__class__.__module__, 'pyramid.tests.test_util') + +class Test_WeakOrderedSet(unittest.TestCase): + def _makeOne(self): + from pyramid.config import WeakOrderedSet + return WeakOrderedSet() + + def test_ctor(self): + wos = self._makeOne() + self.assertEqual(len(wos), 0) + self.assertEqual(wos.last, None) + + def test_add_item(self): + wos = self._makeOne() + reg = Dummy() + wos.add(reg) + self.assertEqual(list(wos), [reg]) + self.assertTrue(reg in wos) + self.assertEqual(wos.last, reg) + + def test_add_multiple_items(self): + wos = self._makeOne() + reg1 = Dummy() + reg2 = Dummy() + wos.add(reg1) + wos.add(reg2) + self.assertEqual(len(wos), 2) + self.assertEqual(list(wos), [reg1, reg2]) + self.assertTrue(reg1 in wos) + self.assertTrue(reg2 in wos) + self.assertEqual(wos.last, reg2) + + def test_add_duplicate_items(self): + wos = self._makeOne() + reg = Dummy() + wos.add(reg) + wos.add(reg) + self.assertEqual(len(wos), 1) + self.assertEqual(list(wos), [reg]) + self.assertTrue(reg in wos) + self.assertEqual(wos.last, reg) + + def test_weakref_removal(self): + wos = self._makeOne() + reg = Dummy() + wos.add(reg) + wos.remove(reg) + self.assertEqual(len(wos), 0) + self.assertEqual(list(wos), []) + self.assertEqual(wos.last, None) + + def test_last_updated(self): + wos = self._makeOne() + reg = Dummy() + reg2 = Dummy() + wos.add(reg) + wos.add(reg2) + wos.remove(reg2) + self.assertEqual(len(wos), 1) + self.assertEqual(list(wos), [reg]) + self.assertEqual(wos.last, reg) + + def test_empty(self): + wos = self._makeOne() + reg = Dummy() + reg2 = Dummy() + wos.add(reg) + wos.add(reg2) + wos.empty() + self.assertEqual(len(wos), 0) + self.assertEqual(list(wos), []) + self.assertEqual(wos.last, None) + +class Test_strings_differ(unittest.TestCase): + def _callFUT(self, *args, **kw): + from pyramid.util import strings_differ + return strings_differ(*args, **kw) + + def test_it_bytes(self): + self.assertFalse(self._callFUT(b'foo', b'foo')) + self.assertTrue(self._callFUT(b'123', b'345')) + self.assertTrue(self._callFUT(b'1234', b'123')) + self.assertTrue(self._callFUT(b'123', b'1234')) + + def test_it_native_str(self): + self.assertFalse(self._callFUT('123', '123')) + self.assertTrue(self._callFUT('123', '1234')) + + def test_it_with_internal_comparator(self): + result = self._callFUT(b'foo', b'foo', compare_digest=None) + self.assertFalse(result) + + result = self._callFUT(b'123', b'abc', compare_digest=None) + self.assertTrue(result) + + def test_it_with_external_comparator(self): + class DummyComparator(object): + called = False + def __init__(self, ret_val): + self.ret_val = ret_val + + def __call__(self, a, b): + self.called = True + return self.ret_val + + dummy_compare = DummyComparator(True) + result = self._callFUT(b'foo', b'foo', compare_digest=dummy_compare) + self.assertTrue(dummy_compare.called) + self.assertFalse(result) + + dummy_compare = DummyComparator(False) + result = self._callFUT(b'123', b'345', compare_digest=dummy_compare) + self.assertTrue(dummy_compare.called) + self.assertTrue(result) + + dummy_compare = DummyComparator(False) + result = self._callFUT(b'abc', b'abc', compare_digest=dummy_compare) + self.assertTrue(dummy_compare.called) + self.assertTrue(result) + +class Test_object_description(unittest.TestCase): + def _callFUT(self, object): + from pyramid.util import object_description + return object_description(object) + + def test_string(self): + self.assertEqual(self._callFUT('abc'), 'abc') + + def test_int(self): + self.assertEqual(self._callFUT(1), '1') + + def test_bool(self): + self.assertEqual(self._callFUT(True), 'True') + + def test_None(self): + self.assertEqual(self._callFUT(None), 'None') + + def test_float(self): + self.assertEqual(self._callFUT(1.2), '1.2') + + def test_tuple(self): + self.assertEqual(self._callFUT(('a', 'b')), "('a', 'b')") + + def test_set(self): + if PY2: + self.assertEqual(self._callFUT(set(['a'])), "set(['a'])") + else: + self.assertEqual(self._callFUT(set(['a'])), "{'a'}") + + def test_list(self): + self.assertEqual(self._callFUT(['a']), "['a']") + + def test_dict(self): + self.assertEqual(self._callFUT({'a':1}), "{'a': 1}") + + def test_nomodule(self): + o = object() + self.assertEqual(self._callFUT(o), 'object %s' % str(o)) + + def test_module(self): + import pyramid + self.assertEqual(self._callFUT(pyramid), 'module pyramid') + + def test_method(self): + self.assertEqual( + self._callFUT(self.test_method), + 'method test_method of class pyramid.tests.test_util.' + 'Test_object_description') + + def test_class(self): + self.assertEqual( + self._callFUT(self.__class__), + 'class pyramid.tests.test_util.Test_object_description') + + def test_function(self): + self.assertEqual( + self._callFUT(dummyfunc), + 'function pyramid.tests.test_util.dummyfunc') + + def test_instance(self): + inst = Dummy() + self.assertEqual( + self._callFUT(inst), + "object %s" % str(inst)) + + def test_shortened_repr(self): + inst = ['1'] * 1000 + self.assertEqual( + self._callFUT(inst), + str(inst)[:100] + ' ... ]') + +class TestTopologicalSorter(unittest.TestCase): + def _makeOne(self, *arg, **kw): + from pyramid.util import TopologicalSorter + return TopologicalSorter(*arg, **kw) + + def test_remove(self): + inst = self._makeOne() + inst.names.append('name') + inst.name2val['name'] = 1 + inst.req_after.add('name') + inst.req_before.add('name') + inst.name2after['name'] = ('bob',) + inst.name2before['name'] = ('fred',) + inst.order.append(('bob', 'name')) + inst.order.append(('name', 'fred')) + inst.remove('name') + self.assertFalse(inst.names) + self.assertFalse(inst.req_before) + self.assertFalse(inst.req_after) + self.assertFalse(inst.name2before) + self.assertFalse(inst.name2after) + self.assertFalse(inst.name2val) + self.assertFalse(inst.order) + + def test_add(self): + from pyramid.util import LAST + sorter = self._makeOne() + sorter.add('name', 'factory') + self.assertEqual(sorter.names, ['name']) + self.assertEqual(sorter.name2val, + {'name':'factory'}) + self.assertEqual(sorter.order, [('name', LAST)]) + sorter.add('name2', 'factory2') + self.assertEqual(sorter.names, ['name', 'name2']) + self.assertEqual(sorter.name2val, + {'name':'factory', 'name2':'factory2'}) + self.assertEqual(sorter.order, + [('name', LAST), ('name2', LAST)]) + sorter.add('name3', 'factory3', before='name2') + self.assertEqual(sorter.names, + ['name', 'name2', 'name3']) + self.assertEqual(sorter.name2val, + {'name':'factory', 'name2':'factory2', + 'name3':'factory3'}) + self.assertEqual(sorter.order, + [('name', LAST), ('name2', LAST), + ('name3', 'name2')]) + + def test_sorted_ordering_1(self): + sorter = self._makeOne() + sorter.add('name1', 'factory1') + sorter.add('name2', 'factory2') + self.assertEqual(sorter.sorted(), + [ + ('name1', 'factory1'), + ('name2', 'factory2'), + ]) + + def test_sorted_ordering_2(self): + from pyramid.util import FIRST + sorter = self._makeOne() + sorter.add('name1', 'factory1') + sorter.add('name2', 'factory2', after=FIRST) + self.assertEqual(sorter.sorted(), + [ + ('name2', 'factory2'), + ('name1', 'factory1'), + ]) + + def test_sorted_ordering_3(self): + from pyramid.util import FIRST + sorter = self._makeOne() + add = sorter.add + add('auth', 'auth_factory', after='browserid') + add('dbt', 'dbt_factory') + add('retry', 'retry_factory', before='txnmgr', after='exceptionview') + add('browserid', 'browserid_factory') + add('txnmgr', 'txnmgr_factory', after='exceptionview') + add('exceptionview', 'excview_factory', after=FIRST) + self.assertEqual(sorter.sorted(), + [ + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ('dbt', 'dbt_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ]) + + def test_sorted_ordering_4(self): + from pyramid.util import FIRST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', after=FIRST) + add('auth', 'auth_factory', after='browserid') + add('retry', 'retry_factory', before='txnmgr', after='exceptionview') + add('browserid', 'browserid_factory') + add('txnmgr', 'txnmgr_factory', after='exceptionview') + add('dbt', 'dbt_factory') + self.assertEqual(sorter.sorted(), + [ + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('dbt', 'dbt_factory'), + ]) + + def test_sorted_ordering_5(self): + from pyramid.util import LAST, FIRST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory') + add('auth', 'auth_factory', after=FIRST) + add('retry', 'retry_factory', before='txnmgr', after='exceptionview') + add('browserid', 'browserid_factory', after=FIRST) + add('txnmgr', 'txnmgr_factory', after='exceptionview', before=LAST) + add('dbt', 'dbt_factory') + self.assertEqual(sorter.sorted(), + [ + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('txnmgr', 'txnmgr_factory'), + ('dbt', 'dbt_factory'), + ]) + + def test_sorted_ordering_missing_before_partial(self): + from pyramid.exceptions import ConfigurationError + sorter = self._makeOne() + add = sorter.add + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', after='browserid') + add('retry', 'retry_factory', before='txnmgr', after='exceptionview') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, sorter.sorted) + + def test_sorted_ordering_missing_after_partial(self): + from pyramid.exceptions import ConfigurationError + sorter = self._makeOne() + add = sorter.add + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', after='txnmgr') + add('retry', 'retry_factory', before='dbt', after='exceptionview') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, sorter.sorted) + + def test_sorted_ordering_missing_before_and_after_partials(self): + from pyramid.exceptions import ConfigurationError + sorter = self._makeOne() + add = sorter.add + add('dbt', 'dbt_factory') + add('auth', 'auth_factory', after='browserid') + add('retry', 'retry_factory', before='foo', after='txnmgr') + add('browserid', 'browserid_factory') + self.assertRaises(ConfigurationError, sorter.sorted) + + def test_sorted_ordering_missing_before_partial_with_fallback(self): + from pyramid.util import LAST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', before=LAST) + add('auth', 'auth_factory', after='browserid') + add('retry', 'retry_factory', before=('txnmgr', LAST), + after='exceptionview') + add('browserid', 'browserid_factory') + add('dbt', 'dbt_factory') + self.assertEqual(sorter.sorted(), + [ + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('dbt', 'dbt_factory'), + ]) + + def test_sorted_ordering_missing_after_partial_with_fallback(self): + from pyramid.util import FIRST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', after=FIRST) + add('auth', 'auth_factory', after=('txnmgr','browserid')) + add('retry', 'retry_factory', after='exceptionview') + add('browserid', 'browserid_factory') + add('dbt', 'dbt_factory') + self.assertEqual(sorter.sorted(), + [ + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ('browserid', 'browserid_factory'), + ('auth', 'auth_factory'), + ('dbt', 'dbt_factory'), + ]) + + def test_sorted_ordering_with_partial_fallbacks(self): + from pyramid.util import LAST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', before=('wontbethere', LAST)) + add('retry', 'retry_factory', after='exceptionview') + add('browserid', 'browserid_factory', before=('wont2', 'exceptionview')) + self.assertEqual(sorter.sorted(), + [ + ('browserid', 'browserid_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_sorted_ordering_with_multiple_matching_fallbacks(self): + from pyramid.util import LAST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', before=LAST) + add('retry', 'retry_factory', after='exceptionview') + add('browserid', 'browserid_factory', before=('retry', 'exceptionview')) + self.assertEqual(sorter.sorted(), + [ + ('browserid', 'browserid_factory'), + ('exceptionview', 'excview_factory'), + ('retry', 'retry_factory'), + ]) + + def test_sorted_ordering_with_missing_fallbacks(self): + from pyramid.exceptions import ConfigurationError + from pyramid.util import LAST + sorter = self._makeOne() + add = sorter.add + add('exceptionview', 'excview_factory', before=LAST) + add('retry', 'retry_factory', after='exceptionview') + add('browserid', 'browserid_factory', before=('txnmgr', 'auth')) + self.assertRaises(ConfigurationError, sorter.sorted) + + def test_sorted_ordering_conflict_direct(self): + from pyramid.exceptions import CyclicDependencyError + sorter = self._makeOne() + add = sorter.add + add('browserid', 'browserid_factory') + add('auth', 'auth_factory', before='browserid', after='browserid') + self.assertRaises(CyclicDependencyError, sorter.sorted) + + def test_sorted_ordering_conflict_indirect(self): + from pyramid.exceptions import CyclicDependencyError + sorter = self._makeOne() + add = sorter.add + add('browserid', 'browserid_factory') + add('auth', 'auth_factory', before='browserid') + add('dbt', 'dbt_factory', after='browserid', before='auth') + self.assertRaises(CyclicDependencyError, sorter.sorted) + +class TestSentinel(unittest.TestCase): + def test_repr(self): + from pyramid.util import Sentinel + r = repr(Sentinel('ABC')) + self.assertEqual(r, 'ABC') + + +class TestCallableName(unittest.TestCase): + def test_valid_ascii(self): + from pyramid.util import get_callable_name + from pyramid.compat import text_ + + if PY2: + name = text_(b'hello world', 'utf-8') + else: + name = b'hello world' + + self.assertEqual(get_callable_name(name), 'hello world') + + def test_invalid_ascii(self): + from pyramid.util import get_callable_name + from pyramid.compat import text_ + from pyramid.exceptions import ConfigurationError + + def get_bad_name(): + if PY2: + name = text_(b'La Pe\xc3\xb1a', 'utf-8') + else: + name = b'La Pe\xc3\xb1a' + + get_callable_name(name) + + self.assertRaises(ConfigurationError, get_bad_name) + + +class Test_hide_attrs(unittest.TestCase): + def _callFUT(self, obj, *attrs): + from pyramid.util import hide_attrs + return hide_attrs(obj, *attrs) + + def _makeDummy(self): + from pyramid.decorator import reify + class Dummy(object): + x = 1 + + @reify + def foo(self): + return self.x + return Dummy() + + def test_restores_attrs(self): + obj = self._makeDummy() + obj.bar = 'asdf' + orig_foo = obj.foo + with self._callFUT(obj, 'foo', 'bar'): + obj.foo = object() + obj.bar = 'nope' + self.assertEqual(obj.foo, orig_foo) + self.assertEqual(obj.bar, 'asdf') + + def test_restores_attrs_on_exception(self): + obj = self._makeDummy() + orig_foo = obj.foo + try: + with self._callFUT(obj, 'foo'): + obj.foo = object() + raise RuntimeError() + except RuntimeError: + self.assertEqual(obj.foo, orig_foo) + else: # pragma: no cover + self.fail("RuntimeError not raised") + + def test_restores_attrs_to_none(self): + obj = self._makeDummy() + obj.foo = None + with self._callFUT(obj, 'foo'): + obj.foo = object() + self.assertEqual(obj.foo, None) + + def test_deletes_attrs(self): + obj = self._makeDummy() + with self._callFUT(obj, 'foo'): + obj.foo = object() + self.assertTrue('foo' not in obj.__dict__) + + def test_does_not_delete_attr_if_no_attr_to_delete(self): + obj = self._makeDummy() + with self._callFUT(obj, 'foo'): + pass + self.assertTrue('foo' not in obj.__dict__) + + +def dummyfunc(): pass + + +class Dummy(object): + pass + + +class Test_is_same_domain(unittest.TestCase): + def _callFUT(self, *args, **kw): + from pyramid.util import is_same_domain + return is_same_domain(*args, **kw) + + def test_it(self): + self.assertTrue(self._callFUT("example.com", "example.com")) + self.assertFalse(self._callFUT("evil.com", "example.com")) + self.assertFalse(self._callFUT("evil.example.com", "example.com")) + self.assertFalse(self._callFUT("example.com", "")) + + def test_with_wildcard(self): + self.assertTrue(self._callFUT("example.com", ".example.com")) + self.assertTrue(self._callFUT("good.example.com", ".example.com")) + + def test_with_port(self): + self.assertTrue(self._callFUT("example.com:8080", "example.com:8080")) + self.assertFalse(self._callFUT("example.com:8080", "example.com")) + self.assertFalse(self._callFUT("example.com", "example.com:8080")) + + +class Test_make_contextmanager(unittest.TestCase): + def _callFUT(self, *args, **kw): + from pyramid.util import make_contextmanager + return make_contextmanager(*args, **kw) + + def test_with_None(self): + mgr = self._callFUT(None) + with mgr() as ctx: + self.assertIsNone(ctx) + + def test_with_generator(self): + def mygen(ctx): + yield ctx + mgr = self._callFUT(mygen) + with mgr('a') as ctx: + self.assertEqual(ctx, 'a') + + def test_with_multiple_yield_generator(self): + def mygen(): + yield 'a' + yield 'b' + mgr = self._callFUT(mygen) + try: + with mgr() as ctx: + self.assertEqual(ctx, 'a') + except RuntimeError: + pass + else: # pragma: no cover + raise AssertionError('expected raise from multiple yields') + + def test_with_regular_fn(self): + def mygen(): + return 'a' + mgr = self._callFUT(mygen) + with mgr() as ctx: + self.assertEqual(ctx, 'a') + + +class Test_takes_one_arg(unittest.TestCase): + def _callFUT(self, view, attr=None, argname=None): + from pyramid.util import takes_one_arg + return takes_one_arg(view, attr=attr, argname=argname) + + def test_requestonly_newstyle_class_no_init(self): + class foo(object): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_requestonly_newstyle_class_init_toomanyargs(self): + class foo(object): + def __init__(self, context, request): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_requestonly_newstyle_class_init_onearg_named_request(self): + class foo(object): + def __init__(self, request): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_newstyle_class_init_onearg_named_somethingelse(self): + class foo(object): + def __init__(self, req): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_newstyle_class_init_defaultargs_firstname_not_request(self): + class foo(object): + def __init__(self, context, request=None): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_newstyle_class_init_defaultargs_firstname_request(self): + class foo(object): + def __init__(self, request, foo=1, bar=2): + """ """ + self.assertTrue(self._callFUT(foo, argname='request')) + + def test_newstyle_class_init_firstname_request_with_secondname(self): + class foo(object): + def __init__(self, request, two): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_newstyle_class_init_noargs(self): + class foo(object): + def __init__(): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_oldstyle_class_no_init(self): + class foo: + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_oldstyle_class_init_toomanyargs(self): + class foo: + def __init__(self, context, request): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_oldstyle_class_init_onearg_named_request(self): + class foo: + def __init__(self, request): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_oldstyle_class_init_onearg_named_somethingelse(self): + class foo: + def __init__(self, req): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_oldstyle_class_init_defaultargs_firstname_not_request(self): + class foo: + def __init__(self, context, request=None): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_oldstyle_class_init_defaultargs_firstname_request(self): + class foo: + def __init__(self, request, foo=1, bar=2): + """ """ + self.assertTrue(self._callFUT(foo, argname='request'), True) + + def test_oldstyle_class_init_noargs(self): + class foo: + def __init__(): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_function_toomanyargs(self): + def foo(context, request): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_function_with_attr_false(self): + def bar(context, request): + """ """ + def foo(context, request): + """ """ + foo.bar = bar + self.assertFalse(self._callFUT(foo, 'bar')) + + def test_function_with_attr_true(self): + def bar(context, request): + """ """ + def foo(request): + """ """ + foo.bar = bar + self.assertTrue(self._callFUT(foo, 'bar')) + + def test_function_onearg_named_request(self): + def foo(request): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_function_onearg_named_somethingelse(self): + def foo(req): + """ """ + self.assertTrue(self._callFUT(foo)) + + def test_function_defaultargs_firstname_not_request(self): + def foo(context, request=None): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_function_defaultargs_firstname_request(self): + def foo(request, foo=1, bar=2): + """ """ + self.assertTrue(self._callFUT(foo, argname='request')) + + def test_function_noargs(self): + def foo(): + """ """ + self.assertFalse(self._callFUT(foo)) + + def test_instance_toomanyargs(self): + class Foo: + def __call__(self, context, request): + """ """ + foo = Foo() + self.assertFalse(self._callFUT(foo)) + + def test_instance_defaultargs_onearg_named_request(self): + class Foo: + def __call__(self, request): + """ """ + foo = Foo() + self.assertTrue(self._callFUT(foo)) + + def test_instance_defaultargs_onearg_named_somethingelse(self): + class Foo: + def __call__(self, req): + """ """ + foo = Foo() + self.assertTrue(self._callFUT(foo)) + + def test_instance_defaultargs_firstname_not_request(self): + class Foo: + def __call__(self, context, request=None): + """ """ + foo = Foo() + self.assertFalse(self._callFUT(foo)) + + def test_instance_defaultargs_firstname_request(self): + class Foo: + def __call__(self, request, foo=1, bar=2): + """ """ + foo = Foo() + self.assertTrue(self._callFUT(foo, argname='request'), True) + + def test_instance_nocall(self): + class Foo: pass + foo = Foo() + self.assertFalse(self._callFUT(foo)) + + def test_method_onearg_named_request(self): + class Foo: + def method(self, request): + """ """ + foo = Foo() + self.assertTrue(self._callFUT(foo.method)) + + def test_function_annotations(self): + def foo(bar): + """ """ + # avoid SyntaxErrors in python2, this if effectively nop + getattr(foo, '__annotations__', {}).update({'bar': 'baz'}) + self.assertTrue(self._callFUT(foo)) + + +class TestSimpleSerializer(unittest.TestCase): + def _makeOne(self): + from pyramid.util import SimpleSerializer + return SimpleSerializer() + + def test_loads(self): + inst = self._makeOne() + self.assertEqual(inst.loads(b'abc'), text_('abc')) + + def test_dumps(self): + inst = self._makeOne() + self.assertEqual(inst.dumps('abc'), bytes_('abc')) diff --git a/tests/test_view.py b/tests/test_view.py new file mode 100644 index 000000000..3344bd739 --- /dev/null +++ b/tests/test_view.py @@ -0,0 +1,1071 @@ +import unittest +import sys + +from zope.interface import implementer + +from pyramid import testing + +from pyramid.interfaces import IRequest + +class BaseTest(object): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _registerView(self, reg, app, name): + from pyramid.interfaces import IViewClassifier + for_ = (IViewClassifier, IRequest, IContext) + from pyramid.interfaces import IView + reg.registerAdapter(app, for_, IView, name) + + def _makeEnviron(self, **extras): + environ = { + 'wsgi.url_scheme':'http', + 'wsgi.version':(1,0), + 'SERVER_NAME':'localhost', + 'SERVER_PORT':'8080', + 'REQUEST_METHOD':'GET', + 'PATH_INFO':'/', + } + environ.update(extras) + return environ + + def _makeRequest(self, **environ): + from pyramid.request import Request + from pyramid.registry import Registry + environ = self._makeEnviron(**environ) + request = Request(environ) + request.registry = Registry() + return request + + def _makeContext(self): + from zope.interface import directlyProvides + context = DummyContext() + directlyProvides(context, IContext) + return context + +class Test_notfound_view_config(BaseTest, unittest.TestCase): + def _makeOne(self, **kw): + from pyramid.view import notfound_view_config + return notfound_view_config(**kw) + + def test_ctor(self): + inst = self._makeOne(attr='attr', path_info='path_info', + append_slash=True) + self.assertEqual(inst.__dict__, + {'attr':'attr', 'path_info':'path_info', + 'append_slash':True}) + + def test_it_function(self): + def view(request): pass + decorator = self._makeOne(attr='attr', renderer='renderer', + append_slash=True) + venusian = DummyVenusian() + decorator.venusian = venusian + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual( + settings, + [{'attr': 'attr', 'venusian': venusian, 'append_slash': True, + 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] + ) + + def test_it_class(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + class view(object): pass + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 4) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['attr'], 'view') + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_call_with_venusian_args(self): + decorator = self._makeOne(_depth=1, _category='foo') + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + category = attachments[0][2] + depth = attachments[0][3] + self.assertEqual(depth, 2) + self.assertEqual(category, 'foo') + +class Test_forbidden_view_config(BaseTest, unittest.TestCase): + def _makeOne(self, **kw): + from pyramid.view import forbidden_view_config + return forbidden_view_config(**kw) + + def test_ctor(self): + inst = self._makeOne(attr='attr', path_info='path_info') + self.assertEqual(inst.__dict__, + {'attr':'attr', 'path_info':'path_info'}) + + def test_it_function(self): + def view(request): pass + decorator = self._makeOne(attr='attr', renderer='renderer') + venusian = DummyVenusian() + decorator.venusian = venusian + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual( + settings, + [{'attr': 'attr', 'venusian': venusian, + 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] + ) + + def test_it_class(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + class view(object): pass + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 4) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['attr'], 'view') + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_call_with_venusian_args(self): + decorator = self._makeOne(_depth=1, _category='foo') + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + category = attachments[0][2] + depth = attachments[0][3] + self.assertEqual(depth, 2) + self.assertEqual(category, 'foo') + +class Test_exception_view_config(BaseTest, unittest.TestCase): + def _makeOne(self, *args, **kw): + from pyramid.view import exception_view_config + return exception_view_config(*args, **kw) + + def test_ctor(self): + inst = self._makeOne(context=Exception, path_info='path_info') + self.assertEqual(inst.__dict__, + {'context':Exception, 'path_info':'path_info'}) + + def test_ctor_positional_exception(self): + inst = self._makeOne(Exception, path_info='path_info') + self.assertEqual(inst.__dict__, + {'context':Exception, 'path_info':'path_info'}) + + def test_ctor_positional_extras(self): + from pyramid.exceptions import ConfigurationError + self.assertRaises(ConfigurationError, lambda: self._makeOne(Exception, True)) + + def test_it_function(self): + def view(request): pass + decorator = self._makeOne(context=Exception, renderer='renderer') + venusian = DummyVenusian() + decorator.venusian = venusian + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual( + settings, + [{'venusian': venusian, 'context': Exception, + 'renderer': 'renderer', '_info': 'codeinfo', 'view': None}] + ) + + def test_it_class(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + class view(object): pass + wrapped = decorator(view) + self.assertTrue(wrapped is view) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 4) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['attr'], 'view') + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_call_with_venusian_args(self): + decorator = self._makeOne(_depth=1, _category='foo') + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + category = attachments[0][2] + depth = attachments[0][3] + self.assertEqual(depth, 2) + self.assertEqual(category, 'foo') + +class RenderViewToResponseTests(BaseTest, unittest.TestCase): + def _callFUT(self, *arg, **kw): + from pyramid.view import render_view_to_response + return render_view_to_response(*arg, **kw) + + def test_call_no_view_registered(self): + request = self._makeRequest() + context = self._makeContext() + result = self._callFUT(context, request, name='notregistered') + self.assertEqual(result, None) + + def test_call_no_registry_on_request(self): + request = self._makeRequest() + del request.registry + context = self._makeContext() + result = self._callFUT(context, request, name='notregistered') + self.assertEqual(result, None) + + def test_call_view_registered_secure(self): + request = self._makeRequest() + context = self._makeContext() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + response = self._callFUT(context, request, name='registered', + secure=True) + self.assertEqual(response.status, '200 OK') + + def test_call_view_registered_insecure_no_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + response = self._callFUT(context, request, name='registered', + secure=False) + self.assertEqual(response.status, '200 OK') + + def test_call_view_registered_insecure_with_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + def anotherview(context, request): + return DummyResponse('anotherview') + view.__call_permissive__ = anotherview + self._registerView(request.registry, view, 'registered') + response = self._callFUT(context, request, name='registered', + secure=False) + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.app_iter, ['anotherview']) + + def test_call_view_with_request_iface_on_request(self): + # See https://github.com/Pylons/pyramid/issues/1643 + from zope.interface import Interface + class IWontBeFound(Interface): pass + context = self._makeContext() + request = self._makeRequest() + request.request_iface = IWontBeFound + response = DummyResponse('aview') + view = make_view(response) + self._registerView(request.registry, view, 'aview') + response = self._callFUT(context, request, name='aview') + self.assertEqual(response.status, '200 OK') + self.assertEqual(response.app_iter, ['aview']) + +class RenderViewToIterableTests(BaseTest, unittest.TestCase): + def _callFUT(self, *arg, **kw): + from pyramid.view import render_view_to_iterable + return render_view_to_iterable(*arg, **kw) + + def test_call_no_view_registered(self): + request = self._makeRequest() + context = self._makeContext() + result = self._callFUT(context, request, name='notregistered') + self.assertEqual(result, None) + + def test_call_view_registered_secure(self): + request = self._makeRequest() + context = self._makeContext() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + iterable = self._callFUT(context, request, name='registered', + secure=True) + self.assertEqual(iterable, ()) + + def test_call_view_registered_insecure_no_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + iterable = self._callFUT(context, request, name='registered', + secure=False) + self.assertEqual(iterable, ()) + + def test_call_view_registered_insecure_with_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + def anotherview(context, request): + return DummyResponse(b'anotherview') + view.__call_permissive__ = anotherview + self._registerView(request.registry, view, 'registered') + iterable = self._callFUT(context, request, name='registered', + secure=False) + self.assertEqual(iterable, [b'anotherview']) + + def test_verify_output_bytestring(self): + from pyramid.request import Request + from pyramid.config import Configurator + from pyramid.view import render_view + from webob.compat import text_type + config = Configurator(settings={}) + def view(request): + request.response.text = text_type('') + return request.response + + config.add_view(name='test', view=view) + config.commit() + + r = Request({}) + r.registry = config.registry + self.assertEqual(render_view(object(), r, 'test'), b'') + + def test_call_request_has_no_registry(self): + request = self._makeRequest() + del request.registry + registry = self.config.registry + context = self._makeContext() + response = DummyResponse() + view = make_view(response) + self._registerView(registry, view, 'registered') + iterable = self._callFUT(context, request, name='registered', + secure=True) + self.assertEqual(iterable, ()) + +class RenderViewTests(BaseTest, unittest.TestCase): + def _callFUT(self, *arg, **kw): + from pyramid.view import render_view + return render_view(*arg, **kw) + + def test_call_no_view_registered(self): + request = self._makeRequest() + context = self._makeContext() + result = self._callFUT(context, request, name='notregistered') + self.assertEqual(result, None) + + def test_call_view_registered_secure(self): + request = self._makeRequest() + context = self._makeContext() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + s = self._callFUT(context, request, name='registered', secure=True) + self.assertEqual(s, b'') + + def test_call_view_registered_insecure_no_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + self._registerView(request.registry, view, 'registered') + s = self._callFUT(context, request, name='registered', secure=False) + self.assertEqual(s, b'') + + def test_call_view_registered_insecure_with_call_permissive(self): + context = self._makeContext() + request = self._makeRequest() + response = DummyResponse() + view = make_view(response) + def anotherview(context, request): + return DummyResponse(b'anotherview') + view.__call_permissive__ = anotherview + self._registerView(request.registry, view, 'registered') + s = self._callFUT(context, request, name='registered', secure=False) + self.assertEqual(s, b'anotherview') + +class TestViewConfigDecorator(unittest.TestCase): + def setUp(self): + testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _getTargetClass(self): + from pyramid.view import view_config + return view_config + + def _makeOne(self, *arg, **kw): + return self._getTargetClass()(*arg, **kw) + + def test_create_defaults(self): + decorator = self._makeOne() + self.assertEqual(decorator.__dict__, {}) + + def test_create_context_trumps_for(self): + decorator = self._makeOne(context='123', for_='456') + self.assertEqual(decorator.context, '123') + + def test_create_for_trumps_context_None(self): + decorator = self._makeOne(context=None, for_='456') + self.assertEqual(decorator.context, '456') + + def test_create_nondefaults(self): + decorator = self._makeOne( + name=None, request_type=None, for_=None, + permission='foo', mapper='mapper', + decorator='decorator', match_param='match_param' + ) + self.assertEqual(decorator.name, None) + self.assertEqual(decorator.request_type, None) + self.assertEqual(decorator.context, None) + self.assertEqual(decorator.permission, 'foo') + self.assertEqual(decorator.mapper, 'mapper') + self.assertEqual(decorator.decorator, 'decorator') + self.assertEqual(decorator.match_param, 'match_param') + + def test_create_with_other_predicates(self): + decorator = self._makeOne(foo=1) + self.assertEqual(decorator.foo, 1) + + def test_create_decorator_tuple(self): + decorator = self._makeOne(decorator=('decorator1', 'decorator2')) + self.assertEqual(decorator.decorator, ('decorator1', 'decorator2')) + + def test_call_function(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 3) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_call_class(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + class foo(object): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 4) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['attr'], 'foo') + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_call_class_attr_already_set(self): + decorator = self._makeOne(attr='abc') + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + class foo(object): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(len(settings[0]), 4) + self.assertEqual(settings[0]['venusian'], venusian) + self.assertEqual(settings[0]['view'], None) # comes from call_venusian + self.assertEqual(settings[0]['attr'], 'abc') + self.assertEqual(settings[0]['_info'], 'codeinfo') + + def test_stacking(self): + decorator1 = self._makeOne(name='1') + venusian1 = DummyVenusian() + decorator1.venusian = venusian1 + venusian2 = DummyVenusian() + decorator2 = self._makeOne(name='2') + decorator2.venusian = venusian2 + def foo(): pass + wrapped1 = decorator1(foo) + wrapped2 = decorator2(wrapped1) + self.assertTrue(wrapped1 is foo) + self.assertTrue(wrapped2 is foo) + config1 = call_venusian(venusian1) + self.assertEqual(len(config1.settings), 1) + self.assertEqual(config1.settings[0]['name'], '1') + config2 = call_venusian(venusian2) + self.assertEqual(len(config2.settings), 1) + self.assertEqual(config2.settings[0]['name'], '2') + + def test_call_as_method(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + decorator.venusian.info.scope = 'class' + def foo(self): pass + def bar(self): pass + class foo(object): + foomethod = decorator(foo) + barmethod = decorator(bar) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 2) + self.assertEqual(settings[0]['attr'], 'foo') + self.assertEqual(settings[1]['attr'], 'bar') + + def test_with_custom_predicates(self): + decorator = self._makeOne(custom_predicates=(1,)) + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(context, request): pass + decorated = decorator(foo) + self.assertTrue(decorated is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(settings[0]['custom_predicates'], (1,)) + + def test_call_with_renderer_string(self): + import pyramid.tests + decorator = self._makeOne(renderer='fixtures/minimal.pt') + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + renderer = settings[0]['renderer'] + self.assertEqual(renderer, 'fixtures/minimal.pt') + self.assertEqual(config.pkg, pyramid.tests) + + def test_call_with_renderer_dict(self): + import pyramid.tests + decorator = self._makeOne(renderer={'a':1}) + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + config = call_venusian(venusian) + settings = config.settings + self.assertEqual(len(settings), 1) + self.assertEqual(settings[0]['renderer'], {'a':1}) + self.assertEqual(config.pkg, pyramid.tests) + + def test_call_with_renderer_IRendererInfo(self): + import pyramid.tests + from pyramid.interfaces import IRendererInfo + @implementer(IRendererInfo) + class DummyRendererHelper(object): + pass + renderer_helper = DummyRendererHelper() + decorator = self._makeOne(renderer=renderer_helper) + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + wrapped = decorator(foo) + self.assertTrue(wrapped is foo) + context = DummyVenusianContext() + config = call_venusian(venusian, context) + settings = config.settings + self.assertEqual(len(settings), 1) + renderer = settings[0]['renderer'] + self.assertTrue(renderer is renderer_helper) + self.assertEqual(config.pkg, pyramid.tests) + + def test_call_withdepth(self): + decorator = self._makeOne(_depth=1) + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + depth = attachments[0][3] + self.assertEqual(depth, 2) + + def test_call_withoutcategory(self): + decorator = self._makeOne() + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + category = attachments[0][2] + self.assertEqual(category, 'pyramid') + + def test_call_withcategory(self): + decorator = self._makeOne(_category='not_pyramid') + venusian = DummyVenusian() + decorator.venusian = venusian + def foo(): pass + decorator(foo) + attachments = venusian.attachments + category = attachments[0][2] + self.assertEqual(category, 'not_pyramid') + +class Test_append_slash_notfound_view(BaseTest, unittest.TestCase): + def _callFUT(self, context, request): + from pyramid.view import append_slash_notfound_view + return append_slash_notfound_view(context, request) + + def _registerMapper(self, reg, match=True): + from pyramid.interfaces import IRoutesMapper + class DummyRoute(object): + def __init__(self, val): + self.val = val + def match(self, path): + return self.val + class DummyMapper(object): + def __init__(self): + self.routelist = [ DummyRoute(match) ] + def get_routes(self): + return self.routelist + mapper = DummyMapper() + reg.registerUtility(mapper, IRoutesMapper) + return mapper + + def test_context_is_not_exception(self): + request = self._makeRequest(PATH_INFO='/abc') + request.exception = ExceptionResponse() + context = DummyContext() + response = self._callFUT(context, request) + self.assertEqual(response.status, '404 Not Found') + self.assertEqual(response.app_iter, ['Not Found']) + + def test_no_mapper(self): + request = self._makeRequest(PATH_INFO='/abc') + context = ExceptionResponse() + response = self._callFUT(context, request) + self.assertEqual(response.status, '404 Not Found') + + def test_no_path(self): + request = self._makeRequest() + context = ExceptionResponse() + self._registerMapper(request.registry, True) + response = self._callFUT(context, request) + self.assertEqual(response.status, '404 Not Found') + + def test_mapper_path_already_slash_ending(self): + request = self._makeRequest(PATH_INFO='/abc/') + context = ExceptionResponse() + self._registerMapper(request.registry, True) + response = self._callFUT(context, request) + self.assertEqual(response.status, '404 Not Found') + + def test_no_route_matches(self): + request = self._makeRequest(PATH_INFO='/abc') + context = ExceptionResponse() + mapper = self._registerMapper(request.registry, True) + mapper.routelist[0].val = None + response = self._callFUT(context, request) + self.assertEqual(response.status, '404 Not Found') + + def test_matches(self): + request = self._makeRequest(PATH_INFO='/abc') + context = ExceptionResponse() + self._registerMapper(request.registry, True) + response = self._callFUT(context, request) + self.assertEqual(response.status, '307 Temporary Redirect') + self.assertEqual(response.location, '/abc/') + + def test_matches_with_script_name(self): + request = self._makeRequest(PATH_INFO='/abc', SCRIPT_NAME='/foo') + context = ExceptionResponse() + self._registerMapper(request.registry, True) + response = self._callFUT(context, request) + self.assertEqual(response.status, '307 Temporary Redirect') + self.assertEqual(response.location, '/foo/abc/') + + def test_with_query_string(self): + request = self._makeRequest(PATH_INFO='/abc', QUERY_STRING='a=1&b=2') + context = ExceptionResponse() + self._registerMapper(request.registry, True) + response = self._callFUT(context, request) + self.assertEqual(response.status, '307 Temporary Redirect') + self.assertEqual(response.location, '/abc/?a=1&b=2') + +class TestAppendSlashNotFoundViewFactory(BaseTest, unittest.TestCase): + def _makeOne(self, notfound_view): + from pyramid.view import AppendSlashNotFoundViewFactory + return AppendSlashNotFoundViewFactory(notfound_view) + + def test_custom_notfound_view(self): + request = self._makeRequest(PATH_INFO='/abc') + context = ExceptionResponse() + def custom_notfound(context, request): + return 'OK' + view = self._makeOne(custom_notfound) + response = view(context, request) + self.assertEqual(response, 'OK') + +class Test_default_exceptionresponse_view(unittest.TestCase): + def _callFUT(self, context, request): + from pyramid.view import default_exceptionresponse_view + return default_exceptionresponse_view(context, request) + + def test_is_exception(self): + context = Exception() + result = self._callFUT(context, None) + self.assertTrue(result is context) + + def test_is_not_exception_context_is_false_still_chose(self): + request = DummyRequest() + request.exception = 0 + result = self._callFUT(None, request) + self.assertTrue(result is None) + + def test_is_not_exception_no_request_exception(self): + context = object() + request = DummyRequest() + request.exception = None + result = self._callFUT(context, request) + self.assertTrue(result is context) + + def test_is_not_exception_request_exception(self): + context = object() + request = DummyRequest() + request.exception = 'abc' + result = self._callFUT(context, request) + self.assertEqual(result, 'abc') + +class Test_view_defaults(unittest.TestCase): + def test_it(self): + from pyramid.view import view_defaults + @view_defaults(route_name='abc', renderer='def') + class Foo(object): pass + self.assertEqual(Foo.__view_defaults__['route_name'],'abc') + self.assertEqual(Foo.__view_defaults__['renderer'],'def') + + def test_it_inheritance_not_overridden(self): + from pyramid.view import view_defaults + @view_defaults(route_name='abc', renderer='def') + class Foo(object): pass + class Bar(Foo): pass + self.assertEqual(Bar.__view_defaults__['route_name'],'abc') + self.assertEqual(Bar.__view_defaults__['renderer'],'def') + + def test_it_inheritance_overriden(self): + from pyramid.view import view_defaults + @view_defaults(route_name='abc', renderer='def') + class Foo(object): pass + @view_defaults(route_name='ghi') + class Bar(Foo): pass + self.assertEqual(Bar.__view_defaults__['route_name'],'ghi') + self.assertFalse('renderer' in Bar.__view_defaults__) + + def test_it_inheritance_overriden_empty(self): + from pyramid.view import view_defaults + @view_defaults(route_name='abc', renderer='def') + class Foo(object): pass + @view_defaults() + class Bar(Foo): pass + self.assertEqual(Bar.__view_defaults__, {}) + +class TestViewMethodsMixin(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + testing.tearDown() + + def _makeOne(self, environ=None): + from pyramid.decorator import reify + from pyramid.view import ViewMethodsMixin + if environ is None: + environ = {} + class Request(ViewMethodsMixin): + def __init__(self, environ): + self.environ = environ + + @reify + def response(self): + return DummyResponse() + request = Request(environ) + request.registry = self.config.registry + return request + + def test_it(self): + def exc_view(exc, request): + self.assertTrue(exc is dummy_exc) + self.assertTrue(request.exception is dummy_exc) + return DummyResponse(b'foo') + self.config.add_view(exc_view, context=RuntimeError) + request = self._makeOne() + dummy_exc = RuntimeError() + try: + raise dummy_exc + except RuntimeError: + response = request.invoke_exception_view() + self.assertEqual(response.app_iter, [b'foo']) + else: # pragma: no cover + self.fail() + + def test_it_hides_attrs(self): + def exc_view(exc, request): + self.assertTrue(exc is not orig_exc) + self.assertTrue(request.exception is not orig_exc) + self.assertTrue(request.exc_info is not orig_exc_info) + self.assertTrue(request.response is not orig_response) + request.response.app_iter = [b'bar'] + return request.response + self.config.add_view(exc_view, context=RuntimeError) + request = self._makeOne() + orig_exc = request.exception = DummyContext() + orig_exc_info = request.exc_info = DummyContext() + orig_response = request.response = DummyResponse(b'foo') + try: + raise RuntimeError + except RuntimeError as ex: + response = request.invoke_exception_view() + self.assertEqual(response.app_iter, [b'bar']) + self.assertTrue(request.exception is ex) + self.assertTrue(request.exc_info[1] is ex) + self.assertTrue(request.response is orig_response) + else: # pragma: no cover + self.fail() + + def test_it_supports_alternate_requests(self): + def exc_view(exc, request): + self.assertTrue(request is other_req) + from pyramid.threadlocal import get_current_request + self.assertTrue(get_current_request() is other_req) + return DummyResponse(b'foo') + self.config.add_view(exc_view, context=RuntimeError) + request = self._makeOne() + other_req = self._makeOne() + try: + raise RuntimeError + except RuntimeError: + response = request.invoke_exception_view(request=other_req) + self.assertEqual(response.app_iter, [b'foo']) + else: # pragma: no cover + self.fail() + + def test_it_supports_threadlocal_registry(self): + def exc_view(exc, request): + return DummyResponse(b'foo') + self.config.add_view(exc_view, context=RuntimeError) + request = self._makeOne() + del request.registry + try: + raise RuntimeError + except RuntimeError: + response = request.invoke_exception_view() + self.assertEqual(response.app_iter, [b'foo']) + else: # pragma: no cover + self.fail() + + def test_it_raises_if_no_registry(self): + request = self._makeOne() + del request.registry + from pyramid.threadlocal import manager + manager.push({'registry': None, 'request': request}) + try: + raise RuntimeError + except RuntimeError: + try: + request.invoke_exception_view() + except RuntimeError as e: + self.assertEqual(e.args[0], "Unable to retrieve registry") + else: # pragma: no cover + self.fail() + finally: + manager.pop() + + def test_it_supports_alternate_exc_info(self): + def exc_view(exc, request): + self.assertTrue(request.exc_info is exc_info) + return DummyResponse(b'foo') + self.config.add_view(exc_view, context=RuntimeError) + request = self._makeOne() + try: + raise RuntimeError + except RuntimeError: + exc_info = sys.exc_info() + response = request.invoke_exception_view(exc_info=exc_info) + self.assertEqual(response.app_iter, [b'foo']) + + def test_it_rejects_secured_view(self): + from pyramid.exceptions import Forbidden + def exc_view(exc, request): pass + self.config.testing_securitypolicy(permissive=False) + self.config.add_view(exc_view, context=RuntimeError, permission='view') + request = self._makeOne() + try: + raise RuntimeError + except RuntimeError: + self.assertRaises(Forbidden, request.invoke_exception_view) + else: # pragma: no cover + self.fail() + + def test_it_allows_secured_view(self): + def exc_view(exc, request): + return DummyResponse(b'foo') + self.config.testing_securitypolicy(permissive=False) + self.config.add_view(exc_view, context=RuntimeError, permission='view') + request = self._makeOne() + try: + raise RuntimeError + except RuntimeError: + response = request.invoke_exception_view(secure=False) + self.assertEqual(response.app_iter, [b'foo']) + else: # pragma: no cover + self.fail() + + def test_it_raises_if_not_found(self): + from pyramid.httpexceptions import HTTPNotFound + request = self._makeOne() + dummy_exc = RuntimeError() + try: + raise dummy_exc + except RuntimeError: + self.assertRaises(HTTPNotFound, request.invoke_exception_view) + else: # pragma: no cover + self.fail() + + def test_it_reraises_if_not_found(self): + request = self._makeOne() + dummy_exc = RuntimeError() + try: + raise dummy_exc + except RuntimeError: + self.assertRaises( + RuntimeError, + lambda: request.invoke_exception_view(reraise=True)) + else: # pragma: no cover + self.fail() + + def test_it_raises_predicate_mismatch(self): + from pyramid.exceptions import PredicateMismatch + def exc_view(exc, request): pass + self.config.add_view(exc_view, context=Exception, request_method='POST') + request = self._makeOne() + request.method = 'GET' + dummy_exc = RuntimeError() + try: + raise dummy_exc + except RuntimeError: + self.assertRaises(PredicateMismatch, request.invoke_exception_view) + else: # pragma: no cover + self.fail() + + def test_it_reraises_after_predicate_mismatch(self): + def exc_view(exc, request): pass + self.config.add_view(exc_view, context=Exception, request_method='POST') + request = self._makeOne() + request.method = 'GET' + dummy_exc = RuntimeError() + try: + raise dummy_exc + except RuntimeError: + self.assertRaises( + RuntimeError, + lambda: request.invoke_exception_view(reraise=True)) + else: # pragma: no cover + self.fail() + +class ExceptionResponse(Exception): + status = '404 Not Found' + app_iter = ['Not Found'] + headerlist = [] + +class DummyContext: + pass + +def make_view(response): + def view(context, request): + return response + return view + +class DummyRequest: + exception = None + request_iface = IRequest + + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + +from pyramid.interfaces import IResponse + +@implementer(IResponse) +class DummyResponse(object): + headerlist = () + app_iter = () + status = '200 OK' + environ = None + def __init__(self, body=None): + if body is None: + self.app_iter = () + else: + self.app_iter = [body] + +from zope.interface import Interface +class IContext(Interface): + pass + +class DummyVenusianInfo(object): + scope = 'notaclass' + module = sys.modules['pyramid.tests'] + codeinfo = 'codeinfo' + +class DummyVenusian(object): + def __init__(self, info=None): + if info is None: + info = DummyVenusianInfo() + self.info = info + self.attachments = [] + + def attach(self, wrapped, callback, category=None, depth=1): + self.attachments.append((wrapped, callback, category, depth)) + return self.info + +class DummyRegistry(object): + pass + +class DummyConfig(object): + def __init__(self): + self.settings = [] + self.registry = DummyRegistry() + + def add_view(self, **kw): + self.settings.append(kw) + + add_notfound_view = add_forbidden_view = add_exception_view = add_view + + def with_package(self, pkg): + self.pkg = pkg + return self + +class DummyVenusianContext(object): + def __init__(self): + self.config = DummyConfig() + +def call_venusian(venusian, context=None): + if context is None: + context = DummyVenusianContext() + for wrapped, callback, category, depth in venusian.attachments: + callback(context, None, None) + return context.config + diff --git a/tests/test_viewderivers.py b/tests/test_viewderivers.py new file mode 100644 index 000000000..6b81cc1e5 --- /dev/null +++ b/tests/test_viewderivers.py @@ -0,0 +1,1795 @@ +import unittest +from zope.interface import implementer + +from pyramid import testing +from pyramid.exceptions import ConfigurationError +from pyramid.interfaces import ( + IResponse, + IRequest, + ) + +class TestDeriveView(unittest.TestCase): + + def setUp(self): + self.config = testing.setUp() + self.config.set_default_csrf_options(require_csrf=False) + + def tearDown(self): + self.config = None + testing.tearDown() + + def _makeRequest(self): + request = DummyRequest() + request.registry = self.config.registry + return request + + def _registerLogger(self): + from pyramid.interfaces import IDebugLogger + logger = DummyLogger() + self.config.registry.registerUtility(logger, IDebugLogger) + return logger + + def _registerSecurityPolicy(self, permissive): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + policy = DummySecurityPolicy(permissive) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + + def test_function_returns_non_adaptable(self): + def view(request): + return None + result = self.config.derive_view(view) + self.assertFalse(result is view) + try: + result(None, None) + except ValueError as e: + self.assertEqual( + e.args[0], + 'Could not convert return value of the view callable function ' + 'pyramid.tests.test_viewderivers.view into a response ' + 'object. The value returned was None. You may have forgotten ' + 'to return a value from the view callable.' + ) + else: # pragma: no cover + raise AssertionError + + def test_function_returns_non_adaptable_dict(self): + def view(request): + return {'a':1} + result = self.config.derive_view(view) + self.assertFalse(result is view) + try: + result(None, None) + except ValueError as e: + self.assertEqual( + e.args[0], + "Could not convert return value of the view callable function " + "pyramid.tests.test_viewderivers.view into a response " + "object. The value returned was {'a': 1}. You may have " + "forgotten to define a renderer in the view configuration." + ) + else: # pragma: no cover + raise AssertionError + + def test_instance_returns_non_adaptable(self): + class AView(object): + def __call__(self, request): + return None + view = AView() + result = self.config.derive_view(view) + self.assertFalse(result is view) + try: + result(None, None) + except ValueError as e: + msg = e.args[0] + self.assertTrue(msg.startswith( + 'Could not convert return value of the view callable object ' + ' into a response object. The value returned was None. You ' + 'may have forgotten to return a value from the view callable.')) + else: # pragma: no cover + raise AssertionError + + def test_function_returns_true_Response_no_renderer(self): + from pyramid.response import Response + r = Response('Hello') + def view(request): + return r + result = self.config.derive_view(view) + self.assertFalse(result is view) + response = result(None, None) + self.assertEqual(response, r) + + def test_function_returns_true_Response_with_renderer(self): + from pyramid.response import Response + r = Response('Hello') + def view(request): + return r + renderer = object() + result = self.config.derive_view(view) + self.assertFalse(result is view) + response = result(None, None) + self.assertEqual(response, r) + + def test_requestonly_default_method_returns_non_adaptable(self): + request = DummyRequest() + class AView(object): + def __init__(self, request): + pass + def __call__(self): + return None + result = self.config.derive_view(AView) + self.assertFalse(result is AView) + try: + result(None, request) + except ValueError as e: + self.assertEqual( + e.args[0], + 'Could not convert return value of the view callable ' + 'method __call__ of ' + 'class pyramid.tests.test_viewderivers.AView into a ' + 'response object. The value returned was None. You may have ' + 'forgotten to return a value from the view callable.' + ) + else: # pragma: no cover + raise AssertionError + + def test_requestonly_nondefault_method_returns_non_adaptable(self): + request = DummyRequest() + class AView(object): + def __init__(self, request): + pass + def theviewmethod(self): + return None + result = self.config.derive_view(AView, attr='theviewmethod') + self.assertFalse(result is AView) + try: + result(None, request) + except ValueError as e: + self.assertEqual( + e.args[0], + 'Could not convert return value of the view callable ' + 'method theviewmethod of ' + 'class pyramid.tests.test_viewderivers.AView into a ' + 'response object. The value returned was None. You may have ' + 'forgotten to return a value from the view callable.' + ) + else: # pragma: no cover + raise AssertionError + + def test_requestonly_function(self): + response = DummyResponse() + def view(request): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(result(None, None), response) + + def test_requestonly_function_with_renderer(self): + response = DummyResponse() + class moo(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, 'OK') + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + def view(request): + return 'OK' + result = self.config.derive_view(view, renderer=moo()) + self.assertFalse(result.__wraps__ is view) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_requestonly_function_with_renderer_request_override(self): + def moo(info): + def inner(value, system): + self.assertEqual(value, 'OK') + self.assertEqual(system['request'], request) + self.assertEqual(system['context'], context) + return b'moo' + return inner + def view(request): + return 'OK' + self.config.add_renderer('moo', moo) + result = self.config.derive_view(view, renderer='string') + self.assertFalse(result is view) + request = self._makeRequest() + request.override_renderer = 'moo' + context = testing.DummyResource() + self.assertEqual(result(context, request).body, b'moo') + + def test_requestonly_function_with_renderer_request_has_view(self): + response = DummyResponse() + class moo(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, 'OK') + self.assertEqual(view_inst, 'view') + self.assertEqual(ctx, context) + return response + def clone(self): + return self + def view(request): + return 'OK' + result = self.config.derive_view(view, renderer=moo()) + self.assertFalse(result.__wraps__ is view) + request = self._makeRequest() + request.__view__ = 'view' + context = testing.DummyResource() + r = result(context, request) + self.assertEqual(r, response) + self.assertFalse(hasattr(request, '__view__')) + + def test_class_without_attr(self): + response = DummyResponse() + class View(object): + def __init__(self, request): + pass + def __call__(self): + return response + result = self.config.derive_view(View) + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, View) + + def test_class_with_attr(self): + response = DummyResponse() + class View(object): + def __init__(self, request): + pass + def another(self): + return response + result = self.config.derive_view(View, attr='another') + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, View) + + def test_as_function_context_and_request(self): + def view(context, request): + return 'OK' + result = self.config.derive_view(view) + self.assertTrue(result.__wraps__ is view) + self.assertFalse(hasattr(result, '__call_permissive__')) + self.assertEqual(view(None, None), 'OK') + + def test_as_function_requestonly(self): + response = DummyResponse() + def view(request): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), response) + + def test_as_newstyle_class_context_and_request(self): + response = DummyResponse() + class view(object): + def __init__(self, context, request): + pass + def __call__(self): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, view) + + def test_as_newstyle_class_requestonly(self): + response = DummyResponse() + class view(object): + def __init__(self, context, request): + pass + def __call__(self): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, view) + + def test_as_oldstyle_class_context_and_request(self): + response = DummyResponse() + class view: + def __init__(self, context, request): + pass + def __call__(self): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, view) + + def test_as_oldstyle_class_requestonly(self): + response = DummyResponse() + class view: + def __init__(self, context, request): + pass + def __call__(self): + return response + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + self.assertEqual(result(None, request), response) + self.assertEqual(request.__view__.__class__, view) + + def test_as_instance_context_and_request(self): + response = DummyResponse() + class View: + def __call__(self, context, request): + return response + view = View() + result = self.config.derive_view(view) + self.assertTrue(result.__wraps__ is view) + self.assertFalse(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), response) + + def test_as_instance_requestonly(self): + response = DummyResponse() + class View: + def __call__(self, request): + return response + view = View() + result = self.config.derive_view(view) + self.assertFalse(result is view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertTrue('test_viewderivers' in result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + self.assertEqual(result(None, None), response) + + def test_with_debug_authorization_no_authpol(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed " + "(no authorization policy in use)") + + def test_with_debug_authorization_authn_policy_no_authz_policy(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict(debug_authorization=True) + from pyramid.interfaces import IAuthenticationPolicy + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + logger = self._registerLogger() + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed " + "(no authorization policy in use)") + + def test_with_debug_authorization_authz_policy_no_authn_policy(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict(debug_authorization=True) + from pyramid.interfaces import IAuthorizationPolicy + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + logger = self._registerLogger() + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed " + "(no authorization policy in use)") + + def test_with_debug_authorization_no_permission(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + self._registerSecurityPolicy(True) + logger = self._registerLogger() + result = self.config._derive_view(view) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): Allowed (" + "no permission registered)") + + def test_debug_auth_permission_authpol_permitted(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(True) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__.__wraps__, view) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): True") + + def test_debug_auth_permission_authpol_permitted_no_request(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(True) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__.__wraps__, view) + self.assertEqual(result(None, None), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url None (view name " + "None against context None): True") + + def test_debug_auth_permission_authpol_denied(self): + from pyramid.httpexceptions import HTTPForbidden + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(False) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__.__wraps__, view) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertRaises(HTTPForbidden, result, None, request) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): False") + + def test_debug_auth_permission_authpol_denied2(self): + view = lambda *arg: 'OK' + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + self._registerLogger() + self._registerSecurityPolicy(False) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + permitted = result.__permitted__(None, None) + self.assertEqual(permitted, False) + + def test_debug_auth_permission_authpol_overridden(self): + from pyramid.security import NO_PERMISSION_REQUIRED + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(False) + result = self.config._derive_view(view, permission=NO_PERMISSION_REQUIRED) + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context None): " + "Allowed (NO_PERMISSION_REQUIRED)") + + def test_debug_auth_permission_authpol_permitted_excview(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = dict( + debug_authorization=True, reload_templates=True) + logger = self._registerLogger() + self._registerSecurityPolicy(True) + result = self.config._derive_view( + view, context=Exception, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertEqual(result.__call_permissive__.__wraps__, view) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(Exception(), request), response) + self.assertEqual(len(logger.messages), 1) + self.assertEqual(logger.messages[0], + "debug_authorization of url url (view name " + "'view_name' against context Exception()): True") + + def test_secured_view_authn_policy_no_authz_policy(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = {} + from pyramid.interfaces import IAuthenticationPolicy + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + + def test_secured_view_authz_policy_no_authn_policy(self): + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = {} + from pyramid.interfaces import IAuthorizationPolicy + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + result = self.config._derive_view(view, permission='view') + self.assertEqual(view.__module__, result.__module__) + self.assertEqual(view.__doc__, result.__doc__) + self.assertEqual(view.__name__, result.__name__) + self.assertFalse(hasattr(result, '__call_permissive__')) + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + self.assertEqual(result(None, request), response) + + def test_secured_view_raises_forbidden_no_name(self): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + from pyramid.httpexceptions import HTTPForbidden + response = DummyResponse() + view = lambda *arg: response + self.config.registry.settings = {} + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + result = self.config._derive_view(view, permission='view') + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + try: + result(None, request) + except HTTPForbidden as e: + self.assertEqual(e.message, + 'Unauthorized: failed permission check') + else: # pragma: no cover + raise AssertionError + + def test_secured_view_raises_forbidden_with_name(self): + from pyramid.interfaces import IAuthenticationPolicy + from pyramid.interfaces import IAuthorizationPolicy + from pyramid.httpexceptions import HTTPForbidden + def myview(request): pass + self.config.registry.settings = {} + policy = DummySecurityPolicy(False) + self.config.registry.registerUtility(policy, IAuthenticationPolicy) + self.config.registry.registerUtility(policy, IAuthorizationPolicy) + result = self.config._derive_view(myview, permission='view') + request = self._makeRequest() + request.view_name = 'view_name' + request.url = 'url' + try: + result(None, request) + except HTTPForbidden as e: + self.assertEqual(e.message, + 'Unauthorized: myview failed permission check') + else: # pragma: no cover + raise AssertionError + + def test_secured_view_skipped_by_default_on_exception_view(self): + from pyramid.request import Request + from pyramid.security import NO_PERMISSION_REQUIRED + def view(request): + raise ValueError + def excview(request): + return 'hello' + self._registerSecurityPolicy(False) + self.config.add_settings({'debug_authorization': True}) + self.config.set_default_permission('view') + self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) + self.config.add_view(excview, context=ValueError, renderer='string') + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + response = request.get_response(app) + self.assertTrue(b'hello' in response.body) + + def test_secured_view_failed_on_explicit_exception_view(self): + from pyramid.httpexceptions import HTTPForbidden + from pyramid.request import Request + from pyramid.security import NO_PERMISSION_REQUIRED + def view(request): + raise ValueError + def excview(request): pass + self._registerSecurityPolicy(False) + self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) + self.config.add_view(excview, context=ValueError, renderer='string', + permission='view') + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + try: + request.get_response(app) + except HTTPForbidden: + pass + else: # pragma: no cover + raise AssertionError + + def test_secured_view_passed_on_explicit_exception_view(self): + from pyramid.request import Request + from pyramid.security import NO_PERMISSION_REQUIRED + def view(request): + raise ValueError + def excview(request): + return 'hello' + self._registerSecurityPolicy(True) + self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) + self.config.add_view(excview, context=ValueError, renderer='string', + permission='view') + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + request.headers['X-CSRF-Token'] = 'foo' + response = request.get_response(app) + self.assertTrue(b'hello' in response.body) + + def test_predicate_mismatch_view_has_no_name(self): + from pyramid.exceptions import PredicateMismatch + response = DummyResponse() + view = lambda *arg: response + def predicate1(context, request): + return False + predicate1.text = lambda *arg: 'text' + result = self.config._derive_view(view, predicates=[predicate1]) + request = self._makeRequest() + request.method = 'POST' + try: + result(None, None) + except PredicateMismatch as e: + self.assertEqual(e.detail, + 'predicate mismatch for view (text)') + else: # pragma: no cover + raise AssertionError + + def test_predicate_mismatch_view_has_name(self): + from pyramid.exceptions import PredicateMismatch + def myview(request): pass + def predicate1(context, request): + return False + predicate1.text = lambda *arg: 'text' + result = self.config._derive_view(myview, predicates=[predicate1]) + request = self._makeRequest() + request.method = 'POST' + try: + result(None, None) + except PredicateMismatch as e: + self.assertEqual(e.detail, + 'predicate mismatch for view myview (text)') + else: # pragma: no cover + raise AssertionError + + def test_predicate_mismatch_exception_has_text_in_detail(self): + from pyramid.exceptions import PredicateMismatch + def myview(request): pass + def predicate1(context, request): + return True + predicate1.text = lambda *arg: 'pred1' + def predicate2(context, request): + return False + predicate2.text = lambda *arg: 'pred2' + result = self.config._derive_view(myview, + predicates=[predicate1, predicate2]) + request = self._makeRequest() + request.method = 'POST' + try: + result(None, None) + except PredicateMismatch as e: + self.assertEqual(e.detail, + 'predicate mismatch for view myview (pred2)') + else: # pragma: no cover + raise AssertionError + + def test_with_predicates_all(self): + response = DummyResponse() + view = lambda *arg: response + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + result = self.config._derive_view(view, + predicates=[predicate1, predicate2]) + request = self._makeRequest() + request.method = 'POST' + next = result(None, None) + self.assertEqual(next, response) + self.assertEqual(predicates, [True, True]) + + def test_with_predicates_checker(self): + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + def predicate2(context, request): + predicates.append(True) + return True + result = self.config._derive_view(view, + predicates=[predicate1, predicate2]) + request = self._makeRequest() + request.method = 'POST' + next = result.__predicated__(None, None) + self.assertEqual(next, True) + self.assertEqual(predicates, [True, True]) + + def test_with_predicates_notall(self): + from pyramid.httpexceptions import HTTPNotFound + view = lambda *arg: 'OK' + predicates = [] + def predicate1(context, request): + predicates.append(True) + return True + predicate1.text = lambda *arg: 'text' + def predicate2(context, request): + predicates.append(True) + return False + predicate2.text = lambda *arg: 'text' + result = self.config._derive_view(view, + predicates=[predicate1, predicate2]) + request = self._makeRequest() + request.method = 'POST' + self.assertRaises(HTTPNotFound, result, None, None) + self.assertEqual(predicates, [True, True]) + + def test_with_wrapper_viewname(self): + from pyramid.response import Response + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + def outer_view(context, request): + self.assertEqual(request.wrapped_response, inner_response) + self.assertEqual(request.wrapped_body, inner_response.body) + self.assertEqual(request.wrapped_view.__original_view__, + inner_view) + return Response(b'outer ' + request.wrapped_body) + self.config.registry.registerAdapter( + outer_view, (IViewClassifier, None, None), IView, 'owrap') + result = self.config._derive_view(inner_view, viewname='inner', + wrapper_viewname='owrap') + self.assertFalse(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + response = result(None, request) + self.assertEqual(response.body, b'outer OK') + + def test_with_wrapper_viewname_notfound(self): + from pyramid.response import Response + inner_response = Response('OK') + def inner_view(context, request): + return inner_response + wrapped = self.config._derive_view(inner_view, viewname='inner', + wrapper_viewname='owrap') + request = self._makeRequest() + self.assertRaises(ValueError, wrapped, None, request) + + def test_as_newstyle_class_context_and_request_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View(object): + def __init__(self, context, request): + pass + def index(self): + return {'a':'1'} + result = self.config._derive_view(View, + renderer=renderer(), attr='index') + self.assertFalse(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_as_newstyle_class_requestonly_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View(object): + def __init__(self, request): + pass + def index(self): + return {'a':'1'} + result = self.config.derive_view(View, + renderer=renderer(), attr='index') + self.assertFalse(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_as_oldstyle_cls_context_request_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View: + def __init__(self, context, request): + pass + def index(self): + return {'a':'1'} + result = self.config.derive_view(View, + renderer=renderer(), attr='index') + self.assertFalse(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_as_oldstyle_cls_requestonly_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst.__class__, View) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View: + def __init__(self, request): + pass + def index(self): + return {'a':'1'} + result = self.config.derive_view(View, + renderer=renderer(), attr='index') + self.assertFalse(result is View) + self.assertEqual(result.__module__, View.__module__) + self.assertEqual(result.__doc__, View.__doc__) + self.assertEqual(result.__name__, View.__name__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_as_instance_context_and_request_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View: + def index(self, context, request): + return {'a':'1'} + view = View() + result = self.config.derive_view(view, + renderer=renderer(), attr='index') + self.assertFalse(result is view) + self.assertEqual(result.__module__, view.__module__) + self.assertEqual(result.__doc__, view.__doc__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_as_instance_requestonly_attr_and_renderer(self): + response = DummyResponse() + class renderer(object): + def render_view(inself, req, resp, view_inst, ctx): + self.assertEqual(req, request) + self.assertEqual(resp, {'a':'1'}) + self.assertEqual(view_inst, view) + self.assertEqual(ctx, context) + return response + def clone(self): + return self + class View: + def index(self, request): + return {'a':'1'} + view = View() + result = self.config.derive_view(view, + renderer=renderer(), attr='index') + self.assertFalse(result is view) + self.assertEqual(result.__module__, view.__module__) + self.assertEqual(result.__doc__, view.__doc__) + request = self._makeRequest() + context = testing.DummyResource() + self.assertEqual(result(context, request), response) + + def test_with_view_mapper_config_specified(self): + response = DummyResponse() + class mapper(object): + def __init__(self, **kw): + self.kw = kw + def __call__(self, view): + def wrapped(context, request): + return response + return wrapped + def view(context, request): return 'NOTOK' + result = self.config._derive_view(view, mapper=mapper) + self.assertFalse(result.__wraps__ is view) + self.assertEqual(result(None, None), response) + + def test_with_view_mapper_view_specified(self): + from pyramid.response import Response + response = Response() + def mapper(**kw): + def inner(view): + def superinner(context, request): + self.assertEqual(request, None) + return response + return superinner + return inner + def view(context, request): return 'NOTOK' + view.__view_mapper__ = mapper + result = self.config.derive_view(view) + self.assertFalse(result.__wraps__ is view) + self.assertEqual(result(None, None), response) + + def test_with_view_mapper_default_mapper_specified(self): + from pyramid.response import Response + response = Response() + def mapper(**kw): + def inner(view): + def superinner(context, request): + self.assertEqual(request, None) + return response + return superinner + return inner + self.config.set_view_mapper(mapper) + def view(context, request): return 'NOTOK' + result = self.config.derive_view(view) + self.assertFalse(result.__wraps__ is view) + self.assertEqual(result(None, None), response) + + def test_attr_wrapped_view_branching_default_phash(self): + from pyramid.config.util import DEFAULT_PHASH + def view(context, request): pass + result = self.config._derive_view(view, phash=DEFAULT_PHASH) + self.assertEqual(result.__wraps__, view) + + def test_attr_wrapped_view_branching_nondefault_phash(self): + def view(context, request): pass + result = self.config._derive_view(view, phash='nondefault') + self.assertNotEqual(result, view) + + def test_http_cached_view_integer(self): + import datetime + from pyramid.response import Response + response = Response('OK') + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, http_cache=3600) + self.assertFalse(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + expires = parse_httpdate(headers['Expires']) + assert_similar_datetime(expires, when) + self.assertEqual(headers['Cache-Control'], 'max-age=3600') + + def test_http_cached_view_timedelta(self): + import datetime + from pyramid.response import Response + response = Response('OK') + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, + http_cache=datetime.timedelta(hours=1)) + self.assertFalse(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + expires = parse_httpdate(headers['Expires']) + assert_similar_datetime(expires, when) + self.assertEqual(headers['Cache-Control'], 'max-age=3600') + + def test_http_cached_view_tuple(self): + import datetime + from pyramid.response import Response + response = Response('OK') + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, + http_cache=(3600, {'public':True})) + self.assertFalse(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + when = datetime.datetime.utcnow() + datetime.timedelta(hours=1) + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + expires = parse_httpdate(headers['Expires']) + assert_similar_datetime(expires, when) + self.assertEqual(headers['Cache-Control'], 'max-age=3600, public') + + def test_http_cached_view_tuple_seconds_None(self): + from pyramid.response import Response + response = Response('OK') + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, + http_cache=(None, {'public':True})) + self.assertFalse(result is inner_view) + self.assertEqual(inner_view.__module__, result.__module__) + self.assertEqual(inner_view.__doc__, result.__doc__) + request = self._makeRequest() + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + self.assertFalse('Expires' in headers) + self.assertEqual(headers['Cache-Control'], 'public') + + def test_http_cached_view_prevent_auto_set(self): + from pyramid.response import Response + response = Response() + response.cache_control.prevent_auto = True + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, http_cache=3600) + request = self._makeRequest() + result = result(None, request) + self.assertEqual(result, response) # doesn't blow up + headers = dict(result.headerlist) + self.assertFalse('Expires' in headers) + self.assertFalse('Cache-Control' in headers) + + def test_http_cached_prevent_http_cache_in_settings(self): + self.config.registry.settings['prevent_http_cache'] = True + from pyramid.response import Response + response = Response() + def inner_view(context, request): + return response + result = self.config._derive_view(inner_view, http_cache=3600) + request = self._makeRequest() + result = result(None, request) + self.assertEqual(result, response) + headers = dict(result.headerlist) + self.assertFalse('Expires' in headers) + self.assertFalse('Cache-Control' in headers) + + def test_http_cached_view_bad_tuple(self): + def view(request): pass + self.assertRaises(ConfigurationError, self.config._derive_view, + view, http_cache=(None,)) + + def test_csrf_view_ignores_GET(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.method = 'GET' + view = self.config._derive_view(inner_view, require_csrf=True) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_fails_with_bad_POST_header(self): + from pyramid.exceptions import BadCSRFToken + def inner_view(request): pass + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.headers = {'X-CSRF-Token': 'bar'} + view = self.config._derive_view(inner_view, require_csrf=True) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_csrf_view_passes_with_good_POST_header(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.headers = {'X-CSRF-Token': 'foo'} + view = self.config._derive_view(inner_view, require_csrf=True) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_fails_with_bad_POST_token(self): + from pyramid.exceptions import BadCSRFToken + def inner_view(request): pass + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'csrf_token': 'bar'} + view = self.config._derive_view(inner_view, require_csrf=True) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_csrf_view_passes_with_good_POST_token(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'csrf_token': 'foo'} + view = self.config._derive_view(inner_view, require_csrf=True) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_https_domain(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "https" + request.domain = "example.com" + request.host_port = "443" + request.referrer = "https://example.com/login/" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'csrf_token': 'foo'} + view = self.config._derive_view(inner_view, require_csrf=True) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_fails_on_bad_PUT_header(self): + from pyramid.exceptions import BadCSRFToken + def inner_view(request): pass + request = self._makeRequest() + request.scheme = "http" + request.method = 'PUT' + request.session = DummySession({'csrf_token': 'foo'}) + request.headers = {'X-CSRF-Token': 'bar'} + view = self.config._derive_view(inner_view, require_csrf=True) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_csrf_view_fails_on_bad_referrer(self): + from pyramid.exceptions import BadCSRFOrigin + def inner_view(request): pass + request = self._makeRequest() + request.method = "POST" + request.scheme = "https" + request.host_port = "443" + request.domain = "example.com" + request.referrer = "https://not-example.com/evil/" + request.registry.settings = {} + view = self.config._derive_view(inner_view, require_csrf=True) + self.assertRaises(BadCSRFOrigin, lambda: view(None, request)) + + def test_csrf_view_fails_on_bad_origin(self): + from pyramid.exceptions import BadCSRFOrigin + def inner_view(request): pass + request = self._makeRequest() + request.method = "POST" + request.scheme = "https" + request.host_port = "443" + request.domain = "example.com" + request.headers = {"Origin": "https://not-example.com/evil/"} + request.registry.settings = {} + view = self.config._derive_view(inner_view, require_csrf=True) + self.assertRaises(BadCSRFOrigin, lambda: view(None, request)) + + def test_csrf_view_enabled_by_default(self): + from pyramid.exceptions import BadCSRFToken + def inner_view(request): pass + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + self.config.set_default_csrf_options(require_csrf=True) + view = self.config._derive_view(inner_view) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_csrf_view_enabled_via_callback(self): + def callback(request): + return True + from pyramid.exceptions import BadCSRFToken + def inner_view(request): pass + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + self.config.set_default_csrf_options(require_csrf=True, callback=callback) + view = self.config._derive_view(inner_view) + self.assertRaises(BadCSRFToken, lambda: view(None, request)) + + def test_csrf_view_disabled_via_callback(self): + def callback(request): + return False + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + self.config.set_default_csrf_options(require_csrf=True, callback=callback) + view = self.config._derive_view(inner_view) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_uses_custom_csrf_token(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'DUMMY': 'foo'} + self.config.set_default_csrf_options(require_csrf=True, token='DUMMY') + view = self.config._derive_view(inner_view) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_uses_custom_csrf_header(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.headers = {'DUMMY': 'foo'} + self.config.set_default_csrf_options(require_csrf=True, header='DUMMY') + view = self.config._derive_view(inner_view) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_uses_custom_methods(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'PUT' + request.session = DummySession({'csrf_token': 'foo'}) + self.config.set_default_csrf_options( + require_csrf=True, safe_methods=['PUT']) + view = self.config._derive_view(inner_view) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_uses_view_option_override(self): + response = DummyResponse() + def inner_view(request): + return response + request = self._makeRequest() + request.scheme = "http" + request.method = 'POST' + request.session = DummySession({'csrf_token': 'foo'}) + request.POST = {'csrf_token': 'bar'} + self.config.set_default_csrf_options(require_csrf=True) + view = self.config._derive_view(inner_view, require_csrf=False) + result = view(None, request) + self.assertTrue(result is response) + + def test_csrf_view_skipped_by_default_on_exception_view(self): + from pyramid.request import Request + def view(request): + raise ValueError + def excview(request): + return 'hello' + self.config.set_default_csrf_options(require_csrf=True) + self.config.set_session_factory( + lambda request: DummySession({'csrf_token': 'foo'})) + self.config.add_view(view, name='foo', require_csrf=False) + self.config.add_view(excview, context=ValueError, renderer='string') + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + response = request.get_response(app) + self.assertTrue(b'hello' in response.body) + + def test_csrf_view_failed_on_explicit_exception_view(self): + from pyramid.exceptions import BadCSRFToken + from pyramid.request import Request + def view(request): + raise ValueError + def excview(request): pass + self.config.set_default_csrf_options(require_csrf=True) + self.config.set_session_factory( + lambda request: DummySession({'csrf_token': 'foo'})) + self.config.add_view(view, name='foo', require_csrf=False) + self.config.add_view(excview, context=ValueError, renderer='string', + require_csrf=True) + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + try: + request.get_response(app) + except BadCSRFToken: + pass + else: # pragma: no cover + raise AssertionError + + def test_csrf_view_passed_on_explicit_exception_view(self): + from pyramid.request import Request + def view(request): + raise ValueError + def excview(request): + return 'hello' + self.config.set_default_csrf_options(require_csrf=True) + self.config.set_session_factory( + lambda request: DummySession({'csrf_token': 'foo'})) + self.config.add_view(view, name='foo', require_csrf=False) + self.config.add_view(excview, context=ValueError, renderer='string', + require_csrf=True) + app = self.config.make_wsgi_app() + request = Request.blank('/foo', base_url='http://example.com') + request.method = 'POST' + request.headers['X-CSRF-Token'] = 'foo' + response = request.get_response(app) + self.assertTrue(b'hello' in response.body) + + +class TestDerivationOrder(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + self.config = None + testing.tearDown() + + def test_right_order_user_sorted(self): + from pyramid.interfaces import IViewDerivers + + self.config.add_view_deriver(None, 'deriv1') + self.config.add_view_deriver(None, 'deriv2', 'decorated_view', 'deriv1') + self.config.add_view_deriver(None, 'deriv3', 'deriv2', 'deriv1') + + derivers = self.config.registry.getUtility(IViewDerivers) + derivers_sorted = derivers.sorted() + dlist = [d for (d, _) in derivers_sorted] + self.assertEqual([ + 'secured_view', + 'csrf_view', + 'owrapped_view', + 'http_cached_view', + 'decorated_view', + 'deriv2', + 'deriv3', + 'deriv1', + 'rendered_view', + 'mapped_view', + ], dlist) + + def test_right_order_implicit(self): + from pyramid.interfaces import IViewDerivers + + self.config.add_view_deriver(None, 'deriv1') + self.config.add_view_deriver(None, 'deriv2') + self.config.add_view_deriver(None, 'deriv3') + + derivers = self.config.registry.getUtility(IViewDerivers) + derivers_sorted = derivers.sorted() + dlist = [d for (d, _) in derivers_sorted] + self.assertEqual([ + 'secured_view', + 'csrf_view', + 'owrapped_view', + 'http_cached_view', + 'decorated_view', + 'deriv3', + 'deriv2', + 'deriv1', + 'rendered_view', + 'mapped_view', + ], dlist) + + def test_right_order_under_rendered_view(self): + from pyramid.interfaces import IViewDerivers + + self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') + + derivers = self.config.registry.getUtility(IViewDerivers) + derivers_sorted = derivers.sorted() + dlist = [d for (d, _) in derivers_sorted] + self.assertEqual([ + 'secured_view', + 'csrf_view', + 'owrapped_view', + 'http_cached_view', + 'decorated_view', + 'rendered_view', + 'deriv1', + 'mapped_view', + ], dlist) + + + def test_right_order_under_rendered_view_others(self): + from pyramid.interfaces import IViewDerivers + + self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') + self.config.add_view_deriver(None, 'deriv2') + self.config.add_view_deriver(None, 'deriv3') + + derivers = self.config.registry.getUtility(IViewDerivers) + derivers_sorted = derivers.sorted() + dlist = [d for (d, _) in derivers_sorted] + self.assertEqual([ + 'secured_view', + 'csrf_view', + 'owrapped_view', + 'http_cached_view', + 'decorated_view', + 'deriv3', + 'deriv2', + 'rendered_view', + 'deriv1', + 'mapped_view', + ], dlist) + + +class TestAddDeriver(unittest.TestCase): + + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + self.config = None + testing.tearDown() + + def test_add_single_deriver(self): + response = DummyResponse() + response.deriv = False + view = lambda *arg: response + + def deriv(view, info): + self.assertFalse(response.deriv) + response.deriv = True + return view + + result = self.config._derive_view(view) + self.assertFalse(response.deriv) + self.config.add_view_deriver(deriv, 'test_deriv') + + result = self.config._derive_view(view) + self.assertTrue(response.deriv) + + def test_override_deriver(self): + flags = {} + + class AView: + def __init__(self): + self.response = DummyResponse() + + def deriv1(view, info): + flags['deriv1'] = True + return view + + def deriv2(view, info): + flags['deriv2'] = True + return view + + view1 = AView() + self.config.add_view_deriver(deriv1, 'test_deriv') + result = self.config._derive_view(view1) + self.assertTrue(flags.get('deriv1')) + self.assertFalse(flags.get('deriv2')) + + flags.clear() + view2 = AView() + self.config.add_view_deriver(deriv2, 'test_deriv') + result = self.config._derive_view(view2) + self.assertFalse(flags.get('deriv1')) + self.assertTrue(flags.get('deriv2')) + + def test_override_mapped_view(self): + from pyramid.viewderivers import VIEW + response = DummyResponse() + view = lambda *arg: response + flags = {} + + def deriv1(view, info): + flags['deriv1'] = True + return view + + result = self.config._derive_view(view) + self.assertFalse(flags.get('deriv1')) + + flags.clear() + self.config.add_view_deriver( + deriv1, name='mapped_view', under='rendered_view', over=VIEW) + result = self.config._derive_view(view) + self.assertTrue(flags.get('deriv1')) + + def test_add_multi_derivers_ordered(self): + from pyramid.viewderivers import INGRESS + response = DummyResponse() + view = lambda *arg: response + response.deriv = [] + + def deriv1(view, info): + response.deriv.append('deriv1') + return view + + def deriv2(view, info): + response.deriv.append('deriv2') + return view + + def deriv3(view, info): + response.deriv.append('deriv3') + return view + + self.config.add_view_deriver(deriv1, 'deriv1') + self.config.add_view_deriver(deriv2, 'deriv2', INGRESS, 'deriv1') + self.config.add_view_deriver(deriv3, 'deriv3', 'deriv2', 'deriv1') + result = self.config._derive_view(view) + self.assertEqual(response.deriv, ['deriv1', 'deriv3', 'deriv2']) + + def test_add_deriver_without_name(self): + from pyramid.interfaces import IViewDerivers + def deriv1(view, info): pass + self.config.add_view_deriver(deriv1) + derivers = self.config.registry.getUtility(IViewDerivers) + self.assertTrue('deriv1' in derivers.names) + + def test_add_deriver_reserves_ingress(self): + from pyramid.exceptions import ConfigurationError + from pyramid.viewderivers import INGRESS + def deriv1(view, info): pass + self.assertRaises( + ConfigurationError, self.config.add_view_deriver, deriv1, INGRESS) + + def test_add_deriver_enforces_ingress_is_first(self): + from pyramid.exceptions import ConfigurationError + from pyramid.viewderivers import INGRESS + def deriv1(view, info): pass + try: + self.config.add_view_deriver(deriv1, over=INGRESS) + except ConfigurationError as ex: + self.assertTrue('cannot be over INGRESS' in ex.args[0]) + else: # pragma: no cover + raise AssertionError + + def test_add_deriver_enforces_view_is_last(self): + from pyramid.exceptions import ConfigurationError + from pyramid.viewderivers import VIEW + def deriv1(view, info): pass + try: + self.config.add_view_deriver(deriv1, under=VIEW) + except ConfigurationError as ex: + self.assertTrue('cannot be under VIEW' in ex.args[0]) + else: # pragma: no cover + raise AssertionError + + def test_add_deriver_enforces_mapped_view_is_last(self): + from pyramid.exceptions import ConfigurationError + def deriv1(view, info): pass + try: + self.config.add_view_deriver(deriv1, 'deriv1', under='mapped_view') + except ConfigurationError as ex: + self.assertTrue('cannot be under "mapped_view"' in ex.args[0]) + else: # pragma: no cover + raise AssertionError + + +class TestDeriverIntegration(unittest.TestCase): + def setUp(self): + self.config = testing.setUp() + + def tearDown(self): + self.config = None + testing.tearDown() + + def _getViewCallable(self, config, ctx_iface=None, request_iface=None, + name=''): + from zope.interface import Interface + from pyramid.interfaces import IRequest + from pyramid.interfaces import IView + from pyramid.interfaces import IViewClassifier + classifier = IViewClassifier + if ctx_iface is None: + ctx_iface = Interface + if request_iface is None: + request_iface = IRequest + return config.registry.adapters.lookup( + (classifier, request_iface, ctx_iface), IView, name=name, + default=None) + + def _makeRequest(self, config): + request = DummyRequest() + request.registry = config.registry + return request + + def test_view_options(self): + response = DummyResponse() + view = lambda *arg: response + response.deriv = [] + + def deriv1(view, info): + response.deriv.append(info.options['deriv1']) + return view + deriv1.options = ('deriv1',) + + def deriv2(view, info): + response.deriv.append(info.options['deriv2']) + return view + deriv2.options = ('deriv2',) + + self.config.add_view_deriver(deriv1, 'deriv1') + self.config.add_view_deriver(deriv2, 'deriv2') + self.config.add_view(view, deriv1='test1', deriv2='test2') + + wrapper = self._getViewCallable(self.config) + request = self._makeRequest(self.config) + request.method = 'GET' + self.assertEqual(wrapper(None, request), response) + self.assertEqual(['test1', 'test2'], response.deriv) + + def test_unexpected_view_options(self): + from pyramid.exceptions import ConfigurationError + def deriv1(view, info): pass + self.config.add_view_deriver(deriv1, 'deriv1') + self.assertRaises( + ConfigurationError, + lambda: self.config.add_view(lambda r: {}, deriv1='test1')) + +@implementer(IResponse) +class DummyResponse(object): + content_type = None + default_content_type = None + body = None + +class DummyRequest: + subpath = () + matchdict = None + request_iface = IRequest + + def __init__(self, environ=None): + if environ is None: + environ = {} + self.environ = environ + self.params = {} + self.POST = {} + self.cookies = {} + self.headers = {} + self.response = DummyResponse() + +class DummyLogger: + def __init__(self): + self.messages = [] + def info(self, msg): + self.messages.append(msg) + warn = info + debug = info + +class DummySecurityPolicy: + def __init__(self, permitted=True): + self.permitted = permitted + + def effective_principals(self, request): + return [] + + def permits(self, context, principals, permission): + return self.permitted + +class DummySession(dict): + def get_csrf_token(self): + return self['csrf_token'] + +def parse_httpdate(s): + import datetime + # cannot use %Z, must use literal GMT; Jython honors timezone + # but CPython does not + return datetime.datetime.strptime(s, "%a, %d %b %Y %H:%M:%S GMT") + +def assert_similar_datetime(one, two): + for attr in ('year', 'month', 'day', 'hour', 'minute'): + one_attr = getattr(one, attr) + two_attr = getattr(two, attr) + if not one_attr == two_attr: # pragma: no cover + raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr)) diff --git a/tests/test_wsgi.py b/tests/test_wsgi.py new file mode 100644 index 000000000..4ddbc9201 --- /dev/null +++ b/tests/test_wsgi.py @@ -0,0 +1,130 @@ +import unittest + +class WSGIAppTests(unittest.TestCase): + def _callFUT(self, app): + from pyramid.wsgi import wsgiapp + return wsgiapp(app) + + def test_wsgiapp_none(self): + self.assertRaises(ValueError, self._callFUT, None) + + def test_decorator(self): + context = DummyContext() + request = DummyRequest() + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + + def test_decorator_object_instance(self): + context = DummyContext() + request = DummyRequest() + app = DummyApp() + decorator = self._callFUT(app) + response = decorator(context, request) + self.assertEqual(response, app) + +class WSGIApp2Tests(unittest.TestCase): + def _callFUT(self, app): + from pyramid.wsgi import wsgiapp2 + return wsgiapp2(app) + + def test_wsgiapp2_none(self): + self.assertRaises(ValueError, self._callFUT, None) + + def test_decorator_with_subpath_and_view_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = ('subpath',) + request.environ = {'SCRIPT_NAME':'/foo', + 'PATH_INFO':'/b/view_name/subpath'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/subpath') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') + + def test_decorator_with_subpath_no_view_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = ('subpath',) + request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/subpath'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/subpath') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b') + + def test_decorator_no_subpath_with_view_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = () + request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/b/view_name'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/b/view_name') + + def test_decorator_traversed_empty_with_view_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = () + request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/view_name'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo/view_name') + + def test_decorator_traversed_empty_no_view_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = () + request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo') + + def test_decorator_traversed_empty_no_view_name_no_script_name(self): + context = DummyContext() + request = DummyRequest() + request.subpath = () + request.environ = {'SCRIPT_NAME':'', 'PATH_INFO':'/'} + decorator = self._callFUT(dummyapp) + response = decorator(context, request) + self.assertEqual(response, dummyapp) + self.assertEqual(request.environ['PATH_INFO'], '/') + self.assertEqual(request.environ['SCRIPT_NAME'], '') + + def test_decorator_on_callable_object_instance(self): + context = DummyContext() + request = DummyRequest() + request.subpath = () + request.environ = {'SCRIPT_NAME':'/foo', 'PATH_INFO':'/'} + app = DummyApp() + decorator = self._callFUT(app) + response = decorator(context, request) + self.assertEqual(response, app) + self.assertEqual(request.environ['PATH_INFO'], '/') + self.assertEqual(request.environ['SCRIPT_NAME'], '/foo') + +def dummyapp(environ, start_response): + """ """ + +class DummyApp(object): + def __call__(self, environ, start_response): + """ """ + +class DummyContext: + pass + +class DummyRequest: + def get_response(self, application): + return application + + def copy(self): + self.copied = True + return self + -- cgit v1.2.3