00001
00002 from six import binary_type
00003 from webob import Request
00004 from webob import Response
00005 from webtest.compat import to_bytes
00006 from webtest.compat import PY3
00007 from webtest.compat import OrderedDict
00008 from webtest.debugapp import debug_app
00009 from webtest import http
00010 from tests.compat import unittest
00011 import os
00012 import six
00013 import mock
00014 import webtest
00015
00016
00017 class TestApp(unittest.TestCase):
00018
00019 def setUp(self):
00020 self.app = webtest.TestApp(debug_app)
00021
00022 def test_encode_multipart_relative_to(self):
00023 app = webtest.TestApp(debug_app,
00024 relative_to=os.path.dirname(__file__))
00025 data = app.encode_multipart(
00026 [], [('file', 'html%s404.html' % os.sep)])
00027 self.assertIn(to_bytes('404.html'), data[-1])
00028
00029 def test_encode_multipart(self):
00030 data = self.app.encode_multipart(
00031 [], [('file', 'data.txt', six.b('data'))])
00032 self.assertIn(to_bytes('data.txt'), data[-1])
00033
00034 data = self.app.encode_multipart(
00035 [], [(six.b('file'), six.b('data.txt'), six.b('data'))])
00036 self.assertIn(to_bytes('data.txt'), data[-1])
00037
00038 data = self.app.encode_multipart(
00039 [('key', 'value')], [])
00040 self.assertIn(to_bytes('name="key"'), data[-1])
00041
00042 data = self.app.encode_multipart(
00043 [(six.b('key'), six.b('value'))], [])
00044 self.assertIn(to_bytes('name="key"'), data[-1])
00045
00046 def test_encode_multipart_content_type(self):
00047 data = self.app.encode_multipart(
00048 [], [('file', 'data.txt', six.b('data'),
00049 'text/x-custom-mime-type')])
00050 self.assertIn(to_bytes('Content-Type: text/x-custom-mime-type'),
00051 data[-1])
00052
00053 data = self.app.encode_multipart(
00054 [('file', webtest.Upload('data.txt', six.b('data'),
00055 'text/x-custom-mime-type'))], [])
00056 self.assertIn(to_bytes('Content-Type: text/x-custom-mime-type'),
00057 data[-1])
00058
00059 def test_get_params(self):
00060 resp = self.app.get('/', 'a=b')
00061 resp.mustcontain('a=b')
00062 resp = self.app.get('/?a=b', dict(c='d'))
00063 resp.mustcontain('a=b', 'c=d')
00064 resp = self.app.get('/?a=b&c=d', dict(e='f'))
00065 resp.mustcontain('a=b', 'c=d', 'e=f')
00066
00067 def test_request_with_testrequest(self):
00068 req = webtest.TestRequest.blank('/')
00069 resp = self.app.request(req, method='POST')
00070 resp.charset = 'ascii'
00071 assert 'REQUEST_METHOD: POST' in resp.text
00072
00073 def test_patch(self):
00074 resp = self.app.patch('/')
00075 self.assertIn('PATCH', resp)
00076
00077 resp = self.app.patch('/', xhr=True)
00078 self.assertIn('PATCH', resp)
00079
00080 def test_custom_headers(self):
00081 resp = self.app.post('/', headers={'Accept': 'text/plain'})
00082 resp.charset = 'ascii'
00083 assert 'HTTP_ACCEPT: text/plain' in resp.text
00084
00085
00086 class TestStatus(unittest.TestCase):
00087
00088 def setUp(self):
00089 self.app = webtest.TestApp(debug_app)
00090
00091 def check_status(self, status, awaiting_status=None):
00092 resp = Response()
00093 resp.request = Request.blank('/')
00094 resp.status = status
00095 return self.app._check_status(awaiting_status, resp)
00096
00097 def test_check_status_asterisk(self):
00098 self.assertEqual(self.check_status('200 Ok', '*'), None)
00099
00100 def test_check_status_almost_asterisk(self):
00101 self.assertEqual(self.check_status('200 Ok', '2*'), None)
00102
00103 def test_check_status_tuple(self):
00104 self.assertEqual(self.check_status('200 Ok', (200,)), None)
00105 self.assertRaises(webtest.AppError,
00106 self.check_status, '200 Ok', (400,))
00107
00108 def test_check_status_none(self):
00109 self.assertEqual(self.check_status('200 Ok', None), None)
00110 self.assertRaises(webtest.AppError, self.check_status, '400 Ok')
00111
00112 def test_check_status_with_custom_reason(self):
00113 self.assertEqual(self.check_status('200 Ok', '200 Ok'), None)
00114 self.assertRaises(webtest.AppError,
00115 self.check_status, '200 Ok', '200 Good Response')
00116 self.assertRaises(webtest.AppError,
00117 self.check_status, '200 Ok', '400 Bad Request')
00118
00119
00120 class TestParserFeature(unittest.TestCase):
00121
00122 def test_parser_features(self):
00123 app = webtest.TestApp(debug_app, parser_features='custom')
00124 self.assertEqual(app.RequestClass.ResponseClass.parser_features,
00125 'custom')
00126
00127
00128 class TestAppError(unittest.TestCase):
00129
00130 def test_app_error(self):
00131 resp = Response(to_bytes('blah'))
00132 err = webtest.AppError('message %s', resp)
00133 self.assertEqual(err.args, ('message blah',))
00134
00135 def test_app_error_with_bytes_message(self):
00136 resp = Response(six.u('\xe9').encode('utf8'))
00137 resp.charset = 'utf8'
00138 err = webtest.AppError(to_bytes('message %s'), resp)
00139 self.assertEqual(err.args, (six.u('message \xe9'),))
00140
00141 def test_app_error_with_unicode(self):
00142 err = webtest.AppError(six.u('messag\xe9 %s'), six.u('\xe9'))
00143 self.assertEqual(err.args, (six.u('messag\xe9 \xe9'),))
00144
00145 def test_app_error_misc(self):
00146 resp = Response(six.u('\xe9').encode('utf8'))
00147 resp.charset = ''
00148
00149 webtest.AppError(to_bytes('message %s'), resp)
00150 webtest.AppError(six.u('messag\xe9 %s'), six.b('\xe9'))
00151
00152
00153 class TestPasteVariables(unittest.TestCase):
00154
00155 def call_FUT(self, **kwargs):
00156 def application(environ, start_response):
00157 resp = Response()
00158 environ['paste.testing_variables'].update(kwargs)
00159 return resp(environ, start_response)
00160 return webtest.TestApp(application)
00161
00162 def test_paste_testing_variables_raises(self):
00163 app = self.call_FUT(body='1')
00164 req = Request.blank('/')
00165 self.assertRaises(ValueError, app.do_request, req, '*', False)
00166
00167 def test_paste_testing_variables(self):
00168 app = self.call_FUT(check='1')
00169 req = Request.blank('/')
00170 resp = app.do_request(req, '*', False)
00171 self.assertEqual(resp.check, '1')
00172
00173
00174 class TestCookies(unittest.TestCase):
00175
00176 def test_supports_providing_cookiejar(self):
00177 cookiejar = six.moves.http_cookiejar.CookieJar()
00178 app = webtest.TestApp(debug_app, cookiejar=cookiejar)
00179 self.assertIs(cookiejar, app.cookiejar)
00180
00181 def test_set_cookie(self):
00182 def cookie_app(environ, start_response):
00183 req = Request(environ)
00184 self.assertEqual(req.cookies['foo'], 'bar')
00185 self.assertEqual(req.cookies['fizz'], ';bar=baz')
00186
00187 status = to_bytes("200 OK")
00188 body = ''
00189 headers = [
00190 ('Content-Type', 'text/html'),
00191 ('Content-Length', str(len(body))),
00192 ]
00193 start_response(status, headers)
00194 return [to_bytes(body)]
00195
00196 app = webtest.TestApp(cookie_app)
00197 app.set_cookie('foo', 'bar')
00198 app.set_cookie('fizz', ';bar=baz')
00199 app.get('/')
00200 app.reset()
00201
00202 def test_preserves_cookies(self):
00203 def cookie_app(environ, start_response):
00204 req = Request(environ)
00205 status = "200 OK"
00206 body = '<html><body><a href="/go/">go</a></body></html>'
00207 headers = [
00208 ('Content-Type', 'text/html'),
00209 ('Content-Length', str(len(body))),
00210 ]
00211 if req.path_info != '/go/':
00212 headers.extend([
00213 ('Set-Cookie', 'spam=eggs'),
00214 ('Set-Cookie', 'foo=bar;baz'),
00215 ])
00216 else:
00217 self.assertEquals(dict(req.cookies),
00218 {'spam': 'eggs', 'foo': 'bar'})
00219 self.assertIn('foo=bar', environ['HTTP_COOKIE'])
00220 self.assertIn('spam=eggs', environ['HTTP_COOKIE'])
00221 start_response(status, headers)
00222 return [to_bytes(body)]
00223
00224 app = webtest.TestApp(cookie_app)
00225 self.assertTrue(not app.cookiejar,
00226 'App should initially contain no cookies')
00227
00228 self.assertFalse(app.cookies)
00229 res = app.get('/')
00230 self.assertEqual(app.cookies['spam'], 'eggs')
00231 self.assertEqual(app.cookies['foo'], 'bar')
00232 res = res.click('go')
00233 self.assertEqual(app.cookies['spam'], 'eggs')
00234 self.assertEqual(app.cookies['foo'], 'bar')
00235
00236 app.reset()
00237 self.assertFalse(bool(app.cookies))
00238
00239 def test_secure_cookies(self):
00240 def cookie_app(environ, start_response):
00241 req = Request(environ)
00242 status = "200 OK"
00243 body = '<html><body><a href="/go/">go</a></body></html>'
00244 headers = [
00245 ('Content-Type', 'text/html'),
00246 ('Content-Length', str(len(body))),
00247 ]
00248 if req.path_info != '/go/':
00249 headers.extend([
00250 ('Set-Cookie', 'spam=eggs; secure'),
00251 ('Set-Cookie', 'foo=bar;baz; secure'),
00252 ])
00253 else:
00254 self.assertEquals(dict(req.cookies),
00255 {'spam': 'eggs', 'foo': 'bar'})
00256 self.assertIn('foo=bar', environ['HTTP_COOKIE'])
00257 self.assertIn('spam=eggs', environ['HTTP_COOKIE'])
00258 start_response(status, headers)
00259 return [to_bytes(body)]
00260
00261 app = webtest.TestApp(cookie_app)
00262
00263 self.assertFalse(app.cookies)
00264 res = app.get('https://localhost/')
00265 self.assertEqual(app.cookies['spam'], 'eggs')
00266 self.assertEqual(app.cookies['foo'], 'bar')
00267 res = res.click('go')
00268 self.assertEqual(app.cookies['spam'], 'eggs')
00269 self.assertEqual(app.cookies['foo'], 'bar')
00270
00271 def test_cookies_readonly(self):
00272 app = webtest.TestApp(debug_app)
00273 try:
00274 app.cookies = {}
00275 except:
00276 pass
00277 else:
00278 self.fail('testapp.cookies should be read-only')
00279
00280 @mock.patch('six.moves.http_cookiejar.time.time')
00281 def test_expires_cookies(self, mock_time):
00282 def cookie_app(environ, start_response):
00283 status = to_bytes("200 OK")
00284 body = ''
00285 headers = [
00286 ('Content-Type', 'text/html'),
00287 ('Content-Length', str(len(body))),
00288 ('Set-Cookie',
00289 'spam=eggs; Expires=Tue, 21-Feb-2013 17:45:00 GMT;'),
00290 ]
00291 start_response(status, headers)
00292 return [to_bytes(body)]
00293 app = webtest.TestApp(cookie_app)
00294 self.assertTrue(not app.cookiejar,
00295 'App should initially contain no cookies')
00296
00297 mock_time.return_value = 1361464946.0
00298 app.get('/')
00299 self.assertTrue(app.cookies, 'Response should have set cookies')
00300
00301 mock_time.return_value = 1461464946.0
00302 app.get('/')
00303 self.assertFalse(app.cookies, 'Response should have unset cookies')
00304
00305 def test_http_cookie(self):
00306 def cookie_app(environ, start_response):
00307 req = Request(environ)
00308 status = to_bytes("200 OK")
00309 body = 'Cookie.'
00310 assert dict(req.cookies) == {'spam': 'eggs'}
00311 assert environ['HTTP_COOKIE'] == 'spam=eggs'
00312 headers = [
00313 ('Content-Type', 'text/html'),
00314 ('Content-Length', str(len(body))),
00315 ]
00316 start_response(status, headers)
00317 return [to_bytes(body)]
00318
00319 app = webtest.TestApp(cookie_app)
00320 self.assertTrue(not app.cookies,
00321 'App should initially contain no cookies')
00322
00323 res = app.get('/', headers=[('Cookie', 'spam=eggs')])
00324 self.assertFalse(app.cookies,
00325 'Response should not have set cookies')
00326 self.assertEqual(res.request.environ['HTTP_COOKIE'], 'spam=eggs')
00327 self.assertEqual(dict(res.request.cookies), {'spam': 'eggs'})
00328
00329 def test_http_localhost_cookie(self):
00330 def cookie_app(environ, start_response):
00331 status = to_bytes("200 OK")
00332 body = 'Cookie.'
00333 headers = [
00334 ('Content-Type', 'text/html'),
00335 ('Content-Length', str(len(body))),
00336 ('Set-Cookie',
00337 'spam=eggs; Domain=localhost;'),
00338 ]
00339 start_response(status, headers)
00340 return [to_bytes(body)]
00341
00342 app = webtest.TestApp(cookie_app)
00343 self.assertTrue(not app.cookies,
00344 'App should initially contain no cookies')
00345
00346 res = app.get('/')
00347 res = app.get('/')
00348 self.assertTrue(app.cookies,
00349 'Response should not have set cookies')
00350 self.assertEqual(res.request.environ['HTTP_COOKIE'], 'spam=eggs')
00351 self.assertEqual(dict(res.request.cookies), {'spam': 'eggs'})
00352
00353
00354 class TestEnviron(unittest.TestCase):
00355
00356 def test_get_extra_environ(self):
00357 app = webtest.TestApp(debug_app,
00358 extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru',
00359 'foo': 'bar'})
00360 res = app.get('http://localhost/')
00361 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00362 self.assertIn("foo: 'bar'", res, res)
00363
00364 res = app.get('http://localhost/', extra_environ={'foo': 'baz'})
00365 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00366 self.assertIn("foo: 'baz'", res, res)
00367
00368 def test_post_extra_environ(self):
00369 app = webtest.TestApp(debug_app,
00370 extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru',
00371 'foo': 'bar'})
00372 res = app.post('http://localhost/')
00373 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00374 self.assertIn("foo: 'bar'", res, res)
00375
00376 res = app.post('http://localhost/', extra_environ={'foo': 'baz'})
00377 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00378 self.assertIn("foo: 'baz'", res, res)
00379
00380 def test_request_extra_environ(self):
00381 app = webtest.TestApp(debug_app,
00382 extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru',
00383 'foo': 'bar'})
00384 res = app.request('http://localhost/', method='GET')
00385 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00386 self.assertIn("foo: 'bar'", res, res)
00387
00388 res = app.request('http://localhost/', method='GET',
00389 environ={'foo': 'baz'})
00390 self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res)
00391 self.assertIn("foo: 'baz'", res, res)
00392
00393
00394 deform_upload_fields_text = """
00395 <input type="hidden" name="_charset_" />
00396 <input type="hidden" name="__formid__" value="deform"/>
00397 <input type="text" name="title" value="" id="deformField1"/>
00398 <input type="hidden" name="__start__" value="fileupload:mapping"/>
00399 <input type="file" name="fileupload" id="deformField2"/>
00400 <input type="hidden" name="__end__" value="fileupload:mapping"/>
00401 <textarea id="deformField3" name="description" rows="10" cols="60">
00402 </textarea>
00403 <button
00404 id="deformSubmit"
00405 name="Submit"
00406 type="submit"
00407 value="Submit">
00408 Submit
00409 </button>
00410 """
00411
00412
00413 def get_submit_app(form_id, form_fields_text):
00414 def submit_app(environ, start_response):
00415 req = Request(environ)
00416 status = "200 OK"
00417 if req.method == "GET":
00418 body = """
00419 <html>
00420 <head><title>form page</title></head>
00421 <body>
00422 <form
00423 id="%s"
00424 action=""
00425 method="POST"
00426 enctype="multipart/form-data"
00427 accept-charset="utf-8">
00428
00429 %s
00430 </form>
00431 </body>
00432 </html>
00433 """ % (form_id, form_fields_text)
00434 else:
00435 body_head = """
00436 <html>
00437 <head><title>display page</title></head>
00438 <body>
00439 """
00440
00441 body_parts = []
00442 for (name, value) in req.POST.items():
00443 if hasattr(value, 'filename'):
00444 body_parts.append("%s:%s:%s\n" % (
00445 name,
00446 value.filename,
00447 value.value.decode('ascii')))
00448 else:
00449 body_parts.append("%s:%s\n" % (
00450 name, value))
00451
00452 body_foot = """ </body>
00453 </html>
00454 """
00455 body = body_head + "".join(body_parts) + body_foot
00456 if not isinstance(body, binary_type):
00457 body = body.encode('utf8')
00458 headers = [
00459 ('Content-Type', 'text/html; charset=utf-8'),
00460 ('Content-Length', str(len(body)))]
00461 start_response(status, headers)
00462 return [body]
00463 return submit_app
00464
00465
00466 class TestFieldOrder(unittest.TestCase):
00467
00468 def test_submit_with_file_upload(self):
00469 uploaded_file_name = 'test.txt'
00470 uploaded_file_contents = 'test content file upload'
00471 if PY3:
00472 uploaded_file_contents = to_bytes(uploaded_file_contents)
00473
00474 deform_upload_file_app = get_submit_app('deform',
00475 deform_upload_fields_text)
00476 app = webtest.TestApp(deform_upload_file_app)
00477 res = app.get('/')
00478 self.assertEqual(res.status_int, 200)
00479 self.assertEqual(
00480 res.headers['content-type'], 'text/html; charset=utf-8')
00481 self.assertEqual(res.content_type, 'text/html')
00482 self.assertEqual(res.charset, 'utf-8')
00483
00484 single_form = res.forms["deform"]
00485 single_form.set("title", "testtitle")
00486 single_form.set("fileupload",
00487 (uploaded_file_name, uploaded_file_contents))
00488 single_form.set("description", "testdescription")
00489 display = single_form.submit("Submit")
00490 self.assertIn("""
00491 _charset_:
00492 __formid__:deform
00493 title:testtitle
00494 __start__:fileupload:mapping
00495 fileupload:test.txt:test content file upload
00496 __end__:fileupload:mapping
00497 description:testdescription
00498 Submit:Submit
00499 """.strip(), display, display)
00500
00501 def test_post_with_file_upload(self):
00502 uploaded_file_name = 'test.txt'
00503 uploaded_file_contents = 'test content file upload'
00504 if PY3:
00505 uploaded_file_contents = to_bytes(uploaded_file_contents)
00506
00507 deform_upload_file_app = get_submit_app('deform',
00508 deform_upload_fields_text)
00509 app = webtest.TestApp(deform_upload_file_app)
00510 display = app.post("/", OrderedDict([
00511 ('_charset_', ''),
00512 ('__formid__', 'deform'),
00513 ('title', 'testtitle'),
00514 ('__start__', 'fileupload:mapping'),
00515 ('fileupload', webtest.Upload(uploaded_file_name,
00516 uploaded_file_contents)),
00517 ('__end__', 'fileupload:mapping'),
00518 ('description', 'testdescription'),
00519 ('Submit', 'Submit')]))
00520
00521 self.assertIn("""
00522 _charset_:
00523 __formid__:deform
00524 title:testtitle
00525 __start__:fileupload:mapping
00526 fileupload:test.txt:test content file upload
00527 __end__:fileupload:mapping
00528 description:testdescription
00529 Submit:Submit""".strip(), display, display)
00530
00531 def test_field_order_is_across_all_fields(self):
00532 fields = """
00533 <input type="text" name="letter" value="a">
00534 <input type="text" name="letter" value="b">
00535 <input type="text" name="number" value="1">
00536 <input type="text" name="letter" value="c">
00537 <input type="text" name="number" value="2">
00538 <input type="submit" name="save" value="Save 1">
00539 <input type="text" name="letter" value="d">
00540 <input type="submit" name="save" value="Save 2">
00541 <input type="text" name="letter" value="e">
00542 """
00543 submit_app = get_submit_app('test', fields)
00544 app = webtest.TestApp(submit_app)
00545 get_res = app.get("/")
00546
00547 display = get_res.forms[0].submit('save', 1)
00548 self.assertIn("""
00549 letter:a
00550 letter:b
00551 number:1
00552 letter:c
00553 number:2
00554 letter:d
00555 save:Save 2
00556 letter:e""".strip(), display, display)
00557
00558
00559 class TestFragments(unittest.TestCase):
00560
00561 def test_url_without_fragments(self):
00562 app = webtest.TestApp(debug_app)
00563 res = app.get('http://localhost/')
00564 self.assertEqual(res.status_int, 200)
00565
00566 def test_url_with_fragments(self):
00567 app = webtest.TestApp(debug_app)
00568 res = app.get('http://localhost/#ananchor')
00569 self.assertEqual(res.status_int, 200)
00570
00571
00572 def application(environ, start_response):
00573 req = Request(environ)
00574 if req.path_info == '/redirect':
00575 req.path_info = '/path'
00576 resp = Response()
00577 resp.status = '302 Found'
00578 resp.location = req.path
00579 else:
00580 resp = Response()
00581 resp.body = to_bytes(
00582 '<html><body><a href="%s">link</a></body></html>' % req.path)
00583 return resp(environ, start_response)
00584
00585
00586 class TestScriptName(unittest.TestCase):
00587
00588 def test_script_name(self):
00589 app = webtest.TestApp(application)
00590
00591 resp = app.get('/script', extra_environ={'SCRIPT_NAME': '/script'})
00592 resp.mustcontain('href="/script"')
00593
00594 resp = app.get('/script/redirect',
00595 extra_environ={'SCRIPT_NAME': '/script'})
00596 self.assertEqual(resp.status_int, 302)
00597 self.assertEqual(resp.location,
00598 'http://localhost/script/path',
00599 resp.location)
00600
00601 resp = resp.follow(extra_environ={'SCRIPT_NAME': '/script'})
00602 resp.mustcontain('href="/script/path"')
00603 resp = resp.click('link')
00604 resp.mustcontain('href="/script/path"')
00605
00606 def test_app_script_name(self):
00607 app = webtest.TestApp(application,
00608 extra_environ={'SCRIPT_NAME': '/script'})
00609 resp = app.get('/script/redirect')
00610 self.assertEqual(resp.status_int, 302)
00611 self.assertEqual(resp.location,
00612 'http://localhost/script/path',
00613 resp.location)
00614
00615 resp = resp.follow()
00616 resp.mustcontain('href="/script/path"')
00617 resp = resp.click('link')
00618 resp.mustcontain('href="/script/path"')
00619
00620 def test_script_name_doesnt_match(self):
00621 app = webtest.TestApp(application)
00622 resp = app.get('/path', extra_environ={'SCRIPT_NAME': '/script'})
00623 resp.mustcontain('href="/script/path"')
00624
00625
00626 class TestWSGIProxy(unittest.TestCase):
00627
00628 def setUp(self):
00629 self.s = http.StopableWSGIServer.create(debug_app)
00630 self.s.wait()
00631
00632 def test_proxy_with_url(self):
00633 app = webtest.TestApp(self.s.application_url)
00634 resp = app.get('/')
00635 self.assertEqual(resp.status_int, 200)
00636
00637 def test_proxy_with_environ(self):
00638 def app(environ, start_response):
00639 pass
00640 os.environ['WEBTEST_TARGET_URL'] = self.s.application_url
00641 app = webtest.TestApp(app)
00642 del os.environ['WEBTEST_TARGET_URL']
00643 resp = app.get('/')
00644 self.assertEqual(resp.status_int, 200)
00645
00646 def tearDown(self):
00647 self.s.shutdown()
00648
00649
00650 class TestAppXhrParam(unittest.TestCase):
00651
00652 def setUp(self):
00653 self.app = webtest.TestApp(debug_app)
00654
00655 def test_xhr_param_change_headers(self):
00656 app = self.app
00657
00658
00659 functions = (app.get, app.post, app.delete,
00660 app.put, app.options)
00661 for func in functions:
00662 resp = func('/', xhr=True)
00663 resp.charset = 'ascii'
00664 self.assertIn('HTTP_X_REQUESTED_WITH: XMLHttpRequest',
00665 resp.text)