1import unittest
2from flask import Flask
3import flask_restful
4from werkzeug import exceptions
5
6
7
8class AcceptTestCase(unittest.TestCase):
9
10    def test_accept_default_application_json(self):
11
12        class Foo(flask_restful.Resource):
13            def get(self):
14                return "data"
15
16        app = Flask(__name__)
17        api = flask_restful.Api(app)
18
19        api.add_resource(Foo, '/')
20
21        with app.test_client() as client:
22            res = client.get('/', headers=[('Accept', 'application/json')])
23            self.assertEqual(res.status_code, 200)
24            self.assertEqual(res.content_type, 'application/json')
25
26
27    def test_accept_no_default_match_acceptable(self):
28
29        class Foo(flask_restful.Resource):
30            def get(self):
31                return "data"
32
33        app = Flask(__name__)
34        api = flask_restful.Api(app, default_mediatype=None)
35
36        api.add_resource(Foo, '/')
37
38        with app.test_client() as client:
39            res = client.get('/', headers=[('Accept', 'application/json')])
40            self.assertEqual(res.status_code, 200)
41            self.assertEqual(res.content_type, 'application/json')
42
43
44    def test_accept_default_override_accept(self):
45
46        class Foo(flask_restful.Resource):
47            def get(self):
48                return "data"
49
50        app = Flask(__name__)
51        api = flask_restful.Api(app)
52
53        api.add_resource(Foo, '/')
54
55        with app.test_client() as client:
56            res = client.get('/', headers=[('Accept', 'text/plain')])
57            self.assertEqual(res.status_code, 200)
58            self.assertEqual(res.content_type, 'application/json')
59
60
61    def test_accept_default_any_pick_first(self):
62
63        class Foo(flask_restful.Resource):
64            def get(self):
65                return "data"
66
67        app = Flask(__name__)
68        api = flask_restful.Api(app)
69
70        @api.representation('text/plain')
71        def text_rep(data, status_code, headers=None):
72            resp = app.make_response((str(data), status_code, headers))
73            return resp
74
75        api.add_resource(Foo, '/')
76
77        with app.test_client() as client:
78            res = client.get('/', headers=[('Accept', '*/*')])
79            self.assertEqual(res.status_code, 200)
80            self.assertEqual(res.content_type, 'application/json')
81
82
83    def test_accept_no_default_no_match_not_acceptable(self):
84
85        class Foo(flask_restful.Resource):
86            def get(self):
87                return "data"
88
89        app = Flask(__name__)
90        api = flask_restful.Api(app, default_mediatype=None)
91
92        api.add_resource(Foo, '/')
93
94        with app.test_client() as client:
95            res = client.get('/', headers=[('Accept', 'text/plain')])
96            self.assertEqual(res.status_code, 406)
97            self.assertEqual(res.content_type, 'application/json')
98
99
100    def test_accept_no_default_custom_repr_match(self):
101
102        class Foo(flask_restful.Resource):
103            def get(self):
104                return "data"
105
106        app = Flask(__name__)
107        api = flask_restful.Api(app, default_mediatype=None)
108        api.representations = {}
109
110        @api.representation('text/plain')
111        def text_rep(data, status_code, headers=None):
112            resp = app.make_response((str(data), status_code, headers))
113            return resp
114
115        api.add_resource(Foo, '/')
116
117        with app.test_client() as client:
118            res = client.get('/', headers=[('Accept', 'text/plain')])
119            self.assertEqual(res.status_code, 200)
120            self.assertEqual(res.content_type, 'text/plain')
121
122
123    def test_accept_no_default_custom_repr_not_acceptable(self):
124
125        class Foo(flask_restful.Resource):
126            def get(self):
127                return "data"
128
129        app = Flask(__name__)
130        api = flask_restful.Api(app, default_mediatype=None)
131        api.representations = {}
132
133        @api.representation('text/plain')
134        def text_rep(data, status_code, headers=None):
135            resp = app.make_response((str(data), status_code, headers))
136            return resp
137
138        api.add_resource(Foo, '/')
139
140        with app.test_client() as client:
141            res = client.get('/', headers=[('Accept', 'application/json')])
142            self.assertEqual(res.status_code, 406)
143            self.assertEqual(res.content_type, 'text/plain')
144
145
146    def test_accept_no_default_match_q0_not_acceptable(self):
147        """
148        q=0 should be considered NotAcceptable,
149        but this depends on werkzeug >= 1.0 which is not yet released
150        so this test is expected to fail until we depend on werkzeug >= 1.0
151        """
152        class Foo(flask_restful.Resource):
153            def get(self):
154                return "data"
155
156        app = Flask(__name__)
157        api = flask_restful.Api(app, default_mediatype=None)
158
159        api.add_resource(Foo, '/')
160
161        with app.test_client() as client:
162            res = client.get('/', headers=[('Accept', 'application/json; q=0')])
163            self.assertEqual(res.status_code, 406)
164            self.assertEqual(res.content_type, 'application/json')
165
166    def test_accept_no_default_accept_highest_quality_of_two(self):
167        class Foo(flask_restful.Resource):
168            def get(self):
169                return "data"
170
171        app = Flask(__name__)
172        api = flask_restful.Api(app, default_mediatype=None)
173
174        @api.representation('text/plain')
175        def text_rep(data, status_code, headers=None):
176            resp = app.make_response((str(data), status_code, headers))
177            return resp
178
179        api.add_resource(Foo, '/')
180
181        with app.test_client() as client:
182            res = client.get('/', headers=[('Accept', 'application/json; q=0.1, text/plain; q=1.0')])
183            self.assertEqual(res.status_code, 200)
184            self.assertEqual(res.content_type, 'text/plain')
185
186
187    def test_accept_no_default_accept_highest_quality_of_three(self):
188        class Foo(flask_restful.Resource):
189            def get(self):
190                return "data"
191
192        app = Flask(__name__)
193        api = flask_restful.Api(app, default_mediatype=None)
194
195        @api.representation('text/html')
196        @api.representation('text/plain')
197        def text_rep(data, status_code, headers=None):
198            resp = app.make_response((str(data), status_code, headers))
199            return resp
200
201        api.add_resource(Foo, '/')
202
203        with app.test_client() as client:
204            res = client.get('/', headers=[('Accept', 'application/json; q=0.1, text/plain; q=0.3, text/html; q=0.2')])
205            self.assertEqual(res.status_code, 200)
206            self.assertEqual(res.content_type, 'text/plain')
207
208
209    def test_accept_no_default_no_representations(self):
210
211        class Foo(flask_restful.Resource):
212            def get(self):
213                return "data"
214
215        app = Flask(__name__)
216        api = flask_restful.Api(app, default_mediatype=None)
217        api.representations = {}
218
219        api.add_resource(Foo, '/')
220
221        with app.test_client() as client:
222            res = client.get('/', headers=[('Accept', 'text/plain')])
223            self.assertEqual(res.status_code, 406)
224            self.assertEqual(res.content_type, 'text/plain')
225
226    def test_accept_invalid_default_no_representations(self):
227
228        class Foo(flask_restful.Resource):
229            def get(self):
230                return "data"
231
232        app = Flask(__name__)
233        api = flask_restful.Api(app, default_mediatype='nonexistant/mediatype')
234        api.representations = {}
235
236        api.add_resource(Foo, '/')
237
238        with app.test_client() as client:
239            res = client.get('/', headers=[('Accept', 'text/plain')])
240            self.assertEqual(res.status_code, 500)
241