Test client

This commit is contained in:
Miguel Grinberg
2022-08-06 12:17:49 +01:00
parent 3a54984b67
commit 199d23f2c7
24 changed files with 774 additions and 492 deletions

View File

@@ -1,11 +1,13 @@
from tests.microdot.test_multidict import TestMultiDict
from tests.microdot.test_request import TestRequest
from tests.microdot.test_response import TestResponse
from tests.microdot.test_url_pattern import TestURLPattern
from tests.microdot.test_microdot import TestMicrodot
from .test_multidict import TestMultiDict
from .test_request import TestRequest
from .test_response import TestResponse
from .test_url_pattern import TestURLPattern
from .test_microdot import TestMicrodot
from tests.microdot_asyncio.test_request_asyncio import TestRequestAsync
from tests.microdot_asyncio.test_response_asyncio import TestResponseAsync
from tests.microdot_asyncio.test_microdot_asyncio import TestMicrodotAsync
from .test_request_asyncio import TestRequestAsync
from .test_response_asyncio import TestResponseAsync
from .test_microdot_asyncio import TestMicrodotAsync
from tests.microdot_utemplate.test_utemplate import TestUTemplate
from .test_utemplate import TestUTemplate
from .test_session import TestSession

View File

@@ -1,466 +0,0 @@
import sys
import unittest
from microdot import Microdot, Response
from tests import mock_socket
def mock_create_thread(f, *args, **kwargs):
f(*args, **kwargs)
class TestMicrodot(unittest.TestCase):
def setUp(self):
# mock socket module
self.original_socket = sys.modules['microdot'].socket
self.original_create_thread = sys.modules['microdot'].create_thread
sys.modules['microdot'].socket = mock_socket
sys.modules['microdot'].create_thread = mock_create_thread
def tearDown(self):
# restore original socket module
sys.modules['microdot'].socket = self.original_socket
sys.modules['microdot'].create_thread = self.original_create_thread
def _add_shutdown(self, app):
@app.route('/shutdown')
def shutdown(req):
app.shutdown()
return ''
mock_socket.add_request('GET', '/shutdown')
def test_get_request(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nfoo'))
def test_post_request(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.route('/', methods=['POST'])
def index_post(req):
return Response('bar')
mock_socket.clear_requests()
fd = mock_socket.add_request('POST', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nbar'))
def test_empty_request(self):
app = Microdot()
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 400 N/A\r\n'))
self.assertIn(b'Content-Length: 11\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nBad request'))
def test_method_decorators(self):
app = Microdot()
@app.get('/get')
def get(req):
return 'GET'
@app.post('/post')
def post(req):
return 'POST'
@app.put('/put')
def put(req):
return 'PUT'
@app.patch('/patch')
def patch(req):
return 'PATCH'
@app.delete('/delete')
def delete(req):
return 'DELETE'
methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
mock_socket.clear_requests()
fds = [mock_socket.add_request(method, '/' + method.lower())
for method in methods]
self._add_shutdown(app)
app.run()
for fd, method in zip(fds, methods):
self.assertTrue(fd.response.endswith(
b'\r\n\r\n' + method.encode()))
def test_tuple_responses(self):
app = Microdot()
@app.route('/body')
def one(req):
return 'one'
@app.route('/body-status')
def two(req):
return 'two', 202
@app.route('/body-headers')
def three(req):
return '<p>three</p>', {'Content-Type': 'text/html'}
@app.route('/body-status-headers')
def four(req):
return '<p>four</p>', 202, {'Content-Type': 'text/html'}
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/body')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\none'))
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/body-status')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 202 N/A\r\n'))
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\ntwo'))
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/body-headers')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Type: text/html\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n<p>three</p>'))
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/body-status-headers')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 202 N/A\r\n'))
self.assertIn(b'Content-Type: text/html\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n<p>four</p>'))
def test_before_after_request(self):
app = Microdot()
@app.before_request
def before_request(req):
if req.path == '/bar':
@req.after_request
def after_request(req, res):
res.headers['X-Two'] = '2'
return res
return 'bar', 202
req.g.message = 'baz'
@app.after_request
def after_request_one(req, res):
res.headers['X-One'] = '1'
@app.after_request
def after_request_two(req, res):
res.set_cookie('foo', 'bar')
return res
@app.route('/bar')
def bar(req):
return 'foo'
@app.route('/baz')
def baz(req):
return req.g.message
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/bar')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 202 N/A\r\n'))
self.assertIn(b'X-One: 1\r\n', fd.response)
self.assertIn(b'X-Two: 2\r\n', fd.response)
self.assertIn(b'Set-Cookie: foo=bar\r\n', fd.response)
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nbar'))
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/baz')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'X-One: 1\r\n', fd.response)
self.assertIn(b'Set-Cookie: foo=bar\r\n', fd.response)
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nbaz'))
def test_400(self):
app = Microdot()
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 400 N/A\r\n'))
self.assertIn(b'Content-Length: 11\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nBad request'))
def test_400_handler(self):
app = Microdot()
@app.errorhandler(400)
def handle_400(req):
return '400'
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n400'))
def test_404(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/foo')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 404 N/A\r\n'))
self.assertIn(b'Content-Length: 9\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nNot found'))
def test_404_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.errorhandler(404)
def handle_404(req):
return '404'
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/foo')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n404'))
def test_405(self):
app = Microdot()
@app.route('/foo')
def index(req):
return 'foo'
mock_socket.clear_requests()
fd = mock_socket.add_request('POST', '/foo')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 405 N/A\r\n'))
self.assertIn(b'Content-Length: 9\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nNot found'))
def test_405_handler(self):
app = Microdot()
@app.route('/foo')
def index(req):
return 'foo'
@app.errorhandler(405)
def handle_404(req):
return '405'
mock_socket.clear_requests()
fd = mock_socket.add_request('POST', '/foo')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n405'))
def test_413(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/foo', body='x' * 17000)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 413 N/A\r\n'))
self.assertIn(b'Content-Length: 17\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nPayload too large'))
def test_413_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.errorhandler(413)
def handle_413(req):
return '413', 400
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/foo', body='x' * 17000)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 400 N/A\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n413'))
def test_500(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 500 N/A\r\n'))
self.assertIn(b'Content-Length: 21\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nInternal server error'))
def test_500_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
@app.errorhandler(500)
def handle_500(req):
return '501', 501
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 501 N/A\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n501'))
def test_exception_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
@app.errorhandler(ZeroDivisionError)
def handle_div_zero(req, exc):
return '501', 501
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 501 N/A\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n501'))
def test_streaming(self):
app = Microdot()
@app.route('/')
def index(req):
def stream():
yield 'foo'
yield b'bar'
return stream()
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nfoobar'))
def test_mount(self):
subapp = Microdot()
@subapp.before_request
def before(req):
req.g.before = 'before'
@subapp.after_request
def after(req, res):
return res.body + b':after'
@subapp.errorhandler(404)
def not_found(req):
return '404', 404
@subapp.route('/app')
def index(req):
return req.g.before + ':foo'
app = Microdot()
app.mount(subapp, url_prefix='/sub')
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/app')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 404 N/A\r\n'))
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n404'))
mock_socket.clear_requests()
fd = mock_socket.add_request('GET', '/sub/app')
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nbefore:foo:after'))

View File

@@ -1,6 +0,0 @@
# Autogenerated file
def render(name):
yield """Hello, """
yield str(name)
yield """!
"""

View File

@@ -10,7 +10,7 @@ from microdot_asyncio import Microdot as MicrodotAsync, Request as RequestAsync
from microdot_jinja import render_template, init_templates
from tests.mock_socket import get_request_fd, get_async_request_fd
init_templates('tests/microdot_jinja/templates')
init_templates('tests/templates')
def _run(coro):
@@ -21,7 +21,7 @@ def _run(coro):
'not supported under MicroPython')
class TestUTemplate(unittest.TestCase):
def test_render_template(self):
s = render_template('hello.txt', name='foo')
s = render_template('hello.jinja.txt', name='foo')
self.assertEqual(s, 'Hello, foo!')
def test_render_template_in_app(self):
@@ -29,7 +29,7 @@ class TestUTemplate(unittest.TestCase):
@app.route('/')
def index(req):
return render_template('hello.txt', name='foo')
return render_template('hello.jinja.txt', name='foo')
req = Request.create(app, get_request_fd('GET', '/'), 'addr')
res = app.dispatch_request(req)
@@ -41,7 +41,7 @@ class TestUTemplate(unittest.TestCase):
@app.route('/')
async def index(req):
return render_template('hello.txt', name='foo')
return render_template('hello.jinja.txt', name='foo')
req = _run(RequestAsync.create(
app, get_async_request_fd('GET', '/'), 'addr'))

529
tests/test_microdot.py Normal file
View File

@@ -0,0 +1,529 @@
import sys
import unittest
from microdot import Microdot, Response
from microdot_test_client import TestClient
from tests import mock_socket
def mock_create_thread(f, *args, **kwargs):
f(*args, **kwargs)
class TestMicrodot(unittest.TestCase):
def _mock_socket(self):
self.original_socket = sys.modules['microdot'].socket
self.original_create_thread = sys.modules['microdot'].create_thread
sys.modules['microdot'].socket = mock_socket
sys.modules['microdot'].create_thread = mock_create_thread
def _unmock_socket(self):
sys.modules['microdot'].socket = self.original_socket
sys.modules['microdot'].create_thread = self.original_create_thread
def _add_shutdown(self, app):
@app.route('/shutdown')
def shutdown(req):
app.shutdown()
return ''
mock_socket.add_request('GET', '/shutdown')
def test_get_request(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
client = TestClient(app)
res = client.get('/')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'foo')
self.assertEqual(res.body, b'foo')
self.assertEqual(res.json, None)
def test_post_request(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.route('/', methods=['POST'])
def index_post(req):
return Response('bar')
client = TestClient(app)
res = client.post('/')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.headers['Content-Length'], '3')
self.assertEqual(res.text, 'bar')
def test_empty_request(self):
self._mock_socket()
app = Microdot()
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 400 N/A\r\n'))
self.assertIn(b'Content-Length: 11\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nBad request'))
self._unmock_socket()
def test_method_decorators(self):
app = Microdot()
@app.get('/get')
def get(req):
return 'GET'
@app.post('/post')
def post(req):
return 'POST'
@app.put('/put')
def put(req):
return 'PUT'
@app.patch('/patch')
def patch(req):
return 'PATCH'
@app.delete('/delete')
def delete(req):
return 'DELETE'
client = TestClient(app)
methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']
for method in methods:
res = getattr(client, method.lower())('/' + method.lower())
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, method)
def test_headers(self):
app = Microdot()
@app.route('/')
def index(req):
return req.headers.get('X-Foo')
client = TestClient(app)
res = client.get('/', headers={'X-Foo': 'bar'})
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'bar')
def test_cookies(self):
app = Microdot()
@app.route('/')
def index(req):
return req.cookies['one'] + req.cookies['two'] + \
req.cookies['three']
client = TestClient(app, cookies={'one': '1', 'two': '2'})
res = client.get('/', headers={'Cookie': 'three=3'})
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '123')
def test_binary_payload(self):
app = Microdot()
@app.post('/')
def index(req):
return req.body
client = TestClient(app)
res = client.post('/', body=b'foo')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'foo')
def test_json_payload(self):
app = Microdot()
@app.post('/dict')
def json_dict(req):
print(req.headers)
return req.json.get('foo')
@app.post('/list')
def json_list(req):
return req.json[0]
client = TestClient(app)
res = client.post('/dict', body={'foo': 'bar'})
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'bar')
res = client.post('/list', body=['foo', 'bar'])
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'foo')
def test_tuple_responses(self):
app = Microdot()
@app.route('/body')
def one(req):
return 'one'
@app.route('/body-status')
def two(req):
return 'two', 202
@app.route('/body-headers')
def three(req):
return '<p>three</p>', {'Content-Type': 'text/html'}
@app.route('/body-status-headers')
def four(req):
return '<p>four</p>', 202, {'Content-Type': 'text/html'}
client = TestClient(app)
res = client.get('/body')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'one')
res = client.get('/body-status')
self.assertEqual(res.status_code, 202)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'two')
res = client.get('/body-headers')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/html')
self.assertEqual(res.text, '<p>three</p>')
res = client.get('/body-status-headers')
self.assertEqual(res.status_code, 202)
self.assertEqual(res.headers['Content-Type'], 'text/html')
self.assertEqual(res.text, '<p>four</p>')
def test_before_after_request(self):
app = Microdot()
@app.before_request
def before_request(req):
if req.path == '/bar':
@req.after_request
def after_request(req, res):
res.headers['X-Two'] = '2'
return res
return 'bar', 202
req.g.message = 'baz'
@app.after_request
def after_request_one(req, res):
res.headers['X-One'] = '1'
@app.after_request
def after_request_two(req, res):
res.set_cookie('foo', 'bar')
return res
@app.route('/bar')
def bar(req):
return 'foo'
@app.route('/baz')
def baz(req):
return req.g.message
client = TestClient(app)
res = client.get('/bar')
self.assertEqual(res.status_code, 202)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.headers['Set-Cookie'], ['foo=bar'])
self.assertEqual(res.headers['X-One'], '1')
self.assertEqual(res.headers['X-Two'], '2')
self.assertEqual(res.text, 'bar')
self.assertEqual(client.cookies['foo'], 'bar')
res = client.get('/baz')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.headers['Set-Cookie'], ['foo=bar'])
self.assertEqual(res.headers['X-One'], '1')
self.assertFalse('X-Two' in res.headers)
self.assertEqual(res.headers['Content-Length'], '3')
self.assertEqual(res.text, 'baz')
def test_400(self):
self._mock_socket()
app = Microdot()
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 400 N/A\r\n'))
self.assertIn(b'Content-Length: 11\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\nBad request'))
self._unmock_socket()
def test_400_handler(self):
self._mock_socket()
app = Microdot()
@app.errorhandler(400)
def handle_400(req):
return '400'
mock_socket.clear_requests()
fd = mock_socket.FakeStream(b'\n')
mock_socket._requests.append(fd)
self._add_shutdown(app)
app.run()
self.assertTrue(fd.response.startswith(b'HTTP/1.0 200 OK\r\n'))
self.assertIn(b'Content-Length: 3\r\n', fd.response)
self.assertIn(b'Content-Type: text/plain\r\n', fd.response)
self.assertTrue(fd.response.endswith(b'\r\n\r\n400'))
self._unmock_socket()
def test_404(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
client = TestClient(app)
res = client.post('/foo')
self.assertEqual(res.status_code, 404)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'Not found')
def test_404_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.errorhandler(404)
def handle_404(req):
return '404'
client = TestClient(app)
res = client.post('/foo')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '404')
def test_405(self):
app = Microdot()
@app.route('/foo')
def index(req):
return 'foo'
client = TestClient(app)
res = client.post('/foo')
self.assertEqual(res.status_code, 405)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'Not found')
def test_405_handler(self):
app = Microdot()
@app.route('/foo')
def index(req):
return 'foo'
@app.errorhandler(405)
def handle_405(req):
return '405', 405
client = TestClient(app)
res = client.patch('/foo')
self.assertEqual(res.status_code, 405)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '405')
def test_413(self):
app = Microdot()
@app.post('/')
def index(req):
return 'foo'
client = TestClient(app)
res = client.post('/foo', body='x' * 17000)
self.assertEqual(res.status_code, 413)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'Payload too large')
def test_413_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 'foo'
@app.errorhandler(413)
def handle_413(req):
return '413', 400
client = TestClient(app)
res = client.post('/foo', body='x' * 17000)
self.assertEqual(res.status_code, 400)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '413')
def test_500(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
client = TestClient(app)
res = client.get('/')
self.assertEqual(res.status_code, 500)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'Internal server error')
def test_500_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
@app.errorhandler(500)
def handle_500(req):
return '501', 501
client = TestClient(app)
res = client.get('/')
self.assertEqual(res.status_code, 501)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '501')
def test_exception_handler(self):
app = Microdot()
@app.route('/')
def index(req):
return 1 / 0
@app.errorhandler(ZeroDivisionError)
def handle_div_zero(req, exc):
return '501', 501
client = TestClient(app)
res = client.get('/')
self.assertEqual(res.status_code, 501)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '501')
def test_json_response(self):
app = Microdot()
@app.route('/dict')
def json_dict(req):
return {'foo': 'bar'}
@app.route('/list')
def json_list(req):
return ['foo', 'bar']
client = TestClient(app)
res = client.get('/dict')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'application/json')
self.assertEqual(res.json, {'foo': 'bar'})
res = client.get('/list')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'application/json')
self.assertEqual(res.json, ['foo', 'bar'])
def test_binary_response(self):
app = Microdot()
@app.route('/bin')
def index(req):
return b'\xff\xfe', {'Content-Type': 'application/octet-stream'}
client = TestClient(app)
res = client.get('/bin')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'],
'application/octet-stream')
self.assertEqual(res.text, None)
self.assertEqual(res.json, None)
self.assertEqual(res.body, b'\xff\xfe')
def test_streaming(self):
app = Microdot()
@app.route('/')
def index(req):
def stream():
yield 'foo'
yield b'bar'
return stream()
client = TestClient(app)
res = client.get('/')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'foobar')
def test_mount(self):
subapp = Microdot()
@subapp.before_request
def before(req):
req.g.before = 'before'
@subapp.after_request
def after(req, res):
return res.body + b':after'
@subapp.errorhandler(404)
def not_found(req):
return '404', 404
@subapp.route('/app')
def index(req):
return req.g.before + ':foo'
app = Microdot()
app.mount(subapp, url_prefix='/sub')
client = TestClient(app)
res = client.get('/app')
self.assertEqual(res.status_code, 404)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, '404')
res = client.get('/sub/app')
self.assertEqual(res.status_code, 200)
self.assertEqual(res.headers['Content-Type'], 'text/plain')
self.assertEqual(res.text, 'before:foo:after')

View File

@@ -9,7 +9,7 @@ from microdot_asyncio import Microdot as MicrodotAsync, Request as RequestAsync
from microdot_utemplate import render_template, init_templates
from tests.mock_socket import get_request_fd, get_async_request_fd
init_templates('tests/microdot_utemplate/templates')
init_templates('tests/templates')
def _run(coro):
@@ -18,7 +18,7 @@ def _run(coro):
class TestUTemplate(unittest.TestCase):
def test_render_template(self):
s = list(render_template('hello.txt', name='foo'))
s = list(render_template('hello.utemplate.txt', name='foo'))
self.assertEqual(s, ['Hello, ', 'foo', '!\n'])
def test_render_template_in_app(self):
@@ -26,7 +26,7 @@ class TestUTemplate(unittest.TestCase):
@app.route('/')
def index(req):
return render_template('hello.txt', name='foo')
return render_template('hello.utemplate.txt', name='foo')
req = Request.create(app, get_request_fd('GET', '/'), 'addr')
res = app.dispatch_request(req)
@@ -38,7 +38,7 @@ class TestUTemplate(unittest.TestCase):
@app.route('/')
async def index(req):
return render_template('hello.txt', name='foo')
return render_template('hello.utemplate.txt', name='foo')
req = _run(RequestAsync.create(
app, get_async_request_fd('GET', '/'), 'addr'))