1 from cherrypy.test import test
2 from cherrypy._cptree import Application
3 test.prefer_parent_path()
4
5 import cherrypy
6
7
8 script_names = ["", "/foo", "/users/fred/blog", "/corp/blog"]
9
11 class Root:
12 def index(self, name="world"):
13 return name
14 index.exposed = True
15
16 def foobar(self):
17 return "bar"
18 foobar.exposed = True
19
20 def default(self, *params):
21 return "default:" + repr(params)
22 default.exposed = True
23
24 def other(self):
25 return "other"
26 other.exposed = True
27
28 def extra(self, *p):
29 return repr(p)
30 extra.exposed = True
31
32 def redirect(self):
33 raise cherrypy.HTTPRedirect('dir1/', 302)
34 redirect.exposed = True
35
36 def notExposed(self):
37 return "not exposed"
38
39 def confvalue(self):
40 return cherrypy.request.config.get("user")
41 confvalue.exposed = True
42
43 def mapped_func(self, ID=None):
44 return "ID is %s" % ID
45 mapped_func.exposed = True
46 setattr(Root, "Von B\xfclow", mapped_func)
47
48
49 class Exposing:
50 def base(self):
51 return "expose works!"
52 cherrypy.expose(base)
53 cherrypy.expose(base, "1")
54 cherrypy.expose(base, "2")
55
56 class ExposingNewStyle(object):
57 def base(self):
58 return "expose works!"
59 cherrypy.expose(base)
60 cherrypy.expose(base, "1")
61 cherrypy.expose(base, "2")
62
63
64 class Dir1:
65 def index(self):
66 return "index for dir1"
67 index.exposed = True
68
69 def myMethod(self):
70 return "myMethod from dir1, path_info is:" + repr(cherrypy.request.path_info)
71 myMethod.exposed = True
72 myMethod._cp_config = {'tools.trailing_slash.extra': True}
73
74 def default(self, *params):
75 return "default for dir1, param is:" + repr(params)
76 default.exposed = True
77
78
79 class Dir2:
80 def index(self):
81 return "index for dir2, path is:" + cherrypy.request.path_info
82 index.exposed = True
83
84 def script_name(self):
85 return cherrypy.tree.script_name()
86 script_name.exposed = True
87
88 def cherrypy_url(self):
89 return cherrypy.url("/extra")
90 cherrypy_url.exposed = True
91
92 def posparam(self, *vpath):
93 return "/".join(vpath)
94 posparam.exposed = True
95
96
97 class Dir3:
98 def default(self):
99 return "default for dir3, not exposed"
100
101 class Dir4:
102 def index(self):
103 return "index for dir4, not exposed"
104
105 class DefNoIndex:
106 def default(self, *args):
107 raise cherrypy.HTTPRedirect("contact")
108 default.exposed = True
109
110
111 class ByMethod:
112 exposed = True
113
114 def __init__(self, *things):
115 self.things = list(things)
116
117 def GET(self):
118 return repr(self.things)
119
120 def POST(self, thing):
121 self.things.append(thing)
122
123 class Collection:
124 default = ByMethod('a', 'bit')
125
126 Root.exposing = Exposing()
127 Root.exposingnew = ExposingNewStyle()
128 Root.dir1 = Dir1()
129 Root.dir1.dir2 = Dir2()
130 Root.dir1.dir2.dir3 = Dir3()
131 Root.dir1.dir2.dir3.dir4 = Dir4()
132 Root.defnoindex = DefNoIndex()
133 Root.bymethod = ByMethod('another')
134 Root.collection = Collection()
135
136 d = cherrypy.dispatch.MethodDispatcher()
137 for url in script_names:
138 conf = {'/': {'user': (url or "/").split("/")[-2]},
139 '/bymethod': {'request.dispatch': d},
140 '/collection': {'request.dispatch': d},
141 }
142 cherrypy.tree.mount(Root(), url, conf)
143
144 cherrypy.config.update({'environment': "test_suite"})
145
146
147 class Isolated:
148 def index(self):
149 return "made it!"
150 index.exposed = True
151
152 cherrypy.tree.mount(Isolated(), "/isolated")
153
154 class AnotherApp:
155
156 exposed = True
157
158 def GET(self):
159 return "milk"
160
161 cherrypy.tree.mount(AnotherApp(), "/app", {'/': {'request.dispatch': d}})
162
163
164 from cherrypy.test import helper
165
167
169 for url in script_names:
170 prefix = self.script_name = url
171
172 self.getPage('/')
173 self.assertBody('world')
174
175 self.getPage("/dir1/myMethod")
176 self.assertBody("myMethod from dir1, path_info is:'/dir1/myMethod'")
177
178 self.getPage("/this/method/does/not/exist")
179 self.assertBody("default:('this', 'method', 'does', 'not', 'exist')")
180
181 self.getPage("/extra/too/much")
182 self.assertBody("('too', 'much')")
183
184 self.getPage("/other")
185 self.assertBody('other')
186
187 self.getPage("/notExposed")
188 self.assertBody("default:('notExposed',)")
189
190 self.getPage("/dir1/dir2/")
191 self.assertBody('index for dir2, path is:/dir1/dir2/')
192
193
194 self.getPage("/dir1/dir2")
195 self.assertStatus((302, 303))
196 self.assertHeader('Location', '%s/dir1/dir2/' % self.base())
197
198
199 self.getPage("/dir1/myMethod/")
200 self.assertStatus((302, 303))
201 self.assertHeader('Location', '%s/dir1/myMethod' % self.base())
202
203
204 self.getPage("/dir1/dir2/dir3/dir4/index")
205 self.assertBody("default for dir1, param is:('dir2', 'dir3', 'dir4', 'index')")
206
207
208
209 self.getPage("/defnoindex")
210 self.assertStatus((302, 303))
211 self.assertHeader('Location', '%s/contact' % self.base())
212 self.getPage("/defnoindex/")
213 self.assertStatus((302, 303))
214 self.assertHeader('Location', '%s/defnoindex/contact' % self.base())
215 self.getPage("/defnoindex/page")
216 self.assertStatus((302, 303))
217 self.assertHeader('Location', '%s/defnoindex/contact' % self.base())
218
219 self.getPage("/redirect")
220 self.assertStatus('302 Found')
221 self.assertHeader('Location', '%s/dir1/' % self.base())
222
223 if not getattr(cherrypy.server, "using_apache", False):
224
225
226 self.getPage("/Von%20B%fclow?ID=14")
227 self.assertBody("ID is 14")
228
229
230
231
232 self.getPage("/page%2Fname")
233 self.assertBody("default:('page/name',)")
234
235 self.getPage("/dir1/dir2/script_name")
236 self.assertBody(url)
237 self.getPage("/dir1/dir2/cherrypy_url")
238 self.assertBody("%s/extra" % self.base())
239
240
241 self.getPage("/confvalue")
242 self.assertBody((url or "/").split("/")[-2])
243
244 self.script_name = ""
245
246
247 self.getPage('http://%s:%s/' % (self.interface(), self.PORT))
248 self.assertBody('world')
249
250
251
252
253 self.getPage("/isolated/")
254 self.assertStatus("200 OK")
255 self.assertBody("made it!")
256 self.getPage("/isolated/doesnt/exist")
257 self.assertStatus("404 Not Found")
258
259
260
261 self.getPage("/foobar")
262 self.assertBody("bar")
263
265 self.getPage("/dir1/dir2/posparam/18/24/hut/hike")
266 self.assertBody("18/24/hut/hike")
267
268
269
270 self.getPage("/dir1/dir2/5/3/sir")
271 self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')")
272
273
274
275 self.getPage("/dir1/dir2/script_name/extra/stuff")
276 self.assertStatus(404)
277
297
299 self.getPage("/bymethod")
300 self.assertBody("['another']")
301 self.assertHeader('Allow', 'GET, HEAD, POST')
302
303 self.getPage("/bymethod", method="HEAD")
304 self.assertBody("")
305 self.assertHeader('Allow', 'GET, HEAD, POST')
306
307 self.getPage("/bymethod", method="POST", body="thing=one")
308 self.assertBody("")
309 self.assertHeader('Allow', 'GET, HEAD, POST')
310
311 self.getPage("/bymethod")
312 self.assertBody("['another', 'one']")
313 self.assertHeader('Allow', 'GET, HEAD, POST')
314
315 self.getPage("/bymethod", method="PUT")
316 self.assertErrorPage(405)
317 self.assertHeader('Allow', 'GET, HEAD, POST')
318
319
320 self.getPage("/collection/silly", method="POST")
321 self.getPage("/collection", method="GET")
322 self.assertBody("['a', 'bit', 'silly']")
323
324
325 self.getPage("/app")
326 self.assertBody("milk")
327
329
330
331
332 a = Application(object(), '/somewhere')
333 self.assertRaises(ValueError, cherrypy.tree.mount, a, '/somewhereelse')
334
335
336
337 a = Application(object(), '/somewhere')
338 try:
339 cherrypy.tree.mount(a, '/somewhere')
340 except ValueError:
341 self.fail("tree.mount must allow script_names which are the same")
342
343 try:
344 cherrypy.tree.mount(a)
345 except ValueError:
346 self.fail("cherrypy.tree.mount incorrectly raised a ValueError")
347
348
349
350
351
352 if __name__ == "__main__":
353 setup_server()
354 helper.testmain()
355