Skip to content

Commit 7c69f9a

Browse files
author
Mathieu Mitchell
committed
Handle non-trailing-slash routes as well
The "official" spec doesn't specify how to behave on a multiple-module endpoint like this one. Follow the least surprise principle and make both work.
1 parent 0b98a29 commit 7c69f9a

2 files changed

Lines changed: 15 additions & 7 deletions

File tree

tests/test_api.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@ def setUp(self):
3333

3434
self.api = Api(self.modules, self.app, self.router)
3535

36+
def generate_module_path(self, module_name):
37+
return '/{0}/'.format(module_name)
38+
3639
def test_list_implemented_methods(self):
3740
self.router.list_implemented_methods.return_value = ['abcd', 'efgh']
3841

39-
output = self.api_client.get('/module1/')
42+
output = self.api_client.get(self.generate_module_path('module1'))
4043
self.router.list_implemented_methods.assert_called_with(self.module1)
4144

4245
assert_that(json.loads(output.data.decode(output.charset)), is_({
@@ -48,7 +51,7 @@ def test_list_implemented_methods(self):
4851

4952
def test_execute_method_returns_string(self):
5053
self.router.invoke_method.return_value = 'simple string'
51-
output = self.api_client.post('/module2/',
54+
output = self.api_client.post(self.generate_module_path('module2'),
5255
headers={'Content-Type': 'application/json'},
5356
data=json.dumps(
5457
{
@@ -66,7 +69,7 @@ def test_execute_method_returns_string(self):
6669

6770
def test_execute_method_returns_list(self):
6871
self.router.invoke_method.return_value = ['a', 'b', 'c']
69-
output = self.api_client.post('/module2/',
72+
output = self.api_client.post(self.generate_module_path('module2'),
7073
headers={'Content-Type': 'application/json'},
7174
data=json.dumps(
7275
{
@@ -83,7 +86,7 @@ def test_execute_method_returns_list(self):
8386
assert_that(json.loads(output.data.decode(output.charset)), is_(['a', 'b', 'c']))
8487

8588
def test_invoking_unknown_module_returns_a_404(self):
86-
output = self.api_client.post('/new_module/',
89+
output = self.api_client.post(self.generate_module_path('new_module'),
8790
headers={'Content-Type': 'application/json'},
8891
data=json.dumps(
8992
{
@@ -99,6 +102,10 @@ def test_invoking_unknown_module_returns_a_404(self):
99102
assert_that(output.status_code, is_(404))
100103

101104
def test_listing_unknown_module_returns_a_404(self):
102-
output = self.api_client.get('/new_module/')
105+
output = self.api_client.get(self.generate_module_path('new_module'))
103106

104107
assert_that(output.status_code, is_(404))
108+
109+
class NoTrailingSlashApiTest(ApiTest):
110+
def generate_module_path(self, module_name):
111+
return '/{0}'.format(module_name)

ubersmith_remote_module_server/api.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ class Api(object):
2121
def __init__(self, modules, app, router):
2222
self.app = app
2323
self.router = router
24+
self.app.url_map.strict_slashes = False
2425

2526
for module_name, module in modules.items():
2627
list_endpoint = functools.partial(self.list_implemented_methods, module)
2728
list_endpoint.__name__ = "list_" + module_name
28-
app.add_url_rule('/{}/'.format(module_name), view_func=list_endpoint, methods=['GET'])
29+
app.add_url_rule('/{}'.format(module_name), view_func=list_endpoint, methods=['GET'])
2930

3031
handle_endpoint = functools.partial(self.handle_remote_invocation, module)
3132
handle_endpoint.__name__ = "handle_" + module_name
32-
app.add_url_rule('/{}/'.format(module_name), view_func=handle_endpoint, methods=['POST'])
33+
app.add_url_rule('/{}'.format(module_name), view_func=handle_endpoint, methods=['POST'])
3334

3435
def list_implemented_methods(self, module):
3536
methods = self.router.list_implemented_methods(module)

0 commit comments

Comments
 (0)