test_response.py
Go to the documentation of this file.
00001 #coding: utf-8
00002 from __future__ import unicode_literals
00003 
00004 import sys
00005 
00006 
00007 import webtest
00008 from webtest.debugapp import debug_app
00009 from webob import Request
00010 from webob.response import gzip_app_iter
00011 from webtest.compat import PY3
00012 
00013 from tests.compat import unittest
00014 
00015 import webbrowser
00016 
00017 
00018 def links_app(environ, start_response):
00019     req = Request(environ)
00020     status = "200 OK"
00021     responses = {
00022         '/': """
00023             <html>
00024                 <head><title>page with links</title></head>
00025                 <body>
00026                     <a href="/foo/">Foo</a>
00027                     <a href='bar'>Bar</a>
00028                     <a href='baz/' id='id_baz'>Baz</a>
00029                     <a href='#' id='fake_baz'>Baz</a>
00030                     <a href='javascript:alert("123")' id='js_baz'>Baz</a>
00031                     <script>
00032                         var link = "<a href='/boo/'>Boo</a>";
00033                     </script>
00034                     <a href='/spam/'>Click me!</a>
00035                     <a href='/egg/'>Click me!</a>
00036                     <button
00037                         id="button1"
00038                         onclick="location.href='/foo/'"
00039                         >Button</button>
00040                     <button
00041                         id="button2">Button</button>
00042                     <button
00043                         id="button3"
00044                         onclick="lomistakecation.href='/foo/'"
00045                         >Button</button>
00046                 </body>
00047             </html>
00048             """,
00049 
00050         '/foo/': (
00051             '<html><body>This is foo. <a href="bar">Bar</a> '
00052             '</body></html>'
00053         ),
00054         '/foo/bar': '<html><body>This is foobar.</body></html>',
00055         '/bar': '<html><body>This is bar.</body></html>',
00056         '/baz/': '<html><body>This is baz.</body></html>',
00057         '/spam/': '<html><body>This is spam.</body></html>',
00058         '/egg/': '<html><body>Just eggs.</body></html>',
00059 
00060         '/utf8/': """
00061             <html>
00062                 <head><title>Тестовая страница</title></head>
00063                 <body>
00064                     <a href='/foo/'>Менделеев</a>
00065                     <a href='/baz/' title='Поэт'>Пушкин</a>
00066                     <img src='/egg/' title='Поэт'>
00067                     <script>
00068                         var link = "<a href='/boo/'>Злодейская ссылка</a>";
00069                     </script>
00070                 </body>
00071             </html>
00072         """,
00073         '/no_form/': """
00074             <html>
00075                 <head><title>Page without form</title></head>
00076                 <body>
00077                     <h1>This is not the form you are looking for</h1>
00078                 </body>
00079             </html>
00080         """,
00081         '/one_forms/': """
00082             <html>
00083                 <head><title>Page without form</title></head>
00084                 <body>
00085                     <form method="POST" id="first_form"></form>
00086                 </body>
00087             </html>
00088         """,
00089         '/many_forms/': """
00090             <html>
00091                 <head><title>Page without form</title></head>
00092                 <body>
00093                     <form method="POST" id="first_form"></form>
00094                     <form method="POST" id="second_form"></form>
00095                 </body>
00096             </html>
00097         """,
00098         '/html_in_anchor/': """
00099             <html>
00100                 <head><title>Page with HTML in an anchor tag</title></head>
00101                 <body>
00102                     <a href='/foo/'>Foo Bar<span class='baz qux'>Quz</span></a>
00103                 </body>
00104             </html>
00105         """,
00106         '/json/': '{"foo": "bar"}',
00107     }
00108 
00109     utf8_paths = ['/utf8/']
00110     body = responses[req.path_info]
00111     body = body.encode('utf8')
00112     headers = [
00113         ('Content-Type', str('text/html')),
00114         ('Content-Length', str(len(body)))
00115     ]
00116     if req.path_info in utf8_paths:
00117         headers[0] = ('Content-Type', str('text/html; charset=utf-8'))
00118 
00119     start_response(str(status), headers)
00120     return [body]
00121 
00122 
00123 def gzipped_app(environ, start_response):
00124     status = "200 OK"
00125     encoded_body = list(gzip_app_iter([b'test']))
00126     headers = [
00127         ('Content-Type', str('text/html')),
00128         ('Content-Encoding', str('gzip')),
00129     ]
00130 
00131     start_response(str(status), headers)
00132     return encoded_body
00133 
00134 
00135 class TestResponse(unittest.TestCase):
00136     def test_repr(self):
00137         def _repr(v):
00138             br = repr(v)
00139             if len(br) > 18:
00140                 br = br[:10] + '...' + br[-5:]
00141                 br += '/%s' % len(v)
00142 
00143             return br
00144 
00145         app = webtest.TestApp(debug_app)
00146         res = app.post('/')
00147         self.assertEqual(
00148             repr(res),
00149             '<200 OK text/plain body=%s>' % _repr(res.body)
00150         )
00151         res.content_type = None
00152         self.assertEqual(
00153             repr(res),
00154             '<200 OK body=%s>' % _repr(res.body)
00155         )
00156         res.location = 'http://pylons.org'
00157         self.assertEqual(
00158             repr(res),
00159             '<200 OK location: http://pylons.org body=%s>' % _repr(res.body)
00160         )
00161 
00162         res.body = b''
00163         self.assertEqual(
00164             repr(res),
00165             '<200 OK location: http://pylons.org no body>'
00166         )
00167 
00168     def test_mustcontains(self):
00169         app = webtest.TestApp(debug_app)
00170         res = app.post('/', params='foobar')
00171         res.mustcontain('foobar')
00172         self.assertRaises(IndexError, res.mustcontain, 'not found')
00173         res.mustcontain('foobar', no='not found')
00174         res.mustcontain('foobar', no=['not found', 'not found either'])
00175         self.assertRaises(IndexError, res.mustcontain, no='foobar')
00176         self.assertRaises(
00177             TypeError,
00178             res.mustcontain, invalid_param='foobar'
00179         )
00180 
00181     def test_click(self):
00182         app = webtest.TestApp(links_app)
00183         self.assertIn('This is foo.', app.get('/').click('Foo'))
00184         self.assertIn(
00185             'This is foobar.',
00186             app.get('/').click('Foo').click('Bar')
00187         )
00188         self.assertIn('This is bar.', app.get('/').click('Bar'))
00189         # should skip non-clickable links
00190         self.assertIn(
00191             'This is baz.',
00192             app.get('/').click('Baz')
00193         )
00194         self.assertIn('This is baz.', app.get('/').click(linkid='id_baz'))
00195         self.assertIn('This is baz.', app.get('/').click(href='baz/'))
00196         self.assertIn(
00197             'This is spam.',
00198             app.get('/').click('Click me!', index=0)
00199         )
00200         self.assertIn(
00201             'Just eggs.',
00202             app.get('/').click('Click me!', index=1)
00203         )
00204         self.assertIn(
00205             'This is foo.',
00206             app.get('/html_in_anchor/').click('baz qux')
00207         )
00208 
00209         def dont_match_anchor_tag():
00210             app.get('/html_in_anchor/').click('href')
00211         self.assertRaises(IndexError, dont_match_anchor_tag)
00212 
00213         def multiple_links():
00214             app.get('/').click('Click me!')
00215         self.assertRaises(IndexError, multiple_links)
00216 
00217         def invalid_index():
00218             app.get('/').click('Click me!', index=2)
00219         self.assertRaises(IndexError, invalid_index)
00220 
00221         def no_links_found():
00222             app.get('/').click('Ham')
00223         self.assertRaises(IndexError, no_links_found)
00224 
00225         def tag_inside_script():
00226             app.get('/').click('Boo')
00227         self.assertRaises(IndexError, tag_inside_script)
00228 
00229     def test_click_utf8(self):
00230         app = webtest.TestApp(links_app, use_unicode=False)
00231         resp = app.get('/utf8/')
00232         self.assertEqual(resp.charset, 'utf-8')
00233         if not PY3:
00234             # No need to deal with that in Py3
00235             self.assertIn("Тестовая страница".encode('utf8'), resp)
00236             self.assertIn("Тестовая страница", resp, resp)
00237             target = 'Менделеев'.encode('utf8')
00238             self.assertIn('This is foo.', resp.click(target, verbose=True))
00239 
00240     def test_click_u(self):
00241         app = webtest.TestApp(links_app)
00242         resp = app.get('/utf8/')
00243 
00244         self.assertIn("Тестовая страница", resp)
00245         self.assertIn('This is foo.', resp.click('Менделеев'))
00246 
00247     def test_clickbutton(self):
00248         app = webtest.TestApp(links_app)
00249         self.assertIn(
00250             'This is foo.',
00251             app.get('/').clickbutton(buttonid='button1', verbose=True)
00252         )
00253         self.assertRaises(
00254             IndexError,
00255             app.get('/').clickbutton, buttonid='button2'
00256         )
00257         self.assertRaises(
00258             IndexError,
00259             app.get('/').clickbutton, buttonid='button3'
00260         )
00261 
00262     def test_xml_attribute(self):
00263         app = webtest.TestApp(links_app)
00264 
00265         resp = app.get('/no_form/')
00266         self.assertRaises(
00267             AttributeError,
00268             getattr,
00269             resp, 'xml'
00270         )
00271 
00272         resp.content_type = 'text/xml'
00273         resp.xml
00274 
00275     @unittest.skipIf('PyPy' in sys.version, 'skip lxml tests on pypy')
00276     def test_lxml_attribute(self):
00277         app = webtest.TestApp(links_app)
00278         resp = app.post('/')
00279         resp.content_type = 'text/xml'
00280         print(resp.body)
00281         print(resp.lxml)
00282 
00283     def test_html_attribute(self):
00284         app = webtest.TestApp(links_app)
00285         res = app.post('/')
00286         res.content_type = 'text/plain'
00287         self.assertRaises(
00288             AttributeError,
00289             getattr, res, 'html'
00290         )
00291 
00292     def test_no_form(self):
00293         app = webtest.TestApp(links_app)
00294 
00295         resp = app.get('/no_form/')
00296         self.assertRaises(
00297             TypeError,
00298             getattr,
00299             resp, 'form'
00300         )
00301 
00302     def test_one_forms(self):
00303         app = webtest.TestApp(links_app)
00304 
00305         resp = app.get('/one_forms/')
00306         self.assertEqual(resp.form.id, 'first_form')
00307 
00308     def test_too_many_forms(self):
00309         app = webtest.TestApp(links_app)
00310 
00311         resp = app.get('/many_forms/')
00312         self.assertRaises(
00313             TypeError,
00314             getattr,
00315             resp, 'form'
00316         )
00317 
00318     def test_showbrowser(self):
00319         def open_new(f):
00320             self.filename = f
00321 
00322         webbrowser.open_new = open_new
00323         app = webtest.TestApp(debug_app)
00324         res = app.post('/')
00325         res.showbrowser()
00326 
00327     def test_unicode_normal_body(self):
00328         app = webtest.TestApp(debug_app)
00329         res = app.post('/')
00330         self.assertRaises(
00331             AttributeError,
00332             getattr, res, 'unicode_normal_body'
00333         )
00334         res.charset = 'latin1'
00335         res.body = 'été'.encode('latin1')
00336         self.assertEqual(res.unicode_normal_body, 'été')
00337 
00338     def test_testbody(self):
00339         app = webtest.TestApp(debug_app)
00340         res = app.post('/')
00341         res.charset = 'utf8'
00342         res.body = 'été'.encode('latin1')
00343         res.testbody
00344 
00345     def test_xml(self):
00346         app = webtest.TestApp(links_app)
00347 
00348         resp = app.get('/no_form/')
00349         self.assertRaises(
00350             AttributeError,
00351             getattr,
00352             resp, 'xml'
00353         )
00354 
00355         resp.content_type = 'text/xml'
00356         resp.xml
00357 
00358     def test_json(self):
00359         app = webtest.TestApp(links_app)
00360 
00361         resp = app.get('/json/')
00362         with self.assertRaises(AttributeError):
00363             resp.json
00364 
00365         resp.content_type = 'text/json'
00366         self.assertIn('foo', resp.json)
00367 
00368         resp.content_type = 'application/json'
00369         self.assertIn('foo', resp.json)
00370 
00371         resp.content_type = 'application/vnd.webtest+json'
00372         self.assertIn('foo', resp.json)
00373 
00374     def test_unicode(self):
00375         app = webtest.TestApp(links_app)
00376 
00377         resp = app.get('/')
00378         if not PY3:
00379             unicode(resp)
00380 
00381         print(resp.__unicode__())
00382 
00383     def test_content_dezips(self):
00384         app = webtest.TestApp(gzipped_app)
00385         resp = app.get('/')
00386         self.assertEqual(resp.body, b'test')
00387 
00388 
00389 class TestFollow(unittest.TestCase):
00390 
00391     def get_redirects_app(self, count=1, locations=None):
00392         """Return an app that issues a redirect ``count`` times"""
00393 
00394         remaining_redirects = [count]  # this means "nonlocal"
00395         if locations is None:
00396             locations = ['/'] * count
00397 
00398         def app(environ, start_response):
00399             headers = [('Content-Type', str('text/html'))]
00400 
00401             if remaining_redirects[0] == 0:
00402                 status = "200 OK"
00403                 body = b"done"
00404             else:
00405                 status = "302 Found"
00406                 body = b''
00407                 nextloc = str(locations.pop(0))
00408                 headers.append(('location', nextloc))
00409                 remaining_redirects[0] -= 1
00410 
00411             headers.append(('Content-Length', str(len(body))))
00412             start_response(str(status), headers)
00413             return [body]
00414 
00415         return webtest.TestApp(app)
00416 
00417     def test_follow_with_cookie(self):
00418         app = webtest.TestApp(debug_app)
00419         app.get('/?header-set-cookie=foo=bar')
00420         self.assertEqual(app.cookies['foo'], 'bar')
00421         resp = app.get('/?status=302%20Found&header-location=/')
00422         resp = resp.follow()
00423         resp.mustcontain('HTTP_COOKIE: foo=bar')
00424 
00425     def test_follow(self):
00426         app = self.get_redirects_app(1)
00427         resp = app.get('/')
00428         self.assertEqual(resp.status_int, 302)
00429 
00430         resp = resp.follow()
00431         self.assertEqual(resp.body, b'done')
00432 
00433         # can't follow non-redirect
00434         self.assertRaises(AssertionError, resp.follow)
00435 
00436     def test_follow_relative(self):
00437         app = self.get_redirects_app(2, ['hello/foo/', 'bar'])
00438         resp = app.get('/')
00439         self.assertEqual(resp.status_int, 302)
00440         resp = resp.follow()
00441         self.assertEqual(resp.status_int, 302)
00442         resp = resp.follow()
00443         self.assertEqual(resp.body, b'done')
00444         self.assertEqual(resp.request.url, 'http://localhost/hello/foo/bar')
00445 
00446     def test_follow_twice(self):
00447         app = self.get_redirects_app(2)
00448         resp = app.get('/').follow()
00449         self.assertEqual(resp.status_int, 302)
00450         resp = resp.follow()
00451         self.assertEqual(resp.status_int, 200)
00452 
00453     def test_maybe_follow_200(self):
00454         app = self.get_redirects_app(0)
00455         resp = app.get('/').maybe_follow()
00456         self.assertEqual(resp.body, b'done')
00457 
00458     def test_maybe_follow_once(self):
00459         app = self.get_redirects_app(1)
00460         resp = app.get('/').maybe_follow()
00461         self.assertEqual(resp.body, b'done')
00462 
00463     def test_maybe_follow_twice(self):
00464         app = self.get_redirects_app(2)
00465         resp = app.get('/').maybe_follow()
00466         self.assertEqual(resp.body, b'done')
00467 
00468     def test_maybe_follow_infinite(self):
00469         app = self.get_redirects_app(100000)
00470         self.assertRaises(AssertionError, app.get('/').maybe_follow)


webtest
Author(s): AlexV
autogenerated on Sat Mar 25 2017 03:32:05