File: test_after_hooks.py

package info (click to toggle)
python-falcon 0.1.8-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 832 kB
  • ctags: 997
  • sloc: python: 4,006; makefile: 39; sh: 16
file content (150 lines) | stat: -rw-r--r-- 4,335 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import json

import falcon
import falcon.testing as testing


def validate_output(req, resp):
    raise falcon.HTTPError(falcon.HTTP_723, title=None)


def serialize_body(req, resp):
    body = resp.body
    if body is not None:
        resp.body = json.dumps(body)
    else:
        resp.body = 'Nothing to see here. Move along.'


def fluffiness(req, resp):
    resp.body = 'fluffy'


def cuteness(req, resp):
    if resp.body == 'fluffy':
        resp.body += ' and cute'


class WrappedRespondersResource(object):

    @falcon.after(serialize_body)
    @falcon.after(validate_output)
    def on_get(self, req, resp):
        self.req = req
        self.resp = resp

    @falcon.after(serialize_body)
    def on_put(self, req, resp):
        self.req = req
        self.resp = resp
        resp.body = {'animal': 'falcon'}


@falcon.after(cuteness)
@falcon.after(fluffiness)
class WrappedClassResource(object):

    # Test that the decorator skips non-callables
    on_post = False

    def __init__(self):
        # Test that the decorator skips non-callables
        self.on_patch = []

    def on_get(self, req, resp):
        self.req = req
        self.resp = resp

    def on_head(self, req, resp):
        self.req = req
        self.resp = resp


class ZooResource(object):

    def on_get(self, req, resp):
        self.resp = resp


class SingleResource(object):

    def on_options(self, req, resp):
        resp.status = falcon.HTTP_501


class TestHooks(testing.TestBase):

    def before(self):
        self.resource = WrappedRespondersResource()
        self.api.add_route(self.test_route, self.resource)

        self.wrapped_resource = WrappedClassResource()
        self.api.add_route('/wrapped', self.wrapped_resource)

    def test_global_hook(self):
        self.assertRaises(TypeError, falcon.API, None, {})
        self.assertRaises(TypeError, falcon.API, None, 0)

        self.api = falcon.API(after=fluffiness)
        zoo_resource = ZooResource()

        self.api.add_route(self.test_route, zoo_resource)

        self.simulate_request(self.test_route)
        self.assertEqual(b'fluffy', zoo_resource.resp.body_encoded)

        # hook does not affect the default on_options
        body = self.simulate_request(self.test_route, method='OPTIONS')
        self.assertEqual(falcon.HTTP_204, self.srmock.status)
        self.assertEqual([], body)

    def test_multiple_global_hook(self):
        self.api = falcon.API(after=[fluffiness, cuteness])
        zoo_resource = ZooResource()

        self.api.add_route(self.test_route, zoo_resource)

        self.simulate_request(self.test_route)
        self.assertEqual(b'fluffy and cute', zoo_resource.resp.body_encoded)

    def test_output_validator(self):
        self.simulate_request(self.test_route)
        self.assertEqual(falcon.HTTP_723, self.srmock.status)
        self.assertEqual(None, self.resource.resp.body_encoded)

    def test_serializer(self):
        self.simulate_request(self.test_route, method='PUT')

        actual_body = self.resource.resp.body_encoded
        self.assertEqual(b'{"animal": "falcon"}', actual_body)

    def test_wrapped_resource(self):
        expected = b'fluffy and cute'

        self.simulate_request('/wrapped')
        self.assertEqual(falcon.HTTP_200, self.srmock.status)
        self.assertEqual(expected, self.wrapped_resource.resp.body_encoded)

        self.simulate_request('/wrapped', method='HEAD')
        self.assertEqual(falcon.HTTP_200, self.srmock.status)

        self.simulate_request('/wrapped', method='POST')
        self.assertEqual(falcon.HTTP_405, self.srmock.status)

        self.simulate_request('/wrapped', method='PATCH')
        self.assertEqual(falcon.HTTP_405, self.srmock.status)

        # decorator does not affect the default on_options
        body = self.simulate_request('/wrapped', method='OPTIONS')
        self.assertEqual(falcon.HTTP_204, self.srmock.status)
        self.assertEqual([], body)

    def test_customized_options(self):
        self.api = falcon.API(after=fluffiness)

        self.api.add_route('/one', SingleResource())

        body = self.simulate_request('/one', method='OPTIONS')
        self.assertEqual(falcon.HTTP_501, self.srmock.status)
        self.assertEqual([b'fluffy'], body)
        self.assertNotIn('allow', self.srmock.headers_dict)