1# -*- coding: utf-8 -*-
2import webapp2
3
4import test_base
5
6
7class NoStringOrUnicodeConversion(object):
8    pass
9
10
11class StringConversion(object):
12    def __str__(self):
13        return 'foo'.encode('utf-8')
14
15
16class UnicodeConversion(object):
17    def __unicode__(self):
18        return 'bar'.decode('utf-8')
19
20
21class TestResponse(test_base.BaseTestCase):
22    def test_write(self):
23        var_1 = NoStringOrUnicodeConversion()
24        var_2 = StringConversion()
25        var_3 = UnicodeConversion()
26
27        rsp = webapp2.Response()
28        rsp.write(var_1)
29        rsp.write(var_2)
30        rsp.write(var_3)
31        self.assertEqual(rsp.body, '%rfoobar' % var_1)
32
33        rsp = webapp2.Response()
34        rsp.write(var_1)
35        rsp.write(var_3)
36        rsp.write(var_2)
37        self.assertEqual(rsp.body, '%rbarfoo' % var_1)
38
39        rsp = webapp2.Response()
40        rsp.write(var_2)
41        rsp.write(var_1)
42        rsp.write(var_3)
43        self.assertEqual(rsp.body, 'foo%rbar' % var_1)
44
45        rsp = webapp2.Response()
46        rsp.write(var_2)
47        rsp.write(var_3)
48        rsp.write(var_1)
49        self.assertEqual(rsp.body, 'foobar%r' % var_1)
50
51        rsp = webapp2.Response()
52        rsp.write(var_3)
53        rsp.write(var_1)
54        rsp.write(var_2)
55        self.assertEqual(rsp.body, 'bar%rfoo' % var_1)
56
57        rsp = webapp2.Response()
58        rsp.write(var_3)
59        rsp.write(var_2)
60        rsp.write(var_1)
61        self.assertEqual(rsp.body, 'barfoo%r' % var_1)
62
63    def test_write2(self):
64        rsp = webapp2.Response()
65        rsp.charset = None
66        rsp.write(u'foo')
67
68        self.assertEqual(rsp.body, u'foo')
69        self.assertEqual(rsp.charset, 'utf-8')
70
71    def test_status(self):
72        rsp = webapp2.Response()
73
74        self.assertEqual(rsp.status, '200 OK')
75        self.assertEqual(rsp.status_int, 200)
76        self.assertEqual(rsp.status_message, 'OK')
77
78        rsp.status = u'200 OK'
79        self.assertEqual(rsp.status, '200 OK')
80        self.assertEqual(rsp.status_int, 200)
81        self.assertEqual(rsp.status_message, 'OK')
82
83        rsp.status_message = 'Weee'
84        self.assertEqual(rsp.status, '200 Weee')
85        self.assertEqual(rsp.status_int, 200)
86        self.assertEqual(rsp.status_message, 'Weee')
87
88        rsp.status = 404
89        self.assertEqual(rsp.status, '404 Not Found')
90        self.assertEqual(rsp.status_int, 404)
91        self.assertEqual(rsp.status_message, 'Not Found')
92
93        rsp.status = '403 Wooo'
94        self.assertEqual(rsp.status, '403 Wooo')
95        self.assertEqual(rsp.status_int, 403)
96        self.assertEqual(rsp.status_message, 'Wooo')
97
98        rsp.status_int = 500
99        self.assertEqual(rsp.status, '500 Internal Server Error')
100        self.assertEqual(rsp.status_int, 500)
101        self.assertEqual(rsp.status_message, 'Internal Server Error')
102
103        self.assertRaises(TypeError, rsp._set_status, ())
104
105    def test_has_error(self):
106        rsp = webapp2.Response()
107        self.assertFalse(rsp.has_error())
108        rsp.status = 400
109        self.assertTrue(rsp.has_error())
110        rsp.status = 404
111        self.assertTrue(rsp.has_error())
112        rsp.status = 500
113        self.assertTrue(rsp.has_error())
114        rsp.status = 200
115        self.assertFalse(rsp.has_error())
116        rsp.status = 302
117        self.assertFalse(rsp.has_error())
118
119    def test_wsgi_write(self):
120        res = []
121
122        def write(status, headers, body):
123            return res.extend([status, headers, body])
124
125        def start_response(status, headers):
126            return lambda body: write(status, headers, body)
127
128        rsp = webapp2.Response(body='Page not found!', status=404)
129        rsp.wsgi_write(start_response)
130
131        rsp = webapp2.Response(status=res[0], body=res[2], headers=res[1])
132        self.assertEqual(rsp.status, '404 Not Found')
133        self.assertEqual(rsp.body, 'Page not found!')
134
135        '''
136        # webob >= 1.0
137        self.assertEqual(res, [
138            '404 Not Found',
139            [
140                ('Content-Type', 'text/html; charset=utf-8'),
141                ('Cache-Control', 'no-cache'),
142                ('Expires', 'Fri, 01 Jan 1990 00:00:00 GMT'),
143                ('Content-Length', '15')
144            ],
145            'Page not found!'
146        ])
147        '''
148
149    def test_get_all(self):
150        rsp = webapp2.Response()
151        rsp.headers.add('Set-Cookie', 'foo=bar;')
152        rsp.headers.add('Set-Cookie', 'baz=ding;')
153
154        self.assertEqual(rsp.headers.get_all('set-cookie'),
155            ['foo=bar;', 'baz=ding;'])
156
157        rsp = webapp2.Response()
158        rsp.headers = {'Set-Cookie': 'foo=bar;'}
159        self.assertEqual(rsp.headers.get_all('set-cookie'), ['foo=bar;'])
160
161    def test_add_header(self):
162        rsp = webapp2.Response()
163        rsp.headers.add_header('Content-Disposition', 'attachment',
164            filename='bud.gif')
165        self.assertEqual(rsp.headers.get('content-disposition'),
166            'attachment; filename="bud.gif"')
167
168        rsp = webapp2.Response()
169        rsp.headers.add_header('Content-Disposition', 'attachment',
170            filename=None)
171        self.assertEqual(rsp.headers.get('content-disposition'),
172            'attachment; filename')
173
174        rsp = webapp2.Response()
175        rsp.headers.add_header('Set-Cookie', '', foo='')
176        self.assertEqual(rsp.headers.get_all('set-cookie'), ['; foo'])
177
178        rsp = webapp2.Response()
179        rsp.headers.add_header('Set-Cookie', '', foo=';')
180        self.assertEqual(rsp.headers.get_all('set-cookie'), ['; foo=";"'])
181
182    # Tests from Python source: wsgiref.headers.Headers
183    def test_headers_MappingInterface(self):
184        rsp = webapp2.Response()
185        test = [('x','y')]
186        self.assertEqual(len(rsp.headers), 3)
187        rsp.headers = test[:]
188        self.assertEqual(len(rsp.headers), 1)
189        self.assertEqual(rsp.headers.keys(), ['x'])
190        self.assertEqual(rsp.headers.values(), ['y'])
191        self.assertEqual(rsp.headers.items(), test)
192        rsp.headers = test
193        self.assertFalse(rsp.headers.items() is test)  # must be copy!
194
195        rsp = webapp2.Response()
196        h = rsp.headers
197        # this doesn't raise an error in wsgiref.headers.Headers
198        # del h['foo']
199
200        h['Foo'] = 'bar'
201        for m in h.has_key, h.__contains__, h.get, h.get_all, h.__getitem__:
202            self.assertTrue(m('foo'))
203            self.assertTrue(m('Foo'))
204            self.assertTrue(m('FOO'))
205            # this doesn't raise an error in wsgiref.headers.Headers
206            # self.assertFalse(m('bar'))
207
208        self.assertEqual(h['foo'],'bar')
209        h['foo'] = 'baz'
210        self.assertEqual(h['FOO'],'baz')
211        self.assertEqual(h.get_all('foo'),['baz'])
212
213        self.assertEqual(h.get("foo","whee"), "baz")
214        self.assertEqual(h.get("zoo","whee"), "whee")
215        self.assertEqual(h.setdefault("foo","whee"), "baz")
216        self.assertEqual(h.setdefault("zoo","whee"), "whee")
217        self.assertEqual(h["foo"],"baz")
218        self.assertEqual(h["zoo"],"whee")
219
220    def test_headers_RequireList(self):
221        def set_headers():
222            rsp = webapp2.Response()
223            rsp.headers = 'foo'
224            return rsp.headers
225
226        self.assertRaises(TypeError, set_headers)
227
228    def test_headers_Extras(self):
229        rsp = webapp2.Response()
230        rsp.headers = []
231        h = rsp.headers
232        self.assertEqual(str(h),'\r\n')
233
234        h.add_header('foo','bar',baz="spam")
235        self.assertEqual(h['foo'], 'bar; baz="spam"')
236        self.assertEqual(str(h),'foo: bar; baz="spam"\r\n\r\n')
237
238        h.add_header('Foo','bar',cheese=None)
239        self.assertEqual(h.get_all('foo'),
240            ['bar; baz="spam"', 'bar; cheese'])
241
242        self.assertEqual(str(h),
243            'foo: bar; baz="spam"\r\n'
244            'Foo: bar; cheese\r\n'
245            '\r\n'
246        )
247
248
249class TestReturnResponse(test_base.BaseTestCase):
250    def test_function_that_returns_response(self):
251        def myfunction(request, *args, **kwargs):
252            return webapp2.Response('Hello, custom response world!')
253
254        app = webapp2.WSGIApplication([
255            ('/', myfunction),
256        ])
257
258        req = webapp2.Request.blank('/')
259        rsp = req.get_response(app)
260        self.assertEqual(rsp.status_int, 200)
261        self.assertEqual(rsp.body, 'Hello, custom response world!')
262
263    def test_function_that_returns_string(self):
264        def myfunction(request, *args, **kwargs):
265            return 'Hello, custom response world!'
266
267        app = webapp2.WSGIApplication([
268            ('/', myfunction),
269        ])
270
271        def custom_dispatcher(router, request, response):
272            response_str = router.default_dispatcher(request, response)
273            return request.app.response_class(response_str)
274
275        app.router.set_dispatcher(custom_dispatcher)
276
277        req = webapp2.Request.blank('/')
278        rsp = req.get_response(app)
279        self.assertEqual(rsp.status_int, 200)
280        self.assertEqual(rsp.body, 'Hello, custom response world!')
281
282    def test_function_that_returns_tuple(self):
283        def myfunction(request, *args, **kwargs):
284            return 'Hello, custom response world!', 404
285
286        app = webapp2.WSGIApplication([
287            ('/', myfunction),
288        ])
289
290        def custom_dispatcher(router, request, response):
291            response_tuple = router.default_dispatcher(request, response)
292            return request.app.response_class(*response_tuple)
293
294        app.router.set_dispatcher(custom_dispatcher)
295
296        req = webapp2.Request.blank('/')
297        rsp = req.get_response(app)
298        self.assertEqual(rsp.status_int, 404)
299        self.assertEqual(rsp.body, 'Hello, custom response world!')
300
301    def test_handle_exception_that_returns_response(self):
302        class HomeHandler(webapp2.RequestHandler):
303            def get(self, **kwargs):
304                raise TypeError()
305
306        app = webapp2.WSGIApplication([
307            webapp2.Route('/', HomeHandler, name='home'),
308        ])
309        app.error_handlers[500] = 'resources.handlers.handle_exception'
310
311        req = webapp2.Request.blank('/')
312        rsp = req.get_response(app)
313        self.assertEqual(rsp.status_int, 200)
314        self.assertEqual(rsp.body, 'Hello, custom response world!')
315
316    def test_return_is_not_wsgi_app(self):
317        class HomeHandler(webapp2.RequestHandler):
318            def get(self, **kwargs):
319                return ''
320
321        app = webapp2.WSGIApplication([
322            webapp2.Route('/', HomeHandler, name='home'),
323        ], debug=False)
324
325        req = webapp2.Request.blank('/')
326        rsp = req.get_response(app)
327        self.assertEqual(rsp.status_int, 500)
328
329
330if __name__ == '__main__':
331    test_base.main()
332