summaryrefslogtreecommitdiff
path: root/pecan/tests
diff options
context:
space:
mode:
Diffstat (limited to 'pecan/tests')
-rw-r--r--pecan/tests/__init__.py20
-rw-r--r--pecan/tests/config_fixtures/bad/importerror.py1
-rw-r--r--pecan/tests/config_fixtures/bad/module_and_underscore.py4
-rw-r--r--pecan/tests/config_fixtures/config.py22
-rw-r--r--pecan/tests/config_fixtures/empty.py2
-rw-r--r--pecan/tests/config_fixtures/foobar.py1
-rw-r--r--pecan/tests/config_fixtures/forcedict.py14
-rw-r--r--pecan/tests/middleware/__init__.py0
-rw-r--r--pecan/tests/middleware/static_fixtures/self.pngbin6976 -> 0 bytes
-rw-r--r--pecan/tests/middleware/static_fixtures/text.txt9
-rw-r--r--pecan/tests/middleware/test_errordocument.py92
-rw-r--r--pecan/tests/middleware/test_recursive.py142
-rw-r--r--pecan/tests/middleware/test_static.py68
-rw-r--r--pecan/tests/scaffold_builder.py172
-rw-r--r--pecan/tests/scaffold_fixtures/__init__.py0
-rw-r--r--pecan/tests/scaffold_fixtures/content_sub/bar/spam.txt_tmpl1
-rw-r--r--pecan/tests/scaffold_fixtures/content_sub/foo_tmpl1
-rw-r--r--pecan/tests/scaffold_fixtures/file_sub/bar_+package+/spam.txt1
-rw-r--r--pecan/tests/scaffold_fixtures/file_sub/foo_+package+1
-rw-r--r--pecan/tests/scaffold_fixtures/simple/bar/spam.txt1
-rw-r--r--pecan/tests/scaffold_fixtures/simple/foo1
-rw-r--r--pecan/tests/templates/__init__.py0
-rw-r--r--pecan/tests/templates/form_colors.html2
-rw-r--r--pecan/tests/templates/form_colors_invalid.html2
-rw-r--r--pecan/tests/templates/form_colors_valid.html2
-rw-r--r--pecan/tests/templates/form_login_invalid.html2
-rw-r--r--pecan/tests/templates/form_login_valid.html2
-rw-r--r--pecan/tests/templates/form_name.html1
-rw-r--r--pecan/tests/templates/form_name_invalid.html3
-rw-r--r--pecan/tests/templates/form_name_invalid_custom.html3
-rw-r--r--pecan/tests/templates/form_name_valid.html1
-rw-r--r--pecan/tests/templates/genshi.html16
-rw-r--r--pecan/tests/templates/genshi_bad.html18
-rw-r--r--pecan/tests/templates/jinja.html11
-rw-r--r--pecan/tests/templates/jinja_bad.html13
-rw-r--r--pecan/tests/templates/kajiki.html11
-rw-r--r--pecan/tests/templates/mako.html11
-rw-r--r--pecan/tests/templates/mako_bad.html6
-rw-r--r--pecan/tests/test_base.py2227
-rw-r--r--pecan/tests/test_commands.py56
-rw-r--r--pecan/tests/test_conf.py346
-rw-r--r--pecan/tests/test_generic.py111
-rw-r--r--pecan/tests/test_hooks.py1711
-rw-r--r--pecan/tests/test_jsonify.py233
-rw-r--r--pecan/tests/test_no_thread_locals.py1440
-rw-r--r--pecan/tests/test_rest.py1640
-rw-r--r--pecan/tests/test_scaffolds.py160
-rw-r--r--pecan/tests/test_secure.py563
-rw-r--r--pecan/tests/test_templating.py50
-rw-r--r--pecan/tests/test_util.py95
50 files changed, 0 insertions, 9289 deletions
diff --git a/pecan/tests/__init__.py b/pecan/tests/__init__.py
deleted file mode 100644
index 4d2df74..0000000
--- a/pecan/tests/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import sys
-import os
-if sys.version_info < (2, 7):
- from unittest2 import TestCase # pragma: nocover
-else:
- from unittest import TestCase # pragma: nocover
-
-
-class PecanTestCase(TestCase):
-
- def setUp(self):
- self.addCleanup(self._reset_global_config)
-
- def _reset_global_config(self):
- from pecan import configuration
- configuration.set_config(
- dict(configuration.initconf()),
- overwrite=True
- )
- os.environ.pop('PECAN_CONFIG', None)
diff --git a/pecan/tests/config_fixtures/bad/importerror.py b/pecan/tests/config_fixtures/bad/importerror.py
deleted file mode 100644
index 592fa5b..0000000
--- a/pecan/tests/config_fixtures/bad/importerror.py
+++ /dev/null
@@ -1 +0,0 @@
-import pecan.thismoduledoesnotexist
diff --git a/pecan/tests/config_fixtures/bad/module_and_underscore.py b/pecan/tests/config_fixtures/bad/module_and_underscore.py
deleted file mode 100644
index e53f416..0000000
--- a/pecan/tests/config_fixtures/bad/module_and_underscore.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import sys
-
-__badattr__ = True
-moduleattr = sys
diff --git a/pecan/tests/config_fixtures/config.py b/pecan/tests/config_fixtures/config.py
deleted file mode 100644
index bba299b..0000000
--- a/pecan/tests/config_fixtures/config.py
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-# Server Specific Configurations
-server = {
- 'port': '8081',
- 'host': '1.1.1.1',
- 'hostport': '{pecan.conf.server.host}:{pecan.conf.server.port}'
-}
-
-# Pecan Application Configurations
-app = {
- 'static_root': 'public',
- 'template_path': 'myproject/templates',
- 'debug': True
-}
-
-# Custom Configurations must be in Python dictionary format::
-#
-# foo = {'bar':'baz'}
-#
-# All configurations are accessible at::
-# pecan.conf
diff --git a/pecan/tests/config_fixtures/empty.py b/pecan/tests/config_fixtures/empty.py
deleted file mode 100644
index b4a9332..0000000
--- a/pecan/tests/config_fixtures/empty.py
+++ /dev/null
@@ -1,2 +0,0 @@
-app = {}
-server = {}
diff --git a/pecan/tests/config_fixtures/foobar.py b/pecan/tests/config_fixtures/foobar.py
deleted file mode 100644
index 5abc475..0000000
--- a/pecan/tests/config_fixtures/foobar.py
+++ /dev/null
@@ -1 +0,0 @@
-foo = "bar"
diff --git a/pecan/tests/config_fixtures/forcedict.py b/pecan/tests/config_fixtures/forcedict.py
deleted file mode 100644
index 4e2c83a..0000000
--- a/pecan/tests/config_fixtures/forcedict.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Pecan Application Configurations
-beaker = {
- 'session.key': 'key',
- 'session.type': 'cookie',
- 'session.validate_key': '1a971a7df182df3e1dec0af7c6913ec7',
- '__force_dict__': True
-}
-
-# Custom Configurations must be in Python dictionary format::
-#
-# foo = {'bar':'baz'}
-#
-# All configurations are accessible at::
-# pecan.conf
diff --git a/pecan/tests/middleware/__init__.py b/pecan/tests/middleware/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/pecan/tests/middleware/__init__.py
+++ /dev/null
diff --git a/pecan/tests/middleware/static_fixtures/self.png b/pecan/tests/middleware/static_fixtures/self.png
deleted file mode 100644
index 9b30321..0000000
--- a/pecan/tests/middleware/static_fixtures/self.png
+++ /dev/null
Binary files differ
diff --git a/pecan/tests/middleware/static_fixtures/text.txt b/pecan/tests/middleware/static_fixtures/text.txt
deleted file mode 100644
index c6defe5..0000000
--- a/pecan/tests/middleware/static_fixtures/text.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a test text file.
-
-Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
-tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
-veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
-commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
-velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-occaecat cupidatat non proident, sunt in culpa qui officia deserunt
-mollit anim id est laborum. \ No newline at end of file
diff --git a/pecan/tests/middleware/test_errordocument.py b/pecan/tests/middleware/test_errordocument.py
deleted file mode 100644
index 29f46e5..0000000
--- a/pecan/tests/middleware/test_errordocument.py
+++ /dev/null
@@ -1,92 +0,0 @@
-import json
-
-from webtest import TestApp
-from six import b as b_
-
-import pecan
-from pecan.middleware.errordocument import ErrorDocumentMiddleware
-from pecan.middleware.recursive import RecursiveMiddleware
-from pecan.tests import PecanTestCase
-
-
-def four_oh_four_app(environ, start_response):
- if environ['PATH_INFO'].startswith('/error'):
- code = environ['PATH_INFO'].split('/')[2]
- start_response("200 OK", [('Content-type', 'text/plain')])
-
- body = "Error: %s" % code
- if environ['QUERY_STRING']:
- body += "\nQS: %s" % environ['QUERY_STRING']
- return [b_(body)]
- start_response("404 Not Found", [('Content-type', 'text/plain')])
- return []
-
-
-class TestErrorDocumentMiddleware(PecanTestCase):
-
- def setUp(self):
- super(TestErrorDocumentMiddleware, self).setUp()
- self.app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
- four_oh_four_app, {404: '/error/404'}
- )))
-
- def test_hit_error_page(self):
- r = self.app.get('/error/404')
- assert r.status_int == 200
- assert r.body == b_('Error: 404')
-
- def test_middleware_routes_to_404_message(self):
- r = self.app.get('/', expect_errors=True)
- assert r.status_int == 404
- assert r.body == b_('Error: 404')
-
- def test_error_endpoint_with_query_string(self):
- app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
- four_oh_four_app, {404: '/error/404?foo=bar'}
- )))
- r = app.get('/', expect_errors=True)
- assert r.status_int == 404
- assert r.body == b_('Error: 404\nQS: foo=bar')
-
- def test_error_with_recursion_loop(self):
- app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
- four_oh_four_app, {404: '/'}
- )))
- r = app.get('/', expect_errors=True)
- assert r.status_int == 404
- assert r.body == b_(
- 'Error: 404 Not Found. (Error page could not be fetched)'
- )
-
- def test_original_exception(self):
-
- class RootController(object):
-
- @pecan.expose()
- def index(self):
- if pecan.request.method != 'POST':
- pecan.abort(405, 'You have to POST, dummy!')
- return 'Hello, World!'
-
- @pecan.expose('json')
- def error(self, status):
- return dict(
- status=int(status),
- reason=pecan.request.environ[
- 'pecan.original_exception'
- ].detail
- )
-
- app = pecan.Pecan(RootController())
- app = RecursiveMiddleware(ErrorDocumentMiddleware(app, {
- 405: '/error/405'
- }))
- app = TestApp(app)
-
- assert app.post('/').status_int == 200
- r = app.get('/', expect_errors=405)
- assert r.status_int == 405
-
- resp = json.loads(r.body.decode())
- assert resp['status'] == 405
- assert resp['reason'] == 'You have to POST, dummy!'
diff --git a/pecan/tests/middleware/test_recursive.py b/pecan/tests/middleware/test_recursive.py
deleted file mode 100644
index ed95d50..0000000
--- a/pecan/tests/middleware/test_recursive.py
+++ /dev/null
@@ -1,142 +0,0 @@
-from webtest import TestApp
-from six import b as b_
-
-from pecan.middleware.recursive import (RecursiveMiddleware,
- ForwardRequestException)
-from pecan.tests import PecanTestCase
-
-
-def simple_app(environ, start_response):
- start_response("200 OK", [('Content-type', 'text/plain')])
- return [b_('requested page returned')]
-
-
-def error_docs_app(environ, start_response):
- if environ['PATH_INFO'] == '/not_found':
- start_response("404 Not found", [('Content-type', 'text/plain')])
- return [b_('Not found')]
- elif environ['PATH_INFO'] == '/error':
- start_response("200 OK", [('Content-type', 'text/plain')])
- return [b_('Page not found')]
- elif environ['PATH_INFO'] == '/recurse':
- raise ForwardRequestException('/recurse')
- else:
- return simple_app(environ, start_response)
-
-
-class Middleware(object):
- def __init__(self, app, url='/error'):
- self.app = app
- self.url = url
-
- def __call__(self, environ, start_response):
- raise ForwardRequestException(self.url)
-
-
-def forward(app):
- app = TestApp(RecursiveMiddleware(app))
- res = app.get('')
-
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '200 OK'
- assert 'requested page returned' in res
- res = app.get('/error')
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '200 OK'
- assert 'Page not found' in res
- res = app.get('/not_found')
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '200 OK'
- assert 'Page not found' in res
- try:
- res = app.get('/recurse')
- except AssertionError as e:
- if str(e).startswith('Forwarding loop detected'):
- pass
- else:
- raise AssertionError('Failed to detect forwarding loop')
-
-
-class TestRecursiveMiddleware(PecanTestCase):
-
- def test_ForwardRequest_url(self):
- class TestForwardRequestMiddleware(Middleware):
- def __call__(self, environ, start_response):
- if environ['PATH_INFO'] != '/not_found':
- return self.app(environ, start_response)
- raise ForwardRequestException(self.url)
- forward(TestForwardRequestMiddleware(error_docs_app))
-
- def test_ForwardRequest_url_with_params(self):
- class TestForwardRequestMiddleware(Middleware):
- def __call__(self, environ, start_response):
- if environ['PATH_INFO'] != '/not_found':
- return self.app(environ, start_response)
- raise ForwardRequestException(self.url + '?q=1')
- forward(TestForwardRequestMiddleware(error_docs_app))
-
- def test_ForwardRequest_environ(self):
- class TestForwardRequestMiddleware(Middleware):
- def __call__(self, environ, start_response):
- if environ['PATH_INFO'] != '/not_found':
- return self.app(environ, start_response)
- environ['PATH_INFO'] = self.url
- raise ForwardRequestException(environ=environ)
- forward(TestForwardRequestMiddleware(error_docs_app))
-
- def test_ForwardRequest_factory(self):
-
- class TestForwardRequestMiddleware(Middleware):
- def __call__(self, environ, start_response):
- if environ['PATH_INFO'] != '/not_found':
- return self.app(environ, start_response)
- environ['PATH_INFO'] = self.url
-
- def factory(app):
-
- class WSGIApp(object):
-
- def __init__(self, app):
- self.app = app
-
- def __call__(self, e, start_response):
- def keep_status_start_response(status, headers,
- exc_info=None):
- return start_response(
- '404 Not Found', headers, exc_info
- )
- return self.app(e, keep_status_start_response)
-
- return WSGIApp(app)
-
- raise ForwardRequestException(factory=factory)
-
- app = TestForwardRequestMiddleware(error_docs_app)
- app = TestApp(RecursiveMiddleware(app))
- res = app.get('')
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '200 OK'
- assert 'requested page returned' in res
- res = app.get('/error')
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '200 OK'
- assert 'Page not found' in res
- res = app.get('/not_found', status=404)
- assert res.headers['content-type'] == 'text/plain'
- assert res.status == '404 Not Found' # Different status
- assert 'Page not found' in res
- try:
- res = app.get('/recurse')
- except AssertionError as e:
- if str(e).startswith('Forwarding loop detected'):
- pass
- else:
- raise AssertionError('Failed to detect forwarding loop')
-
- def test_ForwardRequestException(self):
- class TestForwardRequestExceptionMiddleware(Middleware):
- def __call__(self, environ, start_response):
- if environ['PATH_INFO'] != '/not_found':
- return self.app(environ, start_response)
- raise ForwardRequestException(path_info=self.url)
- forward(TestForwardRequestExceptionMiddleware(error_docs_app))
diff --git a/pecan/tests/middleware/test_static.py b/pecan/tests/middleware/test_static.py
deleted file mode 100644
index 9a0c08c..0000000
--- a/pecan/tests/middleware/test_static.py
+++ /dev/null
@@ -1,68 +0,0 @@
-from pecan.middleware.static import (StaticFileMiddleware, FileWrapper,
- _dump_date)
-from pecan.tests import PecanTestCase
-
-import os
-
-
-class TestStaticFileMiddleware(PecanTestCase):
-
- def setUp(self):
- super(TestStaticFileMiddleware, self).setUp()
-
- def app(environ, start_response):
- response_headers = [('Content-type', 'text/plain')]
- start_response('200 OK', response_headers)
- return ['Hello world!\n']
-
- self.app = StaticFileMiddleware(
- app, os.path.dirname(__file__)
- )
-
- self._status = None
- self._response_headers = None
-
- def _request(self, path):
- def start_response(status, response_headers, exc_info=None):
- self._status = status
- self._response_headers = response_headers
- return self.app(
- dict(PATH_INFO=path),
- start_response
- )
-
- def _get_response_header(self, header):
- for k, v in self._response_headers:
- if k.upper() == header.upper():
- return v
- return None
-
- def test_file_can_be_found(self):
- result = self._request('/static_fixtures/text.txt')
- assert isinstance(result, FileWrapper)
-
- def test_no_file_found_causes_passthrough(self):
- result = self._request('/static_fixtures/nosuchfile.txt')
- assert not isinstance(result, FileWrapper)
- assert result == ['Hello world!\n']
-
- def test_mime_type_works_for_png_files(self):
- self._request('/static_fixtures/self.png')
- assert self._get_response_header('Content-Type') == 'image/png'
-
- def test_file_can_be_closed(self):
- result = self._request('/static_fixtures/text.txt')
- assert result.close() is None
-
- def test_file_can_be_iterated_over(self):
- result = self._request('/static_fixtures/text.txt')
- assert len([x for x in result])
-
- def test_date_dumping_on_unix_timestamps(self):
- result = _dump_date(1331755274.59, ' ')
- assert result == 'Wed, 14 Mar 2012 20:01:14 GMT'
-
- def test_separator_sanitization_still_finds_file(self):
- os.altsep = ':'
- result = self._request(':static_fixtures:text.txt')
- assert isinstance(result, FileWrapper)
diff --git a/pecan/tests/scaffold_builder.py b/pecan/tests/scaffold_builder.py
deleted file mode 100644
index dc039da..0000000
--- a/pecan/tests/scaffold_builder.py
+++ /dev/null
@@ -1,172 +0,0 @@
-import os
-import sys
-import subprocess
-import time
-
-from six import b as b_
-
-from pecan.compat import urlopen, URLError
-from pecan.tests import PecanTestCase
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest # noqa
-
-
-if __name__ == '__main__':
-
- class TestTemplateBuilds(PecanTestCase):
- """
- Used to test the templated quickstart project(s).
- """
-
- @property
- def bin(self):
- return os.path.dirname(sys.executable)
-
- def poll(self, proc):
- limit = 30
- for i in range(limit):
- proc.poll()
-
- # Make sure it's running
- if proc.returncode is None:
- break
- elif i == limit: # pragma: no cover
- raise RuntimeError("Server process didn't start.")
- time.sleep(.1)
-
- def test_project_pecan_serve_command(self):
- # Start the server
- proc = subprocess.Popen([
- os.path.join(self.bin, 'pecan'),
- 'serve',
- 'testing123/config.py'
- ])
-
- try:
- self.poll(proc)
- retries = 30
- while True:
- retries -= 1
- if retries < 0: # pragma: nocover
- raise RuntimeError(
- "The HTTP server has not replied within 3 seconds."
- )
- try:
- # ...and that it's serving (valid) content...
- resp = urlopen('http://localhost:8080/')
- assert resp.getcode()
- assert len(resp.read().decode())
- except URLError:
- pass
- else:
- break
- time.sleep(.1)
- finally:
- proc.terminate()
-
- def test_project_pecan_shell_command(self):
- # Start the server
- proc = subprocess.Popen([
- os.path.join(self.bin, 'pecan'),
- 'shell',
- 'testing123/config.py'
- ],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- stdin=subprocess.PIPE
- )
-
- self.poll(proc)
-
- out, _ = proc.communicate(
- b_('{"model" : model, "conf" : conf, "app" : app}')
- )
- assert 'testing123.model' in out.decode(), out
- assert 'Config(' in out.decode(), out
- assert 'webtest.app.TestApp' in out.decode(), out
-
- try:
- # just in case stdin doesn't close
- proc.terminate()
- except:
- pass
-
- class TestThirdPartyServe(TestTemplateBuilds):
-
- def poll_http(self, name, proc, port):
- try:
- self.poll(proc)
- retries = 30
- while True:
- retries -= 1
- if retries < 0: # pragma: nocover
- raise RuntimeError(
- "The %s server has not replied within"
- " 3 seconds." % name
- )
- try:
- # ...and that it's serving (valid) content...
- resp = urlopen('http://localhost:%d/' % port)
- assert resp.getcode()
- assert len(resp.read().decode())
- except URLError:
- pass
- else:
- break
- time.sleep(.1)
- finally:
- proc.terminate()
-
- class TestGunicornServeCommand(TestThirdPartyServe):
-
- def test_serve_from_config(self):
- # Start the server
- proc = subprocess.Popen([
- os.path.join(self.bin, 'gunicorn_pecan'),
- 'testing123/config.py'
- ])
-
- self.poll_http('gunicorn', proc, 8080)
-
- def test_serve_with_custom_bind(self):
- # Start the server
- proc = subprocess.Popen([
- os.path.join(self.bin, 'gunicorn_pecan'),
- '--bind=0.0.0.0:9191',
- 'testing123/config.py'
- ])
-
- self.poll_http('gunicorn', proc, 9191)
-
- class TestUWSGIServiceCommand(TestThirdPartyServe):
-
- def test_serve_from_config(self):
- # Start the server
- proc = subprocess.Popen([
- os.path.join(self.bin, 'uwsgi'),
- '--http-socket',
- ':8080',
- '--venv',
- sys.prefix,
- '--pecan',
- 'testing123/config.py'
- ])
-
- self.poll_http('uwsgi', proc, 8080)
-
- # First, ensure that the `testing123` package has been installed
- args = [
- os.path.join(os.path.dirname(sys.executable), 'pip'),
- 'install',
- '-U',
- '-e',
- './testing123'
- ]
- process = subprocess.Popen(args)
- _, unused_err = process.communicate()
- assert not process.poll()
-
- unittest.main()
diff --git a/pecan/tests/scaffold_fixtures/__init__.py b/pecan/tests/scaffold_fixtures/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/pecan/tests/scaffold_fixtures/__init__.py
+++ /dev/null
diff --git a/pecan/tests/scaffold_fixtures/content_sub/bar/spam.txt_tmpl b/pecan/tests/scaffold_fixtures/content_sub/bar/spam.txt_tmpl
deleted file mode 100644
index 95a9c91..0000000
--- a/pecan/tests/scaffold_fixtures/content_sub/bar/spam.txt_tmpl
+++ /dev/null
@@ -1 +0,0 @@
-Pecan ${package}
diff --git a/pecan/tests/scaffold_fixtures/content_sub/foo_tmpl b/pecan/tests/scaffold_fixtures/content_sub/foo_tmpl
deleted file mode 100644
index 25591f3..0000000
--- a/pecan/tests/scaffold_fixtures/content_sub/foo_tmpl
+++ /dev/null
@@ -1 +0,0 @@
-YAR ${package}
diff --git a/pecan/tests/scaffold_fixtures/file_sub/bar_+package+/spam.txt b/pecan/tests/scaffold_fixtures/file_sub/bar_+package+/spam.txt
deleted file mode 100644
index 02c61ad..0000000
--- a/pecan/tests/scaffold_fixtures/file_sub/bar_+package+/spam.txt
+++ /dev/null
@@ -1 +0,0 @@
-Pecan
diff --git a/pecan/tests/scaffold_fixtures/file_sub/foo_+package+ b/pecan/tests/scaffold_fixtures/file_sub/foo_+package+
deleted file mode 100644
index 035599b..0000000
--- a/pecan/tests/scaffold_fixtures/file_sub/foo_+package+
+++ /dev/null
@@ -1 +0,0 @@
-YAR
diff --git a/pecan/tests/scaffold_fixtures/simple/bar/spam.txt b/pecan/tests/scaffold_fixtures/simple/bar/spam.txt
deleted file mode 100644
index 02c61ad..0000000
--- a/pecan/tests/scaffold_fixtures/simple/bar/spam.txt
+++ /dev/null
@@ -1 +0,0 @@
-Pecan
diff --git a/pecan/tests/scaffold_fixtures/simple/foo b/pecan/tests/scaffold_fixtures/simple/foo
deleted file mode 100644
index 035599b..0000000
--- a/pecan/tests/scaffold_fixtures/simple/foo
+++ /dev/null
@@ -1 +0,0 @@
-YAR
diff --git a/pecan/tests/templates/__init__.py b/pecan/tests/templates/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/pecan/tests/templates/__init__.py
+++ /dev/null
diff --git a/pecan/tests/templates/form_colors.html b/pecan/tests/templates/form_colors.html
deleted file mode 100644
index cd4fea9..0000000
--- a/pecan/tests/templates/form_colors.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<input type="text" id="colors-0" name="colors-0" value="${data['colors'][0] if data else 'A color'}" />
-<input type="text" id="colors-1" name="colors-1" value="${data['colors'][1] if data else 'A color'}" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_colors_invalid.html b/pecan/tests/templates/form_colors_invalid.html
deleted file mode 100644
index d2d4ed7..0000000
--- a/pecan/tests/templates/form_colors_invalid.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<input type="text" id="colors-0" name="colors-0" value="blue" />
-<input type="text" id="colors-1" name="colors-1" value="" class="error" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_colors_valid.html b/pecan/tests/templates/form_colors_valid.html
deleted file mode 100644
index adecfbf..0000000
--- a/pecan/tests/templates/form_colors_valid.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<input type="text" id="colors-0" name="colors-0" value="blue" />
-<input type="text" id="colors-1" name="colors-1" value="red" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_login_invalid.html b/pecan/tests/templates/form_login_invalid.html
deleted file mode 100644
index cede816..0000000
--- a/pecan/tests/templates/form_login_invalid.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<input type="text" id="username" name="username" value="ryan" />
-<input type="password" id="password" name="password" value="" class="error" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_login_valid.html b/pecan/tests/templates/form_login_valid.html
deleted file mode 100644
index 0587754..0000000
--- a/pecan/tests/templates/form_login_valid.html
+++ /dev/null
@@ -1,2 +0,0 @@
-<input type="text" id="username" name="username" />
-<input type="password" id="password" name="password" value="" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_name.html b/pecan/tests/templates/form_name.html
deleted file mode 100644
index b46181d..0000000
--- a/pecan/tests/templates/form_name.html
+++ /dev/null
@@ -1 +0,0 @@
-<input type="text" id="name" name="name" value="${name if name else ''}" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_name_invalid.html b/pecan/tests/templates/form_name_invalid.html
deleted file mode 100644
index bcbd035..0000000
--- a/pecan/tests/templates/form_name_invalid.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- for: name -->
-<span class="error-message">Please enter a value</span><br />
-<input type="text" id="name" name="name" value="" class="error" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_name_invalid_custom.html b/pecan/tests/templates/form_name_invalid_custom.html
deleted file mode 100644
index cbb631f..0000000
--- a/pecan/tests/templates/form_name_invalid_custom.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<!-- for: name -->
-<span class="error-message">Names must be unique</span><br />
-<input type="text" id="name" name="name" value="Yoann" class="error" /> \ No newline at end of file
diff --git a/pecan/tests/templates/form_name_valid.html b/pecan/tests/templates/form_name_valid.html
deleted file mode 100644
index fc7d693..0000000
--- a/pecan/tests/templates/form_name_valid.html
+++ /dev/null
@@ -1 +0,0 @@
-<input type="text" id="name" name="name" value="Yoann" /> \ No newline at end of file
diff --git a/pecan/tests/templates/genshi.html b/pecan/tests/templates/genshi.html
deleted file mode 100644
index a42aa32..0000000
--- a/pecan/tests/templates/genshi.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
-<head>
- <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
- <title>Hello, ${name}!</title>
-</head>
-
-<body>
- <h1>Hello, ${name}!</h1>
-</body>
-
-</html>
diff --git a/pecan/tests/templates/genshi_bad.html b/pecan/tests/templates/genshi_bad.html
deleted file mode 100644
index 557bc55..0000000
--- a/pecan/tests/templates/genshi_bad.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:py="http://genshi.edgewall.org/"
- xmlns:xi="http://www.w3.org/2001/XInclude">
-
-<head>
- <meta content="text/html; charset=UTF-8" http-equiv="content-type" py:replace="''"/>
- <title>Hello, ${name}!</title>
-<!-- comment out close tag to cause error
-</head>
--->
-
-<body>
- <h1>Hello, ${name}!</h1>
-</body>
-
-</html>
diff --git a/pecan/tests/templates/jinja.html b/pecan/tests/templates/jinja.html
deleted file mode 100644
index e96835a..0000000
--- a/pecan/tests/templates/jinja.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-
-<head>
- <title>Hello, {{name}}!</title>
-</head>
-
-<body>
- <h1>Hello, {{name}}!</h1>
-</body>
-
-</html>
diff --git a/pecan/tests/templates/jinja_bad.html b/pecan/tests/templates/jinja_bad.html
deleted file mode 100644
index 3513871..0000000
--- a/pecan/tests/templates/jinja_bad.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<html>
-
-<head>
- <title>Hello, {{name}}!</title>
-</head>
-
-<body>
- <h1>Hello, {{name}}!</h1>
-</body>
-{# open a block without and name #}
-{% block %}
-
-</html>
diff --git a/pecan/tests/templates/kajiki.html b/pecan/tests/templates/kajiki.html
deleted file mode 100644
index 41c308c..0000000
--- a/pecan/tests/templates/kajiki.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-
-<head>
- <title>Hello, ${name}!</title>
-</head>
-
-<body>
- <h1>Hello, ${name}!</h1>
-</body>
-
-</html>
diff --git a/pecan/tests/templates/mako.html b/pecan/tests/templates/mako.html
deleted file mode 100644
index db60fec..0000000
--- a/pecan/tests/templates/mako.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<html>
-
-<head>
- <title>Hello, ${name}!</title>
-</head>
-
-<body>
- <h1>Hello, ${name}!</h1>
-</body>
-
-</html> \ No newline at end of file
diff --git a/pecan/tests/templates/mako_bad.html b/pecan/tests/templates/mako_bad.html
deleted file mode 100644
index e6caea2..0000000
--- a/pecan/tests/templates/mako_bad.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<%
-
- def bad_indentation:
-return None
-
-%>
diff --git a/pecan/tests/test_base.py b/pecan/tests/test_base.py
deleted file mode 100644
index 8558f82..0000000
--- a/pecan/tests/test_base.py
+++ /dev/null
@@ -1,2227 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import sys
-import os
-import json
-import traceback
-import warnings
-
-import webob
-from webob.exc import HTTPNotFound
-import mock
-from webtest import TestApp
-import six
-from six import b as b_
-from six import u as u_
-from six.moves import cStringIO as StringIO
-
-from pecan import (
- Pecan, Request, Response, expose, request, response, redirect,
- abort, make_app, override_template, render, route
-)
-from pecan.templating import (
- _builtin_renderers as builtin_renderers, error_formatters
-)
-from pecan.decorators import accept_noncanonical
-from pecan.tests import PecanTestCase
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest # pragma: nocover
-else:
- import unittest # pragma: nocover
-
-
-class SampleRootController(object):
- pass
-
-
-class TestAppRoot(PecanTestCase):
-
- def test_controller_lookup_by_string_path(self):
- app = Pecan('pecan.tests.test_base.SampleRootController')
- assert app.root and isinstance(app.root, SampleRootController)
-
-
-class TestEmptyContent(PecanTestCase):
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self):
- pass
-
- @expose()
- def explicit_body(self):
- response.body = b_('Hello, World!')
-
- @expose()
- def empty_body(self):
- response.body = b_('')
-
- @expose()
- def explicit_text(self):
- response.text = six.text_type('Hello, World!')
-
- @expose()
- def empty_text(self):
- response.text = six.text_type('')
-
- @expose()
- def explicit_json(self):
- response.json = {'foo': 'bar'}
-
- @expose()
- def explicit_json_body(self):
- response.json_body = {'foo': 'bar'}
-
- @expose()
- def non_unicode(self):
- return chr(0xc0)
-
- return TestApp(Pecan(RootController()))
-
- def test_empty_index(self):
- r = self.app_.get('/')
- self.assertEqual(r.status_int, 204)
- self.assertNotIn('Content-Type', r.headers)
- self.assertEqual(r.headers['Content-Length'], '0')
- self.assertEqual(len(r.body), 0)
-
- def test_index_with_non_unicode(self):
- r = self.app_.get('/non_unicode/')
- self.assertEqual(r.status_int, 200)
-
- def test_explicit_body(self):
- r = self.app_.get('/explicit_body/')
- self.assertEqual(r.status_int, 200)
- self.assertEqual(r.body, b_('Hello, World!'))
-
- def test_empty_body(self):
- r = self.app_.get('/empty_body/')
- self.assertEqual(r.status_int, 204)
- self.assertEqual(r.body, b_(''))
-
- def test_explicit_text(self):
- r = self.app_.get('/explicit_text/')
- self.assertEqual(r.status_int, 200)
- self.assertEqual(r.body, b_('Hello, World!'))
-
- def test_empty_text(self):
- r = self.app_.get('/empty_text/')
- self.assertEqual(r.status_int, 204)
- self.assertEqual(r.body, b_(''))
-
- def test_explicit_json(self):
- r = self.app_.get('/explicit_json/')
- self.assertEqual(r.status_int, 200)
- json_resp = json.loads(r.body.decode())
- assert json_resp == {'foo': 'bar'}
-
- def test_explicit_json_body(self):
- r = self.app_.get('/explicit_json_body/')
- self.assertEqual(r.status_int, 200)
- json_resp = json.loads(r.body.decode())
- assert json_resp == {'foo': 'bar'}
-
-
-class TestAppIterFile(PecanTestCase):
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self):
- body = six.BytesIO(b_('Hello, World!'))
- response.body_file = body
-
- @expose()
- def empty(self):
- body = six.BytesIO(b_(''))
- response.body_file = body
-
- return TestApp(Pecan(RootController()))
-
- def test_body_generator(self):
- r = self.app_.get('/')
- self.assertEqual(r.status_int, 200)
- assert r.body == b_('Hello, World!')
-
- def test_empty_body_generator(self):
- r = self.app_.get('/empty')
- self.assertEqual(r.status_int, 204)
- assert len(r.body) == 0
-
-
-class TestInvalidURLEncoding(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
-
- @expose()
- def _route(self, args, request):
- assert request.path
-
- return TestApp(Pecan(RootController()))
-
- def test_rest_with_non_utf_8_body(self):
- r = self.app_.get('/%aa/', expect_errors=True)
- assert r.status_int == 400
-
-
-class TestIndexRouting(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- return TestApp(Pecan(RootController()))
-
- def test_empty_root(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- def test_index(self):
- r = self.app_.get('/index')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- def test_index_html(self):
- r = self.app_.get('/index.html')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
-
-class TestObjectDispatch(PecanTestCase):
-
- @property
- def app_(self):
- class SubSubController(object):
- @expose()
- def index(self):
- return '/sub/sub/'
-
- @expose()
- def deeper(self):
- return '/sub/sub/deeper'
-
- class SubController(object):
- @expose()
- def index(self):
- return '/sub/'
-
- @expose()
- def deeper(self):
- return '/sub/deeper'
-
- sub = SubSubController()
-
- class RootController(object):
- @expose()
- def index(self):
- return '/'
-
- @expose()
- def deeper(self):
- return '/deeper'
-
- sub = SubController()
-
- return TestApp(Pecan(RootController()))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- def test_one_level(self):
- r = self.app_.get('/deeper')
- assert r.status_int == 200
- assert r.body == b_('/deeper')
-
- def test_one_level_with_trailing(self):
- r = self.app_.get('/sub/')
- assert r.status_int == 200
- assert r.body == b_('/sub/')
-
- def test_two_levels(self):
- r = self.app_.get('/sub/deeper')
- assert r.status_int == 200
- assert r.body == b_('/sub/deeper')
-
- def test_two_levels_with_trailing(self):
- r = self.app_.get('/sub/sub/')
- assert r.status_int == 200
-
- def test_three_levels(self):
- r = self.app_.get('/sub/sub/deeper')
- assert r.status_int == 200
- assert r.body == b_('/sub/sub/deeper')
-
-
-@unittest.skipIf(not six.PY3, "tests are Python3 specific")
-class TestUnicodePathSegments(PecanTestCase):
-
- def test_unicode_methods(self):
- class RootController(object):
- pass
- setattr(RootController, '🌰', expose()(lambda self: 'Hello, World!'))
- app = TestApp(Pecan(RootController()))
-
- resp = app.get('/%F0%9F%8C%B0/')
- assert resp.status_int == 200
- assert resp.body == b_('Hello, World!')
-
- def test_unicode_child(self):
- class ChildController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- class RootController(object):
- pass
- setattr(RootController, '🌰', ChildController())
- app = TestApp(Pecan(RootController()))
-
- resp = app.get('/%F0%9F%8C%B0/')
- assert resp.status_int == 200
- assert resp.body == b_('Hello, World!')
-
-
-class TestLookups(PecanTestCase):
-
- @property
- def app_(self):
- class LookupController(object):
- def __init__(self, someID):
- self.someID = someID
-
- @expose()
- def index(self):
- return '/%s' % self.someID
-
- @expose()
- def name(self):
- return '/%s/name' % self.someID
-
- class RootController(object):
- @expose()
- def index(self):
- return '/'
-
- @expose()
- def _lookup(self, someID, *remainder):
- return LookupController(someID), remainder
-
- return TestApp(Pecan(RootController()))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- def test_lookup(self):
- r = self.app_.get('/100/')
- assert r.status_int == 200
- assert r.body == b_('/100')
-
- def test_lookup_with_method(self):
- r = self.app_.get('/100/name')
- assert r.status_int == 200
- assert r.body == b_('/100/name')
-
- def test_lookup_with_wrong_argspec(self):
- class RootController(object):
- @expose()
- def _lookup(self, someID):
- return 'Bad arg spec' # pragma: nocover
-
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- app = TestApp(Pecan(RootController()))
- r = app.get('/foo/bar', expect_errors=True)
- assert r.status_int == 404
-
-
-class TestCanonicalLookups(PecanTestCase):
-
- @property
- def app_(self):
- class LookupController(object):
- def __init__(self, someID):
- self.someID = someID
-
- @expose()
- def index(self):
- return self.someID
-
- class UserController(object):
- @expose()
- def _lookup(self, someID, *remainder):
- return LookupController(someID), remainder
-
- class RootController(object):
- users = UserController()
-
- return TestApp(Pecan(RootController()))
-
- def test_canonical_lookup(self):
- assert self.app_.get('/users', expect_errors=404).status_int == 404
- assert self.app_.get('/users/', expect_errors=404).status_int == 404
- assert self.app_.get('/users/100').status_int == 302
- assert self.app_.get('/users/100/').body == b_('100')
-
-
-class TestControllerArguments(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self, id):
- return 'index: %s' % id
-
- @expose()
- def multiple(self, one, two):
- return 'multiple: %s, %s' % (one, two)
-
- @expose()
- def optional(self, id=None):
- return 'optional: %s' % str(id)
-
- @expose()
- def multiple_optional(self, one=None, two=None, three=None):
- return 'multiple_optional: %s, %s, %s' % (one, two, three)
-
- @expose()
- def variable_args(self, *args):
- return 'variable_args: %s' % ', '.join(args)
-
- @expose()
- def variable_kwargs(self, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'variable_kwargs: %s' % ', '.join(data)
-
- @expose()
- def variable_all(self, *args, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'variable_all: %s' % ', '.join(list(args) + data)
-
- @expose()
- def eater(self, id, dummy=None, *args, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'eater: %s, %s, %s' % (
- id,
- dummy,
- ', '.join(list(args) + data)
- )
-
- @staticmethod
- @expose()
- def static(id):
- return "id is %s" % id
-
- @expose()
- def _route(self, args, request):
- if hasattr(self, args[0]):
- return getattr(self, args[0]), args[1:]
- else:
- return self.index, args
-
- return TestApp(Pecan(RootController()))
-
- def test_required_argument(self):
- try:
- r = self.app_.get('/')
- assert r.status_int != 200 # pragma: nocover
- except Exception as ex:
- assert type(ex) == TypeError
- assert ex.args[0] in (
- "index() takes exactly 2 arguments (1 given)",
- "index() missing 1 required positional argument: 'id'"
- ) # this messaging changed in Python 3.3
-
- def test_single_argument(self):
- r = self.app_.get('/1')
- assert r.status_int == 200
- assert r.body == b_('index: 1')
-
- def test_single_argument_with_encoded_url(self):
- r = self.app_.get('/This%20is%20a%20test%21')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_single_argument_with_plus(self):
- r = self.app_.get('/foo+bar')
- assert r.status_int == 200
- assert r.body == b_('index: foo+bar')
-
- def test_single_argument_with_encoded_plus(self):
- r = self.app_.get('/foo%2Bbar')
- assert r.status_int == 200
- assert r.body == b_('index: foo+bar')
-
- def test_two_arguments(self):
- r = self.app_.get('/1/dummy', status=404)
- assert r.status_int == 404
-
- def test_keyword_argument(self):
- r = self.app_.get('/?id=2')
- assert r.status_int == 200
- assert r.body == b_('index: 2')
-
- def test_keyword_argument_with_encoded_url(self):
- r = self.app_.get('/?id=This%20is%20a%20test%21')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_keyword_argument_with_plus(self):
- r = self.app_.get('/?id=foo+bar')
- assert r.status_int == 200
- assert r.body == b_('index: foo bar')
-
- def test_keyword_argument_with_encoded_plus(self):
- r = self.app_.get('/?id=foo%2Bbar')
- assert r.status_int == 200
- assert r.body == b_('index: foo+bar')
-
- def test_argument_and_keyword_argument(self):
- r = self.app_.get('/3?id=three')
- assert r.status_int == 200
- assert r.body == b_('index: 3')
-
- def test_encoded_argument_and_keyword_argument(self):
- r = self.app_.get('/This%20is%20a%20test%21?id=three')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_explicit_kwargs(self):
- r = self.app_.post('/', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_path_with_explicit_kwargs(self):
- r = self.app_.post('/4', {'id': 'four'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_explicit_json_kwargs(self):
- r = self.app_.post_json('/', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_path_with_explicit_json_kwargs(self):
- r = self.app_.post_json('/4', {'id': 'four'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_multiple_kwargs(self):
- r = self.app_.get('/?id=5&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('index: 5')
-
- def test_kwargs_from_root(self):
- r = self.app_.post('/', {'id': '6', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('index: 6')
-
- def test_json_kwargs_from_root(self):
- r = self.app_.post_json('/', {'id': '6', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('index: 6')
-
- # multiple args
-
- def test_multiple_positional_arguments(self):
- r = self.app_.get('/multiple/one/two')
- assert r.status_int == 200
- assert r.body == b_('multiple: one, two')
-
- def test_multiple_positional_arguments_with_url_encode(self):
- r = self.app_.get('/multiple/One%20/Two%21')
- assert r.status_int == 200
- assert r.body == b_('multiple: One , Two!')
-
- def test_multiple_positional_arguments_with_kwargs(self):
- r = self.app_.get('/multiple?one=three&two=four')
- assert r.status_int == 200
- assert r.body == b_('multiple: three, four')
-
- def test_multiple_positional_arguments_with_url_encoded_kwargs(self):
- r = self.app_.get('/multiple?one=Three%20&two=Four%20%21')
- assert r.status_int == 200
- assert r.body == b_('multiple: Three , Four !')
-
- def test_positional_args_with_dictionary_kwargs(self):
- r = self.app_.post('/multiple', {'one': 'five', 'two': 'six'})
- assert r.status_int == 200
- assert r.body == b_('multiple: five, six')
-
- def test_positional_args_with_json_kwargs(self):
- r = self.app_.post_json('/multiple', {'one': 'five', 'two': 'six'})
- assert r.status_int == 200
- assert r.body == b_('multiple: five, six')
-
- def test_positional_args_with_url_encoded_dictionary_kwargs(self):
- r = self.app_.post('/multiple', {'one': 'Five%20', 'two': 'Six%20%21'})
- assert r.status_int == 200
- assert r.body == b_('multiple: Five%20, Six%20%21')
-
- # optional arg
- def test_optional_arg(self):
- r = self.app_.get('/optional')
- assert r.status_int == 200
- assert r.body == b_('optional: None')
-
- def test_multiple_optional(self):
- r = self.app_.get('/optional/1')
- assert r.status_int == 200
- assert r.body == b_('optional: 1')
-
- def test_multiple_optional_url_encoded(self):
- r = self.app_.get('/optional/Some%20Number')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_multiple_optional_missing(self):
- r = self.app_.get('/optional/2/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_with_kwargs(self):
- r = self.app_.get('/optional?id=2')
- assert r.status_int == 200
- assert r.body == b_('optional: 2')
-
- def test_multiple_with_url_encoded_kwargs(self):
- r = self.app_.get('/optional?id=Some%20Number')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_multiple_args_with_url_encoded_kwargs(self):
- r = self.app_.get('/optional/3?id=three')
- assert r.status_int == 200
- assert r.body == b_('optional: 3')
-
- def test_url_encoded_positional_args(self):
- r = self.app_.get('/optional/Some%20Number?id=three')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_kwargs(self):
- r = self.app_.post('/optional', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('optional: 4')
-
- def test_optional_arg_with_json_kwargs(self):
- r = self.app_.post_json('/optional', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('optional: 4')
-
- def test_optional_arg_with_url_encoded_kwargs(self):
- r = self.app_.post('/optional', {'id': 'Some%20Number'})
- assert r.status_int == 200
- assert r.body == b_('optional: Some%20Number')
-
- def test_multiple_positional_arguments_with_dictionary_kwargs(self):
- r = self.app_.post('/optional/5', {'id': 'five'})
- assert r.status_int == 200
- assert r.body == b_('optional: 5')
-
- def test_multiple_positional_arguments_with_json_kwargs(self):
- r = self.app_.post_json('/optional/5', {'id': 'five'})
- assert r.status_int == 200
- assert r.body == b_('optional: 5')
-
- def test_multiple_positional_url_encoded_arguments_with_kwargs(self):
- r = self.app_.post('/optional/Some%20Number', {'id': 'five'})
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_multiple_kwargs(self):
- r = self.app_.get('/optional?id=6&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('optional: 6')
-
- def test_optional_arg_with_multiple_url_encoded_kwargs(self):
- r = self.app_.get('/optional?id=Some%20Number&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_multiple_dictionary_kwargs(self):
- r = self.app_.post('/optional', {'id': '7', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('optional: 7')
-
- def test_optional_arg_with_multiple_json_kwargs(self):
- r = self.app_.post_json('/optional', {'id': '7', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('optional: 7')
-
- def test_optional_arg_with_multiple_url_encoded_dictionary_kwargs(self):
- r = self.app_.post('/optional', {
- 'id': 'Some%20Number',
- 'dummy': 'dummy'
- })
- assert r.status_int == 200
- assert r.body == b_('optional: Some%20Number')
-
- # multiple optional args
-
- def test_multiple_optional_positional_args(self):
- r = self.app_.get('/multiple_optional')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, None')
-
- def test_multiple_optional_positional_args_one_arg(self):
- r = self.app_.get('/multiple_optional/1')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_one_url_encoded_arg(self):
- r = self.app_.get('/multiple_optional/One%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_all_args(self):
- r = self.app_.get('/multiple_optional/1/2/3')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_positional_args_all_url_encoded_args(self):
- r = self.app_.get('/multiple_optional/One%21/Two%21/Three%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, Two!, Three!')
-
- def test_multiple_optional_positional_args_too_many_args(self):
- r = self.app_.get('/multiple_optional/1/2/3/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_optional_positional_args_with_kwargs(self):
- r = self.app_.get('/multiple_optional?one=1')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_url_encoded_kwargs(self):
- r = self.app_.get('/multiple_optional?one=One%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_with_string_kwargs(self):
- r = self.app_.get('/multiple_optional/1?one=one')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_encoded_str_kwargs(self):
- r = self.app_.get('/multiple_optional/One%21?one=one')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_with_dict_kwargs(self):
- r = self.app_.post('/multiple_optional', {'one': '1'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_json_kwargs(self):
- r = self.app_.post_json('/multiple_optional', {'one': '1'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_encoded_dict_kwargs(self):
- r = self.app_.post('/multiple_optional', {'one': 'One%21'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One%21, None, None')
-
- def test_multiple_optional_positional_args_and_dict_kwargs(self):
- r = self.app_.post('/multiple_optional/1', {'one': 'one'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_and_json_kwargs(self):
- r = self.app_.post_json('/multiple_optional/1', {'one': 'one'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_encoded_positional_args_and_dict_kwargs(self):
- r = self.app_.post('/multiple_optional/One%21', {'one': 'one'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_args_with_multiple_kwargs(self):
- r = self.app_.get('/multiple_optional?one=1&two=2&three=3&four=4')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_args_with_multiple_encoded_kwargs(self):
- r = self.app_.get(
- '/multiple_optional?one=One%21&two=Two%21&three=Three%21&four=4'
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, Two!, Three!')
-
- def test_multiple_optional_args_with_multiple_dict_kwargs(self):
- r = self.app_.post(
- '/multiple_optional',
- {'one': '1', 'two': '2', 'three': '3', 'four': '4'}
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_args_with_multiple_json_kwargs(self):
- r = self.app_.post_json(
- '/multiple_optional',
- {'one': '1', 'two': '2', 'three': '3', 'four': '4'}
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_args_with_multiple_encoded_dict_kwargs(self):
- r = self.app_.post(
- '/multiple_optional',
- {
- 'one': 'One%21',
- 'two': 'Two%21',
- 'three': 'Three%21',
- 'four': '4'
- }
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One%21, Two%21, Three%21')
-
- def test_multiple_optional_args_with_last_kwarg(self):
- r = self.app_.get('/multiple_optional?three=3')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, 3')
-
- def test_multiple_optional_args_with_last_encoded_kwarg(self):
- r = self.app_.get('/multiple_optional?three=Three%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, Three!')
-
- def test_multiple_optional_args_with_middle_arg(self):
- r = self.app_.get('/multiple_optional', {'two': '2'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, 2, None')
-
- def test_variable_args(self):
- r = self.app_.get('/variable_args')
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_multiple_variable_args(self):
- r = self.app_.get('/variable_args/1/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_args: 1, dummy')
-
- def test_multiple_encoded_variable_args(self):
- r = self.app_.get('/variable_args/Testing%20One%20Two/Three%21')
- assert r.status_int == 200
- assert r.body == b_('variable_args: Testing One Two, Three!')
-
- def test_variable_args_with_kwargs(self):
- r = self.app_.get('/variable_args?id=2&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_variable_args_with_dict_kwargs(self):
- r = self.app_.post('/variable_args', {'id': '3', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_variable_args_with_json_kwargs(self):
- r = self.app_.post_json(
- '/variable_args',
- {'id': '3', 'dummy': 'dummy'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_variable_kwargs(self):
- r = self.app_.get('/variable_kwargs')
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: ')
-
- def test_multiple_variable_kwargs(self):
- r = self.app_.get('/variable_kwargs/1/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_variable_kwargs_with_explicit_kwargs(self):
- r = self.app_.get('/variable_kwargs?id=2&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=dummy, id=2')
-
- def test_multiple_variable_kwargs_with_explicit_encoded_kwargs(self):
- r = self.app_.get(
- '/variable_kwargs?id=Two%21&dummy=This%20is%20a%20test'
- )
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=This is a test, id=Two!')
-
- def test_multiple_variable_kwargs_with_dict_kwargs(self):
- r = self.app_.post('/variable_kwargs', {'id': '3', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=dummy, id=3')
-
- def test_multiple_variable_kwargs_with_json_kwargs(self):
- r = self.app_.post_json(
- '/variable_kwargs',
- {'id': '3', 'dummy': 'dummy'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=dummy, id=3')
-
- def test_multiple_variable_kwargs_with_encoded_dict_kwargs(self):
- r = self.app_.post(
- '/variable_kwargs',
- {'id': 'Three%21', 'dummy': 'This%20is%20a%20test'}
- )
- assert r.status_int == 200
- result = 'variable_kwargs: dummy=This%20is%20a%20test, id=Three%21'
- assert r.body == b_(result)
-
- def test_variable_all(self):
- r = self.app_.get('/variable_all')
- assert r.status_int == 200
- assert r.body == b_('variable_all: ')
-
- def test_variable_all_with_one_extra(self):
- r = self.app_.get('/variable_all/1')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 1')
-
- def test_variable_all_with_two_extras(self):
- r = self.app_.get('/variable_all/2/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 2, dummy')
-
- def test_variable_mixed(self):
- r = self.app_.get('/variable_all/3?month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 3, day=12, month=1')
-
- def test_variable_mixed_explicit(self):
- r = self.app_.get('/variable_all/4?id=four&month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 4, day=12, id=four, month=1')
-
- def test_variable_post(self):
- r = self.app_.post('/variable_all/5/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 5, dummy')
-
- def test_variable_post_with_kwargs(self):
- r = self.app_.post('/variable_all/6', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('variable_all: 6, day=12, month=1')
-
- def test_variable_post_with_json_kwargs(self):
- r = self.app_.post_json(
- '/variable_all/6',
- {'month': '1', 'day': '12'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_all: 6, day=12, month=1')
-
- def test_variable_post_mixed(self):
- r = self.app_.post(
- '/variable_all/7',
- {'id': 'seven', 'month': '1', 'day': '12'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_all: 7, day=12, id=seven, month=1')
-
- def test_variable_post_mixed_with_json(self):
- r = self.app_.post_json(
- '/variable_all/7',
- {'id': 'seven', 'month': '1', 'day': '12'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_all: 7, day=12, id=seven, month=1')
-
- def test_duplicate_query_parameters_GET(self):
- r = self.app_.get('/variable_kwargs?list=1&list=2')
- l = [u_('1'), u_('2')]
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: list=%s' % l)
-
- def test_duplicate_query_parameters_POST(self):
- r = self.app_.post('/variable_kwargs',
- {'list': ['1', '2']})
- l = [u_('1'), u_('2')]
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: list=%s' % l)
-
- def test_duplicate_query_parameters_POST_mixed(self):
- r = self.app_.post('/variable_kwargs?list=1&list=2',
- {'list': ['3', '4']})
- l = [u_('1'), u_('2'), u_('3'), u_('4')]
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: list=%s' % l)
-
- def test_duplicate_query_parameters_POST_mixed_json(self):
- r = self.app_.post('/variable_kwargs?list=1&list=2',
- {'list': 3})
- l = [u_('1'), u_('2'), u_('3')]
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: list=%s' % l)
-
- def test_staticmethod(self):
- r = self.app_.get('/static/foobar')
- assert r.status_int == 200
- assert r.body == b_('id is foobar')
-
- def test_no_remainder(self):
- try:
- r = self.app_.get('/eater')
- assert r.status_int != 200 # pragma: nocover
- except Exception as ex:
- assert type(ex) == TypeError
- assert ex.args[0] in (
- "eater() takes at least 2 arguments (1 given)",
- "eater() missing 1 required positional argument: 'id'"
- ) # this messaging changed in Python 3.3
-
- def test_one_remainder(self):
- r = self.app_.get('/eater/1')
- assert r.status_int == 200
- assert r.body == b_('eater: 1, None, ')
-
- def test_two_remainders(self):
- r = self.app_.get('/eater/2/dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 2, dummy, ')
-
- def test_many_remainders(self):
- r = self.app_.get('/eater/3/dummy/foo/bar')
- assert r.status_int == 200
- assert r.body == b_('eater: 3, dummy, foo, bar')
-
- def test_remainder_with_kwargs(self):
- r = self.app_.get('/eater/4?month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('eater: 4, None, day=12, month=1')
-
- def test_remainder_with_many_kwargs(self):
- r = self.app_.get('/eater/5?id=five&month=1&day=12&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 5, dummy, day=12, month=1')
-
- def test_post_remainder(self):
- r = self.app_.post('/eater/6')
- assert r.status_int == 200
- assert r.body == b_('eater: 6, None, ')
-
- def test_post_three_remainders(self):
- r = self.app_.post('/eater/7/dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 7, dummy, ')
-
- def test_post_many_remainders(self):
- r = self.app_.post('/eater/8/dummy/foo/bar')
- assert r.status_int == 200
- assert r.body == b_('eater: 8, dummy, foo, bar')
-
- def test_post_remainder_with_kwargs(self):
- r = self.app_.post('/eater/9', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('eater: 9, None, day=12, month=1')
-
- def test_post_empty_remainder_with_json_kwargs(self):
- r = self.app_.post_json('/eater/9/', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('eater: 9, None, day=12, month=1')
-
- def test_post_remainder_with_json_kwargs(self):
- r = self.app_.post_json('/eater/9', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('eater: 9, None, day=12, month=1')
-
- def test_post_many_remainders_with_many_kwargs(self):
- r = self.app_.post(
- '/eater/10',
- {'id': 'ten', 'month': '1', 'day': '12', 'dummy': 'dummy'}
- )
- assert r.status_int == 200
- assert r.body == b_('eater: 10, dummy, day=12, month=1')
-
- def test_post_many_remainders_with_many_json_kwargs(self):
- r = self.app_.post_json(
- '/eater/10',
- {'id': 'ten', 'month': '1', 'day': '12', 'dummy': 'dummy'}
- )
- assert r.status_int == 200
- assert r.body == b_('eater: 10, dummy, day=12, month=1')
-
-
-class TestDefaultErrorRendering(PecanTestCase):
-
- def test_plain_error(self):
- class RootController(object):
- pass
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/', status=404)
- assert r.status_int == 404
- assert r.content_type == 'text/plain'
- assert r.body == b_(HTTPNotFound().plain_body({}))
-
- def test_html_error(self):
- class RootController(object):
- pass
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/', headers={'Accept': 'text/html'}, status=404)
- assert r.status_int == 404
- assert r.content_type == 'text/html'
- assert r.body == b_(HTTPNotFound().html_body({}))
-
- def test_json_error(self):
- class RootController(object):
- pass
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/', headers={'Accept': 'application/json'}, status=404)
- assert r.status_int == 404
- json_resp = json.loads(r.body.decode())
- assert json_resp['code'] == 404
- assert json_resp['description'] is None
- assert json_resp['title'] == 'Not Found'
- assert r.content_type == 'application/json'
-
-
-class TestAbort(PecanTestCase):
-
- def test_abort(self):
- class RootController(object):
- @expose()
- def index(self):
- abort(404)
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/', status=404)
- assert r.status_int == 404
-
- def test_abort_with_detail(self):
- class RootController(object):
- @expose()
- def index(self):
- abort(status_code=401, detail='Not Authorized')
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/', status=401)
- assert r.status_int == 401
-
- def test_abort_keeps_traceback(self):
- last_exc, last_traceback = None, None
-
- try:
- try:
- raise Exception('Bottom Exception')
- except:
- abort(404)
- except Exception:
- last_exc, _, last_traceback = sys.exc_info()
-
- assert last_exc is HTTPNotFound
- assert 'Bottom Exception' in traceback.format_tb(last_traceback)[-1]
-
-
-class TestScriptName(PecanTestCase):
-
- def setUp(self):
- super(TestScriptName, self).setUp()
- self.environ = {'SCRIPT_NAME': '/foo'}
-
- def test_handle_script_name(self):
- class RootController(object):
- @expose()
- def index(self):
- return 'Root Index'
-
- app = TestApp(Pecan(RootController()), extra_environ=self.environ)
- r = app.get('/foo/')
- assert r.status_int == 200
-
-
-class TestRedirect(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self):
- redirect('/testing')
-
- @expose()
- def internal(self):
- redirect('/testing', internal=True)
-
- @expose()
- def bad_internal(self):
- redirect('/testing', internal=True, code=301)
-
- @expose()
- def permanent(self):
- redirect('/testing', code=301)
-
- @expose()
- def testing(self):
- return 'it worked!'
-
- return TestApp(make_app(RootController(), debug=False))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 302
- r = r.follow()
- assert r.status_int == 200
- assert r.body == b_('it worked!')
-
- def test_internal(self):
- r = self.app_.get('/internal')
- assert r.status_int == 200
- assert r.body == b_('it worked!')
-
- def test_internal_with_301(self):
- self.assertRaises(ValueError, self.app_.get, '/bad_internal')
-
- def test_permanent_redirect(self):
- r = self.app_.get('/permanent')
- assert r.status_int == 301
- r = r.follow()
- assert r.status_int == 200
- assert r.body == b_('it worked!')
-
- def test_x_forward_proto(self):
- class ChildController(object):
- @expose()
- def index(self):
- redirect('/testing') # pragma: nocover
-
- class RootController(object):
- @expose()
- def index(self):
- redirect('/testing') # pragma: nocover
-
- @expose()
- def testing(self):
- return 'it worked!' # pragma: nocover
- child = ChildController()
-
- app = TestApp(make_app(RootController(), debug=True))
- res = app.get(
- '/child', extra_environ=dict(HTTP_X_FORWARDED_PROTO='https')
- )
- # non-canonical url will redirect, so we won't get a 301
- assert res.status_int == 302
- # should add trailing / and changes location to https
- assert res.location == 'https://localhost/child/'
- assert res.request.environ['HTTP_X_FORWARDED_PROTO'] == 'https'
-
-
-class TestInternalRedirectContext(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
-
- @expose()
- def redirect_with_context(self):
- request.context['foo'] = 'bar'
- redirect('/testing')
-
- @expose()
- def internal_with_context(self):
- request.context['foo'] = 'bar'
- redirect('/testing', internal=True)
-
- @expose('json')
- def testing(self):
- return request.context
-
- return TestApp(make_app(RootController(), debug=False))
-
- def test_internal_with_request_context(self):
- r = self.app_.get('/internal_with_context')
- assert r.status_int == 200
- assert json.loads(r.body.decode()) == {'foo': 'bar'}
-
- def test_context_does_not_bleed(self):
- r = self.app_.get('/redirect_with_context').follow()
- assert r.status_int == 200
- assert json.loads(r.body.decode()) == {}
-
-
-class TestStreamedResponse(PecanTestCase):
-
- def test_streaming_response(self):
-
- class RootController(object):
- @expose(content_type='text/plain')
- def test(self, foo):
- if foo == 'stream':
- # mimic large file
- contents = six.BytesIO(b_('stream'))
- response.content_type = 'application/octet-stream'
- contents.seek(0, os.SEEK_END)
- response.content_length = contents.tell()
- contents.seek(0, os.SEEK_SET)
- response.app_iter = contents
- return response
- else:
- return 'plain text'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/test/stream')
- assert r.content_type == 'application/octet-stream'
- assert r.body == b_('stream')
-
- r = app.get('/test/plain')
- assert r.content_type == 'text/plain'
- assert r.body == b_('plain text')
-
-
-class TestManualResponse(PecanTestCase):
-
- def test_manual_response(self):
-
- class RootController(object):
- @expose()
- def index(self):
- resp = webob.Response(response.environ)
- resp.body = b_('Hello, World!')
- return resp
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.body == b_('Hello, World!')
-
-
-class TestCustomResponseandRequest(PecanTestCase):
-
- def test_custom_objects(self):
-
- class CustomRequest(Request):
-
- @property
- def headers(self):
- headers = super(CustomRequest, self).headers
- headers['X-Custom-Request'] = 'ABC'
- return headers
-
- class CustomResponse(Response):
-
- @property
- def headers(self):
- headers = super(CustomResponse, self).headers
- headers['X-Custom-Response'] = 'XYZ'
- return headers
-
- class RootController(object):
- @expose()
- def index(self):
- return request.headers.get('X-Custom-Request')
-
- app = TestApp(Pecan(
- RootController(),
- request_cls=CustomRequest,
- response_cls=CustomResponse
- ))
- r = app.get('/')
- assert r.body == b_('ABC')
- assert r.headers.get('X-Custom-Response') == 'XYZ'
-
-
-class TestThreadLocalState(PecanTestCase):
-
- def test_thread_local_dir(self):
- """
- Threadlocal proxies for request and response should properly
- proxy ``dir()`` calls to the underlying webob class.
- """
- class RootController(object):
- @expose()
- def index(self):
- assert 'method' in dir(request)
- assert 'status' in dir(response)
- return '/'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- def test_request_state_cleanup(self):
- """
- After a request, the state local() should be totally clean
- except for state.app (so that objects don't leak between requests)
- """
- from pecan.core import state
-
- class RootController(object):
- @expose()
- def index(self):
- return '/'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- assert state.__dict__ == {}
-
-
-class TestFileTypeExtensions(PecanTestCase):
-
- @property
- def app_(self):
- """
- Test extension splits
- """
- class RootController(object):
- @expose(content_type=None)
- def _default(self, *args):
- ext = request.pecan['extension']
- assert len(args) == 1
- if ext:
- assert ext not in args[0]
- return ext or ''
-
- return TestApp(Pecan(RootController()))
-
- def test_html_extension(self):
- r = self.app_.get('/index.html')
- assert r.status_int == 200
- assert r.body == b_('.html')
-
- def test_image_extension(self):
- r = self.app_.get('/image.png')
- assert r.status_int == 200
- assert r.body == b_('.png')
-
- def test_hidden_file(self):
- r = self.app_.get('/.vimrc')
- assert r.status_int == 204
- assert r.body == b_('')
-
- def test_multi_dot_extension(self):
- r = self.app_.get('/gradient.min.js')
- assert r.status_int == 200
- assert r.body == b_('.js')
-
- def test_bad_content_type(self):
- class RootController(object):
- @expose()
- def index(self):
- return '/'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- r = app.get('/index.html', expect_errors=True)
- assert r.status_int == 200
- assert r.body == b_('/')
-
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = app.get('/index.txt', expect_errors=True)
- assert r.status_int == 404
-
- def test_unknown_file_extension(self):
- class RootController(object):
- @expose(content_type=None)
- def _default(self, *args):
- assert 'example:x.tiny' in args
- assert request.pecan['extension'] is None
- return 'SOME VALUE'
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/example:x.tiny')
- assert r.status_int == 200
- assert r.body == b_('SOME VALUE')
-
- def test_guessing_disabled(self):
- class RootController(object):
- @expose(content_type=None)
- def _default(self, *args):
- assert 'index.html' in args
- assert request.pecan['extension'] is None
- return 'SOME VALUE'
-
- app = TestApp(Pecan(RootController(),
- guess_content_type_from_ext=False))
-
- r = app.get('/index.html')
- assert r.status_int == 200
- assert r.body == b_('SOME VALUE')
-
-
-class TestContentTypeByAcceptHeaders(PecanTestCase):
-
- @property
- def app_(self):
- """
- Test that content type is set appropriately based on Accept headers.
- """
- class RootController(object):
-
- @expose(content_type='text/html')
- @expose(content_type='application/json')
- def index(self, *args):
- return 'Foo'
-
- return TestApp(Pecan(RootController()))
-
- def test_quality(self):
- r = self.app_.get('/', headers={
- 'Accept': 'text/html,application/json;q=0.9,*/*;q=0.8'
- })
- assert r.status_int == 200
- assert r.content_type == 'text/html'
-
- r = self.app_.get('/', headers={
- 'Accept': 'application/json,text/html;q=0.9,*/*;q=0.8'
- })
- assert r.status_int == 200
- assert r.content_type == 'application/json'
-
- def test_file_extension_has_higher_precedence(self):
- r = self.app_.get('/index.html', headers={
- 'Accept': 'application/json,text/html;q=0.9,*/*;q=0.8'
- })
- assert r.status_int == 200
- assert r.content_type == 'text/html'
-
- def test_not_acceptable(self):
- r = self.app_.get('/', headers={
- 'Accept': 'application/xml',
- }, status=406)
- assert r.status_int == 406
-
- def test_accept_header_missing(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.content_type == 'text/html'
-
-
-class TestCanonicalRouting(PecanTestCase):
-
- @property
- def app_(self):
- class ArgSubController(object):
- @expose()
- def index(self, arg):
- return arg
-
- class AcceptController(object):
- @accept_noncanonical
- @expose()
- def index(self):
- return 'accept'
-
- class SubController(object):
- @expose()
- def index(self, **kw):
- return 'subindex'
-
- class RootController(object):
- @expose()
- def index(self):
- return 'index'
-
- sub = SubController()
- arg = ArgSubController()
- accept = AcceptController()
-
- return TestApp(Pecan(RootController()))
-
- def test_root(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert b_('index') in r.body
-
- def test_index(self):
- r = self.app_.get('/index')
- assert r.status_int == 200
- assert b_('index') in r.body
-
- def test_broken_clients(self):
- # for broken clients
- r = self.app_.get('', status=302)
- assert r.status_int == 302
- assert r.location == 'http://localhost/'
-
- def test_sub_controller_with_trailing(self):
- r = self.app_.get('/sub/')
- assert r.status_int == 200
- assert b_('subindex') in r.body
-
- def test_sub_controller_redirect(self):
- r = self.app_.get('/sub', status=302)
- assert r.status_int == 302
- assert r.location == 'http://localhost/sub/'
-
- def test_with_query_string(self):
- # try with query string
- r = self.app_.get('/sub?foo=bar', status=302)
- assert r.status_int == 302
- assert r.location == 'http://localhost/sub/?foo=bar'
-
- def test_posts_fail(self):
- try:
- self.app_.post('/sub', dict(foo=1))
- raise Exception("Post should fail") # pragma: nocover
- except Exception as e:
- assert isinstance(e, RuntimeError)
-
- def test_with_args(self):
- r = self.app_.get('/arg/index/foo')
- assert r.status_int == 200
- assert r.body == b_('foo')
-
- def test_accept_noncanonical(self):
- r = self.app_.get('/accept/')
- assert r.status_int == 200
- assert r.body == b_('accept')
-
- def test_accept_noncanonical_no_trailing_slash(self):
- r = self.app_.get('/accept')
- assert r.status_int == 200
- assert r.body == b_('accept')
-
-
-class TestNonCanonical(PecanTestCase):
-
- @property
- def app_(self):
- class ArgSubController(object):
- @expose()
- def index(self, arg):
- return arg # pragma: nocover
-
- class AcceptController(object):
- @accept_noncanonical
- @expose()
- def index(self):
- return 'accept' # pragma: nocover
-
- class SubController(object):
- @expose()
- def index(self, **kw):
- return 'subindex'
-
- class RootController(object):
- @expose()
- def index(self):
- return 'index'
-
- sub = SubController()
- arg = ArgSubController()
- accept = AcceptController()
-
- return TestApp(Pecan(RootController(), force_canonical=False))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert b_('index') in r.body
-
- def test_subcontroller(self):
- r = self.app_.get('/sub')
- assert r.status_int == 200
- assert b_('subindex') in r.body
-
- def test_subcontroller_with_kwargs(self):
- r = self.app_.post('/sub', dict(foo=1))
- assert r.status_int == 200
- assert b_('subindex') in r.body
-
- def test_sub_controller_with_trailing(self):
- r = self.app_.get('/sub/')
- assert r.status_int == 200
- assert b_('subindex') in r.body
-
- def test_proxy(self):
- class RootController(object):
- @expose()
- def index(self):
- request.testing = True
- assert request.testing is True
- del request.testing
- assert hasattr(request, 'testing') is False
- return '/'
-
- app = TestApp(make_app(RootController(), debug=True))
- r = app.get('/')
- assert r.status_int == 200
-
- def test_app_wrap(self):
- class RootController(object):
- pass
-
- wrapped_apps = []
-
- def wrap(app):
- wrapped_apps.append(app)
- return app
-
- make_app(RootController(), wrap_app=wrap, debug=True)
- assert len(wrapped_apps) == 1
-
-
-class TestLogging(PecanTestCase):
-
- def test_logging_setup(self):
- class RootController(object):
- @expose()
- def index(self):
- import logging
- logging.getLogger('pecantesting').info('HELLO WORLD')
- return "HELLO WORLD"
-
- f = StringIO()
-
- app = TestApp(make_app(RootController(), logging={
- 'loggers': {
- 'pecantesting': {
- 'level': 'INFO', 'handlers': ['memory']
- }
- },
- 'handlers': {
- 'memory': {
- 'level': 'INFO',
- 'class': 'logging.StreamHandler',
- 'stream': f
- }
- }
- }))
-
- app.get('/')
- assert f.getvalue() == 'HELLO WORLD\n'
-
- def test_logging_setup_with_config_obj(self):
- class RootController(object):
- @expose()
- def index(self):
- import logging
- logging.getLogger('pecantesting').info('HELLO WORLD')
- return "HELLO WORLD"
-
- f = StringIO()
-
- from pecan.configuration import conf_from_dict
- app = TestApp(make_app(RootController(), logging=conf_from_dict({
- 'loggers': {
- 'pecantesting': {
- 'level': 'INFO', 'handlers': ['memory']
- }
- },
- 'handlers': {
- 'memory': {
- 'level': 'INFO',
- 'class': 'logging.StreamHandler',
- 'stream': f
- }
- }
- })))
-
- app.get('/')
- assert f.getvalue() == 'HELLO WORLD\n'
-
-
-class TestEngines(PecanTestCase):
-
- template_path = os.path.join(os.path.dirname(__file__), 'templates')
-
- @unittest.skipIf('genshi' not in builtin_renderers, 'Genshi not installed')
- def test_genshi(self):
-
- class RootController(object):
- @expose('genshi:genshi.html')
- def index(self, name='Jonathan'):
- return dict(name=name)
-
- @expose('genshi:genshi_bad.html')
- def badtemplate(self):
- return dict()
-
- app = TestApp(
- Pecan(RootController(), template_path=self.template_path)
- )
- r = app.get('/')
- assert r.status_int == 200
- assert b_("<h1>Hello, Jonathan!</h1>") in r.body
-
- r = app.get('/index.html?name=World')
- assert r.status_int == 200
- assert b_("<h1>Hello, World!</h1>") in r.body
-
- error_msg = None
- try:
- r = app.get('/badtemplate.html')
- except Exception as e:
- for error_f in error_formatters:
- error_msg = error_f(e)
- if error_msg:
- break
- assert error_msg is not None
-
- @unittest.skipIf('kajiki' not in builtin_renderers, 'Kajiki not installed')
- def test_kajiki(self):
-
- class RootController(object):
- @expose('kajiki:kajiki.html')
- def index(self, name='Jonathan'):
- return dict(name=name)
-
- app = TestApp(
- Pecan(RootController(), template_path=self.template_path)
- )
- r = app.get('/')
- assert r.status_int == 200
- assert b_("<h1>Hello, Jonathan!</h1>") in r.body
-
- r = app.get('/index.html?name=World')
- assert r.status_int == 200
- assert b_("<h1>Hello, World!</h1>") in r.body
-
- @unittest.skipIf('jinja' not in builtin_renderers, 'Jinja not installed')
- def test_jinja(self):
-
- class RootController(object):
- @expose('jinja:jinja.html')
- def index(self, name='Jonathan'):
- return dict(name=name)
-
- @expose('jinja:jinja_bad.html')
- def badtemplate(self):
- return dict()
-
- app = TestApp(
- Pecan(RootController(), template_path=self.template_path)
- )
- r = app.get('/')
- assert r.status_int == 200
- assert b_("<h1>Hello, Jonathan!</h1>") in r.body
-
- error_msg = None
- try:
- r = app.get('/badtemplate.html')
- except Exception as e:
- for error_f in error_formatters:
- error_msg = error_f(e)
- if error_msg:
- break
- assert error_msg is not None
-
- @unittest.skipIf('mako' not in builtin_renderers, 'Mako not installed')
- def test_mako(self):
-
- class RootController(object):
- @expose('mako:mako.html')
- def index(self, name='Jonathan'):
- return dict(name=name)
-
- @expose('mako:mako_bad.html')
- def badtemplate(self):
- return dict()
-
- app = TestApp(
- Pecan(RootController(), template_path=self.template_path)
- )
- r = app.get('/')
- assert r.status_int == 200
- assert b_("<h1>Hello, Jonathan!</h1>") in r.body
-
- r = app.get('/index.html?name=World')
- assert r.status_int == 200
- assert b_("<h1>Hello, World!</h1>") in r.body
-
- error_msg = None
- try:
- r = app.get('/badtemplate.html')
- except Exception as e:
- for error_f in error_formatters:
- error_msg = error_f(e)
- if error_msg:
- break
- assert error_msg is not None
-
- def test_json(self):
- try:
- from simplejson import loads
- except:
- from json import loads # noqa
-
- expected_result = dict(
- name='Jonathan',
- age=30, nested=dict(works=True)
- )
-
- class RootController(object):
- @expose('json')
- def index(self):
- return expected_result
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- result = dict(loads(r.body.decode()))
- assert result == expected_result
-
- def test_override_template(self):
- class RootController(object):
- @expose('foo.html')
- def index(self):
- override_template(None, content_type='text/plain')
- return 'Override'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- assert b_('Override') in r.body
- assert r.content_type == 'text/plain'
-
- def test_render(self):
- class RootController(object):
- @expose()
- def index(self, name='Jonathan'):
- return render('mako.html', dict(name=name))
-
- app = TestApp(
- Pecan(RootController(), template_path=self.template_path)
- )
- r = app.get('/')
- assert r.status_int == 200
- assert b_("<h1>Hello, Jonathan!</h1>") in r.body
-
- def test_default_json_renderer(self):
-
- class RootController(object):
- @expose()
- def index(self, name='Bill'):
- return dict(name=name)
-
- app = TestApp(Pecan(RootController(), default_renderer='json'))
- r = app.get('/')
- assert r.status_int == 200
- result = dict(json.loads(r.body.decode()))
- assert result == {'name': 'Bill'}
-
- def test_default_json_renderer_with_explicit_content_type(self):
-
- class RootController(object):
- @expose(content_type='text/plain')
- def index(self, name='Bill'):
- return name
-
- app = TestApp(Pecan(RootController(), default_renderer='json'))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_("Bill")
-
-
-class TestDeprecatedRouteMethod(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
-
- @expose()
- def index(self, *args):
- return ', '.join(args)
-
- @expose()
- def _route(self, args):
- return self.index, args
-
- return TestApp(Pecan(RootController()))
-
- def test_required_argument(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = self.app_.get('/foo/bar/')
- assert r.status_int == 200
- assert b_('foo, bar') in r.body
-
-
-class TestExplicitRoute(PecanTestCase):
-
- def test_alternate_route(self):
-
- class RootController(object):
-
- @expose(route='some-path')
- def some_path(self):
- return 'Hello, World!'
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/some-path/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- r = app.get('/some_path/', expect_errors=True)
- assert r.status_int == 404
-
- def test_manual_route(self):
-
- class SubController(object):
-
- @expose(route='some-path')
- def some_path(self):
- return 'Hello, World!'
-
- class RootController(object):
- pass
-
- route(RootController, 'some-controller', SubController())
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/some-controller/some-path/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- r = app.get('/some-controller/some_path/', expect_errors=True)
- assert r.status_int == 404
-
- def test_manual_route_conflict(self):
-
- class SubController(object):
- pass
-
- class RootController(object):
-
- @expose()
- def hello(self):
- return 'Hello, World!'
-
- self.assertRaises(
- RuntimeError,
- route,
- RootController,
- 'hello',
- SubController()
- )
-
- def test_custom_route_on_index(self):
-
- class RootController(object):
-
- @expose(route='some-path')
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/some-path/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- r = app.get('/index/', expect_errors=True)
- assert r.status_int == 404
-
- def test_custom_route_with_attribute_conflict(self):
-
- class RootController(object):
-
- @expose(route='mock')
- def greet(self):
- return 'Hello, World!'
-
- @expose()
- def mock(self):
- return 'You are not worthy!'
-
- app = TestApp(Pecan(RootController()))
-
- self.assertRaises(
- RuntimeError,
- app.get,
- '/mock/'
- )
-
- def test_conflicting_custom_routes(self):
-
- class RootController(object):
-
- @expose(route='testing')
- def foo(self):
- return 'Foo!'
-
- @expose(route='testing')
- def bar(self):
- return 'Bar!'
-
- app = TestApp(Pecan(RootController()))
-
- self.assertRaises(
- RuntimeError,
- app.get,
- '/testing/'
- )
-
- def test_conflicting_custom_routes_in_subclass(self):
-
- class BaseController(object):
-
- @expose(route='testing')
- def foo(self):
- return request.path
-
- class ChildController(BaseController):
- pass
-
- class RootController(BaseController):
- child = ChildController()
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/testing/')
- assert r.body == b_('/testing/')
-
- r = app.get('/child/testing/')
- assert r.body == b_('/child/testing/')
-
- def test_custom_route_prohibited_on_lookup(self):
- try:
- class RootController(object):
-
- @expose(route='some-path')
- def _lookup(self):
- return 'Hello, World!'
- except ValueError:
- pass
- else:
- raise AssertionError(
- '_lookup cannot be used with a custom path segment'
- )
-
- def test_custom_route_prohibited_on_default(self):
- try:
- class RootController(object):
-
- @expose(route='some-path')
- def _default(self):
- return 'Hello, World!'
- except ValueError:
- pass
- else:
- raise AssertionError(
- '_default cannot be used with a custom path segment'
- )
-
- def test_custom_route_prohibited_on_route(self):
- try:
- class RootController(object):
-
- @expose(route='some-path')
- def _route(self):
- return 'Hello, World!'
- except ValueError:
- pass
- else:
- raise AssertionError(
- '_route cannot be used with a custom path segment'
- )
-
- def test_custom_route_with_generic_controllers(self):
-
- class RootController(object):
-
- @expose(route='some-path', generic=True)
- def foo(self):
- return 'Hello, World!'
-
- @foo.when(method='POST')
- def handle_post(self):
- return 'POST!'
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/some-path/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- r = app.get('/foo/', expect_errors=True)
- assert r.status_int == 404
-
- r = app.post('/some-path/')
- assert r.status_int == 200
- assert r.body == b_('POST!')
-
- r = app.post('/foo/', expect_errors=True)
- assert r.status_int == 404
-
- def test_custom_route_prohibited_on_generic_controllers(self):
- try:
- class RootController(object):
-
- @expose(generic=True)
- def foo(self):
- return 'Hello, World!'
-
- @foo.when(method='POST', route='some-path')
- def handle_post(self):
- return 'POST!'
- except ValueError:
- pass
- else:
- raise AssertionError(
- 'generic controllers cannot be used with a custom path segment'
- )
-
- def test_invalid_route_arguments(self):
- class C(object):
-
- def secret(self):
- return {}
-
- self.assertRaises(TypeError, route)
- self.assertRaises(TypeError, route, 'some-path', lambda x: x)
- self.assertRaises(TypeError, route, 'some-path', C.secret)
- self.assertRaises(TypeError, route, C, {}, C())
-
- for path in (
- 'VARIED-case-PATH',
- 'this,custom,path',
- '123-path',
- 'path(with-parens)',
- 'path;with;semicolons',
- 'path:with:colons',
- 'v2.0',
- '~username',
- 'somepath!',
- 'four*four',
- 'one+two',
- '@twitterhandle',
- 'package=pecan'
- ):
- handler = C()
- route(C, path, handler)
- assert getattr(C, path, handler)
-
- self.assertRaises(ValueError, route, C, '/path/', C())
- self.assertRaises(ValueError, route, C, '.', C())
- self.assertRaises(ValueError, route, C, '..', C())
- self.assertRaises(ValueError, route, C, 'path?', C())
- self.assertRaises(ValueError, route, C, 'percent%20encoded', C())
diff --git a/pecan/tests/test_commands.py b/pecan/tests/test_commands.py
deleted file mode 100644
index e9d6ead..0000000
--- a/pecan/tests/test_commands.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from pecan.tests import PecanTestCase
-
-
-class TestCommandManager(PecanTestCase):
-
- def test_commands(self):
- from pecan.commands import ServeCommand, ShellCommand, CreateCommand
- from pecan.commands.base import CommandManager
- m = CommandManager()
- assert m.commands['serve'] == ServeCommand
- assert m.commands['shell'] == ShellCommand
- assert m.commands['create'] == CreateCommand
-
-
-class TestCommandRunner(PecanTestCase):
-
- def test_commands(self):
- from pecan.commands import (
- ServeCommand, ShellCommand, CreateCommand, CommandRunner
- )
- runner = CommandRunner()
- assert runner.commands['serve'] == ServeCommand
- assert runner.commands['shell'] == ShellCommand
- assert runner.commands['create'] == CreateCommand
-
- def test_run(self):
- from pecan.commands import CommandRunner
- runner = CommandRunner()
- self.assertRaises(
- RuntimeError,
- runner.run,
- ['serve', 'missing_file.py']
- )
-
-
-class TestCreateCommand(PecanTestCase):
-
- def test_run(self):
- from pecan.commands import CreateCommand
-
- class FakeArg(object):
- project_name = 'default'
- template_name = 'default'
-
- class FakeScaffold(object):
- def copy_to(self, project_name):
- assert project_name == 'default'
-
- class FakeManager(object):
- scaffolds = {
- 'default': FakeScaffold
- }
-
- c = CreateCommand()
- c.manager = FakeManager()
- c.run(FakeArg())
diff --git a/pecan/tests/test_conf.py b/pecan/tests/test_conf.py
deleted file mode 100644
index e682885..0000000
--- a/pecan/tests/test_conf.py
+++ /dev/null
@@ -1,346 +0,0 @@
-import os
-import sys
-import tempfile
-
-from pecan.tests import PecanTestCase
-from six import b as b_
-
-
-__here__ = os.path.dirname(__file__)
-
-
-class TestConf(PecanTestCase):
-
- def test_update_config_fail_identifier(self):
- """Fail when naming does not pass correctness"""
- from pecan import configuration
- bad_dict = {'bad name': 'value'}
- self.assertRaises(ValueError, configuration.Config, bad_dict)
-
- def test_update_set_config(self):
- """Update an empty configuration with the default values"""
- from pecan import configuration
-
- conf = configuration.initconf()
- conf.update(configuration.conf_from_file(os.path.join(
- __here__,
- 'config_fixtures/config.py'
- )))
-
- self.assertEqual(conf.app.root, None)
- self.assertEqual(conf.app.template_path, 'myproject/templates')
- self.assertEqual(conf.app.static_root, 'public')
-
- self.assertEqual(conf.server.host, '1.1.1.1')
- self.assertEqual(conf.server.port, '8081')
-
- def test_update_set_default_config(self):
- """Update an empty configuration with the default values"""
- from pecan import configuration
-
- conf = configuration.initconf()
- conf.update(configuration.conf_from_file(os.path.join(
- __here__,
- 'config_fixtures/empty.py'
- )))
-
- self.assertEqual(conf.app.root, None)
- self.assertEqual(conf.app.template_path, '')
- self.assertEqual(conf.app.static_root, 'public')
-
- self.assertEqual(conf.server.host, '0.0.0.0')
- self.assertEqual(conf.server.port, '8080')
-
- def test_update_force_dict(self):
- """Update an empty configuration with the default values"""
- from pecan import configuration
- conf = configuration.initconf()
- conf.update(configuration.conf_from_file(os.path.join(
- __here__,
- 'config_fixtures/forcedict.py'
- )))
-
- self.assertEqual(conf.app.root, None)
- self.assertEqual(conf.app.template_path, '')
- self.assertEqual(conf.app.static_root, 'public')
-
- self.assertEqual(conf.server.host, '0.0.0.0')
- self.assertEqual(conf.server.port, '8080')
-
- self.assertTrue(isinstance(conf.beaker, dict))
- self.assertEqual(conf.beaker['session.key'], 'key')
- self.assertEqual(conf.beaker['session.type'], 'cookie')
- self.assertEqual(
- conf.beaker['session.validate_key'],
- '1a971a7df182df3e1dec0af7c6913ec7'
- )
- self.assertEqual(conf.beaker.get('__force_dict__'), None)
-
- def test_update_config_with_dict(self):
- from pecan import configuration
- conf = configuration.initconf()
- d = {'attr': True}
- conf['attr'] = d
- self.assertTrue(conf.attr.attr)
-
- def test_config_repr(self):
- from pecan import configuration
- conf = configuration.Config({'a': 1})
- self.assertEqual(repr(conf), "Config({'a': 1})")
-
- def test_config_from_dict(self):
- from pecan import configuration
- conf = configuration.conf_from_dict({})
- conf['path'] = '%(confdir)s'
- self.assertTrue(os.path.samefile(conf['path'], os.getcwd()))
-
- def test_config_from_file(self):
- from pecan import configuration
- path = os.path.join(
- os.path.dirname(__file__), 'config_fixtures', 'config.py'
- )
- configuration.conf_from_file(path)
-
- def test_config_illegal_ids(self):
- from pecan import configuration
- conf = configuration.Config({})
- conf.update(configuration.conf_from_file(os.path.join(
- __here__,
- 'config_fixtures/bad/module_and_underscore.py'
- )))
- self.assertEqual([], list(conf))
-
- def test_config_missing_file(self):
- from pecan import configuration
- path = ('doesnotexist.py',)
- configuration.Config({})
- self.assertRaises(
- RuntimeError,
- configuration.conf_from_file,
- os.path.join(__here__, 'config_fixtures', *path)
- )
-
- def test_config_missing_file_on_path(self):
- from pecan import configuration
- path = ('bad', 'bad', 'doesnotexist.py',)
- configuration.Config({})
-
- self.assertRaises(
- RuntimeError,
- configuration.conf_from_file,
- os.path.join(__here__, 'config_fixtures', *path)
- )
-
- def test_config_with_syntax_error(self):
- from pecan import configuration
- with tempfile.NamedTemporaryFile('wb') as f:
- f.write(b_('\n'.join(['if false', 'var = 3'])))
- f.flush()
- configuration.Config({})
-
- self.assertRaises(
- SyntaxError,
- configuration.conf_from_file,
- f.name
- )
-
- def test_config_with_non_package_relative_import(self):
- from pecan import configuration
- with tempfile.NamedTemporaryFile('wb', suffix='.py') as f:
- f.write(b_('\n'.join(['from . import variables'])))
- f.flush()
- configuration.Config({})
-
- try:
- configuration.conf_from_file(f.name)
- except (ValueError, SystemError) as e:
- assert 'relative import' in str(e)
- else:
- raise AssertionError(
- "A relative import-related error should have been raised"
- )
-
- def test_config_with_bad_import(self):
- from pecan import configuration
- path = ('bad', 'importerror.py')
- configuration.Config({})
-
- self.assertRaises(
- ImportError,
- configuration.conf_from_file,
- os.path.join(
- __here__,
- 'config_fixtures',
- *path
- )
- )
-
- def test_config_dir(self):
- from pecan import configuration
- if sys.version_info >= (2, 6):
- conf = configuration.Config({})
- self.assertEqual([], dir(conf))
- conf = configuration.Config({'a': 1})
- self.assertEqual(['a'], dir(conf))
-
- def test_config_bad_key(self):
- from pecan import configuration
- conf = configuration.Config({'a': 1})
- assert conf.a == 1
- self.assertRaises(AttributeError, getattr, conf, 'b')
-
- def test_config_get_valid_key(self):
- from pecan import configuration
- conf = configuration.Config({'a': 1})
- assert conf.get('a') == 1
-
- def test_config_get_invalid_key(self):
- from pecan import configuration
- conf = configuration.Config({'a': 1})
- assert conf.get('b') is None
-
- def test_config_get_invalid_key_return_default(self):
- from pecan import configuration
- conf = configuration.Config({'a': 1})
- assert conf.get('b', True) is True
-
- def test_config_to_dict(self):
- from pecan import configuration
- conf = configuration.initconf()
-
- assert isinstance(conf, configuration.Config)
-
- to_dict = conf.to_dict()
-
- assert isinstance(to_dict, dict)
- assert to_dict['server']['host'] == '0.0.0.0'
- assert to_dict['server']['port'] == '8080'
- assert to_dict['app']['modules'] == []
- assert to_dict['app']['root'] is None
- assert to_dict['app']['static_root'] == 'public'
- assert to_dict['app']['template_path'] == ''
-
- def test_config_to_dict_nested(self):
- from pecan import configuration
- """have more than one level nesting and convert to dict"""
- conf = configuration.initconf()
- nested = {'one': {'two': 2}}
- conf['nested'] = nested
-
- to_dict = conf.to_dict()
-
- assert isinstance(to_dict, dict)
- assert to_dict['server']['host'] == '0.0.0.0'
- assert to_dict['server']['port'] == '8080'
- assert to_dict['app']['modules'] == []
- assert to_dict['app']['root'] is None
- assert to_dict['app']['static_root'] == 'public'
- assert to_dict['app']['template_path'] == ''
- assert to_dict['nested']['one']['two'] == 2
-
- def test_config_to_dict_prefixed(self):
- from pecan import configuration
- """Add a prefix for keys"""
- conf = configuration.initconf()
-
- assert isinstance(conf, configuration.Config)
-
- to_dict = conf.to_dict('prefix_')
-
- assert isinstance(to_dict, dict)
- assert to_dict['prefix_server']['prefix_host'] == '0.0.0.0'
- assert to_dict['prefix_server']['prefix_port'] == '8080'
- assert to_dict['prefix_app']['prefix_modules'] == []
- assert to_dict['prefix_app']['prefix_root'] is None
- assert to_dict['prefix_app']['prefix_static_root'] == 'public'
- assert to_dict['prefix_app']['prefix_template_path'] == ''
-
-
-class TestGlobalConfig(PecanTestCase):
-
- def tearDown(self):
- from pecan import configuration
- configuration.set_config(
- dict(configuration.initconf()),
- overwrite=True
- )
-
- def test_paint_from_dict(self):
- from pecan import configuration
- configuration.set_config({'foo': 'bar'})
- assert dict(configuration._runtime_conf) != {'foo': 'bar'}
- self.assertEqual(configuration._runtime_conf.foo, 'bar')
-
- def test_overwrite_from_dict(self):
- from pecan import configuration
- configuration.set_config({'foo': 'bar'}, overwrite=True)
- assert dict(configuration._runtime_conf) == {'foo': 'bar'}
-
- def test_paint_from_file(self):
- from pecan import configuration
- configuration.set_config(os.path.join(
- __here__,
- 'config_fixtures/foobar.py'
- ))
- assert dict(configuration._runtime_conf) != {'foo': 'bar'}
- assert configuration._runtime_conf.foo == 'bar'
-
- def test_overwrite_from_file(self):
- from pecan import configuration
- configuration.set_config(
- os.path.join(
- __here__,
- 'config_fixtures/foobar.py',
- ),
- overwrite=True
- )
- assert dict(configuration._runtime_conf) == {'foo': 'bar'}
-
- def test_set_config_none_type(self):
- from pecan import configuration
- self.assertRaises(RuntimeError, configuration.set_config, None)
-
- def test_set_config_to_dir(self):
- from pecan import configuration
- self.assertRaises(RuntimeError, configuration.set_config, '/')
-
-
-class TestConfFromEnv(PecanTestCase):
- #
- # Note that there is a good chance of pollution if ``tearDown`` does not
- # reset the configuration like this class does. If implementing new classes
- # for configuration this tearDown **needs to be implemented**
- #
-
- def setUp(self):
- super(TestConfFromEnv, self).setUp()
- self.addCleanup(self._remove_config_key)
-
- from pecan import configuration
- self.get_conf_path_from_env = configuration.get_conf_path_from_env
-
- def _remove_config_key(self):
- os.environ.pop('PECAN_CONFIG', None)
-
- def test_invalid_path(self):
- os.environ['PECAN_CONFIG'] = '/'
- msg = "PECAN_CONFIG was set to an invalid path: /"
- self.assertRaisesRegexp(
- RuntimeError,
- msg,
- self.get_conf_path_from_env
- )
-
- def test_is_not_set(self):
- msg = "PECAN_CONFIG is not set and " \
- "no config file was passed as an argument."
- self.assertRaisesRegexp(
- RuntimeError,
- msg,
- self.get_conf_path_from_env
- )
-
- def test_return_valid_path(self):
- __here__ = os.path.abspath(__file__)
- os.environ['PECAN_CONFIG'] = __here__
- assert self.get_conf_path_from_env() == __here__
diff --git a/pecan/tests/test_generic.py b/pecan/tests/test_generic.py
deleted file mode 100644
index 0478799..0000000
--- a/pecan/tests/test_generic.py
+++ /dev/null
@@ -1,111 +0,0 @@
-from webtest import TestApp
-try:
- from simplejson import dumps
-except:
- from json import dumps # noqa
-
-from six import b as b_
-
-from pecan import Pecan, expose, abort
-from pecan.tests import PecanTestCase
-
-
-class TestGeneric(PecanTestCase):
-
- def test_simple_generic(self):
- class RootController(object):
- @expose(generic=True)
- def index(self):
- pass
-
- @index.when(method='POST', template='json')
- def do_post(self):
- return dict(result='POST')
-
- @index.when(method='GET')
- def do_get(self):
- return 'GET'
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('GET')
-
- r = app.post('/')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(result='POST')))
-
- r = app.get('/do_get', status=404)
- assert r.status_int == 404
-
- def test_generic_allow_header(self):
- class RootController(object):
- @expose(generic=True)
- def index(self):
- abort(405)
-
- @index.when(method='POST', template='json')
- def do_post(self):
- return dict(result='POST')
-
- @index.when(method='GET')
- def do_get(self):
- return 'GET'
-
- @index.when(method='PATCH')
- def do_patch(self):
- return 'PATCH'
-
- app = TestApp(Pecan(RootController()))
- r = app.delete('/', expect_errors=True)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'GET, PATCH, POST'
-
- def test_nested_generic(self):
-
- class SubSubController(object):
- @expose(generic=True)
- def index(self):
- return 'GET'
-
- @index.when(method='DELETE', template='json')
- def do_delete(self, name, *args):
- return dict(result=name, args=', '.join(args))
-
- class SubController(object):
- sub = SubSubController()
-
- class RootController(object):
- sub = SubController()
-
- app = TestApp(Pecan(RootController()))
- r = app.get('/sub/sub/')
- assert r.status_int == 200
- assert r.body == b_('GET')
-
- r = app.delete('/sub/sub/joe/is/cool')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(result='joe', args='is, cool')))
-
-
-class TestGenericWithSpecialMethods(PecanTestCase):
-
- def test_generics_not_allowed(self):
-
- class C(object):
-
- def _default(self):
- pass
-
- def _lookup(self):
- pass
-
- def _route(self):
- pass
-
- for method in (C._default, C._lookup, C._route):
- self.assertRaises(
- ValueError,
- expose(generic=True),
- getattr(method, '__func__', method)
- )
diff --git a/pecan/tests/test_hooks.py b/pecan/tests/test_hooks.py
deleted file mode 100644
index a15368e..0000000
--- a/pecan/tests/test_hooks.py
+++ /dev/null
@@ -1,1711 +0,0 @@
-import inspect
-import operator
-
-from webtest import TestApp
-from six import PY3
-from six import b as b_
-from six import u as u_
-from six.moves import cStringIO as StringIO
-
-from pecan import make_app, expose, redirect, abort, rest, Request, Response
-from pecan.hooks import (
- PecanHook, TransactionHook, HookController, RequestViewerHook
-)
-from pecan.configuration import Config
-from pecan.decorators import transactional, after_commit, after_rollback
-from pecan.tests import PecanTestCase
-
-# The `inspect.Arguments` namedtuple is different between PY2/3
-kwargs = operator.attrgetter('varkw' if PY3 else 'keywords')
-
-
-class TestHooks(PecanTestCase):
-
- def test_basic_single_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- def before(self, state):
- run_hook.append('before')
-
- def after(self, state):
- run_hook.append('after')
-
- def on_error(self, state, e):
- run_hook.append('error')
-
- app = TestApp(make_app(RootController(), hooks=[SimpleHook()]))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'before'
- assert run_hook[2] == 'inside'
- assert run_hook[3] == 'after'
-
- def test_basic_multi_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def __init__(self, id):
- self.id = str(id)
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- app = TestApp(make_app(RootController(), hooks=[
- SimpleHook(1), SimpleHook(2), SimpleHook(3)
- ]))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 10
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'on_route2'
- assert run_hook[2] == 'on_route3'
- assert run_hook[3] == 'before1'
- assert run_hook[4] == 'before2'
- assert run_hook[5] == 'before3'
- assert run_hook[6] == 'inside'
- assert run_hook[7] == 'after3'
- assert run_hook[8] == 'after2'
- assert run_hook[9] == 'after1'
-
- def test_partial_hooks(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello World!'
-
- @expose()
- def causeerror(self):
- return [][1]
-
- class ErrorHook(PecanHook):
- def on_error(self, state, e):
- run_hook.append('error')
-
- class OnRouteHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- app = TestApp(make_app(RootController(), hooks=[
- ErrorHook(), OnRouteHook()
- ]))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello World!')
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'inside'
-
- run_hook = []
- try:
- response = app.get('/causeerror')
- except Exception as e:
- assert isinstance(e, IndexError)
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'error'
-
- def test_on_error_response_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def causeerror(self):
- return [][1]
-
- class ErrorHook(PecanHook):
- def on_error(self, state, e):
- run_hook.append('error')
-
- r = Response()
- r.text = u_('on_error')
-
- return r
-
- app = TestApp(make_app(RootController(), hooks=[
- ErrorHook()
- ]))
-
- response = app.get('/causeerror')
-
- assert len(run_hook) == 1
- assert run_hook[0] == 'error'
- assert response.text == 'on_error'
-
- def test_prioritized_hooks(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def __init__(self, id, priority=None):
- self.id = str(id)
- if priority:
- self.priority = priority
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- papp = make_app(RootController(), hooks=[
- SimpleHook(1, 3), SimpleHook(2, 2), SimpleHook(3, 1)
- ])
- app = TestApp(papp)
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 10
- assert run_hook[0] == 'on_route3'
- assert run_hook[1] == 'on_route2'
- assert run_hook[2] == 'on_route1'
- assert run_hook[3] == 'before3'
- assert run_hook[4] == 'before2'
- assert run_hook[5] == 'before1'
- assert run_hook[6] == 'inside'
- assert run_hook[7] == 'after1'
- assert run_hook[8] == 'after2'
- assert run_hook[9] == 'after3'
-
- def test_basic_isolated_hook(self):
- run_hook = []
-
- class SimpleHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- def before(self, state):
- run_hook.append('before')
-
- def after(self, state):
- run_hook.append('after')
-
- def on_error(self, state, e):
- run_hook.append('error')
-
- class SubSubController(object):
- @expose()
- def index(self):
- run_hook.append('inside_sub_sub')
- return 'Deep inside here!'
-
- class SubController(HookController):
- __hooks__ = [SimpleHook()]
-
- @expose()
- def index(self):
- run_hook.append('inside_sub')
- return 'Inside here!'
-
- sub = SubSubController()
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- sub = SubController()
-
- app = TestApp(make_app(RootController()))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 1
- assert run_hook[0] == 'inside'
-
- run_hook = []
-
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('Inside here!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'before'
- assert run_hook[1] == 'inside_sub'
- assert run_hook[2] == 'after'
-
- run_hook = []
- response = app.get('/sub/sub/')
- assert response.status_int == 200
- assert response.body == b_('Deep inside here!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'before'
- assert run_hook[1] == 'inside_sub_sub'
- assert run_hook[2] == 'after'
-
- def test_isolated_hook_with_global_hook(self):
- run_hook = []
-
- class SimpleHook(PecanHook):
- def __init__(self, id):
- self.id = str(id)
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- class SubController(HookController):
- __hooks__ = [SimpleHook(2)]
-
- @expose()
- def index(self):
- run_hook.append('inside_sub')
- return 'Inside here!'
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- sub = SubController()
-
- app = TestApp(make_app(RootController(), hooks=[SimpleHook(1)]))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'before1'
- assert run_hook[2] == 'inside'
- assert run_hook[3] == 'after1'
-
- run_hook = []
-
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('Inside here!')
-
- assert len(run_hook) == 6
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'before2'
- assert run_hook[2] == 'before1'
- assert run_hook[3] == 'inside_sub'
- assert run_hook[4] == 'after1'
- assert run_hook[5] == 'after2'
-
- def test_mixin_hooks(self):
- run_hook = []
-
- class HelperHook(PecanHook):
- priority = 2
-
- def before(self, state):
- run_hook.append('helper - before hook')
-
- # we'll use the same hook instance to avoid duplicate calls
- helper_hook = HelperHook()
-
- class LastHook(PecanHook):
- priority = 200
-
- def before(self, state):
- run_hook.append('last - before hook')
-
- class SimpleHook(PecanHook):
- priority = 1
-
- def before(self, state):
- run_hook.append('simple - before hook')
-
- class HelperMixin(object):
- __hooks__ = [helper_hook]
-
- class LastMixin(object):
- __hooks__ = [LastHook()]
-
- class SubController(HookController, HelperMixin):
- __hooks__ = [LastHook()]
-
- @expose()
- def index(self):
- return "This is sub controller!"
-
- class RootController(HookController, LastMixin):
- __hooks__ = [SimpleHook(), helper_hook]
-
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- sub = SubController()
-
- papp = make_app(RootController())
- app = TestApp(papp)
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'simple - before hook', run_hook[0]
- assert run_hook[1] == 'helper - before hook', run_hook[1]
- assert run_hook[2] == 'last - before hook', run_hook[2]
- assert run_hook[3] == 'inside', run_hook[3]
-
- run_hook = []
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('This is sub controller!')
-
- assert len(run_hook) == 4, run_hook
- assert run_hook[0] == 'simple - before hook', run_hook[0]
- assert run_hook[1] == 'helper - before hook', run_hook[1]
- assert run_hook[2] == 'last - before hook', run_hook[2]
- # LastHook is invoked once again -
- # for each different instance of the Hook in the two Controllers
- assert run_hook[3] == 'last - before hook', run_hook[3]
-
-
-class TestStateAccess(PecanTestCase):
-
- def setUp(self):
- super(TestStateAccess, self).setUp()
- self.args = None
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- @expose()
- def greet(self, name):
- return 'Hello, %s!' % name
-
- @expose()
- def greetmore(self, *args):
- return 'Hello, %s!' % args[0]
-
- @expose()
- def kwargs(self, **kw):
- return 'Hello, %s!' % kw['name']
-
- @expose()
- def mixed(self, first, second, *args):
- return 'Mixed'
-
- class SimpleHook(PecanHook):
- def before(inself, state):
- self.args = (state.controller, state.arguments)
-
- self.root = RootController()
- self.app = TestApp(make_app(self.root, hooks=[SimpleHook()]))
-
- def test_no_args(self):
- self.app.get('/')
- assert self.args[0] == self.root.index
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_single_arg(self):
- self.app.get('/greet/joe')
- assert self.args[0] == self.root.greet
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['joe']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_single_vararg(self):
- self.app.get('/greetmore/joe')
- assert self.args[0] == self.root.greetmore
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == ['joe']
- assert kwargs(self.args[1]) == {}
-
- def test_single_kw(self):
- self.app.get('/kwargs/?name=joe')
- assert self.args[0] == self.root.kwargs
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'name': 'joe'}
-
- def test_single_kw_post(self):
- self.app.post('/kwargs/', params={'name': 'joe'})
- assert self.args[0] == self.root.kwargs
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'name': 'joe'}
-
- def test_mixed_args(self):
- self.app.get('/mixed/foo/bar/spam/eggs')
- assert self.args[0] == self.root.mixed
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['foo', 'bar']
- assert self.args[1].varargs == ['spam', 'eggs']
-
-
-class TestStateAccessWithoutThreadLocals(PecanTestCase):
-
- def setUp(self):
- super(TestStateAccessWithoutThreadLocals, self).setUp()
- self.args = None
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- return 'Hello, World!'
-
- @expose()
- def greet(self, req, resp, name):
- return 'Hello, %s!' % name
-
- @expose()
- def greetmore(self, req, resp, *args):
- return 'Hello, %s!' % args[0]
-
- @expose()
- def kwargs(self, req, resp, **kw):
- return 'Hello, %s!' % kw['name']
-
- @expose()
- def mixed(self, req, resp, first, second, *args):
- return 'Mixed'
-
- class SimpleHook(PecanHook):
- def before(inself, state):
- self.args = (state.controller, state.arguments)
-
- self.root = RootController()
- self.app = TestApp(make_app(
- self.root,
- hooks=[SimpleHook()],
- use_context_locals=False
- ))
-
- def test_no_args(self):
- self.app.get('/')
- assert self.args[0] == self.root.index
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 2
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_single_arg(self):
- self.app.get('/greet/joe')
- assert self.args[0] == self.root.greet
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 3
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].args[2] == 'joe'
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_single_vararg(self):
- self.app.get('/greetmore/joe')
- assert self.args[0] == self.root.greetmore
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 2
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].varargs == ['joe']
- assert kwargs(self.args[1]) == {}
-
- def test_single_kw(self):
- self.app.get('/kwargs/?name=joe')
- assert self.args[0] == self.root.kwargs
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 2
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'name': 'joe'}
-
- def test_single_kw_post(self):
- self.app.post('/kwargs/', params={'name': 'joe'})
- assert self.args[0] == self.root.kwargs
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 2
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'name': 'joe'}
-
- def test_mixed_args(self):
- self.app.get('/mixed/foo/bar/spam/eggs')
- assert self.args[0] == self.root.mixed
- assert isinstance(self.args[1], inspect.Arguments)
- assert len(self.args[1].args) == 4
- assert isinstance(self.args[1].args[0], Request)
- assert isinstance(self.args[1].args[1], Response)
- assert self.args[1].args[2:] == ['foo', 'bar']
- assert self.args[1].varargs == ['spam', 'eggs']
-
-
-class TestRestControllerStateAccess(PecanTestCase):
-
- def setUp(self):
- super(TestRestControllerStateAccess, self).setUp()
- self.args = None
-
- class RootController(rest.RestController):
-
- @expose()
- def _default(self, _id, *args, **kw):
- return 'Default'
-
- @expose()
- def get_all(self, **kw):
- return 'All'
-
- @expose()
- def get_one(self, _id, *args, **kw):
- return 'One'
-
- @expose()
- def post(self, *args, **kw):
- return 'POST'
-
- @expose()
- def put(self, _id, *args, **kw):
- return 'PUT'
-
- @expose()
- def delete(self, _id, *args, **kw):
- return 'DELETE'
-
- class SimpleHook(PecanHook):
- def before(inself, state):
- self.args = (state.controller, state.arguments)
-
- self.root = RootController()
- self.app = TestApp(make_app(self.root, hooks=[SimpleHook()]))
-
- def test_get_all(self):
- self.app.get('/')
- assert self.args[0] == self.root.get_all
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_get_all_with_kwargs(self):
- self.app.get('/?foo=bar')
- assert self.args[0] == self.root.get_all
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'foo': 'bar'}
-
- def test_get_one(self):
- self.app.get('/1')
- assert self.args[0] == self.root.get_one
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_get_one_with_varargs(self):
- self.app.get('/1/2/3')
- assert self.args[0] == self.root.get_one
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == ['2', '3']
- assert kwargs(self.args[1]) == {}
-
- def test_get_one_with_kwargs(self):
- self.app.get('/1?foo=bar')
- assert self.args[0] == self.root.get_one
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'foo': 'bar'}
-
- def test_post(self):
- self.app.post('/')
- assert self.args[0] == self.root.post
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_post_with_varargs(self):
- self.app.post('/foo/bar')
- assert self.args[0] == self.root.post
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == ['foo', 'bar']
- assert kwargs(self.args[1]) == {}
-
- def test_post_with_kwargs(self):
- self.app.post('/', params={'foo': 'bar'})
- assert self.args[0] == self.root.post
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == []
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'foo': 'bar'}
-
- def test_put(self):
- self.app.put('/1')
- assert self.args[0] == self.root.put
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_put_with_method_argument(self):
- self.app.post('/1?_method=put')
- assert self.args[0] == self.root.put
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'_method': 'put'}
-
- def test_put_with_varargs(self):
- self.app.put('/1/2/3')
- assert self.args[0] == self.root.put
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == ['2', '3']
- assert kwargs(self.args[1]) == {}
-
- def test_put_with_kwargs(self):
- self.app.put('/1?foo=bar')
- assert self.args[0] == self.root.put
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'foo': 'bar'}
-
- def test_delete(self):
- self.app.delete('/1')
- assert self.args[0] == self.root.delete
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {}
-
- def test_delete_with_method_argument(self):
- self.app.post('/1?_method=delete')
- assert self.args[0] == self.root.delete
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'_method': 'delete'}
-
- def test_delete_with_varargs(self):
- self.app.delete('/1/2/3')
- assert self.args[0] == self.root.delete
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == ['2', '3']
- assert kwargs(self.args[1]) == {}
-
- def test_delete_with_kwargs(self):
- self.app.delete('/1?foo=bar')
- assert self.args[0] == self.root.delete
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'foo': 'bar'}
-
- def test_post_with_invalid_method_kwarg(self):
- self.app.post('/1?_method=invalid')
- assert self.args[0] == self.root._default
- assert isinstance(self.args[1], inspect.Arguments)
- assert self.args[1].args == ['1']
- assert self.args[1].varargs == []
- assert kwargs(self.args[1]) == {'_method': 'invalid'}
-
-
-class TestTransactionHook(PecanTestCase):
- def test_transaction_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- @expose()
- def redirect(self):
- redirect('/')
-
- @expose()
- def error(self):
- return [][1]
-
- def gen(event):
- return lambda: run_hook.append(event)
-
- app = TestApp(make_app(RootController(), hooks=[
- TransactionHook(
- start=gen('start'),
- start_ro=gen('start_ro'),
- commit=gen('commit'),
- rollback=gen('rollback'),
- clear=gen('clear')
- )
- ]))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- response = app.post('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'commit'
- assert run_hook[3] == 'clear'
-
- #
- # test hooks for GET /redirect
- # This controller should always be non-transactional
- #
-
- run_hook = []
-
- response = app.get('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 2
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
-
- #
- # test hooks for POST /redirect
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'commit'
- assert run_hook[2] == 'clear'
-
- run_hook = []
- try:
- response = app.post('/error')
- except IndexError:
- pass
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- def test_transaction_hook_with_after_actions(self):
- run_hook = []
-
- def action(name):
- def action_impl():
- run_hook.append(name)
- return action_impl
-
- class RootController(object):
- @expose()
- @after_commit(action('action-one'))
- def index(self):
- run_hook.append('inside')
- return 'Index Method!'
-
- @expose()
- @transactional()
- @after_commit(action('action-two'))
- def decorated(self):
- run_hook.append('inside')
- return 'Decorated Method!'
-
- @expose()
- @after_rollback(action('action-three'))
- def rollback(self):
- abort(500)
-
- @expose()
- @transactional()
- @after_rollback(action('action-four'))
- def rollback_decorated(self):
- abort(500)
-
- def gen(event):
- return lambda: run_hook.append(event)
-
- app = TestApp(make_app(RootController(), hooks=[
- TransactionHook(
- start=gen('start'),
- start_ro=gen('start_ro'),
- commit=gen('commit'),
- rollback=gen('rollback'),
- clear=gen('clear')
- )
- ]))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Index Method!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- response = app.post('/')
- assert response.status_int == 200
- assert response.body == b_('Index Method!')
-
- assert len(run_hook) == 5
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'commit'
- assert run_hook[3] == 'action-one'
- assert run_hook[4] == 'clear'
-
- run_hook = []
-
- response = app.get('/decorated')
- assert response.status_int == 200
- assert response.body == b_('Decorated Method!')
-
- assert len(run_hook) == 7
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'inside'
- assert run_hook[4] == 'commit'
- assert run_hook[5] == 'action-two'
- assert run_hook[6] == 'clear'
-
- run_hook = []
-
- response = app.get('/rollback', expect_errors=True)
- assert response.status_int == 500
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
-
- run_hook = []
-
- response = app.post('/rollback', expect_errors=True)
- assert response.status_int == 500
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'action-three'
- assert run_hook[3] == 'clear'
-
- run_hook = []
-
- response = app.get('/rollback_decorated', expect_errors=True)
- assert response.status_int == 500
-
- assert len(run_hook) == 6
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'action-four'
- assert run_hook[5] == 'clear'
-
- run_hook = []
-
- response = app.get('/fourohfour', status=404)
- assert response.status_int == 404
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
-
- def test_transaction_hook_with_transactional_decorator(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- @expose()
- def redirect(self):
- redirect('/')
-
- @expose()
- @transactional()
- def redirect_transactional(self):
- redirect('/')
-
- @expose()
- @transactional(False)
- def redirect_rollback(self):
- redirect('/')
-
- @expose()
- def error(self):
- return [][1]
-
- @expose()
- @transactional(False)
- def error_rollback(self):
- return [][1]
-
- @expose()
- @transactional()
- def error_transactional(self):
- return [][1]
-
- def gen(event):
- return lambda: run_hook.append(event)
-
- app = TestApp(make_app(RootController(), hooks=[
- TransactionHook(
- start=gen('start'),
- start_ro=gen('start_ro'),
- commit=gen('commit'),
- rollback=gen('rollback'),
- clear=gen('clear')
- )
- ]))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- # test hooks for /
-
- response = app.post('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'commit'
- assert run_hook[3] == 'clear'
-
- #
- # test hooks for GET /redirect
- # This controller should always be non-transactional
- #
-
- run_hook = []
-
- response = app.get('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 2
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
-
- #
- # test hooks for POST /redirect
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'commit'
- assert run_hook[2] == 'clear'
-
- #
- # test hooks for GET /redirect_transactional
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
-
- response = app.get('/redirect_transactional')
- assert response.status_int == 302
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'commit'
- assert run_hook[4] == 'clear'
-
- #
- # test hooks for POST /redirect_transactional
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect_transactional')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'commit'
- assert run_hook[2] == 'clear'
-
- #
- # test hooks for GET /redirect_rollback
- # This controller should always be transactional,
- # *except* in the case of redirects
- #
- run_hook = []
-
- response = app.get('/redirect_rollback')
- assert response.status_int == 302
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'clear'
-
- #
- # test hooks for POST /redirect_rollback
- # This controller should always be transactional,
- # *except* in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect_rollback')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- #
- # Exceptions (other than HTTPFound) should *always*
- # rollback no matter what
- #
- run_hook = []
-
- try:
- response = app.post('/error')
- except IndexError:
- pass
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- try:
- response = app.get('/error')
- except IndexError:
- pass
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
-
- run_hook = []
-
- try:
- response = app.post('/error_transactional')
- except IndexError:
- pass
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- try:
- response = app.get('/error_transactional')
- except IndexError:
- pass
-
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'clear'
-
- run_hook = []
-
- try:
- response = app.post('/error_rollback')
- except IndexError:
- pass
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- try:
- response = app.get('/error_rollback')
- except IndexError:
- pass
-
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'clear'
-
- def test_transaction_hook_with_transactional_class_decorator(self):
- run_hook = []
-
- @transactional()
- class RootController(object):
- @expose()
- def index(self):
- run_hook.append('inside')
- return 'Hello, World!'
-
- @expose()
- def redirect(self):
- redirect('/')
-
- @expose()
- @transactional(False)
- def redirect_rollback(self):
- redirect('/')
-
- @expose()
- def error(self):
- return [][1]
-
- @expose(generic=True)
- def generic(self):
- pass
-
- @generic.when(method='GET')
- def generic_get(self):
- run_hook.append('inside')
- return 'generic get'
-
- @generic.when(method='POST')
- def generic_post(self):
- run_hook.append('inside')
- return 'generic post'
-
- def gen(event):
- return lambda: run_hook.append(event)
-
- app = TestApp(make_app(RootController(), hooks=[
- TransactionHook(
- start=gen('start'),
- start_ro=gen('start_ro'),
- commit=gen('commit'),
- rollback=gen('rollback'),
- clear=gen('clear')
- )
- ]))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 6
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'inside'
- assert run_hook[4] == 'commit'
- assert run_hook[5] == 'clear'
-
- run_hook = []
-
- # test hooks for /
-
- response = app.post('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'commit'
- assert run_hook[3] == 'clear'
-
- #
- # test hooks for GET /redirect
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
- response = app.get('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'commit'
- assert run_hook[4] == 'clear'
-
- #
- # test hooks for POST /redirect
- # This controller should always be transactional,
- # even in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'commit'
- assert run_hook[2] == 'clear'
-
- #
- # test hooks for GET /redirect_rollback
- # This controller should always be transactional,
- # *except* in the case of redirects
- #
- run_hook = []
-
- response = app.get('/redirect_rollback')
- assert response.status_int == 302
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'clear'
-
- #
- # test hooks for POST /redirect_rollback
- # This controller should always be transactional,
- # *except* in the case of redirects
- #
-
- run_hook = []
-
- response = app.post('/redirect_rollback')
- assert response.status_int == 302
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- #
- # Exceptions (other than HTTPFound) should *always*
- # rollback no matter what
- #
- run_hook = []
-
- try:
- response = app.post('/error')
- except IndexError:
- pass
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'rollback'
- assert run_hook[2] == 'clear'
-
- run_hook = []
-
- try:
- response = app.get('/error')
- except IndexError:
- pass
-
- assert len(run_hook) == 5
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'rollback'
- assert run_hook[4] == 'clear'
-
- #
- # test hooks for GET /generic
- # This controller should always be transactional,
- #
-
- run_hook = []
-
- response = app.get('/generic')
- assert response.status_int == 200
- assert response.body == b_('generic get')
- assert len(run_hook) == 6
- assert run_hook[0] == 'start_ro'
- assert run_hook[1] == 'clear'
- assert run_hook[2] == 'start'
- assert run_hook[3] == 'inside'
- assert run_hook[4] == 'commit'
- assert run_hook[5] == 'clear'
-
- #
- # test hooks for POST /generic
- # This controller should always be transactional,
- #
-
- run_hook = []
-
- response = app.post('/generic')
- assert response.status_int == 200
- assert response.body == b_('generic post')
- assert len(run_hook) == 4
- assert run_hook[0] == 'start'
- assert run_hook[1] == 'inside'
- assert run_hook[2] == 'commit'
- assert run_hook[3] == 'clear'
-
- def test_transaction_hook_with_broken_hook(self):
- """
- In a scenario where a preceding hook throws an exception,
- ensure that TransactionHook still rolls back properly.
- """
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- def gen(event):
- return lambda: run_hook.append(event)
-
- class MyCustomException(Exception):
- pass
-
- class MyHook(PecanHook):
-
- def on_route(self, state):
- raise MyCustomException('BROKEN!')
-
- app = TestApp(make_app(RootController(), hooks=[
- MyHook(),
- TransactionHook(
- start=gen('start'),
- start_ro=gen('start_ro'),
- commit=gen('commit'),
- rollback=gen('rollback'),
- clear=gen('clear')
- )
- ]))
-
- self.assertRaises(
- MyCustomException,
- app.get,
- '/'
- )
-
- assert len(run_hook) == 1
- assert run_hook[0] == 'clear'
-
-
-class TestRequestViewerHook(PecanTestCase):
-
- def test_basic_single_default_hook(self):
-
- _stdout = StringIO()
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(
- make_app(
- RootController(), hooks=lambda: [
- RequestViewerHook(writer=_stdout)
- ]
- )
- )
- response = app.get('/')
-
- out = _stdout.getvalue()
-
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
- assert 'path' in out
- assert 'method' in out
- assert 'status' in out
- assert 'method' in out
- assert 'params' in out
- assert 'hooks' in out
- assert '200 OK' in out
- assert "['RequestViewerHook']" in out
- assert '/' in out
-
- def test_bad_response_from_app(self):
- """When exceptions are raised the hook deals with them properly"""
-
- _stdout = StringIO()
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(
- make_app(
- RootController(), hooks=lambda: [
- RequestViewerHook(writer=_stdout)
- ]
- )
- )
- response = app.get('/404', expect_errors=True)
-
- out = _stdout.getvalue()
-
- assert response.status_int == 404
- assert 'path' in out
- assert 'method' in out
- assert 'status' in out
- assert 'method' in out
- assert 'params' in out
- assert 'hooks' in out
- assert '404 Not Found' in out
- assert "['RequestViewerHook']" in out
- assert '/' in out
-
- def test_single_item(self):
-
- _stdout = StringIO()
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(
- make_app(
- RootController(),
- hooks=lambda: [
- RequestViewerHook(
- config={'items': ['path']}, writer=_stdout
- )
- ]
- )
- )
- response = app.get('/')
-
- out = _stdout.getvalue()
-
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
- assert '/' in out
- assert 'path' in out
- assert 'method' not in out
- assert 'status' not in out
- assert 'method' not in out
- assert 'params' not in out
- assert 'hooks' not in out
- assert '200 OK' not in out
- assert "['RequestViewerHook']" not in out
-
- def test_single_blacklist_item(self):
-
- _stdout = StringIO()
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(
- make_app(
- RootController(),
- hooks=lambda: [
- RequestViewerHook(
- config={'blacklist': ['/']}, writer=_stdout
- )
- ]
- )
- )
- response = app.get('/')
-
- out = _stdout.getvalue()
-
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
- assert out == ''
-
- def test_item_not_in_defaults(self):
-
- _stdout = StringIO()
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- app = TestApp(
- make_app(
- RootController(),
- hooks=lambda: [
- RequestViewerHook(
- config={'items': ['date']}, writer=_stdout
- )
- ]
- )
- )
- response = app.get('/')
-
- out = _stdout.getvalue()
-
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
- assert 'date' in out
- assert 'method' not in out
- assert 'status' not in out
- assert 'method' not in out
- assert 'params' not in out
- assert 'hooks' not in out
- assert '200 OK' not in out
- assert "['RequestViewerHook']" not in out
- assert '/' not in out
-
- def test_hook_formatting(self):
- hooks = ['<pecan.hooks.RequestViewerHook object at 0x103a5f910>']
- viewer = RequestViewerHook()
- formatted = viewer.format_hooks(hooks)
-
- assert formatted == ['RequestViewerHook']
-
- def test_deal_with_pecan_configs(self):
- """If config comes from pecan.conf convert it to dict"""
- conf = Config(conf_dict={'items': ['url']})
- viewer = RequestViewerHook(conf)
-
- assert viewer.items == ['url']
-
-
-class TestRestControllerWithHooks(PecanTestCase):
-
- def test_restcontroller_with_hooks(self):
-
- class SomeHook(PecanHook):
-
- def before(self, state):
- state.response.headers['X-Testing'] = 'XYZ'
-
- class BaseController(rest.RestController):
-
- @expose()
- def delete(self, _id):
- return 'Deleting %s' % _id
-
- class RootController(BaseController, HookController):
-
- __hooks__ = [SomeHook()]
-
- @expose()
- def get_all(self):
- return 'Hello, World!'
-
- @staticmethod
- def static(cls):
- return 'static'
-
- @property
- def foo(self):
- return 'bar'
-
- def testing123(self):
- return 'bar'
-
- unhashable = [1, 'two', 3]
-
- app = TestApp(
- make_app(
- RootController()
- )
- )
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
- assert response.headers['X-Testing'] == 'XYZ'
-
- response = app.delete('/100/')
- assert response.status_int == 200
- assert response.body == b_('Deleting 100')
- assert response.headers['X-Testing'] == 'XYZ'
diff --git a/pecan/tests/test_jsonify.py b/pecan/tests/test_jsonify.py
deleted file mode 100644
index 2dcd663..0000000
--- a/pecan/tests/test_jsonify.py
+++ /dev/null
@@ -1,233 +0,0 @@
-from datetime import datetime, date
-from decimal import Decimal
-try:
- from simplejson import loads
-except:
- from json import loads # noqa
-try:
- from sqlalchemy import orm, schema, types
- from sqlalchemy.engine import create_engine
-except ImportError:
- create_engine = None # noqa
-
-from webtest import TestApp
-from webob.multidict import MultiDict
-
-from pecan.jsonify import jsonify, encode, ResultProxy, RowProxy
-from pecan import Pecan, expose
-from pecan.tests import PecanTestCase
-
-
-def make_person():
- class Person(object):
- def __init__(self, first_name, last_name):
- self.first_name = first_name
- self.last_name = last_name
-
- @property
- def name(self):
- return '%s %s' % (self.first_name, self.last_name)
- return Person
-
-
-def test_simple_rule():
- Person = make_person()
-
- # create a Person instance
- p = Person('Jonathan', 'LaCour')
-
- # register a generic JSON rule
- @jsonify.when_type(Person)
- def jsonify_person(obj):
- return dict(
- name=obj.name
- )
-
- # encode the object using our new rule
- result = loads(encode(p))
- assert result['name'] == 'Jonathan LaCour'
- assert len(result) == 1
-
-
-class TestJsonify(PecanTestCase):
-
- def test_simple_jsonify(self):
- Person = make_person()
-
- # register a generic JSON rule
- @jsonify.when_type(Person)
- def jsonify_person(obj):
- return dict(
- name=obj.name
- )
-
- class RootController(object):
- @expose('json')
- def index(self):
- # create a Person instance
- p = Person('Jonathan', 'LaCour')
- return p
-
- app = TestApp(Pecan(RootController()))
-
- r = app.get('/')
- assert r.status_int == 200
- assert loads(r.body.decode()) == {'name': 'Jonathan LaCour'}
-
-
-class TestJsonifyGenericEncoder(PecanTestCase):
- def test_json_callable(self):
- class JsonCallable(object):
- def __init__(self, arg):
- self.arg = arg
-
- def __json__(self):
- return {"arg": self.arg}
-
- result = encode(JsonCallable('foo'))
- assert loads(result) == {'arg': 'foo'}
-
- def test_datetime(self):
- today = date.today()
- now = datetime.now()
-
- result = encode(today)
- assert loads(result) == str(today)
-
- result = encode(now)
- assert loads(result) == str(now)
-
- def test_decimal(self):
- # XXX Testing for float match which is inexact
-
- d = Decimal('1.1')
- result = encode(d)
- assert loads(result) == float(d)
-
- def test_multidict(self):
- md = MultiDict()
- md.add('arg', 'foo')
- md.add('arg', 'bar')
- result = encode(md)
- assert loads(result) == {'arg': ['foo', 'bar']}
-
- def test_fallback_to_builtin_encoder(self):
- class Foo(object):
- pass
-
- self.assertRaises(TypeError, encode, Foo())
-
-
-class TestJsonifySQLAlchemyGenericEncoder(PecanTestCase):
-
- def setUp(self):
- super(TestJsonifySQLAlchemyGenericEncoder, self).setUp()
- if not create_engine:
- self.create_fake_proxies()
- else:
- self.create_sa_proxies()
-
- def create_fake_proxies(self):
-
- # create a fake SA object
- class FakeSAObject(object):
- def __init__(self):
- self._sa_class_manager = object()
- self._sa_instance_state = 'awesome'
- self.id = 1
- self.first_name = 'Jonathan'
- self.last_name = 'LaCour'
-
- # create a fake result proxy
- class FakeResultProxy(ResultProxy):
- def __init__(self):
- self.rowcount = -1
- self.rows = []
-
- def __iter__(self):
- return iter(self.rows)
-
- def append(self, row):
- self.rows.append(row)
-
- # create a fake row proxy
- class FakeRowProxy(RowProxy):
- def __init__(self, arg=None):
- self.row = dict(arg)
-
- def __getitem__(self, key):
- return self.row.__getitem__(key)
-
- def keys(self):
- return self.row.keys()
-
- # get the SA objects
- self.sa_object = FakeSAObject()
- self.result_proxy = FakeResultProxy()
- self.result_proxy.append(
- FakeRowProxy([
- ('id', 1),
- ('first_name', 'Jonathan'),
- ('last_name', 'LaCour')
- ])
- )
- self.result_proxy.append(
- FakeRowProxy([
- ('id', 2), ('first_name', 'Yoann'), ('last_name', 'Roman')
- ]))
- self.row_proxy = FakeRowProxy([
- ('id', 1), ('first_name', 'Jonathan'), ('last_name', 'LaCour')
- ])
-
- def create_sa_proxies(self):
-
- # create the table and mapper
- metadata = schema.MetaData()
- user_table = schema.Table(
- 'user',
- metadata,
- schema.Column('id', types.Integer, primary_key=True),
- schema.Column('first_name', types.Unicode(25)),
- schema.Column('last_name', types.Unicode(25))
- )
-
- class User(object):
- pass
- orm.mapper(User, user_table)
-
- # create the session
- engine = create_engine('sqlite:///:memory:')
- metadata.bind = engine
- metadata.create_all()
- session = orm.sessionmaker(bind=engine)()
-
- # add some dummy data
- user_table.insert().execute([
- {'first_name': 'Jonathan', 'last_name': 'LaCour'},
- {'first_name': 'Yoann', 'last_name': 'Roman'}
- ])
-
- # get the SA objects
- self.sa_object = session.query(User).first()
- select = user_table.select()
- self.result_proxy = select.execute()
- self.row_proxy = select.execute().fetchone()
-
- def test_sa_object(self):
- result = encode(self.sa_object)
- assert loads(result) == {
- 'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'
- }
-
- def test_result_proxy(self):
- result = encode(self.result_proxy)
- assert loads(result) == {'count': 2, 'rows': [
- {'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'},
- {'id': 2, 'first_name': 'Yoann', 'last_name': 'Roman'}
- ]}
-
- def test_row_proxy(self):
- result = encode(self.row_proxy)
- assert loads(result) == {
- 'id': 1, 'first_name': 'Jonathan', 'last_name': 'LaCour'
- }
diff --git a/pecan/tests/test_no_thread_locals.py b/pecan/tests/test_no_thread_locals.py
deleted file mode 100644
index 1ca418e..0000000
--- a/pecan/tests/test_no_thread_locals.py
+++ /dev/null
@@ -1,1440 +0,0 @@
-import time
-from json import dumps, loads
-import warnings
-
-from webtest import TestApp
-from six import b as b_
-from six import u as u_
-import webob
-import mock
-
-from pecan import Pecan, expose, abort, Request, Response
-from pecan.rest import RestController
-from pecan.hooks import PecanHook, HookController
-from pecan.tests import PecanTestCase
-
-
-class TestThreadingLocalUsage(PecanTestCase):
-
- @property
- def root(self):
- class RootController(object):
- @expose()
- def index(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return 'Hello, World!'
-
- @expose()
- def warning(self):
- return ("This should be unroutable because (req, resp) are not"
- " arguments. It should raise a TypeError.")
-
- @expose(generic=True)
- def generic(self):
- return ("This should be unroutable because (req, resp) are not"
- " arguments. It should raise a TypeError.")
-
- @generic.when(method='PUT')
- def generic_put(self, _id):
- return ("This should be unroutable because (req, resp) are not"
- " arguments. It should raise a TypeError.")
-
- return RootController
-
- def test_locals_are_not_used(self):
- with mock.patch('threading.local', side_effect=AssertionError()):
-
- app = TestApp(Pecan(self.root(), use_context_locals=False))
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- self.assertRaises(AssertionError, Pecan, self.root)
-
- def test_threadlocal_argument_warning(self):
- with mock.patch('threading.local', side_effect=AssertionError()):
-
- app = TestApp(Pecan(self.root(), use_context_locals=False))
- self.assertRaises(
- TypeError,
- app.get,
- '/warning/'
- )
-
- def test_threadlocal_argument_warning_on_generic(self):
- with mock.patch('threading.local', side_effect=AssertionError()):
-
- app = TestApp(Pecan(self.root(), use_context_locals=False))
- self.assertRaises(
- TypeError,
- app.get,
- '/generic/'
- )
-
- def test_threadlocal_argument_warning_on_generic_delegate(self):
- with mock.patch('threading.local', side_effect=AssertionError()):
-
- app = TestApp(Pecan(self.root(), use_context_locals=False))
- self.assertRaises(
- TypeError,
- app.put,
- '/generic/'
- )
-
-
-class TestIndexRouting(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return 'Hello, World!'
-
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_empty_root(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- def test_index(self):
- r = self.app_.get('/index')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
- def test_index_html(self):
- r = self.app_.get('/index.html')
- assert r.status_int == 200
- assert r.body == b_('Hello, World!')
-
-
-class TestManualResponse(PecanTestCase):
-
- def test_manual_response(self):
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- resp = webob.Response(resp.environ)
- resp.body = b_('Hello, World!')
- return resp
-
- app = TestApp(Pecan(RootController(), use_context_locals=False))
- r = app.get('/')
- assert r.body == b_('Hello, World!'), r.body
-
-
-class TestDispatch(PecanTestCase):
-
- @property
- def app_(self):
- class SubSubController(object):
- @expose()
- def index(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/sub/sub/'
-
- @expose()
- def deeper(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/sub/sub/deeper'
-
- class SubController(object):
- @expose()
- def index(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/sub/'
-
- @expose()
- def deeper(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/sub/deeper'
-
- sub = SubSubController()
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/'
-
- @expose()
- def deeper(self, req, resp):
- assert isinstance(req, webob.BaseRequest)
- assert isinstance(resp, webob.Response)
- return '/deeper'
-
- sub = SubController()
-
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- def test_one_level(self):
- r = self.app_.get('/deeper')
- assert r.status_int == 200
- assert r.body == b_('/deeper')
-
- def test_one_level_with_trailing(self):
- r = self.app_.get('/sub/')
- assert r.status_int == 200
- assert r.body == b_('/sub/')
-
- def test_two_levels(self):
- r = self.app_.get('/sub/deeper')
- assert r.status_int == 200
- assert r.body == b_('/sub/deeper')
-
- def test_two_levels_with_trailing(self):
- r = self.app_.get('/sub/sub/')
- assert r.status_int == 200
-
- def test_three_levels(self):
- r = self.app_.get('/sub/sub/deeper')
- assert r.status_int == 200
- assert r.body == b_('/sub/sub/deeper')
-
-
-class TestLookups(PecanTestCase):
-
- @property
- def app_(self):
- class LookupController(object):
- def __init__(self, someID):
- self.someID = someID
-
- @expose()
- def index(self, req, resp):
- return '/%s' % self.someID
-
- @expose()
- def name(self, req, resp):
- return '/%s/name' % self.someID
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- return '/'
-
- @expose()
- def _lookup(self, someID, *remainder):
- return LookupController(someID), remainder
-
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_index(self):
- r = self.app_.get('/')
- assert r.status_int == 200
- assert r.body == b_('/')
-
- def test_lookup(self):
- r = self.app_.get('/100/')
- assert r.status_int == 200
- assert r.body == b_('/100')
-
- def test_lookup_with_method(self):
- r = self.app_.get('/100/name')
- assert r.status_int == 200
- assert r.body == b_('/100/name')
-
- def test_lookup_with_wrong_argspec(self):
- class RootController(object):
- @expose()
- def _lookup(self, someID):
- return 'Bad arg spec' # pragma: nocover
-
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- app = TestApp(Pecan(RootController(), use_context_locals=False))
- r = app.get('/foo/bar', expect_errors=True)
- assert r.status_int == 404
-
-
-class TestCanonicalLookups(PecanTestCase):
-
- @property
- def app_(self):
- class LookupController(object):
- def __init__(self, someID):
- self.someID = someID
-
- @expose()
- def index(self, req, resp):
- return self.someID
-
- class UserController(object):
- @expose()
- def _lookup(self, someID, *remainder):
- return LookupController(someID), remainder
-
- class RootController(object):
- users = UserController()
-
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_canonical_lookup(self):
- assert self.app_.get('/users', expect_errors=404).status_int == 404
- assert self.app_.get('/users/', expect_errors=404).status_int == 404
- assert self.app_.get('/users/100').status_int == 302
- assert self.app_.get('/users/100/').body == b_('100')
-
-
-class TestControllerArguments(PecanTestCase):
-
- @property
- def app_(self):
- class RootController(object):
- @expose()
- def index(self, req, resp, id):
- return 'index: %s' % id
-
- @expose()
- def multiple(self, req, resp, one, two):
- return 'multiple: %s, %s' % (one, two)
-
- @expose()
- def optional(self, req, resp, id=None):
- return 'optional: %s' % str(id)
-
- @expose()
- def multiple_optional(self, req, resp, one=None, two=None,
- three=None):
- return 'multiple_optional: %s, %s, %s' % (one, two, three)
-
- @expose()
- def variable_args(self, req, resp, *args):
- return 'variable_args: %s' % ', '.join(args)
-
- @expose()
- def variable_kwargs(self, req, resp, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'variable_kwargs: %s' % ', '.join(data)
-
- @expose()
- def variable_all(self, req, resp, *args, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'variable_all: %s' % ', '.join(list(args) + data)
-
- @expose()
- def eater(self, req, resp, id, dummy=None, *args, **kwargs):
- data = [
- '%s=%s' % (key, kwargs[key])
- for key in sorted(kwargs.keys())
- ]
- return 'eater: %s, %s, %s' % (
- id,
- dummy,
- ', '.join(list(args) + data)
- )
-
- @expose()
- def _route(self, args, request):
- if hasattr(self, args[0]):
- return getattr(self, args[0]), args[1:]
- else:
- return self.index, args
-
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_required_argument(self):
- try:
- r = self.app_.get('/')
- assert r.status_int != 200 # pragma: nocover
- except Exception as ex:
- assert type(ex) == TypeError
- assert ex.args[0] in (
- "index() takes exactly 4 arguments (3 given)",
- "index() missing 1 required positional argument: 'id'"
- ) # this messaging changed in Python 3.3
-
- def test_single_argument(self):
- r = self.app_.get('/1')
- assert r.status_int == 200
- assert r.body == b_('index: 1')
-
- def test_single_argument_with_encoded_url(self):
- r = self.app_.get('/This%20is%20a%20test%21')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_two_arguments(self):
- r = self.app_.get('/1/dummy', status=404)
- assert r.status_int == 404
-
- def test_keyword_argument(self):
- r = self.app_.get('/?id=2')
- assert r.status_int == 200
- assert r.body == b_('index: 2')
-
- def test_keyword_argument_with_encoded_url(self):
- r = self.app_.get('/?id=This%20is%20a%20test%21')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_argument_and_keyword_argument(self):
- r = self.app_.get('/3?id=three')
- assert r.status_int == 200
- assert r.body == b_('index: 3')
-
- def test_encoded_argument_and_keyword_argument(self):
- r = self.app_.get('/This%20is%20a%20test%21?id=three')
- assert r.status_int == 200
- assert r.body == b_('index: This is a test!')
-
- def test_explicit_kwargs(self):
- r = self.app_.post('/', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_path_with_explicit_kwargs(self):
- r = self.app_.post('/4', {'id': 'four'})
- assert r.status_int == 200
- assert r.body == b_('index: 4')
-
- def test_multiple_kwargs(self):
- r = self.app_.get('/?id=5&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('index: 5')
-
- def test_kwargs_from_root(self):
- r = self.app_.post('/', {'id': '6', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('index: 6')
-
- # multiple args
-
- def test_multiple_positional_arguments(self):
- r = self.app_.get('/multiple/one/two')
- assert r.status_int == 200
- assert r.body == b_('multiple: one, two')
-
- def test_multiple_positional_arguments_with_url_encode(self):
- r = self.app_.get('/multiple/One%20/Two%21')
- assert r.status_int == 200
- assert r.body == b_('multiple: One , Two!')
-
- def test_multiple_positional_arguments_with_kwargs(self):
- r = self.app_.get('/multiple?one=three&two=four')
- assert r.status_int == 200
- assert r.body == b_('multiple: three, four')
-
- def test_multiple_positional_arguments_with_url_encoded_kwargs(self):
- r = self.app_.get('/multiple?one=Three%20&two=Four%20%21')
- assert r.status_int == 200
- assert r.body == b_('multiple: Three , Four !')
-
- def test_positional_args_with_dictionary_kwargs(self):
- r = self.app_.post('/multiple', {'one': 'five', 'two': 'six'})
- assert r.status_int == 200
- assert r.body == b_('multiple: five, six')
-
- def test_positional_args_with_url_encoded_dictionary_kwargs(self):
- r = self.app_.post('/multiple', {'one': 'Five%20', 'two': 'Six%20%21'})
- assert r.status_int == 200
- assert r.body == b_('multiple: Five%20, Six%20%21')
-
- # optional arg
- def test_optional_arg(self):
- r = self.app_.get('/optional')
- assert r.status_int == 200
- assert r.body == b_('optional: None')
-
- def test_multiple_optional(self):
- r = self.app_.get('/optional/1')
- assert r.status_int == 200
- assert r.body == b_('optional: 1')
-
- def test_multiple_optional_url_encoded(self):
- r = self.app_.get('/optional/Some%20Number')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_multiple_optional_missing(self):
- r = self.app_.get('/optional/2/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_with_kwargs(self):
- r = self.app_.get('/optional?id=2')
- assert r.status_int == 200
- assert r.body == b_('optional: 2')
-
- def test_multiple_with_url_encoded_kwargs(self):
- r = self.app_.get('/optional?id=Some%20Number')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_multiple_args_with_url_encoded_kwargs(self):
- r = self.app_.get('/optional/3?id=three')
- assert r.status_int == 200
- assert r.body == b_('optional: 3')
-
- def test_url_encoded_positional_args(self):
- r = self.app_.get('/optional/Some%20Number?id=three')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_kwargs(self):
- r = self.app_.post('/optional', {'id': '4'})
- assert r.status_int == 200
- assert r.body == b_('optional: 4')
-
- def test_optional_arg_with_url_encoded_kwargs(self):
- r = self.app_.post('/optional', {'id': 'Some%20Number'})
- assert r.status_int == 200
- assert r.body == b_('optional: Some%20Number')
-
- def test_multiple_positional_arguments_with_dictionary_kwargs(self):
- r = self.app_.post('/optional/5', {'id': 'five'})
- assert r.status_int == 200
- assert r.body == b_('optional: 5')
-
- def test_multiple_positional_url_encoded_arguments_with_kwargs(self):
- r = self.app_.post('/optional/Some%20Number', {'id': 'five'})
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_multiple_kwargs(self):
- r = self.app_.get('/optional?id=6&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('optional: 6')
-
- def test_optional_arg_with_multiple_url_encoded_kwargs(self):
- r = self.app_.get('/optional?id=Some%20Number&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('optional: Some Number')
-
- def test_optional_arg_with_multiple_dictionary_kwargs(self):
- r = self.app_.post('/optional', {'id': '7', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('optional: 7')
-
- def test_optional_arg_with_multiple_url_encoded_dictionary_kwargs(self):
- r = self.app_.post('/optional', {
- 'id': 'Some%20Number',
- 'dummy': 'dummy'
- })
- assert r.status_int == 200
- assert r.body == b_('optional: Some%20Number')
-
- # multiple optional args
-
- def test_multiple_optional_positional_args(self):
- r = self.app_.get('/multiple_optional')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, None')
-
- def test_multiple_optional_positional_args_one_arg(self):
- r = self.app_.get('/multiple_optional/1')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_one_url_encoded_arg(self):
- r = self.app_.get('/multiple_optional/One%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_all_args(self):
- r = self.app_.get('/multiple_optional/1/2/3')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_positional_args_all_url_encoded_args(self):
- r = self.app_.get('/multiple_optional/One%21/Two%21/Three%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, Two!, Three!')
-
- def test_multiple_optional_positional_args_too_many_args(self):
- r = self.app_.get('/multiple_optional/1/2/3/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_optional_positional_args_with_kwargs(self):
- r = self.app_.get('/multiple_optional?one=1')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_url_encoded_kwargs(self):
- r = self.app_.get('/multiple_optional?one=One%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_with_string_kwargs(self):
- r = self.app_.get('/multiple_optional/1?one=one')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_encoded_str_kwargs(self):
- r = self.app_.get('/multiple_optional/One%21?one=one')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_positional_args_with_dict_kwargs(self):
- r = self.app_.post('/multiple_optional', {'one': '1'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_positional_args_with_encoded_dict_kwargs(self):
- r = self.app_.post('/multiple_optional', {'one': 'One%21'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One%21, None, None')
-
- def test_multiple_optional_positional_args_and_dict_kwargs(self):
- r = self.app_.post('/multiple_optional/1', {'one': 'one'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, None, None')
-
- def test_multiple_optional_encoded_positional_args_and_dict_kwargs(self):
- r = self.app_.post('/multiple_optional/One%21', {'one': 'one'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, None, None')
-
- def test_multiple_optional_args_with_multiple_kwargs(self):
- r = self.app_.get('/multiple_optional?one=1&two=2&three=3&four=4')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_args_with_multiple_encoded_kwargs(self):
- r = self.app_.get(
- '/multiple_optional?one=One%21&two=Two%21&three=Three%21&four=4'
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One!, Two!, Three!')
-
- def test_multiple_optional_args_with_multiple_dict_kwargs(self):
- r = self.app_.post(
- '/multiple_optional',
- {'one': '1', 'two': '2', 'three': '3', 'four': '4'}
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: 1, 2, 3')
-
- def test_multiple_optional_args_with_multiple_encoded_dict_kwargs(self):
- r = self.app_.post(
- '/multiple_optional',
- {
- 'one': 'One%21',
- 'two': 'Two%21',
- 'three': 'Three%21',
- 'four': '4'
- }
- )
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: One%21, Two%21, Three%21')
-
- def test_multiple_optional_args_with_last_kwarg(self):
- r = self.app_.get('/multiple_optional?three=3')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, 3')
-
- def test_multiple_optional_args_with_last_encoded_kwarg(self):
- r = self.app_.get('/multiple_optional?three=Three%21')
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, None, Three!')
-
- def test_multiple_optional_args_with_middle_arg(self):
- r = self.app_.get('/multiple_optional', {'two': '2'})
- assert r.status_int == 200
- assert r.body == b_('multiple_optional: None, 2, None')
-
- def test_variable_args(self):
- r = self.app_.get('/variable_args')
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_multiple_variable_args(self):
- r = self.app_.get('/variable_args/1/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_args: 1, dummy')
-
- def test_multiple_encoded_variable_args(self):
- r = self.app_.get('/variable_args/Testing%20One%20Two/Three%21')
- assert r.status_int == 200
- assert r.body == b_('variable_args: Testing One Two, Three!')
-
- def test_variable_args_with_kwargs(self):
- r = self.app_.get('/variable_args?id=2&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_variable_args_with_dict_kwargs(self):
- r = self.app_.post('/variable_args', {'id': '3', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('variable_args: ')
-
- def test_variable_kwargs(self):
- r = self.app_.get('/variable_kwargs')
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: ')
-
- def test_multiple_variable_kwargs(self):
- r = self.app_.get('/variable_kwargs/1/dummy', status=404)
- assert r.status_int == 404
-
- def test_multiple_variable_kwargs_with_explicit_kwargs(self):
- r = self.app_.get('/variable_kwargs?id=2&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=dummy, id=2')
-
- def test_multiple_variable_kwargs_with_explicit_encoded_kwargs(self):
- r = self.app_.get(
- '/variable_kwargs?id=Two%21&dummy=This%20is%20a%20test'
- )
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=This is a test, id=Two!')
-
- def test_multiple_variable_kwargs_with_dict_kwargs(self):
- r = self.app_.post('/variable_kwargs', {'id': '3', 'dummy': 'dummy'})
- assert r.status_int == 200
- assert r.body == b_('variable_kwargs: dummy=dummy, id=3')
-
- def test_multiple_variable_kwargs_with_encoded_dict_kwargs(self):
- r = self.app_.post(
- '/variable_kwargs',
- {'id': 'Three%21', 'dummy': 'This%20is%20a%20test'}
- )
- assert r.status_int == 200
- result = 'variable_kwargs: dummy=This%20is%20a%20test, id=Three%21'
- assert r.body == b_(result)
-
- def test_variable_all(self):
- r = self.app_.get('/variable_all')
- assert r.status_int == 200
- assert r.body == b_('variable_all: ')
-
- def test_variable_all_with_one_extra(self):
- r = self.app_.get('/variable_all/1')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 1')
-
- def test_variable_all_with_two_extras(self):
- r = self.app_.get('/variable_all/2/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 2, dummy')
-
- def test_variable_mixed(self):
- r = self.app_.get('/variable_all/3?month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 3, day=12, month=1')
-
- def test_variable_mixed_explicit(self):
- r = self.app_.get('/variable_all/4?id=four&month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 4, day=12, id=four, month=1')
-
- def test_variable_post(self):
- r = self.app_.post('/variable_all/5/dummy')
- assert r.status_int == 200
- assert r.body == b_('variable_all: 5, dummy')
-
- def test_variable_post_with_kwargs(self):
- r = self.app_.post('/variable_all/6', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('variable_all: 6, day=12, month=1')
-
- def test_variable_post_mixed(self):
- r = self.app_.post(
- '/variable_all/7',
- {'id': 'seven', 'month': '1', 'day': '12'}
- )
- assert r.status_int == 200
- assert r.body == b_('variable_all: 7, day=12, id=seven, month=1')
-
- def test_no_remainder(self):
- try:
- r = self.app_.get('/eater')
- assert r.status_int != 200 # pragma: nocover
- except Exception as ex:
- assert type(ex) == TypeError
- assert ex.args[0] in (
- "eater() takes at least 4 arguments (3 given)",
- "eater() missing 1 required positional argument: 'id'"
- ) # this messaging changed in Python 3.3
-
- def test_one_remainder(self):
- r = self.app_.get('/eater/1')
- assert r.status_int == 200
- assert r.body == b_('eater: 1, None, ')
-
- def test_two_remainders(self):
- r = self.app_.get('/eater/2/dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 2, dummy, ')
-
- def test_many_remainders(self):
- r = self.app_.get('/eater/3/dummy/foo/bar')
- assert r.status_int == 200
- assert r.body == b_('eater: 3, dummy, foo, bar')
-
- def test_remainder_with_kwargs(self):
- r = self.app_.get('/eater/4?month=1&day=12')
- assert r.status_int == 200
- assert r.body == b_('eater: 4, None, day=12, month=1')
-
- def test_remainder_with_many_kwargs(self):
- r = self.app_.get('/eater/5?id=five&month=1&day=12&dummy=dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 5, dummy, day=12, month=1')
-
- def test_post_remainder(self):
- r = self.app_.post('/eater/6')
- assert r.status_int == 200
- assert r.body == b_('eater: 6, None, ')
-
- def test_post_three_remainders(self):
- r = self.app_.post('/eater/7/dummy')
- assert r.status_int == 200
- assert r.body == b_('eater: 7, dummy, ')
-
- def test_post_many_remainders(self):
- r = self.app_.post('/eater/8/dummy/foo/bar')
- assert r.status_int == 200
- assert r.body == b_('eater: 8, dummy, foo, bar')
-
- def test_post_remainder_with_kwargs(self):
- r = self.app_.post('/eater/9', {'month': '1', 'day': '12'})
- assert r.status_int == 200
- assert r.body == b_('eater: 9, None, day=12, month=1')
-
- def test_post_many_remainders_with_many_kwargs(self):
- r = self.app_.post(
- '/eater/10',
- {'id': 'ten', 'month': '1', 'day': '12', 'dummy': 'dummy'}
- )
- assert r.status_int == 200
- assert r.body == b_('eater: 10, dummy, day=12, month=1')
-
-
-class TestRestController(PecanTestCase):
-
- @property
- def app_(self):
-
- class OthersController(object):
-
- @expose()
- def index(self, req, resp):
- return 'OTHERS'
-
- @expose()
- def echo(self, req, resp, value):
- return str(value)
-
- class ThingsController(RestController):
- data = ['zero', 'one', 'two', 'three']
-
- _custom_actions = {'count': ['GET'], 'length': ['GET', 'POST']}
-
- others = OthersController()
-
- @expose()
- def get_one(self, req, resp, id):
- return self.data[int(id)]
-
- @expose('json')
- def get_all(self, req, resp):
- return dict(items=self.data)
-
- @expose()
- def length(self, req, resp, id, value=None):
- length = len(self.data[int(id)])
- if value:
- length += len(value)
- return str(length)
-
- @expose()
- def post(self, req, resp, value):
- self.data.append(value)
- resp.status = 302
- return 'CREATED'
-
- @expose()
- def edit(self, req, resp, id):
- return 'EDIT %s' % self.data[int(id)]
-
- @expose()
- def put(self, req, resp, id, value):
- self.data[int(id)] = value
- return 'UPDATED'
-
- @expose()
- def get_delete(self, req, resp, id):
- return 'DELETE %s' % self.data[int(id)]
-
- @expose()
- def delete(self, req, resp, id):
- del self.data[int(id)]
- return 'DELETED'
-
- @expose()
- def reset(self, req, resp):
- return 'RESET'
-
- @expose()
- def post_options(self, req, resp):
- return 'OPTIONS'
-
- @expose()
- def options(self, req, resp):
- abort(500)
-
- @expose()
- def other(self, req, resp):
- abort(500)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- return TestApp(Pecan(RootController(), use_context_locals=False))
-
- def test_get_all(self):
- r = self.app_.get('/things')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=['zero', 'one', 'two', 'three'])))
-
- def test_get_one(self):
- for i, value in enumerate(['zero', 'one', 'two', 'three']):
- r = self.app_.get('/things/%d' % i)
- assert r.status_int == 200
- assert r.body == b_(value)
-
- def test_post(self):
- r = self.app_.post('/things', {'value': 'four'})
- assert r.status_int == 302
- assert r.body == b_('CREATED')
-
- def test_custom_action(self):
- r = self.app_.get('/things/3/edit')
- assert r.status_int == 200
- assert r.body == b_('EDIT three')
-
- def test_put(self):
- r = self.app_.put('/things/3', {'value': 'THREE!'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- def test_put_with_method_parameter_and_get(self):
- r = self.app_.get('/things/3?_method=put', {'value': 'X'}, status=405)
- assert r.status_int == 405
-
- def test_put_with_method_parameter_and_post(self):
- r = self.app_.post('/things/3?_method=put', {'value': 'THREE!'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- def test_get_delete(self):
- r = self.app_.get('/things/3/delete')
- assert r.status_int == 200
- assert r.body == b_('DELETE three')
-
- def test_delete_method(self):
- r = self.app_.delete('/things/3')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- def test_delete_with_method_parameter(self):
- r = self.app_.get('/things/3?_method=DELETE', status=405)
- assert r.status_int == 405
-
- def test_delete_with_method_parameter_and_post(self):
- r = self.app_.post('/things/3?_method=DELETE')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- def test_custom_method_type(self):
- r = self.app_.request('/things', method='RESET')
- assert r.status_int == 200
- assert r.body == b_('RESET')
-
- def test_custom_method_type_with_method_parameter(self):
- r = self.app_.get('/things?_method=RESET')
- assert r.status_int == 200
- assert r.body == b_('RESET')
-
- def test_options(self):
- r = self.app_.request('/things', method='OPTIONS')
- assert r.status_int == 200
- assert r.body == b_('OPTIONS')
-
- def test_options_with_method_parameter(self):
- r = self.app_.post('/things', {'_method': 'OPTIONS'})
- assert r.status_int == 200
- assert r.body == b_('OPTIONS')
-
- def test_other_custom_action(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = self.app_.request('/things/other', method='MISC', status=405)
- assert r.status_int == 405
-
- def test_other_custom_action_with_method_parameter(self):
- r = self.app_.post('/things/other', {'_method': 'MISC'}, status=405)
- assert r.status_int == 405
-
- def test_nested_controller_with_trailing_slash(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = self.app_.request('/things/others/', method='MISC')
- assert r.status_int == 200
- assert r.body == b_('OTHERS')
-
- def test_nested_controller_without_trailing_slash(self):
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = self.app_.request('/things/others', method='MISC', status=302)
- assert r.status_int == 302
-
- def test_invalid_custom_action(self):
- r = self.app_.get('/things?_method=BAD', status=405)
- assert r.status_int == 405
-
- def test_named_action(self):
- # test custom "GET" request "length"
- r = self.app_.get('/things/1/length')
- assert r.status_int == 200
- assert r.body == b_(str(len('one')))
-
- def test_named_nested_action(self):
- # test custom "GET" request through subcontroller
- r = self.app_.get('/things/others/echo?value=test')
- assert r.status_int == 200
- assert r.body == b_('test')
-
- def test_nested_post(self):
- # test custom "POST" request through subcontroller
- r = self.app_.post('/things/others/echo', {'value': 'test'})
- assert r.status_int == 200
- assert r.body == b_('test')
-
-
-class TestHooks(PecanTestCase):
-
- def test_basic_single_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- def before(self, state):
- run_hook.append('before')
-
- def after(self, state):
- run_hook.append('after')
-
- def on_error(self, state, e):
- run_hook.append('error')
-
- app = TestApp(Pecan(
- RootController(),
- hooks=[SimpleHook()],
- use_context_locals=False
- ))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'before'
- assert run_hook[2] == 'inside'
- assert run_hook[3] == 'after'
-
- def test_basic_multi_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def __init__(self, id):
- self.id = str(id)
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- app = TestApp(Pecan(RootController(), hooks=[
- SimpleHook(1), SimpleHook(2), SimpleHook(3)
- ], use_context_locals=False))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 10
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'on_route2'
- assert run_hook[2] == 'on_route3'
- assert run_hook[3] == 'before1'
- assert run_hook[4] == 'before2'
- assert run_hook[5] == 'before3'
- assert run_hook[6] == 'inside'
- assert run_hook[7] == 'after3'
- assert run_hook[8] == 'after2'
- assert run_hook[9] == 'after1'
-
- def test_partial_hooks(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello World!'
-
- @expose()
- def causeerror(self, req, resp):
- return [][1]
-
- class ErrorHook(PecanHook):
- def on_error(self, state, e):
- run_hook.append('error')
-
- class OnRouteHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- app = TestApp(Pecan(RootController(), hooks=[
- ErrorHook(), OnRouteHook()
- ], use_context_locals=False))
-
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello World!')
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'inside'
-
- run_hook = []
- try:
- response = app.get('/causeerror')
- except Exception as e:
- assert isinstance(e, IndexError)
-
- assert len(run_hook) == 2
- assert run_hook[0] == 'on_route'
- assert run_hook[1] == 'error'
-
- def test_on_error_response_hook(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def causeerror(self, req, resp):
- return [][1]
-
- class ErrorHook(PecanHook):
- def on_error(self, state, e):
- run_hook.append('error')
-
- r = webob.Response()
- r.text = u_('on_error')
-
- return r
-
- app = TestApp(Pecan(RootController(), hooks=[
- ErrorHook()
- ], use_context_locals=False))
-
- response = app.get('/causeerror')
-
- assert len(run_hook) == 1
- assert run_hook[0] == 'error'
- assert response.text == 'on_error'
-
- def test_prioritized_hooks(self):
- run_hook = []
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello, World!'
-
- class SimpleHook(PecanHook):
- def __init__(self, id, priority=None):
- self.id = str(id)
- if priority:
- self.priority = priority
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- papp = Pecan(RootController(), hooks=[
- SimpleHook(1, 3), SimpleHook(2, 2), SimpleHook(3, 1)
- ], use_context_locals=False)
- app = TestApp(papp)
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 10
- assert run_hook[0] == 'on_route3'
- assert run_hook[1] == 'on_route2'
- assert run_hook[2] == 'on_route1'
- assert run_hook[3] == 'before3'
- assert run_hook[4] == 'before2'
- assert run_hook[5] == 'before1'
- assert run_hook[6] == 'inside'
- assert run_hook[7] == 'after1'
- assert run_hook[8] == 'after2'
- assert run_hook[9] == 'after3'
-
- def test_basic_isolated_hook(self):
- run_hook = []
-
- class SimpleHook(PecanHook):
- def on_route(self, state):
- run_hook.append('on_route')
-
- def before(self, state):
- run_hook.append('before')
-
- def after(self, state):
- run_hook.append('after')
-
- def on_error(self, state, e):
- run_hook.append('error')
-
- class SubSubController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside_sub_sub')
- return 'Deep inside here!'
-
- class SubController(HookController):
- __hooks__ = [SimpleHook()]
-
- @expose()
- def index(self, req, resp):
- run_hook.append('inside_sub')
- return 'Inside here!'
-
- sub = SubSubController()
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello, World!'
-
- sub = SubController()
-
- app = TestApp(Pecan(RootController(), use_context_locals=False))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 1
- assert run_hook[0] == 'inside'
-
- run_hook = []
-
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('Inside here!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'before'
- assert run_hook[1] == 'inside_sub'
- assert run_hook[2] == 'after'
-
- run_hook = []
- response = app.get('/sub/sub/')
- assert response.status_int == 200
- assert response.body == b_('Deep inside here!')
-
- assert len(run_hook) == 3
- assert run_hook[0] == 'before'
- assert run_hook[1] == 'inside_sub_sub'
- assert run_hook[2] == 'after'
-
- def test_isolated_hook_with_global_hook(self):
- run_hook = []
-
- class SimpleHook(PecanHook):
- def __init__(self, id):
- self.id = str(id)
-
- def on_route(self, state):
- run_hook.append('on_route' + self.id)
-
- def before(self, state):
- run_hook.append('before' + self.id)
-
- def after(self, state):
- run_hook.append('after' + self.id)
-
- def on_error(self, state, e):
- run_hook.append('error' + self.id)
-
- class SubController(HookController):
- __hooks__ = [SimpleHook(2)]
-
- @expose()
- def index(self, req, resp):
- run_hook.append('inside_sub')
- return 'Inside here!'
-
- class RootController(object):
- @expose()
- def index(self, req, resp):
- run_hook.append('inside')
- return 'Hello, World!'
-
- sub = SubController()
-
- app = TestApp(Pecan(
- RootController(),
- hooks=[SimpleHook(1)],
- use_context_locals=False
- ))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- assert len(run_hook) == 4
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'before1'
- assert run_hook[2] == 'inside'
- assert run_hook[3] == 'after1'
-
- run_hook = []
-
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('Inside here!')
-
- assert len(run_hook) == 6
- assert run_hook[0] == 'on_route1'
- assert run_hook[1] == 'before2'
- assert run_hook[2] == 'before1'
- assert run_hook[3] == 'inside_sub'
- assert run_hook[4] == 'after1'
- assert run_hook[5] == 'after2'
-
-
-class TestGeneric(PecanTestCase):
-
- @property
- def root(self):
- class RootController(object):
-
- def __init__(self, unique):
- self.unique = unique
-
- @expose(generic=True, template='json')
- def index(self, req, resp):
- assert self.__class__.__name__ == 'RootController'
- assert isinstance(req, Request)
- assert isinstance(resp, Response)
- assert self.unique == req.headers.get('X-Unique')
- return {'hello': 'world'}
-
- @index.when(method='POST', template='json')
- def index_post(self, req, resp):
- assert self.__class__.__name__ == 'RootController'
- assert isinstance(req, Request)
- assert isinstance(resp, Response)
- assert self.unique == req.headers.get('X-Unique')
- return req.json
-
- @expose(template='json')
- def echo(self, req, resp):
- assert self.__class__.__name__ == 'RootController'
- assert isinstance(req, Request)
- assert isinstance(resp, Response)
- assert self.unique == req.headers.get('X-Unique')
- return req.json
-
- @expose(template='json')
- def extra(self, req, resp, first, second):
- assert self.__class__.__name__ == 'RootController'
- assert isinstance(req, Request)
- assert isinstance(resp, Response)
- assert self.unique == req.headers.get('X-Unique')
- return {'first': first, 'second': second}
-
- return RootController
-
- def test_generics_with_im_self_default(self):
- uniq = str(time.time())
- with mock.patch('threading.local', side_effect=AssertionError()):
- app = TestApp(Pecan(self.root(uniq), use_context_locals=False))
- r = app.get('/', headers={'X-Unique': uniq})
- assert r.status_int == 200
- json_resp = loads(r.body.decode())
- assert json_resp['hello'] == 'world'
-
- def test_generics_with_im_self_with_method(self):
- uniq = str(time.time())
- with mock.patch('threading.local', side_effect=AssertionError()):
- app = TestApp(Pecan(self.root(uniq), use_context_locals=False))
- r = app.post_json('/', {'foo': 'bar'}, headers={'X-Unique': uniq})
- assert r.status_int == 200
- json_resp = loads(r.body.decode())
- assert json_resp['foo'] == 'bar'
-
- def test_generics_with_im_self_with_path(self):
- uniq = str(time.time())
- with mock.patch('threading.local', side_effect=AssertionError()):
- app = TestApp(Pecan(self.root(uniq), use_context_locals=False))
- r = app.post_json('/echo/', {'foo': 'bar'},
- headers={'X-Unique': uniq})
- assert r.status_int == 200
- json_resp = loads(r.body.decode())
- assert json_resp['foo'] == 'bar'
-
- def test_generics_with_im_self_with_extra_args(self):
- uniq = str(time.time())
- with mock.patch('threading.local', side_effect=AssertionError()):
- app = TestApp(Pecan(self.root(uniq), use_context_locals=False))
- r = app.get('/extra/123/456', headers={'X-Unique': uniq})
- assert r.status_int == 200
- json_resp = loads(r.body.decode())
- assert json_resp['first'] == '123'
- assert json_resp['second'] == '456'
diff --git a/pecan/tests/test_rest.py b/pecan/tests/test_rest.py
deleted file mode 100644
index ba4d141..0000000
--- a/pecan/tests/test_rest.py
+++ /dev/null
@@ -1,1640 +0,0 @@
-# -*- coding: utf-8 -*-
-
-import struct
-import sys
-import warnings
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest # pragma: nocover
-else:
- import unittest # pragma: nocover
-
-try:
- from simplejson import dumps, loads
-except:
- from json import dumps, loads # noqa
-
-from six import b as b_, PY3
-from webtest import TestApp
-
-from pecan import abort, expose, make_app, response, redirect
-from pecan.rest import RestController
-from pecan.tests import PecanTestCase
-
-
-class TestRestController(PecanTestCase):
-
- def test_basic_rest(self):
-
- class OthersController(object):
-
- @expose()
- def index(self):
- return 'OTHERS'
-
- @expose()
- def echo(self, value):
- return str(value)
-
- class ThingsController(RestController):
- data = ['zero', 'one', 'two', 'three']
-
- _custom_actions = {'count': ['GET'], 'length': ['GET', 'POST']}
-
- others = OthersController()
-
- @expose()
- def get_one(self, id):
- return self.data[int(id)]
-
- @expose('json')
- def get_all(self):
- return dict(items=self.data)
-
- @expose()
- def length(self, id, value=None):
- length = len(self.data[int(id)])
- if value:
- length += len(value)
- return str(length)
-
- @expose()
- def get_count(self):
- return str(len(self.data))
-
- @expose()
- def new(self):
- return 'NEW'
-
- @expose()
- def post(self, value):
- self.data.append(value)
- response.status = 302
- return 'CREATED'
-
- @expose()
- def edit(self, id):
- return 'EDIT %s' % self.data[int(id)]
-
- @expose()
- def put(self, id, value):
- self.data[int(id)] = value
- return 'UPDATED'
-
- @expose()
- def get_delete(self, id):
- return 'DELETE %s' % self.data[int(id)]
-
- @expose()
- def delete(self, id):
- del self.data[int(id)]
- return 'DELETED'
-
- @expose()
- def reset(self):
- return 'RESET'
-
- @expose()
- def post_options(self):
- return 'OPTIONS'
-
- @expose()
- def options(self):
- abort(500)
-
- @expose()
- def other(self):
- abort(500)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- r = app.get('/things')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=ThingsController.data)))
-
- # test get_one
- for i, value in enumerate(ThingsController.data):
- r = app.get('/things/%d' % i)
- assert r.status_int == 200
- assert r.body == b_(value)
-
- # test post
- r = app.post('/things', {'value': 'four'})
- assert r.status_int == 302
- assert r.body == b_('CREATED')
-
- # make sure it works
- r = app.get('/things/4')
- assert r.status_int == 200
- assert r.body == b_('four')
-
- # test edit
- r = app.get('/things/3/edit')
- assert r.status_int == 200
- assert r.body == b_('EDIT three')
-
- # test put
- r = app.put('/things/4', {'value': 'FOUR'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/things/4')
- assert r.status_int == 200
- assert r.body == b_('FOUR')
-
- # test put with _method parameter and GET
- r = app.get('/things/4?_method=put', {'value': 'FOUR!'}, status=405)
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/things/4')
- assert r.status_int == 200
- assert r.body == b_('FOUR')
-
- # test put with _method parameter and POST
- r = app.post('/things/4?_method=put', {'value': 'FOUR!'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/things/4')
- assert r.status_int == 200
- assert r.body == b_('FOUR!')
-
- # test get delete
- r = app.get('/things/4/delete')
- assert r.status_int == 200
- assert r.body == b_('DELETE FOUR!')
-
- # test delete
- r = app.delete('/things/4')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/things')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 4
-
- # test delete with _method parameter and GET
- r = app.get('/things/3?_method=DELETE', status=405)
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/things')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 4
-
- # test delete with _method parameter and POST
- r = app.post('/things/3?_method=DELETE')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/things')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 3
-
- # test "RESET" custom action
- r = app.request('/things', method='RESET')
- assert r.status_int == 200
- assert r.body == b_('RESET')
-
- # test "RESET" custom action with _method parameter
- r = app.get('/things?_method=RESET')
- assert r.status_int == 200
- assert r.body == b_('RESET')
-
- # test the "OPTIONS" custom action
- r = app.request('/things', method='OPTIONS')
- assert r.status_int == 200
- assert r.body == b_('OPTIONS')
-
- # test the "OPTIONS" custom action with the _method parameter
- r = app.post('/things', {'_method': 'OPTIONS'})
- assert r.status_int == 200
- assert r.body == b_('OPTIONS')
-
- # test the "other" custom action
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = app.request('/things/other', method='MISC', status=405)
- assert r.status_int == 405
-
- # test the "other" custom action with the _method parameter
- r = app.post('/things/other', {'_method': 'MISC'}, status=405)
- assert r.status_int == 405
-
- # test the "others" custom action
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = app.request('/things/others/', method='MISC')
- assert r.status_int == 200
- assert r.body == b_('OTHERS')
-
- # test the "others" custom action missing trailing slash
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = app.request('/things/others', method='MISC', status=302)
- assert r.status_int == 302
-
- # test the "others" custom action with the _method parameter
- r = app.get('/things/others/?_method=MISC')
- assert r.status_int == 200
- assert r.body == b_('OTHERS')
-
- # test an invalid custom action
- r = app.get('/things?_method=BAD', status=405)
- assert r.status_int == 405
-
- # test custom "GET" request "count"
- r = app.get('/things/count')
- assert r.status_int == 200
- assert r.body == b_('3')
-
- # test custom "GET" request "length"
- r = app.get('/things/1/length')
- assert r.status_int == 200
- assert r.body == b_(str(len('one')))
-
- # test custom "GET" request through subcontroller
- r = app.get('/things/others/echo?value=test')
- assert r.status_int == 200
- assert r.body == b_('test')
-
- # test custom "POST" request "length"
- r = app.post('/things/1/length', {'value': 'test'})
- assert r.status_int == 200
- assert r.body == b_(str(len('onetest')))
-
- # test custom "POST" request through subcontroller
- r = app.post('/things/others/echo', {'value': 'test'})
- assert r.status_int == 200
- assert r.body == b_('test')
-
- def test_getall_with_trailing_slash(self):
-
- class ThingsController(RestController):
-
- data = ['zero', 'one', 'two', 'three']
-
- @expose('json')
- def get_all(self):
- return dict(items=self.data)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- r = app.get('/things/')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=ThingsController.data)))
-
- def test_405_with_lookup(self):
-
- class LookupController(RestController):
-
- def __init__(self, _id):
- self._id = _id
-
- @expose()
- def get_all(self):
- return 'ID: %s' % self._id
-
- class ThingsController(RestController):
-
- @expose()
- def _lookup(self, _id, *remainder):
- return LookupController(_id), remainder
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # these should 405
- for path in ('/things', '/things/'):
- r = app.get(path, expect_errors=True)
- assert r.status_int == 405
-
- r = app.get('/things/foo')
- assert r.status_int == 200
- assert r.body == b_('ID: foo')
-
- def test_getall_with_lookup(self):
-
- class LookupController(RestController):
-
- def __init__(self, _id):
- self._id = _id
-
- @expose()
- def get_all(self):
- return 'ID: %s' % self._id
-
- class ThingsController(RestController):
-
- data = ['zero', 'one', 'two', 'three']
-
- @expose()
- def _lookup(self, _id, *remainder):
- return LookupController(_id), remainder
-
- @expose('json')
- def get_all(self):
- return dict(items=self.data)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- for path in ('/things', '/things/'):
- r = app.get(path)
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=ThingsController.data)))
-
- r = app.get('/things/foo')
- assert r.status_int == 200
- assert r.body == b_('ID: foo')
-
- def test_simple_nested_rest(self):
-
- class BarController(RestController):
-
- @expose()
- def post(self):
- return "BAR-POST"
-
- @expose()
- def delete(self, id_):
- return "BAR-%s" % id_
-
- class FooController(RestController):
-
- bar = BarController()
-
- @expose()
- def post(self):
- return "FOO-POST"
-
- @expose()
- def delete(self, id_):
- return "FOO-%s" % id_
-
- class RootController(object):
- foo = FooController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- r = app.post('/foo')
- assert r.status_int == 200
- assert r.body == b_("FOO-POST")
-
- r = app.delete('/foo/1')
- assert r.status_int == 200
- assert r.body == b_("FOO-1")
-
- r = app.post('/foo/bar')
- assert r.status_int == 200
- assert r.body == b_("BAR-POST")
-
- r = app.delete('/foo/bar/2')
- assert r.status_int == 200
- assert r.body == b_("BAR-2")
-
- def test_complicated_nested_rest(self):
-
- class BarsController(RestController):
-
- data = [['zero-zero', 'zero-one'], ['one-zero', 'one-one']]
-
- @expose()
- def get_one(self, foo_id, id):
- return self.data[int(foo_id)][int(id)]
-
- @expose('json')
- def get_all(self, foo_id):
- return dict(items=self.data[int(foo_id)])
-
- @expose()
- def new(self, foo_id):
- return 'NEW FOR %s' % foo_id
-
- @expose()
- def post(self, foo_id, value):
- foo_id = int(foo_id)
- if len(self.data) < foo_id + 1:
- self.data.extend([[]] * (foo_id - len(self.data) + 1))
- self.data[foo_id].append(value)
- response.status = 302
- return 'CREATED FOR %s' % foo_id
-
- @expose()
- def edit(self, foo_id, id):
- return 'EDIT %s' % self.data[int(foo_id)][int(id)]
-
- @expose()
- def put(self, foo_id, id, value):
- self.data[int(foo_id)][int(id)] = value
- return 'UPDATED'
-
- @expose()
- def get_delete(self, foo_id, id):
- return 'DELETE %s' % self.data[int(foo_id)][int(id)]
-
- @expose()
- def delete(self, foo_id, id):
- del self.data[int(foo_id)][int(id)]
- return 'DELETED'
-
- class FoosController(RestController):
-
- data = ['zero', 'one']
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return self.data[int(id)]
-
- @expose('json')
- def get_all(self):
- return dict(items=self.data)
-
- @expose()
- def new(self):
- return 'NEW'
-
- @expose()
- def edit(self, id):
- return 'EDIT %s' % self.data[int(id)]
-
- @expose()
- def post(self, value):
- self.data.append(value)
- response.status = 302
- return 'CREATED'
-
- @expose()
- def put(self, id, value):
- self.data[int(id)] = value
- return 'UPDATED'
-
- @expose()
- def get_delete(self, id):
- return 'DELETE %s' % self.data[int(id)]
-
- @expose()
- def delete(self, id):
- del self.data[int(id)]
- return 'DELETED'
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- r = app.get('/foos')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=FoosController.data)))
-
- # test nested get_all
- r = app.get('/foos/1/bars')
- assert r.status_int == 200
- assert r.body == b_(dumps(dict(items=BarsController.data[1])))
-
- # test get_one
- for i, value in enumerate(FoosController.data):
- r = app.get('/foos/%d' % i)
- assert r.status_int == 200
- assert r.body == b_(value)
-
- # test nested get_one
- for i, value in enumerate(FoosController.data):
- for j, value in enumerate(BarsController.data[i]):
- r = app.get('/foos/%s/bars/%s' % (i, j))
- assert r.status_int == 200
- assert r.body == b_(value)
-
- # test post
- r = app.post('/foos', {'value': 'two'})
- assert r.status_int == 302
- assert r.body == b_('CREATED')
-
- # make sure it works
- r = app.get('/foos/2')
- assert r.status_int == 200
- assert r.body == b_('two')
-
- # test nested post
- r = app.post('/foos/2/bars', {'value': 'two-zero'})
- assert r.status_int == 302
- assert r.body == b_('CREATED FOR 2')
-
- # make sure it works
- r = app.get('/foos/2/bars/0')
- assert r.status_int == 200
- assert r.body == b_('two-zero')
-
- # test edit
- r = app.get('/foos/1/edit')
- assert r.status_int == 200
- assert r.body == b_('EDIT one')
-
- # test nested edit
- r = app.get('/foos/1/bars/1/edit')
- assert r.status_int == 200
- assert r.body == b_('EDIT one-one')
-
- # test put
- r = app.put('/foos/2', {'value': 'TWO'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/foos/2')
- assert r.status_int == 200
- assert r.body == b_('TWO')
-
- # test nested put
- r = app.put('/foos/2/bars/0', {'value': 'TWO-ZERO'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/foos/2/bars/0')
- assert r.status_int == 200
- assert r.body == b_('TWO-ZERO')
-
- # test put with _method parameter and GET
- r = app.get('/foos/2?_method=put', {'value': 'TWO!'}, status=405)
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/foos/2')
- assert r.status_int == 200
- assert r.body == b_('TWO')
-
- # test nested put with _method parameter and GET
- r = app.get(
- '/foos/2/bars/0?_method=put',
- {'value': 'ZERO-TWO!'}, status=405
- )
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/foos/2/bars/0')
- assert r.status_int == 200
- assert r.body == b_('TWO-ZERO')
-
- # test put with _method parameter and POST
- r = app.post('/foos/2?_method=put', {'value': 'TWO!'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/foos/2')
- assert r.status_int == 200
- assert r.body == b_('TWO!')
-
- # test nested put with _method parameter and POST
- r = app.post('/foos/2/bars/0?_method=put', {'value': 'TWO-ZERO!'})
- assert r.status_int == 200
- assert r.body == b_('UPDATED')
-
- # make sure it works
- r = app.get('/foos/2/bars/0')
- assert r.status_int == 200
- assert r.body == b_('TWO-ZERO!')
-
- # test get delete
- r = app.get('/foos/2/delete')
- assert r.status_int == 200
- assert r.body == b_('DELETE TWO!')
-
- # test nested get delete
- r = app.get('/foos/2/bars/0/delete')
- assert r.status_int == 200
- assert r.body == b_('DELETE TWO-ZERO!')
-
- # test nested delete
- r = app.delete('/foos/2/bars/0')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/foos/2/bars')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 0
-
- # test delete
- r = app.delete('/foos/2')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/foos')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 2
-
- # test nested delete with _method parameter and GET
- r = app.get('/foos/1/bars/1?_method=DELETE', status=405)
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/foos/1/bars')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 2
-
- # test delete with _method parameter and GET
- r = app.get('/foos/1?_method=DELETE', status=405)
- assert r.status_int == 405
-
- # make sure it works
- r = app.get('/foos')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 2
-
- # test nested delete with _method parameter and POST
- r = app.post('/foos/1/bars/1?_method=DELETE')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/foos/1/bars')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 1
-
- # test delete with _method parameter and POST
- r = app.post('/foos/1?_method=DELETE')
- assert r.status_int == 200
- assert r.body == b_('DELETED')
-
- # make sure it works
- r = app.get('/foos')
- assert r.status_int == 200
- assert len(loads(r.body.decode())['items']) == 1
-
- def test_nested_get_all(self):
-
- class BarsController(RestController):
-
- @expose()
- def get_one(self, foo_id, id):
- return '4'
-
- @expose()
- def get_all(self, foo_id):
- return '3'
-
- class FoosController(RestController):
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return '2'
-
- @expose()
- def get_all(self):
- return '1'
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foos/')
- assert r.status_int == 200
- assert r.body == b_('1')
-
- r = app.get('/foos/1/')
- assert r.status_int == 200
- assert r.body == b_('2')
-
- r = app.get('/foos/1/bars/')
- assert r.status_int == 200
- assert r.body == b_('3')
-
- r = app.get('/foos/1/bars/2/')
- assert r.status_int == 200
- assert r.body == b_('4')
-
- r = app.get('/foos/bars/', status=404)
- assert r.status_int == 404
-
- r = app.get('/foos/bars/1', status=404)
- assert r.status_int == 404
-
- def test_nested_get_all_with_lookup(self):
-
- class BarsController(RestController):
-
- @expose()
- def get_one(self, foo_id, id):
- return '4'
-
- @expose()
- def get_all(self, foo_id):
- return '3'
-
- @expose('json')
- def _lookup(self, id, *remainder):
- redirect('/lookup-hit/')
-
- class FoosController(RestController):
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return '2'
-
- @expose()
- def get_all(self):
- return '1'
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foos/')
- assert r.status_int == 200
- assert r.body == b_('1')
-
- r = app.get('/foos/1/')
- assert r.status_int == 200
- assert r.body == b_('2')
-
- r = app.get('/foos/1/bars/')
- assert r.status_int == 200
- assert r.body == b_('3')
-
- r = app.get('/foos/1/bars/2/')
- assert r.status_int == 200
- assert r.body == b_('4')
-
- r = app.get('/foos/bars/')
- assert r.status_int == 302
- assert r.headers['Location'].endswith('/lookup-hit/')
-
- r = app.get('/foos/bars/1')
- assert r.status_int == 302
- assert r.headers['Location'].endswith('/lookup-hit/')
-
- def test_bad_rest(self):
-
- class ThingsController(RestController):
- pass
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- r = app.get('/things', status=405)
- assert r.status_int == 405
-
- # test get_one
- r = app.get('/things/1', status=405)
- assert r.status_int == 405
-
- # test post
- r = app.post('/things', {'value': 'one'}, status=405)
- assert r.status_int == 405
-
- # test edit
- r = app.get('/things/1/edit', status=405)
- assert r.status_int == 405
-
- # test put
- r = app.put('/things/1', {'value': 'ONE'}, status=405)
-
- # test put with _method parameter and GET
- r = app.get('/things/1?_method=put', {'value': 'ONE!'}, status=405)
- assert r.status_int == 405
-
- # test put with _method parameter and POST
- r = app.post('/things/1?_method=put', {'value': 'ONE!'}, status=405)
- assert r.status_int == 405
-
- # test get delete
- r = app.get('/things/1/delete', status=405)
- assert r.status_int == 405
-
- # test delete
- r = app.delete('/things/1', status=405)
- assert r.status_int == 405
-
- # test delete with _method parameter and GET
- r = app.get('/things/1?_method=DELETE', status=405)
- assert r.status_int == 405
-
- # test delete with _method parameter and POST
- r = app.post('/things/1?_method=DELETE', status=405)
- assert r.status_int == 405
-
- # test "RESET" custom action
- with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- r = app.request('/things', method='RESET', status=405)
- assert r.status_int == 405
-
- def test_nested_rest_with_missing_intermediate_id(self):
-
- class BarsController(RestController):
-
- data = [['zero-zero', 'zero-one'], ['one-zero', 'one-one']]
-
- @expose('json')
- def get_all(self, foo_id):
- return dict(items=self.data[int(foo_id)])
-
- class FoosController(RestController):
-
- data = ['zero', 'one']
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return self.data[int(id)]
-
- @expose('json')
- def get_all(self):
- return dict(items=self.data)
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get_all
- r = app.get('/foos')
- self.assertEqual(r.status_int, 200)
- self.assertEqual(r.body, b_(dumps(dict(items=FoosController.data))))
-
- # test nested get_all
- r = app.get('/foos/1/bars')
- self.assertEqual(r.status_int, 200)
- self.assertEqual(r.body, b_(dumps(dict(items=BarsController.data[1]))))
-
- r = app.get('/foos/bars', expect_errors=True)
- self.assertEqual(r.status_int, 404)
-
- def test_custom_with_trailing_slash(self):
-
- class CustomController(RestController):
-
- _custom_actions = {
- 'detail': ['GET'],
- 'create': ['POST'],
- 'update': ['PUT'],
- 'remove': ['DELETE'],
- }
-
- @expose()
- def detail(self):
- return 'DETAIL'
-
- @expose()
- def create(self):
- return 'CREATE'
-
- @expose()
- def update(self, id):
- return id
-
- @expose()
- def remove(self, id):
- return id
-
- app = TestApp(make_app(CustomController()))
-
- r = app.get('/detail')
- assert r.status_int == 200
- assert r.body == b_('DETAIL')
-
- r = app.get('/detail/')
- assert r.status_int == 200
- assert r.body == b_('DETAIL')
-
- r = app.post('/create')
- assert r.status_int == 200
- assert r.body == b_('CREATE')
-
- r = app.post('/create/')
- assert r.status_int == 200
- assert r.body == b_('CREATE')
-
- r = app.put('/update/123')
- assert r.status_int == 200
- assert r.body == b_('123')
-
- r = app.put('/update/123/')
- assert r.status_int == 200
- assert r.body == b_('123')
-
- r = app.delete('/remove/456')
- assert r.status_int == 200
- assert r.body == b_('456')
-
- r = app.delete('/remove/456/')
- assert r.status_int == 200
- assert r.body == b_('456')
-
- def test_custom_delete(self):
-
- class OthersController(object):
-
- @expose()
- def index(self):
- return 'DELETE'
-
- @expose()
- def reset(self, id):
- return str(id)
-
- class ThingsController(RestController):
-
- others = OthersController()
-
- @expose()
- def delete_fail(self):
- abort(500)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test bad delete
- r = app.delete('/things/delete_fail', status=405)
- assert r.status_int == 405
-
- # test bad delete with _method parameter and GET
- r = app.get('/things/delete_fail?_method=delete', status=405)
- assert r.status_int == 405
-
- # test bad delete with _method parameter and POST
- r = app.post('/things/delete_fail', {'_method': 'delete'}, status=405)
- assert r.status_int == 405
-
- # test custom delete without ID
- r = app.delete('/things/others/')
- assert r.status_int == 200
- assert r.body == b_('DELETE')
-
- # test custom delete without ID with _method parameter and GET
- r = app.get('/things/others/?_method=delete', status=405)
- assert r.status_int == 405
-
- # test custom delete without ID with _method parameter and POST
- r = app.post('/things/others/', {'_method': 'delete'})
- assert r.status_int == 200
- assert r.body == b_('DELETE')
-
- # test custom delete with ID
- r = app.delete('/things/others/reset/1')
- assert r.status_int == 200
- assert r.body == b_('1')
-
- # test custom delete with ID with _method parameter and GET
- r = app.get('/things/others/reset/1?_method=delete', status=405)
- assert r.status_int == 405
-
- # test custom delete with ID with _method parameter and POST
- r = app.post('/things/others/reset/1', {'_method': 'delete'})
- assert r.status_int == 200
- assert r.body == b_('1')
-
- def test_get_with_var_args(self):
-
- class OthersController(object):
-
- @expose()
- def index(self, one, two, three):
- return 'NESTED: %s, %s, %s' % (one, two, three)
-
- class ThingsController(RestController):
-
- others = OthersController()
-
- @expose()
- def get_one(self, *args):
- return ', '.join(args)
-
- class RootController(object):
- things = ThingsController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test get request
- r = app.get('/things/one/two/three')
- assert r.status_int == 200
- assert r.body == b_('one, two, three')
-
- # test nested get request
- r = app.get('/things/one/two/three/others/')
- assert r.status_int == 200
- assert r.body == b_('NESTED: one, two, three')
-
- def test_sub_nested_rest(self):
-
- class BazsController(RestController):
-
- data = [[['zero-zero-zero']]]
-
- @expose()
- def get_one(self, foo_id, bar_id, id):
- return self.data[int(foo_id)][int(bar_id)][int(id)]
-
- class BarsController(RestController):
-
- data = [['zero-zero']]
-
- bazs = BazsController()
-
- @expose()
- def get_one(self, foo_id, id):
- return self.data[int(foo_id)][int(id)]
-
- class FoosController(RestController):
-
- data = ['zero']
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return self.data[int(id)]
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- # test sub-nested get_one
- r = app.get('/foos/0/bars/0/bazs/0')
- assert r.status_int == 200
- assert r.body == b_('zero-zero-zero')
-
- def test_sub_nested_rest_with_overwrites(self):
-
- class FinalController(object):
-
- @expose()
- def index(self):
- return 'FINAL'
-
- @expose()
- def named(self):
- return 'NAMED'
-
- class BazsController(RestController):
-
- data = [[['zero-zero-zero']]]
-
- final = FinalController()
-
- @expose()
- def get_one(self, foo_id, bar_id, id):
- return self.data[int(foo_id)][int(bar_id)][int(id)]
-
- @expose()
- def post(self):
- return 'POST-GRAND-CHILD'
-
- @expose()
- def put(self, id):
- return 'PUT-GRAND-CHILD'
-
- class BarsController(RestController):
-
- data = [['zero-zero']]
-
- bazs = BazsController()
-
- @expose()
- def get_one(self, foo_id, id):
- return self.data[int(foo_id)][int(id)]
-
- @expose()
- def post(self):
- return 'POST-CHILD'
-
- @expose()
- def put(self, id):
- return 'PUT-CHILD'
-
- class FoosController(RestController):
-
- data = ['zero']
-
- bars = BarsController()
-
- @expose()
- def get_one(self, id):
- return self.data[int(id)]
-
- @expose()
- def post(self):
- return 'POST'
-
- @expose()
- def put(self, id):
- return 'PUT'
-
- class RootController(object):
- foos = FoosController()
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- r = app.post('/foos')
- assert r.status_int == 200
- assert r.body == b_('POST')
-
- r = app.put('/foos/0')
- assert r.status_int == 200
- assert r.body == b_('PUT')
-
- r = app.post('/foos/bars')
- assert r.status_int == 200
- assert r.body == b_('POST-CHILD')
-
- r = app.put('/foos/bars/0')
- assert r.status_int == 200
- assert r.body == b_('PUT-CHILD')
-
- r = app.post('/foos/bars/bazs')
- assert r.status_int == 200
- assert r.body == b_('POST-GRAND-CHILD')
-
- r = app.put('/foos/bars/bazs/0')
- assert r.status_int == 200
- assert r.body == b_('PUT-GRAND-CHILD')
-
- r = app.get('/foos/bars/bazs/final/')
- assert r.status_int == 200
- assert r.body == b_('FINAL')
-
- r = app.get('/foos/bars/bazs/final/named')
- assert r.status_int == 200
- assert r.body == b_('NAMED')
-
- def test_post_with_kwargs_only(self):
-
- class RootController(RestController):
-
- @expose()
- def get_all(self):
- return 'INDEX'
-
- @expose('json')
- def post(self, **kw):
- return kw
-
- # create the app
- app = TestApp(make_app(RootController()))
-
- r = app.get('/')
- assert r.status_int == 200
- assert r.body == b_('INDEX')
-
- kwargs = {'foo': 'bar', 'spam': 'eggs'}
- r = app.post('/', kwargs)
- assert r.status_int == 200
- assert r.namespace['foo'] == 'bar'
- assert r.namespace['spam'] == 'eggs'
-
- def test_nested_rest_with_lookup(self):
-
- class SubController(RestController):
-
- @expose()
- def get_all(self):
- return "SUB"
-
- class FinalController(RestController):
-
- def __init__(self, id_):
- self.id_ = id_
-
- @expose()
- def get_all(self):
- return "FINAL-%s" % self.id_
-
- @expose()
- def post(self):
- return "POST-%s" % self.id_
-
- class LookupController(RestController):
-
- sub = SubController()
-
- def __init__(self, id_):
- self.id_ = id_
-
- @expose()
- def _lookup(self, id_, *remainder):
- return FinalController(id_), remainder
-
- @expose()
- def get_all(self):
- raise AssertionError("Never Reached")
-
- @expose()
- def post(self):
- return "POST-LOOKUP-%s" % self.id_
-
- @expose()
- def put(self, id_):
- return "PUT-LOOKUP-%s-%s" % (self.id_, id_)
-
- @expose()
- def delete(self, id_):
- return "DELETE-LOOKUP-%s-%s" % (self.id_, id_)
-
- class FooController(RestController):
-
- @expose()
- def _lookup(self, id_, *remainder):
- return LookupController(id_), remainder
-
- @expose()
- def get_one(self, id_):
- return "GET ONE"
-
- @expose()
- def get_all(self):
- return "INDEX"
-
- @expose()
- def post(self):
- return "POST"
-
- @expose()
- def put(self, id_):
- return "PUT-%s" % id_
-
- @expose()
- def delete(self, id_):
- return "DELETE-%s" % id_
-
- class RootController(RestController):
- foo = FooController()
-
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foo')
- assert r.status_int == 200
- assert r.body == b_('INDEX')
-
- r = app.post('/foo')
- assert r.status_int == 200
- assert r.body == b_('POST')
-
- r = app.get('/foo/1')
- assert r.status_int == 200
- assert r.body == b_('GET ONE')
-
- r = app.post('/foo/1')
- assert r.status_int == 200
- assert r.body == b_('POST-LOOKUP-1')
-
- r = app.put('/foo/1')
- assert r.status_int == 200
- assert r.body == b_('PUT-1')
-
- r = app.delete('/foo/1')
- assert r.status_int == 200
- assert r.body == b_('DELETE-1')
-
- r = app.put('/foo/1/2')
- assert r.status_int == 200
- assert r.body == b_('PUT-LOOKUP-1-2')
-
- r = app.delete('/foo/1/2')
- assert r.status_int == 200
- assert r.body == b_('DELETE-LOOKUP-1-2')
-
- r = app.get('/foo/1/2')
- assert r.status_int == 200
- assert r.body == b_('FINAL-2')
-
- r = app.post('/foo/1/2')
- assert r.status_int == 200
- assert r.body == b_('POST-2')
-
- def test_nested_rest_with_default(self):
-
- class FooController(RestController):
-
- @expose()
- def _default(self, *remainder):
- return "DEFAULT %s" % remainder
-
- class RootController(RestController):
- foo = FooController()
-
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foo/missing')
- assert r.status_int == 200
- assert r.body == b_("DEFAULT missing")
-
- def test_rest_with_non_utf_8_body(self):
- if PY3:
- # webob+PY3 doesn't suffer from this bug; the POST parsing in PY3
- # seems to more gracefully detect the bytestring
- return
-
- class FooController(RestController):
-
- @expose()
- def post(self):
- return "POST"
-
- class RootController(RestController):
- foo = FooController()
-
- app = TestApp(make_app(RootController()))
-
- data = struct.pack('255h', *range(0, 255))
- r = app.post('/foo/', data, expect_errors=True)
- assert r.status_int == 400
-
- def test_dynamic_rest_lookup(self):
- class BarController(RestController):
- @expose()
- def get_all(self):
- return "BAR"
-
- @expose()
- def put(self):
- return "PUT_BAR"
-
- @expose()
- def delete(self):
- return "DELETE_BAR"
-
- class BarsController(RestController):
- @expose()
- def _lookup(self, id_, *remainder):
- return BarController(), remainder
-
- @expose()
- def get_all(self):
- return "BARS"
-
- @expose()
- def post(self):
- return "POST_BARS"
-
- class FooController(RestController):
- bars = BarsController()
-
- @expose()
- def get_all(self):
- return "FOO"
-
- @expose()
- def put(self):
- return "PUT_FOO"
-
- @expose()
- def delete(self):
- return "DELETE_FOO"
-
- class FoosController(RestController):
- @expose()
- def _lookup(self, id_, *remainder):
- return FooController(), remainder
-
- @expose()
- def get_all(self):
- return "FOOS"
-
- @expose()
- def post(self):
- return "POST_FOOS"
-
- class RootController(RestController):
- foos = FoosController()
-
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foos')
- assert r.status_int == 200
- assert r.body == b_('FOOS')
-
- r = app.post('/foos')
- assert r.status_int == 200
- assert r.body == b_('POST_FOOS')
-
- r = app.get('/foos/foo')
- assert r.status_int == 200
- assert r.body == b_('FOO')
-
- r = app.put('/foos/foo')
- assert r.status_int == 200
- assert r.body == b_('PUT_FOO')
-
- r = app.delete('/foos/foo')
- assert r.status_int == 200
- assert r.body == b_('DELETE_FOO')
-
- r = app.get('/foos/foo/bars')
- assert r.status_int == 200
- assert r.body == b_('BARS')
-
- r = app.post('/foos/foo/bars')
- assert r.status_int == 200
- assert r.body == b_('POST_BARS')
-
- r = app.get('/foos/foo/bars/bar')
- assert r.status_int == 200
- assert r.body == b_('BAR')
-
- r = app.put('/foos/foo/bars/bar')
- assert r.status_int == 200
- assert r.body == b_('PUT_BAR')
-
- r = app.delete('/foos/foo/bars/bar')
- assert r.status_int == 200
- assert r.body == b_('DELETE_BAR')
-
- def test_method_not_allowed_get(self):
- class ThingsController(RestController):
-
- @expose()
- def put(self, id_, value):
- response.status = 200
-
- @expose()
- def delete(self, id_):
- response.status = 200
-
- app = TestApp(make_app(ThingsController()))
- r = app.get('/', status=405)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'DELETE, PUT'
-
- def test_method_not_allowed_post(self):
- class ThingsController(RestController):
-
- @expose()
- def get_one(self):
- return dict()
-
- app = TestApp(make_app(ThingsController()))
- r = app.post('/', {'foo': 'bar'}, status=405)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'GET'
-
- def test_method_not_allowed_put(self):
- class ThingsController(RestController):
-
- @expose()
- def get_one(self):
- return dict()
-
- app = TestApp(make_app(ThingsController()))
- r = app.put('/123', status=405)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'GET'
-
- def test_method_not_allowed_delete(self):
- class ThingsController(RestController):
-
- @expose()
- def get_one(self):
- return dict()
-
- app = TestApp(make_app(ThingsController()))
- r = app.delete('/123', status=405)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'GET'
-
- def test_proper_allow_header_multiple_gets(self):
- class ThingsController(RestController):
-
- @expose()
- def get_all(self):
- return dict()
-
- @expose()
- def get(self):
- return dict()
-
- app = TestApp(make_app(ThingsController()))
- r = app.put('/123', status=405)
- assert r.status_int == 405
- assert r.headers['Allow'] == 'GET'
-
- def test_rest_with_utf8_uri(self):
-
- class FooController(RestController):
- key = chr(0x1F330) if PY3 else unichr(0x1F330)
- data = {key: 'Success!'}
-
- @expose()
- def get_one(self, id_):
- return self.data[id_]
-
- @expose()
- def get_all(self):
- return "Hello, World!"
-
- @expose()
- def put(self, id_, value):
- return self.data[id_]
-
- @expose()
- def delete(self, id_):
- return self.data[id_]
-
- class RootController(RestController):
- foo = FooController()
-
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foo/%F0%9F%8C%B0')
- assert r.status_int == 200
- assert r.body == b'Success!'
-
- r = app.put('/foo/%F0%9F%8C%B0', {'value': 'pecans'})
- assert r.status_int == 200
- assert r.body == b'Success!'
-
- r = app.delete('/foo/%F0%9F%8C%B0')
- assert r.status_int == 200
- assert r.body == b'Success!'
-
- r = app.get('/foo/')
- assert r.status_int == 200
- assert r.body == b'Hello, World!'
-
- @unittest.skipIf(not PY3, "test is Python3 specific")
- def test_rest_with_utf8_endpoint(self):
- class ChildController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- class FooController(RestController):
- pass
-
- # okay, so it's technically a chestnut, but close enough...
- setattr(FooController, '🌰', ChildController())
-
- class RootController(RestController):
- foo = FooController()
-
- app = TestApp(make_app(RootController()))
-
- r = app.get('/foo/%F0%9F%8C%B0/')
- assert r.status_int == 200
- assert r.body == b'Hello, World!'
-
-
-class TestExplicitRoute(PecanTestCase):
-
- def test_alternate_route(self):
-
- class RootController(RestController):
-
- @expose(route='some-path')
- def get_all(self):
- return "Hello, World!"
-
- self.assertRaises(
- ValueError,
- RootController
- )
diff --git a/pecan/tests/test_scaffolds.py b/pecan/tests/test_scaffolds.py
deleted file mode 100644
index 669aa7d..0000000
--- a/pecan/tests/test_scaffolds.py
+++ /dev/null
@@ -1,160 +0,0 @@
-import os
-import sys
-import tempfile
-import shutil
-
-from six.moves import cStringIO as StringIO
-
-from pecan.tests import PecanTestCase
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest # noqa
-
-
-class TestPecanScaffold(PecanTestCase):
-
- def test_normalize_pkg_name(self):
- from pecan.scaffolds import PecanScaffold
- s = PecanScaffold()
- assert s.normalize_pkg_name('sam') == 'sam'
- assert s.normalize_pkg_name('sam1') == 'sam1'
- assert s.normalize_pkg_name('sam_') == 'sam_'
- assert s.normalize_pkg_name('Sam') == 'sam'
- assert s.normalize_pkg_name('SAM') == 'sam'
- assert s.normalize_pkg_name('sam ') == 'sam'
- assert s.normalize_pkg_name(' sam') == 'sam'
- assert s.normalize_pkg_name('sam$') == 'sam'
- assert s.normalize_pkg_name('sam-sam') == 'samsam'
-
-
-class TestScaffoldUtils(PecanTestCase):
-
- def setUp(self):
- super(TestScaffoldUtils, self).setUp()
- self.scaffold_destination = tempfile.mkdtemp()
- self.out = sys.stdout
-
- sys.stdout = StringIO()
-
- def tearDown(self):
- shutil.rmtree(self.scaffold_destination)
- sys.stdout = self.out
-
- def test_copy_dir(self):
- from pecan.scaffolds import PecanScaffold
-
- class SimpleScaffold(PecanScaffold):
- _scaffold_dir = ('pecan', os.path.join(
- 'tests', 'scaffold_fixtures', 'simple'
- ))
-
- SimpleScaffold().copy_to(os.path.join(
- self.scaffold_destination,
- 'someapp'
- ), out_=StringIO())
-
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'foo'
- ))
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'bar', 'spam.txt'
- ))
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'foo'
- ), 'r').read().strip() == 'YAR'
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'foo'
- ), 'r').read().strip() == 'YAR'
-
- def test_destination_directory_levels_deep(self):
- from pecan.scaffolds import copy_dir
- f = StringIO()
- copy_dir(
- (
- 'pecan', os.path.join('tests', 'scaffold_fixtures', 'simple')
- ),
- os.path.join(self.scaffold_destination, 'some', 'app'),
- {},
- out_=f
- )
-
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'some', 'app', 'foo')
- )
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'some', 'app', 'bar', 'spam.txt')
- )
- assert open(os.path.join(
- self.scaffold_destination, 'some', 'app', 'foo'
- ), 'r').read().strip() == 'YAR'
- assert open(os.path.join(
- self.scaffold_destination, 'some', 'app', 'bar', 'spam.txt'
- ), 'r').read().strip() == 'Pecan'
-
- def test_destination_directory_already_exists(self):
- from pecan.scaffolds import copy_dir
- f = StringIO()
- copy_dir(
- (
- 'pecan', os.path.join('tests', 'scaffold_fixtures', 'simple')
- ),
- os.path.join(self.scaffold_destination),
- {},
- out_=f
- )
- assert 'already exists' in f.getvalue()
-
- def test_copy_dir_with_filename_substitution(self):
- from pecan.scaffolds import copy_dir
- copy_dir(
- (
- 'pecan', os.path.join('tests', 'scaffold_fixtures', 'file_sub')
- ),
- os.path.join(
- self.scaffold_destination, 'someapp'
- ),
- {'package': 'thingy'},
- out_=StringIO()
- )
-
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'foo_thingy')
- )
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'bar_thingy', 'spam.txt')
- )
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'foo_thingy'
- ), 'r').read().strip() == 'YAR'
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'bar_thingy', 'spam.txt'
- ), 'r').read().strip() == 'Pecan'
-
- def test_copy_dir_with_file_content_substitution(self):
- from pecan.scaffolds import copy_dir
- copy_dir(
- (
- 'pecan',
- os.path.join('tests', 'scaffold_fixtures', 'content_sub'),
- ),
- os.path.join(
- self.scaffold_destination, 'someapp'
- ),
- {'package': 'thingy'},
- out_=StringIO()
- )
-
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'foo')
- )
- assert os.path.isfile(os.path.join(
- self.scaffold_destination, 'someapp', 'bar', 'spam.txt')
- )
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'foo'
- ), 'r').read().strip() == 'YAR thingy'
- assert open(os.path.join(
- self.scaffold_destination, 'someapp', 'bar', 'spam.txt'
- ), 'r').read().strip() == 'Pecan thingy'
diff --git a/pecan/tests/test_secure.py b/pecan/tests/test_secure.py
deleted file mode 100644
index 1d30ea3..0000000
--- a/pecan/tests/test_secure.py
+++ /dev/null
@@ -1,563 +0,0 @@
-import sys
-
-from six import b as b_
-from webtest import TestApp
-
-from pecan import expose, make_app
-from pecan.secure import secure, unlocked, SecureController
-from pecan.tests import PecanTestCase
-
-if sys.version_info < (2, 7):
- import unittest2 as unittest
-else:
- import unittest # noqa
-
-try:
- set()
-except:
- from sets import Set as set
-
-
-class TestSecure(PecanTestCase):
- def test_simple_secure(self):
- authorized = False
-
- class SecretController(SecureController):
- @expose()
- def index(self):
- return 'Index'
-
- @expose()
- @unlocked
- def allowed(self):
- return 'Allowed!'
-
- @classmethod
- def check_permissions(cls):
- return authorized
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- @expose()
- @secure(lambda: False)
- def locked(self):
- return 'No dice!'
-
- @expose()
- @secure(lambda: True)
- def unlocked(self):
- return 'Sure thing'
-
- secret = SecretController()
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- response = app.get('/unlocked')
- assert response.status_int == 200
- assert response.body == b_('Sure thing')
-
- response = app.get('/locked', expect_errors=True)
- assert response.status_int == 401
-
- response = app.get('/secret/', expect_errors=True)
- assert response.status_int == 401
-
- response = app.get('/secret/allowed')
- assert response.status_int == 200
- assert response.body == b_('Allowed!')
-
- def test_unlocked_attribute(self):
- class AuthorizedSubController(object):
- @expose()
- def index(self):
- return 'Index'
-
- @expose()
- def allowed(self):
- return 'Allowed!'
-
- class SecretController(SecureController):
- @expose()
- def index(self):
- return 'Index'
-
- @expose()
- @unlocked
- def allowed(self):
- return 'Allowed!'
-
- authorized = unlocked(AuthorizedSubController())
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello, World!'
-
- @expose()
- @secure(lambda: False)
- def locked(self):
- return 'No dice!'
-
- @expose()
- @secure(lambda: True)
- def unlocked(self):
- return 'Sure thing'
-
- secret = SecretController()
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello, World!')
-
- response = app.get('/unlocked')
- assert response.status_int == 200
- assert response.body == b_('Sure thing')
-
- response = app.get('/locked', expect_errors=True)
- assert response.status_int == 401
-
- response = app.get('/secret/', expect_errors=True)
- assert response.status_int == 401
-
- response = app.get('/secret/allowed')
- assert response.status_int == 200
- assert response.body == b_('Allowed!')
-
- response = app.get('/secret/authorized/')
- assert response.status_int == 200
- assert response.body == b_('Index')
-
- response = app.get('/secret/authorized/allowed')
- assert response.status_int == 200
- assert response.body == b_('Allowed!')
-
- def test_secure_attribute(self):
- authorized = False
-
- class SubController(object):
- @expose()
- def index(self):
- return 'Hello from sub!'
-
- class RootController(object):
- @expose()
- def index(self):
- return 'Hello from root!'
-
- sub = secure(SubController(), lambda: authorized)
-
- app = TestApp(make_app(RootController()))
- response = app.get('/')
- assert response.status_int == 200
- assert response.body == b_('Hello from root!')
-
- response = app.get('/sub/', expect_errors=True)
- assert response.status_int == 401
-
- authorized = True
- response = app.get('/sub/')
- assert response.status_int == 200
- assert response.body == b_('Hello from sub!')
-
- def test_secured_generic_controller(self):
- authorized = False
-
- class RootController(object):
-
- @classmethod
- def check_permissions(cls):
- return authorized
-
- @expose(generic=True)
- def index(self):
- return 'Index'
-
- @secure('check_permissions')
- @index.when(method='POST')
- def index_post(self):
- return 'I should not be allowed'
-
- @secure('check_permissions')
- @expose(generic=True)
- def secret(self):
- return 'I should not be allowed'
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/')
- assert response.status_int == 200
- response = app.post('/', expect_errors=True)
- assert response.status_int == 401
- response = app.get('/secret/', expect_errors=True)
- assert response.status_int == 401
-
- def test_secured_generic_controller_lambda(self):
- authorized = False
-
- class RootController(object):
-
- @expose(generic=True)
- def index(self):
- return 'Index'
-
- @secure(lambda: authorized)
- @index.when(method='POST')
- def index_post(self):
- return 'I should not be allowed'
-
- @secure(lambda: authorized)
- @expose(generic=True)
- def secret(self):
- return 'I should not be allowed'
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/')
- assert response.status_int == 200
- response = app.post('/', expect_errors=True)
- assert response.status_int == 401
- response = app.get('/secret/', expect_errors=True)
- assert response.status_int == 401
-
- def test_secured_generic_controller_secure_attribute(self):
- authorized = False
-
- class SecureController(object):
-
- @expose(generic=True)
- def index(self):
- return 'I should not be allowed'
-
- @index.when(method='POST')
- def index_post(self):
- return 'I should not be allowed'
-
- @expose(generic=True)
- def secret(self):
- return 'I should not be allowed'
-
- class RootController(object):
- sub = secure(SecureController(), lambda: authorized)
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/sub/', expect_errors=True)
- assert response.status_int == 401
- response = app.post('/sub/', expect_errors=True)
- assert response.status_int == 401
- response = app.get('/sub/secret/', expect_errors=True)
- assert response.status_int == 401
-
- def test_secured_generic_controller_secure_attribute_with_unlocked(self):
-
- class RootController(SecureController):
-
- @unlocked
- @expose(generic=True)
- def index(self):
- return 'Unlocked!'
-
- @unlocked
- @index.when(method='POST')
- def index_post(self):
- return 'Unlocked!'
-
- @expose(generic=True)
- def secret(self):
- return 'I should not be allowed'
-
- app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
- response = app.get('/')
- assert response.status_int == 200
- response = app.post('/')
- assert response.status_int == 200
- response = app.get('/secret/', expect_errors=True)
- assert response.status_int == 401
-
- def test_state_attribute(self):
- from pecan.secure import Any, Protected
- assert repr(Any) == '<SecureState Any>'
- assert bool(Any) is False
-
- assert repr(Protected) == '<SecureState Protected>'
- assert bool(Protected) is True
-
- def test_secure_obj_only_failure(self):
- class Foo(object):
- pass
-
- try:
- secure(Foo())
- except Exception as e:
- assert isinstance(e, TypeError)
-
-
-class TestObjectPathSecurity(PecanTestCase):
-
- def setUp(self):
- super(TestObjectPathSecurity, self).setUp()
- permissions_checked = set()
-
- class DeepSecretController(SecureController):
- authorized = False
-
- @expose()
- @unlocked
- def _lookup(self, someID, *remainder):
- if someID == 'notfound':
- return None
- return SubController(someID), remainder
-
- @expose()
- def index(self):
- return 'Deep Secret'
-
- @classmethod
- def check_permissions(cls):
- permissions_checked.add('deepsecret')
- return cls.authorized
-
- class SubController(object):
- def __init__(self, myID):
- self.myID = myID
-
- @expose()
- def index(self):
- return 'Index %s' % self.myID
-
- deepsecret = DeepSecretController()
-
- class SecretController(SecureController):
- authorized = False
- independent_authorization = False
-
- @expose()
- def _lookup(self, someID, *remainder):
- if someID == 'notfound':
- return None
- elif someID == 'lookup_wrapped':
- return self.wrapped, remainder
- return SubController(someID), remainder
-
- @secure('independent_check_permissions')
- @expose()
- def independent(self):
- return 'Independent Security'
-
- wrapped = secure(
- SubController('wrapped'), 'independent_check_permissions'
- )
-
- @classmethod
- def check_permissions(cls):
- permissions_checked.add('secretcontroller')
- return cls.authorized
-
- @classmethod
- def independent_check_permissions(cls):
- permissions_checked.add('independent')
- return cls.independent_authorization
-
- class NotSecretController(object):
- @expose()
- def _lookup(self, someID, *remainder):
- if someID == 'notfound':
- return None
- return SubController(someID), remainder
-
- unlocked = unlocked(SubController('unlocked'))
-
- class RootController(object):
- secret = SecretController()
- notsecret = NotSecretController()
-
- self.deepsecret_cls = DeepSecretController
- self.secret_cls = SecretController
-
- self.permissions_checked = permissions_checked
- self.app = TestApp(make_app(
- RootController(),
- debug=True,
- static_root='tests/static'
- ))
-
- def tearDown(self):
- self.permissions_checked.clear()
- self.secret_cls.authorized = False
- self.deepsecret_cls.authorized = False
-
- def test_sub_of_both_not_secret(self):
- response = self.app.get('/notsecret/hi/')
- assert response.status_int == 200
- assert response.body == b_('Index hi')
-
- def test_protected_lookup(self):
- response = self.app.get('/secret/hi/', expect_errors=True)
- assert response.status_int == 401
-
- self.secret_cls.authorized = True
- response = self.app.get('/secret/hi/')
- assert response.status_int == 200
- assert response.body == b_('Index hi')
- assert 'secretcontroller' in self.permissions_checked
-
- def test_secured_notfound_lookup(self):
- response = self.app.get('/secret/notfound/', expect_errors=True)
- assert response.status_int == 404
-
- def test_secret_through_lookup(self):
- response = self.app.get(
- '/notsecret/hi/deepsecret/', expect_errors=True
- )
- assert response.status_int == 401
-
- def test_layered_protection(self):
- response = self.app.get('/secret/hi/deepsecret/', expect_errors=True)
- assert response.status_int == 401
- assert 'secretcontroller' in self.permissions_checked
-
- self.secret_cls.authorized = True
- response = self.app.get('/secret/hi/deepsecret/', expect_errors=True)
- assert response.status_int == 401
- assert 'secretcontroller' in self.permissions_checked
- assert 'deepsecret' in self.permissions_checked
-
- self.deepsecret_cls.authorized = True
- response = self.app.get('/secret/hi/deepsecret/')
- assert response.status_int == 200
- assert response.body == b_('Deep Secret')
- assert 'secretcontroller' in self.permissions_checked
- assert 'deepsecret' in self.permissions_checked
-
- def test_cyclical_protection(self):
- self.secret_cls.authorized = True
- self.deepsecret_cls.authorized = True
- response = self.app.get('/secret/1/deepsecret/2/deepsecret/')
- assert response.status_int == 200
- assert response.body == b_('Deep Secret')
- assert 'secretcontroller' in self.permissions_checked
- assert 'deepsecret' in self.permissions_checked
-
- def test_unlocked_lookup(self):
- response = self.app.get('/notsecret/1/deepsecret/2/')
- assert response.status_int == 200
- assert response.body == b_('Index 2')
- assert 'deepsecret' not in self.permissions_checked
-
- response = self.app.get(
- '/notsecret/1/deepsecret/notfound/', expect_errors=True
- )
- assert response.status_int == 404
- assert 'deepsecret' not in self.permissions_checked
-
- def test_mixed_protection(self):
- self.secret_cls.authorized = True
- response = self.app.get(
- '/secret/1/deepsecret/notfound/', expect_errors=True
- )
- assert response.status_int == 404
- assert 'secretcontroller' in self.permissions_checked
- assert 'deepsecret' not in self.permissions_checked
-
- def test_independent_check_failure(self):
- response = self.app.get('/secret/independent/', expect_errors=True)
- assert response.status_int == 401
- assert len(self.permissions_checked) == 1
- assert 'independent' in self.permissions_checked
-
- def test_independent_check_success(self):
- self.secret_cls.independent_authorization = True
- response = self.app.get('/secret/independent')
- assert response.status_int == 200
- assert response.body == b_('Independent Security')
- assert len(self.permissions_checked) == 1
- assert 'independent' in self.permissions_checked
-
- def test_wrapped_attribute_failure(self):
- self.secret_cls.independent_authorization = False
- response = self.app.get('/secret/wrapped/', expect_errors=True)
- assert response.status_int == 401
- assert len(self.permissions_checked) == 1
- assert 'independent' in self.permissions_checked
-
- def test_wrapped_attribute_success(self):
- self.secret_cls.independent_authorization = True
- response = self.app.get('/secret/wrapped/')
- assert response.status_int == 200
- assert response.body == b_('Index wrapped')
- assert len(self.permissions_checked) == 1
- assert 'independent' in self.permissions_checked
-
- def test_lookup_to_wrapped_attribute_on_self(self):
- self.secret_cls.authorized = True
- self.secret_cls.independent_authorization = True
- response = self.app.get('/secret/lookup_wrapped/')
- assert response.status_int == 200
- assert response.body == b_('Index wrapped')
- assert len(self.permissions_checked) == 2
- assert 'independent' in self.permissions_checked
- assert 'secretcontroller' in self.permissions_checked
-
- def test_unlocked_attribute_in_insecure(self):
- response = self.app.get('/notsecret/unlocked/')
- assert response.status_int == 200
- assert response.body == b_('Index unlocked')
-
-
-class SecureControllerSharedPermissionsRegression(PecanTestCase):
- """Regression tests for https://github.com/dreamhost/pecan/issues/131"""
-
- def setUp(self):
- super(SecureControllerSharedPermissionsRegression, self).setUp()
-
- class Parent(object):
- @expose()
- def index(self):
- return 'hello'
-
- class UnsecuredChild(Parent):
- pass
-
- class SecureChild(Parent, SecureController):
- @classmethod
- def check_permissions(cls):
- return False
-
- class RootController(object):
-
- secured = SecureChild()
- unsecured = UnsecuredChild()
-
- self.app = TestApp(make_app(RootController()))
-
- def test_inherited_security(self):
- assert self.app.get('/secured/', status=401).status_int == 401
- assert self.app.get('/unsecured/').status_int == 200
diff --git a/pecan/tests/test_templating.py b/pecan/tests/test_templating.py
deleted file mode 100644
index 5fffb0c..0000000
--- a/pecan/tests/test_templating.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import tempfile
-
-from six import b as b_
-
-from pecan.templating import RendererFactory, format_line_context
-from pecan.tests import PecanTestCase
-
-
-class TestTemplate(PecanTestCase):
- def setUp(self):
- super(TestTemplate, self).setUp()
- self.rf = RendererFactory()
-
- def test_available(self):
- self.assertTrue(self.rf.available('json'))
- self.assertFalse(self.rf.available('badrenderer'))
-
- def test_create_bad(self):
- self.assertEqual(self.rf.get('doesnotexist', '/'), None)
-
- def test_extra_vars(self):
- extra_vars = self.rf.extra_vars
- self.assertEqual(extra_vars.make_ns({}), {})
-
- extra_vars.update({'foo': 1})
- self.assertEqual(extra_vars.make_ns({}), {'foo': 1})
-
- def test_update_extra_vars(self):
- extra_vars = self.rf.extra_vars
- extra_vars.update({'foo': 1})
-
- self.assertEqual(extra_vars.make_ns({'bar': 2}), {'foo': 1, 'bar': 2})
- self.assertEqual(extra_vars.make_ns({'foo': 2}), {'foo': 2})
-
-
-class TestTemplateLineFormat(PecanTestCase):
-
- def setUp(self):
- super(TestTemplateLineFormat, self).setUp()
- self.f = tempfile.NamedTemporaryFile()
-
- def tearDown(self):
- del self.f
-
- def test_format_line_context(self):
- for i in range(11):
- self.f.write(b_('Testing Line %d\n' % i))
- self.f.flush()
-
- assert format_line_context(self.f.name, 0).count('Testing Line') == 10
diff --git a/pecan/tests/test_util.py b/pecan/tests/test_util.py
deleted file mode 100644
index 00e81f5..0000000
--- a/pecan/tests/test_util.py
+++ /dev/null
@@ -1,95 +0,0 @@
-import functools
-import inspect
-import unittest
-
-from pecan import expose
-from pecan import util
-
-
-class TestArgSpec(unittest.TestCase):
-
- @property
- def controller(self):
-
- class RootController(object):
-
- @expose()
- def index(self, a, b, c=1, *args, **kwargs):
- return 'Hello, World!'
-
- @staticmethod
- @expose()
- def static_index(a, b, c=1, *args, **kwargs):
- return 'Hello, World!'
-
- return RootController()
-
- def test_no_decorator(self):
- expected = inspect.getargspec(self.controller.index.__func__)
- actual = util.getargspec(self.controller.index.__func__)
- assert expected == actual
-
- expected = inspect.getargspec(self.controller.static_index)
- actual = util.getargspec(self.controller.static_index)
- assert expected == actual
-
- def test_simple_decorator(self):
- def dec(f):
- return f
-
- expected = inspect.getargspec(self.controller.index.__func__)
- actual = util.getargspec(dec(self.controller.index.__func__))
- assert expected == actual
-
- expected = inspect.getargspec(self.controller.static_index)
- actual = util.getargspec(dec(self.controller.static_index))
- assert expected == actual
-
- def test_simple_wrapper(self):
- def dec(f):
- @functools.wraps(f)
- def wrapped(*a, **kw):
- return f(*a, **kw)
- return wrapped
-
- expected = inspect.getargspec(self.controller.index.__func__)
- actual = util.getargspec(dec(self.controller.index.__func__))
- assert expected == actual
-
- expected = inspect.getargspec(self.controller.static_index)
- actual = util.getargspec(dec(self.controller.static_index))
- assert expected == actual
-
- def test_multiple_decorators(self):
- def dec(f):
- @functools.wraps(f)
- def wrapped(*a, **kw):
- return f(*a, **kw)
- return wrapped
-
- expected = inspect.getargspec(self.controller.index.__func__)
- actual = util.getargspec(dec(dec(dec(self.controller.index.__func__))))
- assert expected == actual
-
- expected = inspect.getargspec(self.controller.static_index)
- actual = util.getargspec(dec(dec(dec(
- self.controller.static_index))))
- assert expected == actual
-
- def test_decorator_with_args(self):
- def dec(flag):
- def inner(f):
- @functools.wraps(f)
- def wrapped(*a, **kw):
- return f(*a, **kw)
- return wrapped
- return inner
-
- expected = inspect.getargspec(self.controller.index.__func__)
- actual = util.getargspec(dec(True)(self.controller.index.__func__))
- assert expected == actual
-
- expected = inspect.getargspec(self.controller.static_index)
- actual = util.getargspec(dec(True)(
- self.controller.static_index))
- assert expected == actual