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  test.prefer_parent_path() 
  3   
  4  import cherrypy 
  5   
  6   
  7  script_names = ["", "/foo", "/users/fred/blog", "/corp/blog"] 
  8   
9 -def setup_server():
10 class Root: 11 def index(self, name="world"): 12 return name
13 index.exposed = True 14 15 def foobar(self): 16 return "bar" 17 foobar.exposed = True 18 19 def default(self, *params): 20 return "default:" + repr(params) 21 default.exposed = True 22 23 def other(self): 24 return "other" 25 other.exposed = True 26 27 def extra(self, *p): 28 return repr(p) 29 extra.exposed = True 30 31 def redirect(self): 32 raise cherrypy.HTTPRedirect('dir1/', 302) 33 redirect.exposed = True 34 35 def notExposed(self): 36 return "not exposed" 37 38 def confvalue(self): 39 return cherrypy.request.config.get("user") 40 confvalue.exposed = True 41 42 def mapped_func(self, ID=None): 43 return "ID is %s" % ID 44 mapped_func.exposed = True 45 setattr(Root, "Von B\xfclow", mapped_func) 46 47 48 class Exposing: 49 def base(self): 50 return "expose works!" 51 cherrypy.expose(base) 52 cherrypy.expose(base, "1") 53 cherrypy.expose(base, "2") 54 55 class ExposingNewStyle(object): 56 def base(self): 57 return "expose works!" 58 cherrypy.expose(base) 59 cherrypy.expose(base, "1") 60 cherrypy.expose(base, "2") 61 62 63 class Dir1: 64 def index(self): 65 return "index for dir1" 66 index.exposed = True 67 68 def myMethod(self): 69 return "myMethod from dir1, path_info is:" + repr(cherrypy.request.path_info) 70 myMethod.exposed = True 71 myMethod._cp_config = {'tools.trailing_slash.extra': True} 72 73 def default(self, *params): 74 return "default for dir1, param is:" + repr(params) 75 default.exposed = True 76 77 78 class Dir2: 79 def index(self): 80 return "index for dir2, path is:" + cherrypy.request.path_info 81 index.exposed = True 82 83 def script_name(self): 84 return cherrypy.tree.script_name() 85 script_name.exposed = True 86 87 def cherrypy_url(self): 88 return cherrypy.url("/extra") 89 cherrypy_url.exposed = True 90 91 def posparam(self, *vpath): 92 return "/".join(vpath) 93 posparam.exposed = True 94 95 96 class Dir3: 97 def default(self): 98 return "default for dir3, not exposed" 99 100 class Dir4: 101 def index(self): 102 return "index for dir4, not exposed" 103 104 class DefNoIndex: 105 def default(self, *args): 106 raise cherrypy.HTTPRedirect("contact") 107 default.exposed = True 108 109 # MethodDispatcher code 110 class ByMethod: 111 exposed = True 112 113 def __init__(self, *things): 114 self.things = list(things) 115 116 def GET(self): 117 return repr(self.things) 118 119 def POST(self, thing): 120 self.things.append(thing) 121 122 class Collection: 123 default = ByMethod('a', 'bit') 124 125 Root.exposing = Exposing() 126 Root.exposingnew = ExposingNewStyle() 127 Root.dir1 = Dir1() 128 Root.dir1.dir2 = Dir2() 129 Root.dir1.dir2.dir3 = Dir3() 130 Root.dir1.dir2.dir3.dir4 = Dir4() 131 Root.defnoindex = DefNoIndex() 132 Root.bymethod = ByMethod('another') 133 Root.collection = Collection() 134 135 for url in script_names: 136 d = cherrypy.dispatch.MethodDispatcher() 137 conf = {'/': {'user': (url or "/").split("/")[-2]}, 138 '/bymethod': {'request.dispatch': d}, 139 '/collection': {'request.dispatch': d}, 140 } 141 cherrypy.tree.mount(Root(), url, conf) 142 143 cherrypy.config.update({'environment': "test_suite"}) 144 145 146 class Isolated: 147 def index(self): 148 return "made it!" 149 index.exposed = True 150 151 cherrypy.tree.mount(Isolated(), "/isolated") 152 153 154 from cherrypy.test import helper 155
156 -class ObjectMappingTest(helper.CPWebCase):
157
158 - def testObjectMapping(self):
159 for url in script_names: 160 prefix = self.script_name = url 161 162 self.getPage('/') 163 self.assertBody('world') 164 165 self.getPage("/dir1/myMethod") 166 self.assertBody("myMethod from dir1, path_info is:'/dir1/myMethod'") 167 168 self.getPage("/this/method/does/not/exist") 169 self.assertBody("default:('this', 'method', 'does', 'not', 'exist')") 170 171 self.getPage("/extra/too/much") 172 self.assertBody("('too', 'much')") 173 174 self.getPage("/other") 175 self.assertBody('other') 176 177 self.getPage("/notExposed") 178 self.assertBody("default:('notExposed',)") 179 180 self.getPage("/dir1/dir2/") 181 self.assertBody('index for dir2, path is:/dir1/dir2/') 182 183 # Test omitted trailing slash (should be redirected by default). 184 self.getPage("/dir1/dir2") 185 self.assertStatus((302, 303)) 186 self.assertHeader('Location', '%s/dir1/dir2/' % self.base()) 187 188 # Test extra trailing slash (should be redirected if configured). 189 self.getPage("/dir1/myMethod/") 190 self.assertStatus((302, 303)) 191 self.assertHeader('Location', '%s/dir1/myMethod' % self.base()) 192 193 # Test that default method must be exposed in order to match. 194 self.getPage("/dir1/dir2/dir3/dir4/index") 195 self.assertBody("default for dir1, param is:('dir2', 'dir3', 'dir4', 'index')") 196 197 # Test *vpath when default() is defined but not index() 198 # This also tests HTTPRedirect with default. 199 self.getPage("/defnoindex") 200 self.assertStatus((302, 303)) 201 self.assertHeader('Location', '%s/contact' % self.base()) 202 self.getPage("/defnoindex/") 203 self.assertStatus((302, 303)) 204 self.assertHeader('Location', '%s/defnoindex/contact' % self.base()) 205 self.getPage("/defnoindex/page") 206 self.assertStatus((302, 303)) 207 self.assertHeader('Location', '%s/defnoindex/contact' % self.base()) 208 209 self.getPage("/redirect") 210 self.assertStatus('302 Found') 211 self.assertHeader('Location', '%s/dir1/' % self.base()) 212 213 # Test that we can use URL's which aren't all valid Python identifiers 214 # This should also test the %XX-unquoting of URL's. 215 self.getPage("/Von%20B%fclow?ID=14") 216 self.assertBody("ID is 14") 217 218 # Test that %2F in the path doesn't get unquoted too early; 219 # that is, it should not be used to separate path components. 220 # See ticket #393. 221 self.getPage("/page%2Fname") 222 self.assertBody("default:('page/name',)") 223 224 self.getPage("/dir1/dir2/script_name") 225 self.assertBody(url) 226 self.getPage("/dir1/dir2/cherrypy_url") 227 self.assertBody("%s/extra" % self.base()) 228 229 # Test that configs don't overwrite each other from diferent apps 230 self.getPage("/confvalue") 231 self.assertBody((url or "/").split("/")[-2]) 232 233 self.script_name = "" 234 235 # Test absoluteURI's in the Request-Line 236 self.getPage('http://localhost/') 237 self.assertBody('world') 238 239 # Test that the "isolated" app doesn't leak url's into the root app. 240 # If it did leak, Root.default() would answer with 241 # "default:('isolated', 'doesnt', 'exist')". 242 self.getPage("/isolated/") 243 self.assertStatus("200 OK") 244 self.assertBody("made it!") 245 self.getPage("/isolated/doesnt/exist") 246 self.assertStatus("404 Not Found") 247 248 # Make sure /foobar maps to Root.foobar and not to the app 249 # mounted at /foo. See http://www.cherrypy.org/ticket/573 250 self.getPage("/foobar") 251 self.assertBody("bar")
252
253 - def testPositionalParams(self):
254 self.getPage("/dir1/dir2/posparam/18/24/hut/hike") 255 self.assertBody("18/24/hut/hike") 256 257 # intermediate index methods should not receive posparams; 258 # only the "final" index method should do so. 259 self.getPage("/dir1/dir2/5/3/sir") 260 self.assertBody("default for dir1, param is:('dir2', '5', '3', 'sir')")
261
262 - def testExpose(self):
263 # Test the cherrypy.expose function/decorator 264 self.getPage("/exposing/base") 265 self.assertBody("expose works!") 266 267 self.getPage("/exposing/1") 268 self.assertBody("expose works!") 269 270 self.getPage("/exposing/2") 271 self.assertBody("expose works!") 272 273 self.getPage("/exposingnew/base") 274 self.assertBody("expose works!") 275 276 self.getPage("/exposingnew/1") 277 self.assertBody("expose works!") 278 279 self.getPage("/exposingnew/2") 280 self.assertBody("expose works!")
281
282 - def testMethodDispatch(self):
283 self.getPage("/bymethod") 284 self.assertBody("['another']") 285 self.assertHeader('Allow', 'GET, HEAD, POST') 286 287 self.getPage("/bymethod", method="HEAD") 288 self.assertBody("") 289 self.assertHeader('Allow', 'GET, HEAD, POST') 290 291 self.getPage("/bymethod", method="POST", body="thing=one") 292 self.assertBody("") 293 self.assertHeader('Allow', 'GET, HEAD, POST') 294 295 self.getPage("/bymethod") 296 self.assertBody("['another', 'one']") 297 self.assertHeader('Allow', 'GET, HEAD, POST') 298 299 self.getPage("/bymethod", method="PUT") 300 self.assertErrorPage(405) 301 self.assertHeader('Allow', 'GET, HEAD, POST') 302 303 # Test default with posparams 304 self.getPage("/collection/silly", method="POST") 305 self.getPage("/collection", method="GET") 306 self.assertBody("['a', 'bit', 'silly']")
307 308 309 if __name__ == "__main__": 310 setup_server() 311 helper.testmain() 312