import webtest from webtest.debugapp import debug_app from webob import Request from webob.response import gzip_app_iter from tests.compat import unittest import webbrowser def links_app(environ, start_response): req = Request(environ) status = "200 OK" responses = { '/': """ page with links Foo Bar Baz Baz Baz Click me! Click me! """, '/foo/': ( 'This is foo. Bar ' '' ), '/foo/bar': 'This is foobar.', '/bar': 'This is bar.', '/baz/': 'This is baz.', '/spam/': 'This is spam.', '/egg/': 'Just eggs.', '/utf8/': """ Тестовая страница Менделеев Пушкин """, '/no_form/': """ Page without form

This is not the form you are looking for

""", '/one_forms/': """ Page without form
""", '/many_forms/': """ Page without form
""", '/html_in_anchor/': """ Page with HTML in an anchor tag Foo BarQuz """, '/json/': '{"foo": "bar"}', } utf8_paths = ['/utf8/'] body = responses[req.path_info] body = body.encode('utf8') headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))) ] if req.path_info in utf8_paths: headers[0] = ('Content-Type', 'text/html; charset=utf-8') # PEP 3333 requires native strings: headers = [(str(k), str(v)) for k, v in headers] start_response(str(status), headers) return [body] def svg_application(env, start_response): start_response('200 OK', [('Content-Type', 'image/svg+xml')]) return [ b"""""" b"""""" b"""""" ] def gzipped_app(environ, start_response): status = "200 OK" encoded_body = list(gzip_app_iter([b'test'])) headers = [ ('Content-Type', 'text/html'), ('Content-Encoding', 'gzip'), ] # PEP 3333 requires native strings: headers = [(str(k), str(v)) for k, v in headers] start_response(str(status), headers) return encoded_body class TestResponse(unittest.TestCase): def test_repr(self): def _repr(v): br = repr(v) if len(br) > 18: br = br[:10] + '...' + br[-5:] br += '/%s' % len(v) return br app = webtest.TestApp(debug_app) res = app.post('/') self.assertEqual( repr(res), '<200 OK text/plain body=%s>' % _repr(res.body) ) res.content_type = None self.assertEqual( repr(res), '<200 OK body=%s>' % _repr(res.body) ) res.location = 'http://pylons.org' self.assertEqual( repr(res), '<200 OK location: http://pylons.org body=%s>' % _repr(res.body) ) res.body = b'' self.assertEqual( repr(res), '<200 OK location: http://pylons.org no body>' ) def test_mustcontains(self): app = webtest.TestApp(debug_app) res = app.post('/', params='foobar') res.mustcontain('foobar') self.assertRaises(IndexError, res.mustcontain, 'not found') res.mustcontain('foobar', no='not found') res.mustcontain('foobar', no=['not found', 'not found either']) self.assertRaises(IndexError, res.mustcontain, no='foobar') self.assertRaises( TypeError, res.mustcontain, invalid_param='foobar' ) def test_click(self): app = webtest.TestApp(links_app) self.assertIn('This is foo.', app.get('/').click('Foo')) self.assertIn( 'This is foobar.', app.get('/').click('Foo').click('Bar') ) self.assertIn('This is bar.', app.get('/').click('Bar')) # should skip non-clickable links self.assertIn( 'This is baz.', app.get('/').click('Baz') ) self.assertIn('This is baz.', app.get('/').click(linkid='id_baz')) self.assertIn('This is baz.', app.get('/').click(href='baz/')) self.assertIn( 'This is spam.', app.get('/').click('Click me!', index=0) ) self.assertIn( 'Just eggs.', app.get('/').click('Click me!', index=1) ) self.assertIn( 'This is foo.', app.get('/html_in_anchor/').click('baz qux') ) def dont_match_anchor_tag(): app.get('/html_in_anchor/').click('href') self.assertRaises(IndexError, dont_match_anchor_tag) def multiple_links(): app.get('/').click('Click me!') self.assertRaises(IndexError, multiple_links) def invalid_index(): app.get('/').click('Click me!', index=2) self.assertRaises(IndexError, invalid_index) def no_links_found(): app.get('/').click('Ham') self.assertRaises(IndexError, no_links_found) def tag_inside_script(): app.get('/').click('Boo') self.assertRaises(IndexError, tag_inside_script) def test_click_utf8(self): app = webtest.TestApp(links_app, use_unicode=False) resp = app.get('/utf8/') self.assertEqual(resp.charset, 'utf-8') def test_click_u(self): app = webtest.TestApp(links_app) resp = app.get('/utf8/') self.assertIn("Тестовая страница", resp) self.assertIn('This is foo.', resp.click('Менделеев')) def test_clickbutton(self): app = webtest.TestApp(links_app) self.assertIn( 'This is foo.', app.get('/').clickbutton(buttonid='button1', verbose=True) ) self.assertIn( 'This is foo.', app.get('/').clickbutton(buttonid='button3', onclick=r".*href='(.*?)'", verbose=True) ) self.assertRaises( IndexError, app.get('/').clickbutton, buttonid='button2' ) self.assertRaises( IndexError, app.get('/').clickbutton, buttonid='button3' ) def test_referer(self): app = webtest.TestApp(links_app) resp = app.get('/').click('Foo') self.assertIn('Referer', resp.request.headers) self.assertEqual(resp.request.headers['Referer'], 'http://localhost/') resp = app.get('/').clickbutton(buttonid='button1') self.assertIn('Referer', resp.request.headers) self.assertEqual(resp.request.headers['Referer'], 'http://localhost/') resp = app.get('/one_forms/').form.submit() self.assertIn('Referer', resp.request.headers) self.assertEqual(resp.request.headers['Referer'], 'http://localhost/one_forms/') def test_xml_attribute(self): app = webtest.TestApp(links_app) resp = app.get('/no_form/') self.assertRaises( AttributeError, getattr, resp, 'xml' ) resp.content_type = 'text/xml' resp.xml def test_lxml_attribute(self): app = webtest.TestApp(links_app) resp = app.post('/') resp.content_type = 'text/xml' print(resp.body) print(resp.lxml) def test_lxml_attribute_with_encoding_declaration(self): app = webtest.TestApp(svg_application) resp = app.get('/') print(resp.body) print(resp.lxml) def test_html_attribute(self): app = webtest.TestApp(links_app) res = app.post('/') res.content_type = 'text/plain' self.assertRaises( AttributeError, getattr, res, 'html' ) def test_no_form(self): app = webtest.TestApp(links_app) resp = app.get('/no_form/') self.assertRaises( TypeError, getattr, resp, 'form' ) def test_one_forms(self): app = webtest.TestApp(links_app) resp = app.get('/one_forms/') self.assertEqual(resp.form.id, 'first_form') def test_too_many_forms(self): app = webtest.TestApp(links_app) resp = app.get('/many_forms/') self.assertRaises( TypeError, getattr, resp, 'form' ) def test_showbrowser(self): def open_new(f): self.filename = f webbrowser.open_new = open_new app = webtest.TestApp(debug_app) res = app.post('/') res.showbrowser() def test_unicode_normal_body(self): app = webtest.TestApp(debug_app) res = app.post('/') self.assertRaises( AttributeError, getattr, res, 'unicode_normal_body' ) res.charset = 'latin1' res.body = 'été'.encode('latin1') self.assertEqual(res.unicode_normal_body, 'été') def test_testbody(self): app = webtest.TestApp(debug_app) res = app.post('/') res.charset = 'utf8' res.body = 'été'.encode('latin1') res.testbody def test_xml(self): app = webtest.TestApp(links_app) resp = app.get('/no_form/') self.assertRaises( AttributeError, getattr, resp, 'xml' ) resp.content_type = 'text/xml' resp.xml def test_json(self): app = webtest.TestApp(links_app) resp = app.get('/json/') with self.assertRaises(AttributeError): resp.json resp.content_type = 'text/json' self.assertIn('foo', resp.json) resp.content_type = 'application/json' self.assertIn('foo', resp.json) resp.content_type = 'application/vnd.webtest+json' self.assertIn('foo', resp.json) def test_unicode(self): app = webtest.TestApp(links_app) resp = app.get('/') print(resp.__unicode__()) def test_content_dezips(self): app = webtest.TestApp(gzipped_app) resp = app.get('/') self.assertEqual(resp.body, b'test') class TestFollow(unittest.TestCase): def get_redirects_app(self, count=1, locations=None): """Return an app that issues a redirect ``count`` times""" remaining_redirects = [count] # this means "nonlocal" if locations is None: locations = ['/'] * count def app(environ, start_response): headers = [('Content-Type', 'text/html')] if remaining_redirects[0] == 0: status = "200 OK" body = b"done" else: status = "302 Found" body = b'' nextloc = str(locations.pop(0)) headers.append(('location', nextloc)) remaining_redirects[0] -= 1 headers.append(('Content-Length', str(len(body)))) # PEP 3333 requires native strings: headers = [(str(k), str(v)) for k, v in headers] start_response(str(status), headers) return [body] return webtest.TestApp(app) def test_follow_with_cookie(self): app = webtest.TestApp(debug_app) app.get('/?header-set-cookie=foo=bar') self.assertEqual(app.cookies['foo'], 'bar') resp = app.get('/?status=302%20Found&header-location=/') resp = resp.follow() resp.mustcontain('HTTP_COOKIE: foo=bar') def test_follow(self): app = self.get_redirects_app(1) resp = app.get('/') self.assertEqual(resp.status_int, 302) resp = resp.follow() self.assertEqual(resp.body, b'done') # can't follow non-redirect self.assertRaises(AssertionError, resp.follow) def test_follow_relative(self): app = self.get_redirects_app(2, ['hello/foo/', 'bar']) resp = app.get('/') self.assertEqual(resp.status_int, 302) resp = resp.follow() self.assertEqual(resp.status_int, 302) resp = resp.follow() self.assertEqual(resp.body, b'done') self.assertEqual(resp.request.url, 'http://localhost/hello/foo/bar') def test_follow_twice(self): app = self.get_redirects_app(2) resp = app.get('/').follow() self.assertEqual(resp.status_int, 302) resp = resp.follow() self.assertEqual(resp.status_int, 200) def test_maybe_follow_200(self): app = self.get_redirects_app(0) resp = app.get('/').maybe_follow() self.assertEqual(resp.body, b'done') def test_maybe_follow_once(self): app = self.get_redirects_app(1) resp = app.get('/').maybe_follow() self.assertEqual(resp.body, b'done') def test_maybe_follow_twice(self): app = self.get_redirects_app(2) resp = app.get('/').maybe_follow() self.assertEqual(resp.body, b'done') def test_maybe_follow_infinite(self): app = self.get_redirects_app(100000) self.assertRaises(AssertionError, app.get('/').maybe_follow)