1"""test_resources""" 2import unittest 3from nose.tools import eq_, assert_raises 4 5from routes import * 6 7class TestResourceGeneration(unittest.TestCase): 8 def _assert_restful_routes(self, m, options, path_prefix=''): 9 baseroute = '/' + path_prefix + options['controller'] 10 eq_(baseroute, m.generate(action='index', **options)) 11 eq_(baseroute + '.xml', m.generate(action='index', format='xml', **options)) 12 eq_(baseroute + '/new', m.generate(action='new', **options)) 13 eq_(baseroute + '/1', m.generate(action='show', id='1', **options)) 14 eq_(baseroute + '/1/edit', m.generate(action='edit',id='1', **options)) 15 eq_(baseroute + '/1.xml', m.generate(action='show', id='1',format='xml', **options)) 16 17 eq_(baseroute, m.generate(action='create', method='post', **options)) 18 eq_(baseroute + '/1', m.generate(action='update', method='put', id='1', **options)) 19 eq_(baseroute + '/1', m.generate(action='delete', method='delete', id='1', **options)) 20 21 def test_resources(self): 22 m = Mapper() 23 m.resource('message', 'messages') 24 m.resource('massage', 'massages') 25 m.resource('passage', 'passages') 26 m.create_regs(['messages']) 27 options = dict(controller='messages') 28 eq_('/messages', url_for('messages')) 29 eq_('/messages.xml', url_for('formatted_messages', format='xml')) 30 eq_('/messages/1', url_for('message', id=1)) 31 eq_('/messages/1.xml', url_for('formatted_message', id=1, format='xml')) 32 eq_('/messages/new', url_for('new_message')) 33 eq_('/messages/1.xml', url_for('formatted_message', id=1, format='xml')) 34 eq_('/messages/1/edit', url_for('edit_message', id=1)) 35 eq_('/messages/1/edit.xml', url_for('formatted_edit_message', id=1, format='xml')) 36 self._assert_restful_routes(m, options) 37 38 def test_resources_with_path_prefix(self): 39 m = Mapper() 40 m.resource('message', 'messages', path_prefix='/thread/:threadid') 41 m.create_regs(['messages']) 42 options = dict(controller='messages', threadid='5') 43 self._assert_restful_routes(m, options, path_prefix='thread/5/') 44 45 def test_resources_with_collection_action(self): 46 m = Mapper() 47 m.resource('message', 'messages', collection=dict(rss='GET')) 48 m.create_regs(['messages']) 49 options = dict(controller='messages') 50 self._assert_restful_routes(m, options) 51 eq_('/messages/rss', m.generate(controller='messages', action='rss')) 52 eq_('/messages/rss', url_for('rss_messages')) 53 eq_('/messages/rss.xml', m.generate(controller='messages', action='rss', format='xml')) 54 eq_('/messages/rss.xml', url_for('formatted_rss_messages', format='xml')) 55 56 def test_resources_with_member_action(self): 57 for method in ['put', 'post']: 58 m = Mapper() 59 m.resource('message', 'messages', member=dict(mark=method)) 60 m.create_regs(['messages']) 61 options = dict(controller='messages') 62 self._assert_restful_routes(m, options) 63 eq_('/messages/1/mark', m.generate(method=method, action='mark', id='1', **options)) 64 eq_('/messages/1/mark.xml', 65 m.generate(method=method, action='mark', id='1', format='xml', **options)) 66 67 def test_resources_with_new_action(self): 68 m = Mapper() 69 m.resource('message', 'messages/', new=dict(preview='POST')) 70 m.create_regs(['messages']) 71 options = dict(controller='messages') 72 self._assert_restful_routes(m, options) 73 eq_('/messages/new/preview', m.generate(controller='messages', action='preview', method='post')) 74 eq_('/messages/new/preview', url_for('preview_new_message')) 75 eq_('/messages/new/preview.xml', 76 m.generate(controller='messages', action='preview', method='post', format='xml')) 77 eq_('/messages/new/preview.xml', url_for('formatted_preview_new_message', format='xml')) 78 79 def test_resources_with_name_prefix(self): 80 m = Mapper() 81 m.resource('message', 'messages', name_prefix='category_', new=dict(preview='POST')) 82 m.create_regs(['messages']) 83 options = dict(controller='messages') 84 self._assert_restful_routes(m, options) 85 eq_('/messages/new/preview', url_for('category_preview_new_message')) 86 assert_raises(Exception, url_for, 'category_preview_new_message', method='get') 87 88 def test_resources_with_requirements(self): 89 m = Mapper() 90 m.resource('message', 'messages', path_prefix='/{project_id}/{user_id}/', 91 requirements={'project_id': r'[0-9a-f]{4}', 'user_id': r'\d+'}) 92 options = dict(controller='messages', project_id='cafe', user_id='123') 93 self._assert_restful_routes(m, options, path_prefix='cafe/123/') 94 95 # in addition to the positive tests we need to guarantee we 96 # are not matching when the requirements don't match. 97 eq_({'action': u'create', 'project_id': u'cafe', 'user_id': u'123', 'controller': u'messages'}, 98 m.match('/cafe/123/messages')) 99 eq_(None, m.match('/extensions/123/messages')) 100 eq_(None, m.match('/b0a3/123b/messages')) 101 eq_(None, m.match('/foo/bar/messages')) 102 103 104class TestResourceRecognition(unittest.TestCase): 105 def test_resource(self): 106 m = Mapper() 107 m.resource('person', 'people') 108 m.create_regs(['people']) 109 110 con = request_config() 111 con.mapper = m 112 def test_path(path, method): 113 env = dict(HTTP_HOST='example.com', PATH_INFO=path, REQUEST_METHOD=method) 114 con.mapper_dict = {} 115 con.environ = env 116 117 test_path('/people', 'GET') 118 eq_({'controller':'people', 'action':'index'}, con.mapper_dict) 119 test_path('/people.xml', 'GET') 120 eq_({'controller':'people', 'action':'index', 'format':'xml'}, con.mapper_dict) 121 122 test_path('/people', 'POST') 123 eq_({'controller':'people', 'action':'create'}, con.mapper_dict) 124 test_path('/people.html', 'POST') 125 eq_({'controller':'people', 'action':'create', 'format':'html'}, con.mapper_dict) 126 127 test_path('/people/2.xml', 'GET') 128 eq_({'controller':'people', 'action':'show', 'id':'2', 'format':'xml'}, con.mapper_dict) 129 test_path('/people/2', 'GET') 130 eq_({'controller':'people', 'action':'show', 'id':'2'}, con.mapper_dict) 131 132 test_path('/people/2/edit', 'GET') 133 eq_({'controller':'people', 'action':'edit', 'id':'2'}, con.mapper_dict) 134 test_path('/people/2/edit.xml', 'GET') 135 eq_({'controller':'people', 'action':'edit', 'id':'2', 'format':'xml'}, con.mapper_dict) 136 137 test_path('/people/2', 'DELETE') 138 eq_({'controller':'people', 'action':'delete', 'id':'2'}, con.mapper_dict) 139 140 test_path('/people/2', 'PUT') 141 eq_({'controller':'people', 'action':'update', 'id':'2'}, con.mapper_dict ) 142 test_path('/people/2.json', 'PUT') 143 eq_({'controller':'people', 'action':'update', 'id':'2', 'format':'json'}, con.mapper_dict ) 144 145 # Test for dots in urls 146 test_path('/people/2\.13', 'PUT') 147 eq_({'controller':'people', 'action':'update', 'id':'2\.13'}, con.mapper_dict) 148 test_path('/people/2\.13.xml', 'PUT') 149 eq_({'controller':'people', 'action':'update', 'id':'2\.13', 'format':'xml'}, con.mapper_dict) 150 test_path('/people/user\.name', 'PUT') 151 eq_({'controller':'people', 'action':'update', 'id':'user\.name'}, con.mapper_dict) 152 test_path('/people/user\.\.\.name', 'PUT') 153 eq_({'controller':'people', 'action':'update', 'id':'user\.\.\.name'}, con.mapper_dict) 154 test_path('/people/user\.name\.has\.dots', 'PUT') 155 eq_({'controller':'people', 'action':'update', 'id':'user\.name\.has\.dots'}, con.mapper_dict) 156 test_path('/people/user\.name\.is\.something.xml', 'PUT') 157 eq_({'controller':'people', 'action':'update', 'id':'user\.name\.is\.something', 'format':'xml'}, con.mapper_dict) 158 test_path('/people/user\.name\.ends\.with\.dot\..xml', 'PUT') 159 eq_({'controller':'people', 'action':'update', 'id':'user\.name\.ends\.with\.dot\.', 'format':'xml'}, con.mapper_dict) 160 test_path('/people/user\.name\.ends\.with\.dot\.', 'PUT') 161 eq_({'controller':'people', 'action':'update', 'id':'user\.name\.ends\.with\.dot\.'}, con.mapper_dict) 162 test_path('/people/\.user\.name\.starts\.with\.dot', 'PUT') 163 eq_({'controller':'people', 'action':'update', 'id':'\.user\.name\.starts\.with\.dot'}, con.mapper_dict) 164 test_path('/people/user\.name.json', 'PUT') 165 eq_({'controller':'people', 'action':'update', 'id':'user\.name', 'format':'json'}, con.mapper_dict) 166 167 def test_resource_with_nomin(self): 168 m = Mapper() 169 m.minimization = False 170 m.resource('person', 'people') 171 m.create_regs(['people']) 172 173 con = request_config() 174 con.mapper = m 175 def test_path(path, method): 176 env = dict(HTTP_HOST='example.com', PATH_INFO=path, REQUEST_METHOD=method) 177 con.mapper_dict = {} 178 con.environ = env 179 180 test_path('/people', 'GET') 181 eq_({'controller':'people', 'action':'index'}, con.mapper_dict) 182 183 test_path('/people', 'POST') 184 eq_({'controller':'people', 'action':'create'}, con.mapper_dict) 185 186 test_path('/people/2', 'GET') 187 eq_({'controller':'people', 'action':'show', 'id':'2'}, con.mapper_dict) 188 test_path('/people/2/edit', 'GET') 189 eq_({'controller':'people', 'action':'edit', 'id':'2'}, con.mapper_dict) 190 191 test_path('/people/2', 'DELETE') 192 eq_({'controller':'people', 'action':'delete', 'id':'2'}, con.mapper_dict) 193 194 test_path('/people/2', 'PUT') 195 eq_({'controller':'people', 'action':'update', 'id':'2'}, con.mapper_dict) 196 197 def test_resource_created_with_parent_resource(self): 198 m = Mapper() 199 m.resource('location', 'locations', 200 parent_resource=dict(member_name='region', 201 collection_name='regions')) 202 m.create_regs(['locations']) 203 204 con = request_config() 205 con.mapper = m 206 def test_path(path, method): 207 env = dict(HTTP_HOST='example.com', PATH_INFO=path, 208 REQUEST_METHOD=method) 209 con.mapper_dict = {} 210 con.environ = env 211 212 test_path('/regions/13/locations', 'GET') 213 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 214 'action': 'index'}) 215 url = url_for('region_locations', region_id=13) 216 eq_(url, '/regions/13/locations') 217 218 test_path('/regions/13/locations', 'POST') 219 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 220 'action': 'create'}) 221 # new 222 url = url_for('region_new_location', region_id=13) 223 eq_(url, '/regions/13/locations/new') 224 # create 225 url = url_for('region_locations', region_id=13) 226 eq_(url, '/regions/13/locations') 227 228 test_path('/regions/13/locations/60', 'GET') 229 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 230 'id': '60', 'action': 'show'}) 231 url = url_for('region_location', region_id=13, id=60) 232 eq_(url, '/regions/13/locations/60') 233 234 test_path('/regions/13/locations/60/edit', 'GET') 235 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 236 'id': '60', 'action': 'edit'}) 237 url = url_for('region_edit_location', region_id=13, id=60) 238 eq_(url, '/regions/13/locations/60/edit') 239 240 test_path('/regions/13/locations/60', 'DELETE') 241 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 242 'id': '60', 'action': 'delete'}) 243 url = url_for('region_location', region_id=13, id=60) 244 eq_(url, '/regions/13/locations/60') 245 246 test_path('/regions/13/locations/60', 'PUT') 247 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 248 'id': '60', 'action': 'update'}) 249 url = url_for('region_location', region_id=13, id=60) 250 eq_(url, '/regions/13/locations/60') 251 252 # Make sure ``path_prefix`` overrides work 253 # empty ``path_prefix`` (though I'm not sure why someone would do this) 254 m = Mapper() 255 m.resource('location', 'locations', 256 parent_resource=dict(member_name='region', 257 collection_name='regions'), 258 path_prefix='') 259 url = url_for('region_locations') 260 eq_(url, '/locations') 261 # different ``path_prefix`` 262 m = Mapper() 263 m.resource('location', 'locations', 264 parent_resource=dict(member_name='region', 265 collection_name='regions'), 266 path_prefix='areas/:area_id') 267 url = url_for('region_locations', area_id=51) 268 eq_(url, '/areas/51/locations') 269 270 # Make sure ``name_prefix`` overrides work 271 # empty ``name_prefix`` 272 m = Mapper() 273 m.resource('location', 'locations', 274 parent_resource=dict(member_name='region', 275 collection_name='regions'), 276 name_prefix='') 277 url = url_for('locations', region_id=51) 278 eq_(url, '/regions/51/locations') 279 # different ``name_prefix`` 280 m = Mapper() 281 m.resource('location', 'locations', 282 parent_resource=dict(member_name='region', 283 collection_name='regions'), 284 name_prefix='area_') 285 url = url_for('area_locations', region_id=51) 286 eq_(url, '/regions/51/locations') 287 288 # Make sure ``path_prefix`` and ``name_prefix`` overrides work together 289 # empty ``path_prefix`` 290 m = Mapper() 291 m.resource('location', 'locations', 292 parent_resource=dict(member_name='region', 293 collection_name='regions'), 294 path_prefix='', 295 name_prefix='place_') 296 url = url_for('place_locations') 297 eq_(url, '/locations') 298 # empty ``name_prefix`` 299 m = Mapper() 300 m.resource('location', 'locations', 301 parent_resource=dict(member_name='region', 302 collection_name='regions'), 303 path_prefix='areas/:area_id', 304 name_prefix='') 305 url = url_for('locations', area_id=51) 306 eq_(url, '/areas/51/locations') 307 # different ``path_prefix`` and ``name_prefix`` 308 m = Mapper() 309 m.resource('location', 'locations', 310 parent_resource=dict(member_name='region', 311 collection_name='regions'), 312 path_prefix='areas/:area_id', 313 name_prefix='place_') 314 url = url_for('place_locations', area_id=51) 315 eq_(url, '/areas/51/locations') 316 317 def test_resource_created_with_parent_resource_nomin(self): 318 m = Mapper() 319 m.minimization = False 320 m.resource('location', 'locations', 321 parent_resource=dict(member_name='region', 322 collection_name='regions')) 323 m.create_regs(['locations']) 324 325 con = request_config() 326 con.mapper = m 327 def test_path(path, method): 328 env = dict(HTTP_HOST='example.com', PATH_INFO=path, 329 REQUEST_METHOD=method) 330 con.mapper_dict = {} 331 con.environ = env 332 333 test_path('/regions/13/locations', 'GET') 334 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 335 'action': 'index'}) 336 url = url_for('region_locations', region_id=13) 337 eq_(url, '/regions/13/locations') 338 339 test_path('/regions/13/locations', 'POST') 340 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 341 'action': 'create'}) 342 # new 343 url = url_for('region_new_location', region_id=13) 344 eq_(url, '/regions/13/locations/new') 345 # create 346 url = url_for('region_locations', region_id=13) 347 eq_(url, '/regions/13/locations') 348 349 test_path('/regions/13/locations/60', 'GET') 350 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 351 'id': '60', 'action': 'show'}) 352 url = url_for('region_location', region_id=13, id=60) 353 eq_(url, '/regions/13/locations/60') 354 355 test_path('/regions/13/locations/60/edit', 'GET') 356 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 357 'id': '60', 'action': 'edit'}) 358 url = url_for('region_edit_location', region_id=13, id=60) 359 eq_(url, '/regions/13/locations/60/edit') 360 361 test_path('/regions/13/locations/60', 'DELETE') 362 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 363 'id': '60', 'action': 'delete'}) 364 url = url_for('region_location', region_id=13, id=60) 365 eq_(url, '/regions/13/locations/60') 366 367 test_path('/regions/13/locations/60', 'PUT') 368 eq_(con.mapper_dict, {'region_id': '13', 'controller': 'locations', 369 'id': '60', 'action': 'update'}) 370 url = url_for('region_location', region_id=13, id=60) 371 eq_(url, '/regions/13/locations/60') 372 373 # Make sure ``path_prefix`` overrides work 374 # empty ``path_prefix`` (though I'm not sure why someone would do this) 375 m = Mapper() 376 m.resource('location', 'locations', 377 parent_resource=dict(member_name='region', 378 collection_name='regions'), 379 path_prefix='/') 380 url = url_for('region_locations') 381 eq_(url, '/locations') 382 # different ``path_prefix`` 383 m = Mapper() 384 m.resource('location', 'locations', 385 parent_resource=dict(member_name='region', 386 collection_name='regions'), 387 path_prefix='areas/:area_id') 388 url = url_for('region_locations', area_id=51) 389 eq_(url, '/areas/51/locations') 390 391 # Make sure ``name_prefix`` overrides work 392 # empty ``name_prefix`` 393 m = Mapper() 394 m.resource('location', 'locations', 395 parent_resource=dict(member_name='region', 396 collection_name='regions'), 397 name_prefix='') 398 url = url_for('locations', region_id=51) 399 eq_(url, '/regions/51/locations') 400 # different ``name_prefix`` 401 m = Mapper() 402 m.resource('location', 'locations', 403 parent_resource=dict(member_name='region', 404 collection_name='regions'), 405 name_prefix='area_') 406 url = url_for('area_locations', region_id=51) 407 eq_(url, '/regions/51/locations') 408 409 # Make sure ``path_prefix`` and ``name_prefix`` overrides work together 410 # empty ``path_prefix`` 411 m = Mapper() 412 m.resource('location', 'locations', 413 parent_resource=dict(member_name='region', 414 collection_name='regions'), 415 path_prefix='', 416 name_prefix='place_') 417 url = url_for('place_locations') 418 eq_(url, '/locations') 419 # empty ``name_prefix`` 420 m = Mapper() 421 m.resource('location', 'locations', 422 parent_resource=dict(member_name='region', 423 collection_name='regions'), 424 path_prefix='areas/:area_id', 425 name_prefix='') 426 url = url_for('locations', area_id=51) 427 eq_(url, '/areas/51/locations') 428 # different ``path_prefix`` and ``name_prefix`` 429 m = Mapper() 430 m.resource('location', 'locations', 431 parent_resource=dict(member_name='region', 432 collection_name='regions'), 433 path_prefix='areas/:area_id', 434 name_prefix='place_') 435 url = url_for('place_locations', area_id=51) 436 eq_(url, '/areas/51/locations') 437 438 439 440if __name__ == '__main__': 441 unittest.main() 442