1import pytest
2
3import falcon
4from falcon import testing
5
6
7def test_custom_router_add_route_should_be_used():
8    check = []
9
10    class CustomRouter(object):
11        def add_route(self, uri_template, *args, **kwargs):
12            check.append(uri_template)
13
14        def find(self, uri):
15            pass
16
17    app = falcon.API(router=CustomRouter())
18    app.add_route('/test', 'resource')
19
20    assert len(check) == 1
21    assert '/test' in check
22
23
24def test_custom_router_find_should_be_used():
25
26    def resource(req, resp, **kwargs):
27        resp.body = '{{"uri_template": "{0}"}}'.format(req.uri_template)
28
29    class CustomRouter(object):
30        def __init__(self):
31            self.reached_backwards_compat = False
32
33        def find(self, uri, req=None):
34            if uri == '/test/42':
35                return resource, {'GET': resource}, {}, '/test/{id}'
36
37            if uri == '/test/42/no-uri-template':
38                return resource, {'GET': resource}, {}, None
39
40            if uri == '/test/42/uri-template/backwards-compat':
41                return resource, {'GET': resource}, {}
42
43            if uri == '/404/backwards-compat':
44                self.reached_backwards_compat = True
45                return (None, None, None)
46
47            return None
48
49    router = CustomRouter()
50    app = falcon.API(router=router)
51    client = testing.TestClient(app)
52
53    response = client.simulate_request(path='/test/42')
54    assert response.content == b'{"uri_template": "/test/{id}"}'
55
56    response = client.simulate_request(path='/test/42/no-uri-template')
57    assert response.content == b'{"uri_template": "None"}'
58
59    response = client.simulate_request(path='/test/42/uri-template/backwards-compat')
60    assert response.content == b'{"uri_template": "None"}'
61
62    for uri in ('/404', '/404/backwards-compat'):
63        response = client.simulate_request(path=uri)
64        assert not response.content
65        assert response.status == falcon.HTTP_404
66
67    assert router.reached_backwards_compat
68
69
70def test_can_pass_additional_params_to_add_route():
71
72    check = []
73
74    class CustomRouter(object):
75        def add_route(self, uri_template, resource, **kwargs):
76            name = kwargs['name']
77            self._index = {name: uri_template}
78            check.append(name)
79
80        def find(self, uri):
81            pass
82
83    app = falcon.API(router=CustomRouter())
84    app.add_route('/test', 'resource', name='my-url-name')
85
86    assert len(check) == 1
87    assert 'my-url-name' in check
88
89    # NOTE(kgriffs): Extra values must be passed as kwargs, since that makes
90    #   it a lot easier for overriden methods to simply ignore options they
91    #   don't care about.
92    with pytest.raises(TypeError):
93        app.add_route('/test', 'resource', 'xarg1', 'xarg2')
94
95
96def test_custom_router_takes_req_positional_argument():
97    def responder(req, resp):
98        resp.body = 'OK'
99
100    class CustomRouter(object):
101        def find(self, uri, req):
102            if uri == '/test' and isinstance(req, falcon.Request):
103                return responder, {'GET': responder}, {}, None
104
105    router = CustomRouter()
106    app = falcon.API(router=router)
107    client = testing.TestClient(app)
108    response = client.simulate_request(path='/test')
109    assert response.content == b'OK'
110
111
112def test_custom_router_takes_req_keyword_argument():
113    def responder(req, resp):
114        resp.body = 'OK'
115
116    class CustomRouter(object):
117        def find(self, uri, req=None):
118            if uri == '/test' and isinstance(req, falcon.Request):
119                return responder, {'GET': responder}, {}, None
120
121    router = CustomRouter()
122    app = falcon.API(router=router)
123    client = testing.TestClient(app)
124    response = client.simulate_request(path='/test')
125    assert response.content == b'OK'
126