Fix a bug in default file not found handler, make creating Requests less painful...
[fwx] / src / test_fwx.py
1 import unittest
2 from unittest import mock
3
4 import fwx
5
6 class RequestTests(unittest.TestCase):
7     def test_GET(self):
8         request = fwx.Request('GET', '/', {
9             'QUERY_STRING': 'foo=bar&baz=qux',
10         })
11
12         self.assertEqual(request.GET['foo'], ['bar'])
13         self.assertEqual(request.GET['baz'], ['qux'])
14
15     def test_parameters(self):
16         request = fwx.Request('GET', '/', {
17             'QUERY_STRING': 'foo=bar&baz=qux',
18         })
19
20         self.assertEqual(request.parameters['foo'], ['bar'])
21         self.assertEqual(request.parameters['baz'], ['qux'])
22
23 class ResponseTests(unittest.TestCase):
24     def test_content_can_be_positional_argument(self):
25         response = fwx.Response('Hello, world\n', content_type='text/plain')
26
27         self.assertEqual(response.content, 'Hello, world\n')
28
29     def test_content_can_be_keyword_argument(self):
30         response = fwx.Response(content='Hello, world\n', content_type='text/plain')
31
32         self.assertEqual(response.content, 'Hello, world\n')
33
34     def test_status_defaults_to_200(self):
35         response = fwx.Response(
36             content_type='text/plain',
37             content='Hello, world\n',
38         )
39
40         self.assertEqual(response.status, 200)
41
42     def test_headers(self):
43         response = fwx.Response(
44             content_type='text/plain',
45             content='Hello, world\n',
46         )
47
48         self.assertEqual(
49             response.headers,
50             (
51                 ('Content-Type', 'text/plain'),
52             ),
53         )
54
55 class HTMLResponseTests(unittest.TestCase):
56     def test_sets_content_type(self):
57         response = fwx.HTMLResponse('<html><body>Hello, world</body></html>')
58         self.assertEqual(response.content_type, 'text/html')
59
60 class JSONResponseTests(unittest.TestCase):
61     def test_sets_content_type(self):
62         response = fwx.JSONResponse({ 'foo': 'bar', 'baz': 42 })
63         self.assertEqual(response.content_type, 'application/json')
64
65     def test_sets_content(self):
66         response = fwx.JSONResponse({ 'foo': 'bar', 'baz': 42 })
67         self.assertEqual(response.content, '{"foo": "bar", "baz": 42}')
68
69     def test_sets_content_json(self):
70         response = fwx.JSONResponse({ 'foo': 'bar', 'baz': 42 })
71         self.assertEqual(response.content_json, {"foo": "bar", "baz": 42})
72
73 class TextResponseTests(unittest.TestCase):
74     def test_sets_content_type(self):
75         response = fwx.TextResponse('Hello, world\n')
76         self.assertEqual(response.content_type, 'text/plain')
77
78 class RedirectResponse(unittest.TestCase):
79     def test_takes_location_as_positional_argument(self):
80         response = fwx.RedirectResponse('/location')
81         self.assertEqual(response.location, '/location')
82
83     def test_takes_location_as_keyword_argument(self):
84         response = fwx.RedirectResponse(location='/location')
85         self.assertEqual(response.location, '/location')
86
87     def test_permanent_defaults_to_true(self):
88         response = fwx.RedirectResponse('/location')
89         self.assertEqual(response.permanent, True)
90
91     def test_status(self):
92         self.assertEqual(
93             fwx.RedirectResponse('/location', permanent=True).status,
94             308,
95         )
96         self.assertEqual(
97             fwx.RedirectResponse('/location', permanent=False).status,
98             307,
99         )
100
101     def test_headers(self):
102         self.assertEqual(
103             fwx.RedirectResponse('/location').headers,
104             (('Location','/location'),),
105         )
106
107     def test_content(self):
108         self.assertEqual(
109             fwx.RedirectResponse('/location').content,
110             (b'',),
111         )
112
113 class _get_status_Tests(unittest.TestCase):
114     def test_basic(self):
115         self.assertEqual(fwx._get_status(mock.MagicMock(status=200)), '200 OK')
116         self.assertEqual(fwx._get_status(mock.MagicMock(status=307)), '307 Temporary Redirect')
117         self.assertEqual(fwx._get_status(mock.MagicMock(status=308)), '308 Permanent Redirect')
118
119 class _get_content_Tests(unittest.TestCase):
120     def test_bytes(self):
121         self.assertEqual(
122             fwx._get_content(mock.MagicMock(content=b'Hello, world\n')),
123             (b'Hello, world\n',),
124         )
125
126     def test_str(self):
127         self.assertEqual(
128             fwx._get_content(mock.MagicMock(content='Hello, world\n')),
129             (b'Hello, world\n',),
130         )
131
132 class route_on_subpath_Tests(unittest.TestCase):
133     def test_routes(self):
134         router = fwx.route_on_subpath(
135             routes={
136                 'foo': lambda request: fwx.TextResponse('foo'),
137                 'bar': lambda request: fwx.TextResponse('bar'),
138                 'baz': lambda request: fwx.TextResponse('baz'),
139             },
140         )
141
142         self.assertEqual(
143             router(fwx.Request('GET', '/bar/bara/anne/')).content,
144             'bar',
145         )
146
147     def test_resets_subpath(self):
148         router = fwx.route_on_subpath(
149             routes={
150                 'foo': lambda request: fwx.TextResponse('foo'),
151                 'bar': lambda request: fwx.TextResponse(request.subpath),
152                 'baz': lambda request: fwx.TextResponse('baz'),
153             },
154         )
155
156         self.assertEqual(
157             router(fwx.Request('GET', '/bar/bara/anne/')).content,
158             'bara/anne/',
159         )
160
161     def test_leaves_path_intact(self):
162         router = fwx.route_on_subpath(
163             routes={
164                 'foo': lambda request: fwx.TextResponse('foo'),
165                 'bar': lambda request: fwx.TextResponse(request.path),
166                 'baz': lambda request: fwx.TextResponse('baz'),
167             },
168         )
169
170         self.assertEqual(
171             router(fwx.Request('GET', '/bar/bara/anne/')).content,
172             '/bar/bara/anne/',
173         )
174
175 class default_file_not_found_Tests(unittest.TestCase):
176     def test_responds(self):
177         response = fwx.default_file_not_found_handler(
178             fwx.Request('GET', '/bar/bara/anne/'),
179         )
180
181         self.assertNotEqual(response, None)
182
183 if __name__ == '__main__':
184     unittest.main()