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