Package cherrypy :: Package test :: Module test_objectmapping
[hide private]
[frames] | no frames]

Source Code for Module cherrypy.test.test_objectmapping

  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   
10 -def setup_server():
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 # MethodDispatcher code 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
166 -class ObjectMappingTest(helper.CPWebCase):
167
168 - def testObjectMapping(self):
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 # Test omitted trailing slash (should be redirected by default). 194 self.getPage("/dir1/dir2") 195 self.assertStatus((302, 303)) 196 self.assertHeader('Location', '%s/dir1/dir2/' % self.base()) 197 198 # Test extra trailing slash (should be redirected if configured). 199 self.getPage("/dir1/myMethod/") 200 self.assertStatus((302, 303)) 201 self.assertHeader('Location', '%s/dir1/myMethod' % self.base()) 202 203 # Test that default method must be exposed in order to match. 204 self.getPage("/dir1/dir2/dir3/dir4/index") 205 self.assertBody("default for dir1, param is:('dir2', 'dir3', 'dir4', 'index')") 206 207 # Test *vpath when default() is defined but not index() 208 # This also tests HTTPRedirect with default. 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 # Test that we can use URL's which aren't all valid Python identifiers 225 # This should also test the %XX-unquoting of URL's. 226 self.getPage("/Von%20B%fclow?ID=14") 227 self.assertBody("ID is 14") 228 229 # Test that %2F in the path doesn't get unquoted too early; 230 # that is, it should not be used to separate path components. 231 # See ticket #393. 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 # Test that configs don't overwrite each other from diferent apps 241 self.getPage("/confvalue") 242 self.assertBody((url or "/").split("/")[-2]) 243 244 self.script_name = "" 245 246 # Test absoluteURI's in the Request-Line 247 self.getPage('http://%s:%s/' % (self.interface(), self.PORT)) 248 self.assertBody('world') 249 250 # Test that the "isolated" app doesn't leak url's into the root app. 251 # If it did leak, Root.default() would answer with 252 # "default:('isolated', 'doesnt', 'exist')". 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 # Make sure /foobar maps to Root.foobar and not to the app 260 # mounted at /foo. See http://www.cherrypy.org/ticket/573 261 self.getPage("/foobar") 262 self.assertBody("bar")
263
264 - def testPositionalParams(self):
265 self.getPage("/dir1/dir2/posparam/18/24/hut/hike") 266 self.assertBody("18/24/hut/hike") 267 268 # intermediate index methods should not receive posparams; 269 # only the "final" index method should do so. 270 self.getPage("/dir1/dir2/5/3/sir") 271 self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')") 272 273 # test that extra positional args raises an 404 Not Found 274 # See http://www.cherrypy.org/ticket/733. 275 self.getPage("/dir1/dir2/script_name/extra/stuff") 276 self.assertStatus(404)
277
278 - def testExpose(self):
279 # Test the cherrypy.expose function/decorator 280 self.getPage("/exposing/base") 281 self.assertBody("expose works!") 282 283 self.getPage("/exposing/1") 284 self.assertBody("expose works!") 285 286 self.getPage("/exposing/2") 287 self.assertBody("expose works!") 288 289 self.getPage("/exposingnew/base") 290 self.assertBody("expose works!") 291 292 self.getPage("/exposingnew/1") 293 self.assertBody("expose works!") 294 295 self.getPage("/exposingnew/2") 296 self.assertBody("expose works!")
297
298 - def testMethodDispatch(self):
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 # Test default with posparams 320 self.getPage("/collection/silly", method="POST") 321 self.getPage("/collection", method="GET") 322 self.assertBody("['a', 'bit', 'silly']") 323 324 # Test custom dispatcher set on app root (see #737). 325 self.getPage("/app") 326 self.assertBody("milk")
327
328 - def testTreeMounting(self):
329 330 # When mounting an application instance, 331 # we can't specify a script name in the call to mount. 332 a = Application(object(), '/somewhere') 333 self.assertRaises(ValueError, cherrypy.tree.mount, a, '/somewhereelse') 334 335 # When mounting an application instance, 336 # we can't specify a script name in the call to mount. 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