1 import cherrypy
2 from cherrypy._cpcompat import ntou
3 from cherrypy._cptree import Application
4 from cherrypy.test import helper
5
6 script_names = ["", "/foo", "/users/fred/blog", "/corp/blog"]
7
8
10
12 class Root:
13
14 def index(self, name="world"):
15 return name
16 index.exposed = True
17
18 def foobar(self):
19 return "bar"
20 foobar.exposed = True
21
22 def default(self, *params, **kwargs):
23 return "default:" + repr(params)
24 default.exposed = True
25
26 def other(self):
27 return "other"
28 other.exposed = True
29
30 def extra(self, *p):
31 return repr(p)
32 extra.exposed = True
33
34 def redirect(self):
35 raise cherrypy.HTTPRedirect('dir1/', 302)
36 redirect.exposed = True
37
38 def notExposed(self):
39 return "not exposed"
40
41 def confvalue(self):
42 return cherrypy.request.config.get("user")
43 confvalue.exposed = True
44
45 def redirect_via_url(self, path):
46 raise cherrypy.HTTPRedirect(cherrypy.url(path))
47 redirect_via_url.exposed = True
48
49 def translate_html(self):
50 return "OK"
51 translate_html.exposed = True
52
53 def mapped_func(self, ID=None):
54 return "ID is %s" % ID
55 mapped_func.exposed = True
56 setattr(Root, "Von B\xfclow", mapped_func)
57
58 class Exposing:
59
60 def base(self):
61 return "expose works!"
62 cherrypy.expose(base)
63 cherrypy.expose(base, "1")
64 cherrypy.expose(base, "2")
65
66 class ExposingNewStyle(object):
67
68 def base(self):
69 return "expose works!"
70 cherrypy.expose(base)
71 cherrypy.expose(base, "1")
72 cherrypy.expose(base, "2")
73
74 class Dir1:
75
76 def index(self):
77 return "index for dir1"
78 index.exposed = True
79
80 def myMethod(self):
81 return "myMethod from dir1, path_info is:" + repr(
82 cherrypy.request.path_info)
83 myMethod.exposed = True
84 myMethod._cp_config = {'tools.trailing_slash.extra': True}
85
86 def default(self, *params):
87 return "default for dir1, param is:" + repr(params)
88 default.exposed = True
89
90 class Dir2:
91
92 def index(self):
93 return "index for dir2, path is:" + cherrypy.request.path_info
94 index.exposed = True
95
96 def script_name(self):
97 return cherrypy.tree.script_name()
98 script_name.exposed = True
99
100 def cherrypy_url(self):
101 return cherrypy.url("/extra")
102 cherrypy_url.exposed = True
103
104 def posparam(self, *vpath):
105 return "/".join(vpath)
106 posparam.exposed = True
107
108 class Dir3:
109
110 def default(self):
111 return "default for dir3, not exposed"
112
113 class Dir4:
114
115 def index(self):
116 return "index for dir4, not exposed"
117
118 class DefNoIndex:
119
120 def default(self, *args):
121 raise cherrypy.HTTPRedirect("contact")
122 default.exposed = True
123
124
125 class ByMethod:
126 exposed = True
127
128 def __init__(self, *things):
129 self.things = list(things)
130
131 def GET(self):
132 return repr(self.things)
133
134 def POST(self, thing):
135 self.things.append(thing)
136
137 class Collection:
138 default = ByMethod('a', 'bit')
139
140 Root.exposing = Exposing()
141 Root.exposingnew = ExposingNewStyle()
142 Root.dir1 = Dir1()
143 Root.dir1.dir2 = Dir2()
144 Root.dir1.dir2.dir3 = Dir3()
145 Root.dir1.dir2.dir3.dir4 = Dir4()
146 Root.defnoindex = DefNoIndex()
147 Root.bymethod = ByMethod('another')
148 Root.collection = Collection()
149
150 d = cherrypy.dispatch.MethodDispatcher()
151 for url in script_names:
152 conf = {'/': {'user': (url or "/").split("/")[-2]},
153 '/bymethod': {'request.dispatch': d},
154 '/collection': {'request.dispatch': d},
155 }
156 cherrypy.tree.mount(Root(), url, conf)
157
158 class Isolated:
159
160 def index(self):
161 return "made it!"
162 index.exposed = True
163
164 cherrypy.tree.mount(Isolated(), "/isolated")
165
166 class AnotherApp:
167
168 exposed = True
169
170 def GET(self):
171 return "milk"
172
173 cherrypy.tree.mount(AnotherApp(), "/app",
174 {'/': {'request.dispatch': d}})
175 setup_server = staticmethod(setup_server)
176
178 for url in script_names:
179 prefix = self.script_name = url
180
181 self.getPage('/')
182 self.assertBody('world')
183
184 self.getPage("/dir1/myMethod")
185 self.assertBody(
186 "myMethod from dir1, path_info is:'/dir1/myMethod'")
187
188 self.getPage("/this/method/does/not/exist")
189 self.assertBody(
190 "default:('this', 'method', 'does', 'not', 'exist')")
191
192 self.getPage("/extra/too/much")
193 self.assertBody("('too', 'much')")
194
195 self.getPage("/other")
196 self.assertBody('other')
197
198 self.getPage("/notExposed")
199 self.assertBody("default:('notExposed',)")
200
201 self.getPage("/dir1/dir2/")
202 self.assertBody('index for dir2, path is:/dir1/dir2/')
203
204
205 self.getPage("/dir1/dir2")
206 self.assertStatus(301)
207 self.assertHeader('Location', '%s/dir1/dir2/' % self.base())
208
209
210 self.getPage("/dir1/myMethod/")
211 self.assertStatus(301)
212 self.assertHeader('Location', '%s/dir1/myMethod' % self.base())
213
214
215 self.getPage("/dir1/dir2/dir3/dir4/index")
216 self.assertBody(
217 "default for dir1, param is:('dir2', 'dir3', 'dir4', 'index')")
218
219
220
221 self.getPage("/defnoindex")
222 self.assertStatus((302, 303))
223 self.assertHeader('Location', '%s/contact' % self.base())
224 self.getPage("/defnoindex/")
225 self.assertStatus((302, 303))
226 self.assertHeader('Location', '%s/defnoindex/contact' %
227 self.base())
228 self.getPage("/defnoindex/page")
229 self.assertStatus((302, 303))
230 self.assertHeader('Location', '%s/defnoindex/contact' %
231 self.base())
232
233 self.getPage("/redirect")
234 self.assertStatus('302 Found')
235 self.assertHeader('Location', '%s/dir1/' % self.base())
236
237 if not getattr(cherrypy.server, "using_apache", False):
238
239
240
241 self.getPage("/Von%20B%fclow?ID=14")
242 self.assertBody("ID is 14")
243
244
245
246
247 self.getPage("/page%2Fname")
248 self.assertBody("default:('page/name',)")
249
250 self.getPage("/dir1/dir2/script_name")
251 self.assertBody(url)
252 self.getPage("/dir1/dir2/cherrypy_url")
253 self.assertBody("%s/extra" % self.base())
254
255
256 self.getPage("/confvalue")
257 self.assertBody((url or "/").split("/")[-2])
258
259 self.script_name = ""
260
261
262 self.getPage('http://%s:%s/' % (self.interface(), self.PORT))
263 self.assertBody('world')
264
265 self.getPage('http://%s:%s/abs/?service=http://192.168.0.1/x/y/z' %
266 (self.interface(), self.PORT))
267 self.assertBody("default:('abs',)")
268
269 self.getPage('/rel/?service=http://192.168.120.121:8000/x/y/z')
270 self.assertBody("default:('rel',)")
271
272
273
274
275 self.getPage("/isolated/")
276 self.assertStatus("200 OK")
277 self.assertBody("made it!")
278 self.getPage("/isolated/doesnt/exist")
279 self.assertStatus("404 Not Found")
280
281
282
283
284 self.getPage("/foobar")
285 self.assertBody("bar")
286
299
323
325 self.getPage("/dir1/dir2/posparam/18/24/hut/hike")
326 self.assertBody("18/24/hut/hike")
327
328
329
330 self.getPage("/dir1/dir2/5/3/sir")
331 self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')")
332
333
334
335 self.getPage("/dir1/dir2/script_name/extra/stuff")
336 self.assertStatus(404)
337
357
359 self.getPage("/bymethod")
360 self.assertBody("['another']")
361 self.assertHeader('Allow', 'GET, HEAD, POST')
362
363 self.getPage("/bymethod", method="HEAD")
364 self.assertBody("")
365 self.assertHeader('Allow', 'GET, HEAD, POST')
366
367 self.getPage("/bymethod", method="POST", body="thing=one")
368 self.assertBody("")
369 self.assertHeader('Allow', 'GET, HEAD, POST')
370
371 self.getPage("/bymethod")
372 self.assertBody(repr(['another', ntou('one')]))
373 self.assertHeader('Allow', 'GET, HEAD, POST')
374
375 self.getPage("/bymethod", method="PUT")
376 self.assertErrorPage(405)
377 self.assertHeader('Allow', 'GET, HEAD, POST')
378
379
380 self.getPage("/collection/silly", method="POST")
381 self.getPage("/collection", method="GET")
382 self.assertBody("['a', 'bit', 'silly']")
383
384
385 self.getPage("/app")
386 self.assertBody("milk")
387
389 class Root(object):
390
391 def hello(self):
392 return "Hello world!"
393 hello.exposed = True
394
395
396
397 a = Application(Root(), '/somewhere')
398 self.assertRaises(ValueError, cherrypy.tree.mount, a, '/somewhereelse')
399
400
401 a = Application(Root(), '/somewhere')
402
403 cherrypy.tree.mount(a, '/somewhere')
404 self.getPage('/somewhere/hello')
405 self.assertStatus(200)
406
407 del cherrypy.tree.apps['/somewhere']
408 cherrypy.tree.mount(a)
409 self.getPage('/somewhere/hello')
410 self.assertStatus(200)
411
412
413
414 a = Application(Root(), script_name=None)
415
416 self.assertRaises(TypeError, cherrypy.tree.mount, a, None)
417