1# -*- coding: utf-8 -*-
2import webapp2
3
4from webapp2_extras.routes import (DomainRoute, HandlerPrefixRoute,
5    RedirectRoute, NamePrefixRoute, PathPrefixRoute)
6
7import test_base
8
9
10class HomeHandler(webapp2.RequestHandler):
11    def get(self, **kwargs):
12        self.response.out.write('home sweet home')
13
14
15app = webapp2.WSGIApplication([
16    #RedirectRoute('/', name='home', handler=HomeHandler),
17    RedirectRoute('/redirect-me-easily', redirect_to='/i-was-redirected-easily'),
18    RedirectRoute('/redirect-me-easily2', redirect_to='/i-was-redirected-easily', defaults={'_code': 302}),
19    RedirectRoute('/redirect-me-easily3', redirect_to='/i-was-redirected-easily', defaults={'_permanent': False}),
20    RedirectRoute('/strict-foo', HomeHandler, 'foo-strict', strict_slash=True),
21    RedirectRoute('/strict-bar/', HomeHandler, 'bar-strict', strict_slash=True),
22    RedirectRoute('/redirect-to-name-destination', name='redirect-to-name-destination', handler=HomeHandler),
23    RedirectRoute('/redirect-to-name', redirect_to_name='redirect-to-name-destination'),
24])
25
26
27class TestRedirectRoute(test_base.BaseTestCase):
28    def test_route_redirect_to(self):
29        route = RedirectRoute('/foo', redirect_to='/bar')
30        router = webapp2.Router([route])
31        route_match, args, kwargs = router.match(webapp2.Request.blank('/foo'))
32        self.assertEqual(route_match, route)
33        self.assertEqual(args, ())
34        self.assertEqual(kwargs, {'_uri': '/bar'})
35
36    def test_easy_redirect_to(self):
37        req = webapp2.Request.blank('/redirect-me-easily')
38        rsp = req.get_response(app)
39        self.assertEqual(rsp.status_int, 301)
40        self.assertEqual(rsp.body, '')
41        self.assertEqual(rsp.headers['Location'], 'http://localhost/i-was-redirected-easily')
42
43        req = webapp2.Request.blank('/redirect-me-easily2')
44        rsp = req.get_response(app)
45        self.assertEqual(rsp.status_int, 302)
46        self.assertEqual(rsp.body, '')
47        self.assertEqual(rsp.headers['Location'], 'http://localhost/i-was-redirected-easily')
48
49        req = webapp2.Request.blank('/redirect-me-easily3')
50        rsp = req.get_response(app)
51        self.assertEqual(rsp.status_int, 302)
52        self.assertEqual(rsp.body, '')
53        self.assertEqual(rsp.headers['Location'], 'http://localhost/i-was-redirected-easily')
54
55    def test_redirect_to_name(self):
56        req = webapp2.Request.blank('/redirect-to-name')
57        rsp = req.get_response(app)
58        self.assertEqual(rsp.status_int, 301)
59        self.assertEqual(rsp.body, '')
60        self.assertEqual(rsp.headers['Location'], 'http://localhost/redirect-to-name-destination')
61
62    def test_strict_slash(self):
63        req = webapp2.Request.blank('/strict-foo')
64        rsp = req.get_response(app)
65        self.assertEqual(rsp.status_int, 200)
66        self.assertEqual(rsp.body, 'home sweet home')
67
68        req = webapp2.Request.blank('/strict-bar/')
69        rsp = req.get_response(app)
70        self.assertEqual(rsp.status_int, 200)
71        self.assertEqual(rsp.body, 'home sweet home')
72
73        # Now the non-strict...
74
75        req = webapp2.Request.blank('/strict-foo/')
76        rsp = req.get_response(app)
77        self.assertEqual(rsp.status_int, 301)
78        self.assertEqual(rsp.body, '')
79        self.assertEqual(rsp.headers['Location'], 'http://localhost/strict-foo')
80
81        req = webapp2.Request.blank('/strict-bar')
82        rsp = req.get_response(app)
83        self.assertEqual(rsp.status_int, 301)
84        self.assertEqual(rsp.body, '')
85        self.assertEqual(rsp.headers['Location'], 'http://localhost/strict-bar/')
86
87        # Strict slash routes must have a name.
88
89        self.assertRaises(ValueError, RedirectRoute, '/strict-bar/', handler=HomeHandler, strict_slash=True)
90
91    def test_build_only(self):
92        self.assertRaises(ValueError, RedirectRoute, '/', handler=HomeHandler, build_only=True)
93
94
95class TestPrefixRoutes(test_base.BaseTestCase):
96    def test_simple(self):
97        router = webapp2.Router([
98            PathPrefixRoute('/a', [
99                webapp2.Route('/', 'a', 'name-a'),
100                webapp2.Route('/b', 'a/b', 'name-a/b'),
101                webapp2.Route('/c', 'a/c', 'name-a/c'),
102                PathPrefixRoute('/d', [
103                    webapp2.Route('/', 'a/d', 'name-a/d'),
104                    webapp2.Route('/b', 'a/d/b', 'name-a/d/b'),
105                    webapp2.Route('/c', 'a/d/c', 'name-a/d/c'),
106                ]),
107            ])
108        ])
109
110        path = '/a/'
111        match = ((), {})
112        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
113        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a', match[0], match[1]), path)
114
115        path = '/a/b'
116        match = ((), {})
117        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
118        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a/b', match[0], match[1]), path)
119
120        path = '/a/c'
121        match = ((), {})
122        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
123        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a/c', match[0], match[1]), path)
124
125        path = '/a/d/'
126        match = ((), {})
127        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
128        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a/d', match[0], match[1]), path)
129
130        path = '/a/d/b'
131        match = ((), {})
132        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
133        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a/d/b', match[0], match[1]), path)
134
135        path = '/a/d/c'
136        match = ((), {})
137        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
138        self.assertEqual(router.build(webapp2.Request.blank('/'), 'name-a/d/c', match[0], match[1]), path)
139
140    def test_with_variables_name_and_handler(self):
141        router = webapp2.Router([
142            PathPrefixRoute('/user/<username:\w+>', [
143                HandlerPrefixRoute('apps.users.', [
144                    NamePrefixRoute('user-', [
145                        webapp2.Route('/', 'UserOverviewHandler', 'overview'),
146                        webapp2.Route('/profile', 'UserProfileHandler', 'profile'),
147                        webapp2.Route('/projects', 'UserProjectsHandler', 'projects'),
148                    ]),
149                ]),
150            ])
151        ])
152
153        path = '/user/calvin/'
154        match = ((), {'username': 'calvin'})
155        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
156        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-overview', match[0], match[1]), path)
157
158        path = '/user/calvin/profile'
159        match = ((), {'username': 'calvin'})
160        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
161        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-profile', match[0], match[1]), path)
162
163        path = '/user/calvin/projects'
164        match = ((), {'username': 'calvin'})
165        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
166        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-projects', match[0], match[1]), path)
167
168
169class TestDomainRoute(test_base.BaseTestCase):
170    def test_simple(self):
171        router = webapp2.Router([
172            DomainRoute('<subdomain>.<:.*>', [
173                webapp2.Route('/foo', 'FooHandler', 'subdomain-thingie'),
174            ])
175        ])
176
177        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank('/foo'))
178
179        match = router.match(webapp2.Request.blank('http://my-subdomain.app-id.appspot.com/foo'))
180        self.assertEqual(match[1:], ((), {'subdomain': 'my-subdomain'}))
181
182        match = router.match(webapp2.Request.blank('http://another-subdomain.app-id.appspot.com/foo'))
183        self.assertEqual(match[1:], ((), {'subdomain': 'another-subdomain'}))
184
185        url = router.build(webapp2.Request.blank('/'), 'subdomain-thingie', (), {'_netloc': 'another-subdomain.app-id.appspot.com'})
186        self.assertEqual(url, 'http://another-subdomain.app-id.appspot.com/foo')
187
188    def test_with_variables_name_and_handler(self):
189        router = webapp2.Router([
190            DomainRoute('<subdomain>.<:.*>', [
191                PathPrefixRoute('/user/<username:\w+>', [
192                    HandlerPrefixRoute('apps.users.', [
193                        NamePrefixRoute('user-', [
194                            webapp2.Route('/', 'UserOverviewHandler', 'overview'),
195                            webapp2.Route('/profile', 'UserProfileHandler', 'profile'),
196                            webapp2.Route('/projects', 'UserProjectsHandler', 'projects'),
197                        ]),
198                    ]),
199                ])
200            ]),
201        ])
202
203        path = 'http://my-subdomain.app-id.appspot.com/user/calvin/'
204        match = ((), {'username': 'calvin', 'subdomain': 'my-subdomain'})
205        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
206        match[1].pop('subdomain')
207        match[1]['_netloc'] = 'my-subdomain.app-id.appspot.com'
208        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-overview', match[0], match[1]), path)
209
210        path = 'http://my-subdomain.app-id.appspot.com/user/calvin/profile'
211        match = ((), {'username': 'calvin', 'subdomain': 'my-subdomain'})
212        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
213        match[1].pop('subdomain')
214        match[1]['_netloc'] = 'my-subdomain.app-id.appspot.com'
215        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-profile', match[0], match[1]), path)
216
217        path = 'http://my-subdomain.app-id.appspot.com/user/calvin/projects'
218        match = ((), {'username': 'calvin', 'subdomain': 'my-subdomain'})
219        self.assertEqual(router.match(webapp2.Request.blank(path))[1:], match)
220        match[1].pop('subdomain')
221        match[1]['_netloc'] = 'my-subdomain.app-id.appspot.com'
222        self.assertEqual(router.build(webapp2.Request.blank('/'), 'user-projects', match[0], match[1]), path)
223
224    def test_guide_examples(self):
225        router = webapp2.Router([
226            DomainRoute(r'www.mydomain.com', [
227                webapp2.Route('/path1', 'Path1', 'path1'),
228            ]),
229            DomainRoute(r'<subdomain:(?!www\.)[^.]+>.mydomain.com', [
230                webapp2.Route('/path2', 'Path2', 'path2'),
231            ]),
232            DomainRoute(r'<:(app-id\.appspot\.com|www\.mydomain\.com)>', [
233                webapp2.Route('/path3', 'Path3', 'path3'),
234            ]),
235            DomainRoute(r'<subdomain:(?!www)[^.]+>.<:(app-id\.appspot\.com|mydomain\.com)>', [
236                webapp2.Route('/path4', 'Path4', 'path4'),
237            ]),
238        ])
239
240        uri1a = 'http://www.mydomain.com/path1'
241        uri1b = 'http://sub.mydomain.com/path1'
242        uri1c = 'http://www.mydomain.com/invalid-path'
243
244        uri2a = 'http://sub.mydomain.com/path2'
245        uri2b = 'http://www.mydomain.com/path2'
246        uri2c = 'http://sub.mydomain.com/invalid-path'
247        uri2d = 'http://www.mydomain.com/invalid-path'
248
249        uri3a = 'http://app-id.appspot.com/path3'
250        uri3b = 'http://www.mydomain.com/path3'
251        uri3c = 'http://sub.app-id.appspot.com/path3'
252        uri3d = 'http://sub.mydomain.com/path3'
253        uri3e = 'http://app-id.appspot.com/invalid-path'
254        uri3f = 'http://www.mydomain.com/invalid-path'
255
256        uri4a = 'http://sub.app-id.appspot.com/path4'
257        uri4b = 'http://sub.mydomain.com/path4'
258        uri4c = 'http://app-id.appspot.com/path4'
259        uri4d = 'http://www.app-id.appspot.com/path4'
260        uri4e = 'http://www.mydomain.com/path4'
261        uri4f = 'http://sub.app-id.appspot.com/invalid-path'
262        uri4g = 'http://sub.mydomain.com/invalid-path'
263
264        self.assertEqual(router.match(webapp2.Request.blank(uri1a))[1:], ((), {}))
265        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri1b))
266        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri1c))
267
268        self.assertEqual(router.match(webapp2.Request.blank(uri2a))[1:], ((), {'subdomain': 'sub'}))
269        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri2b))
270        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri2c))
271        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri2d))
272
273        self.assertEqual(router.match(webapp2.Request.blank(uri3a))[1:], ((), {}))
274        self.assertEqual(router.match(webapp2.Request.blank(uri3b))[1:], ((), {}))
275        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri3c))
276        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri3d))
277        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri3e))
278        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri3f))
279
280        self.assertEqual(router.match(webapp2.Request.blank(uri4a))[1:], ((), {'subdomain': 'sub'}))
281        self.assertEqual(router.match(webapp2.Request.blank(uri4b))[1:], ((), {'subdomain': 'sub'}))
282        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri4c))
283        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri4d))
284        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri4e))
285        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri4f))
286        self.assertRaises(webapp2.exc.HTTPNotFound, router.match, webapp2.Request.blank(uri4g))
287
288if __name__ == '__main__':
289    test_base.main()