224 lines
5.6 KiB
Python
224 lines
5.6 KiB
Python
"""Application tests for URI templates using simulate_get().
|
|
|
|
These tests differ from those in test_default_router in that they are
|
|
a collection of sanity-checks that exercise the full framework code
|
|
path via simulate_get(), vs. probing the router directly.
|
|
"""
|
|
|
|
import pytest
|
|
import six
|
|
|
|
import falcon
|
|
from falcon import testing
|
|
|
|
|
|
class IDResource(object):
|
|
def __init__(self):
|
|
self.id = None
|
|
self.name = None
|
|
self.called = False
|
|
|
|
def on_get(self, req, resp, id):
|
|
self.id = id
|
|
self.called = True
|
|
self.req = req
|
|
|
|
|
|
class NameResource(object):
|
|
def __init__(self):
|
|
self.id = None
|
|
self.name = None
|
|
self.called = False
|
|
|
|
def on_get(self, req, resp, id, name):
|
|
self.id = id
|
|
self.name = name
|
|
self.called = True
|
|
|
|
|
|
class NameAndDigitResource(object):
|
|
def __init__(self):
|
|
self.id = None
|
|
self.name51 = None
|
|
self.called = False
|
|
|
|
def on_get(self, req, resp, id, name51):
|
|
self.id = id
|
|
self.name51 = name51
|
|
self.called = True
|
|
|
|
|
|
class FileResource(object):
|
|
def __init__(self):
|
|
self.file_id = None
|
|
self.called = False
|
|
|
|
def on_get(self, req, resp, file_id):
|
|
self.file_id = file_id
|
|
self.called = True
|
|
|
|
|
|
class FileDetailsResource(object):
|
|
def __init__(self):
|
|
self.file_id = None
|
|
self.ext = None
|
|
self.called = False
|
|
|
|
def on_get(self, req, resp, file_id, ext):
|
|
self.file_id = file_id
|
|
self.ext = ext
|
|
self.called = True
|
|
|
|
|
|
@pytest.fixture
|
|
def resource():
|
|
return testing.SimpleTestResource()
|
|
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
return testing.TestClient(falcon.API())
|
|
|
|
|
|
def test_root_path(client, resource):
|
|
client.app.add_route('/', resource)
|
|
client.simulate_get('/')
|
|
assert resource.called
|
|
|
|
|
|
def test_no_vars(client, resource):
|
|
client.app.add_route('/hello/world', resource)
|
|
client.simulate_get('/hello/world')
|
|
assert resource.called
|
|
|
|
|
|
@pytest.mark.skipif(six.PY3, reason='Test only applies to Python 2')
|
|
def test_unicode_literal_routes(client, resource):
|
|
client.app.add_route(u'/hello/world', resource)
|
|
client.simulate_get('/hello/world')
|
|
assert resource.called
|
|
|
|
|
|
def test_special_chars(client, resource):
|
|
client.app.add_route('/hello/world.json', resource)
|
|
client.app.add_route('/hello(world)', resource)
|
|
|
|
client.simulate_get('/hello/world_json')
|
|
assert not resource.called
|
|
|
|
client.simulate_get('/helloworld')
|
|
assert not resource.called
|
|
|
|
client.simulate_get('/hello/world.json')
|
|
assert resource.called
|
|
|
|
client.simulate_get('/hello(world)')
|
|
assert resource.called
|
|
|
|
|
|
@pytest.mark.parametrize('field_name', [
|
|
'id',
|
|
'id123',
|
|
'widget_id',
|
|
])
|
|
def test_single(client, resource, field_name):
|
|
template = '/widgets/{{{0}}}'.format(field_name)
|
|
|
|
client.app.add_route(template, resource)
|
|
|
|
client.simulate_get('/widgets/123')
|
|
assert resource.called
|
|
assert resource.captured_kwargs[field_name] == '123'
|
|
|
|
|
|
def test_single_trailing_slash(client):
|
|
resource1 = IDResource()
|
|
client.app.add_route('/1/{id}/', resource1)
|
|
result = client.simulate_get('/1/123')
|
|
assert result.status == falcon.HTTP_200
|
|
assert resource1.called
|
|
assert resource1.id == '123'
|
|
assert resource1.req.path == '/1/123'
|
|
|
|
resource2 = IDResource()
|
|
client.app.add_route('/2/{id}/', resource2)
|
|
result = client.simulate_get('/2/123/')
|
|
assert result.status == falcon.HTTP_200
|
|
assert resource2.called
|
|
assert resource2.id == '123'
|
|
assert resource2.req.path == '/2/123'
|
|
|
|
resource3 = IDResource()
|
|
client.app.add_route('/3/{id}', resource3)
|
|
result = client.simulate_get('/3/123/')
|
|
assert result.status == falcon.HTTP_200
|
|
assert resource3.called
|
|
assert resource3.id == '123'
|
|
assert resource3.req.path == '/3/123'
|
|
|
|
|
|
def test_multiple(client):
|
|
resource = NameResource()
|
|
client.app.add_route('/messages/{id}/names/{name}', resource)
|
|
|
|
test_id = 'bfb54d43-219b-4336-a623-6172f920592e'
|
|
test_name = '758e3922-dd6d-4007-a589-50fba0789365'
|
|
path = '/messages/' + test_id + '/names/' + test_name
|
|
client.simulate_get(path)
|
|
|
|
assert resource.called
|
|
assert resource.id == test_id
|
|
assert resource.name == test_name
|
|
|
|
|
|
@pytest.mark.parametrize('uri_template', [
|
|
'//',
|
|
'//begin',
|
|
'/end//',
|
|
'/in//side',
|
|
])
|
|
def test_empty_path_component(client, resource, uri_template):
|
|
with pytest.raises(ValueError):
|
|
client.app.add_route(uri_template, resource)
|
|
|
|
|
|
@pytest.mark.parametrize('uri_template', [
|
|
'',
|
|
'no',
|
|
'no/leading_slash',
|
|
])
|
|
def test_relative_path(client, resource, uri_template):
|
|
with pytest.raises(ValueError):
|
|
client.app.add_route(uri_template, resource)
|
|
|
|
|
|
@pytest.mark.parametrize('reverse', [True, False])
|
|
def test_same_level_complex_var(client, reverse):
|
|
file_resource = FileResource()
|
|
details_resource = FileDetailsResource()
|
|
|
|
routes = [
|
|
('/files/{file_id}', file_resource),
|
|
('/files/{file_id}.{ext}', details_resource)
|
|
]
|
|
if reverse:
|
|
routes.reverse()
|
|
|
|
for uri_template, resource in routes:
|
|
client.app.add_route(uri_template, resource)
|
|
|
|
file_id_1 = 'bc6b201d-b449-4290-a061-8eeb9f7b1450'
|
|
file_id_2 = '33b7f34c-6ee6-40e6-89a3-742a69b59de0'
|
|
ext = 'a4581b95-bc36-4c08-a3c2-23ba266abdf2'
|
|
path_1 = '/files/' + file_id_1
|
|
path_2 = '/files/' + file_id_2 + '.' + ext
|
|
|
|
client.simulate_get(path_1)
|
|
assert file_resource.called
|
|
assert file_resource.file_id == file_id_1
|
|
|
|
client.simulate_get(path_2)
|
|
assert details_resource.called
|
|
assert details_resource.file_id == file_id_2
|
|
assert details_resource.ext == ext
|