WebTest-2.0.28/0000755000175000017500000000000013140117113013370 5ustar gawelgawel00000000000000WebTest-2.0.28/tox.ini0000644000175000017500000000136213140117112014704 0ustar gawelgawel00000000000000[tox] skip_missing_interpreters=true envlist=py27,py33,py34,py35,py36,coverage [testenv] setenv = LC_ALL=C LANG=C COVERAGE_FILE=.coverage.{envname} deps = nose<1.3.0 .[tests] lxml pyquery mock BeautifulSoup4 PasteDeploy WSGIProxy2 commands = {envbindir}/python --version {envbindir}/pip freeze py{27,33}: {envbindir}/nosetests --with-coverage --with-xunit --xunit-file=nosetests-{envname}.xml [] py{27,33}: {envbindir}/coverage xml -o coverage-{envname}.xml py{34,35,36}: {envbindir}/nosetests [testenv:coverage] deps = coverage setenv = COVERAGE_FILE=.coverage commands = {envbindir}/coverage erase {envbindir}/coverage combine {envbindir}/coverage xml {envbindir}/coverage report --show-missing WebTest-2.0.28/README.rst0000644000175000017500000000051013140117112015052 0ustar gawelgawel00000000000000======= WebTest ======= This wraps any WSGI application and makes it easy to send test requests to that application, without starting up an HTTP server. This provides convenient full-stack testing of applications written with any WSGI-compatible framework. Full docs can be found at https://webtest.readthedocs.io/en/latest/ WebTest-2.0.28/webtest/0000755000175000017500000000000013140117113015045 5ustar gawelgawel00000000000000WebTest-2.0.28/webtest/response.py0000644000175000017500000004636213140117112017267 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- import re from json import loads from webtest import forms from webtest import utils from webtest.compat import print_stderr from webtest.compat import splittype from webtest.compat import splithost from webtest.compat import PY3 from webtest.compat import urlparse from webtest.compat import to_bytes from six import string_types from six import binary_type from six import text_type from bs4 import BeautifulSoup import webob class TestResponse(webob.Response): """ Instances of this class are returned by :class:`~webtest.app.TestApp` methods. """ request = None _forms_indexed = None parser_features = 'html.parser' @property def forms(self): """ Returns a dictionary containing all the forms in the pages as :class:`~webtest.forms.Form` objects. Indexes are both in order (from zero) and by form id (if the form is given an id). See :doc:`forms` for more info on form objects. """ if self._forms_indexed is None: self._parse_forms() return self._forms_indexed @property def form(self): """ If there is only one form on the page, return it as a :class:`~webtest.forms.Form` object; raise a TypeError is there are no form or multiple forms. """ forms_ = self.forms if not forms_: raise TypeError( "You used response.form, but no forms exist") if 1 in forms_: # There is more than one form raise TypeError( "You used response.form, but more than one form exists") return forms_[0] @property def testbody(self): self.decode_content() if self.charset: try: return self.text except UnicodeDecodeError: return self.body.decode(self.charset, 'replace') return self.body.decode('ascii', 'replace') _tag_re = re.compile(r'<(/?)([:a-z0-9_\-]*)(.*?)>', re.S | re.I) def _parse_forms(self): forms_ = self._forms_indexed = {} form_texts = [text_type(f) for f in self.html('form')] for i, text in enumerate(form_texts): form = forms.Form(self, text, self.parser_features) forms_[i] = form if form.id: forms_[form.id] = form def _follow(self, **kw): location = self.headers['location'] abslocation = urlparse.urljoin(self.request.url, location) type_, rest = splittype(abslocation) host, path = splithost(rest) # @@: We should test that it's not a remote redirect return self.test_app.get(abslocation, **kw) def follow(self, **kw): """ If this response is a redirect, follow that redirect. It is an error if it is not a redirect response. Any keyword arguments are passed to :class:`webtest.app.TestApp.get`. Returns another :class:`TestResponse` object. """ assert 300 <= self.status_int < 400, ( "You can only follow redirect responses (not %s)" % self.status) return self._follow(**kw) def maybe_follow(self, **kw): """ Follow all redirects. If this response is not a redirect, do nothing. Any keyword arguments are passed to :class:`webtest.app.TestApp.get`. Returns another :class:`TestResponse` object. """ remaining_redirects = 100 # infinite loops protection response = self while 300 <= response.status_int < 400 and remaining_redirects: response = response._follow(**kw) remaining_redirects -= 1 assert remaining_redirects > 0, "redirects chain looks infinite" return response def click(self, description=None, linkid=None, href=None, index=None, verbose=False, extra_environ=None): """ Click the link as described. Each of ``description``, ``linkid``, and ``url`` are *patterns*, meaning that they are either strings (regular expressions), compiled regular expressions (objects with a ``search`` method), or callables returning true or false. All the given patterns are ANDed together: * ``description`` is a pattern that matches the contents of the anchor (HTML and all -- everything between ```` and ````) * ``linkid`` is a pattern that matches the ``id`` attribute of the anchor. It will receive the empty string if no id is given. * ``href`` is a pattern that matches the ``href`` of the anchor; the literal content of that attribute, not the fully qualified attribute. If more than one link matches, then the ``index`` link is followed. If ``index`` is not given and more than one link matches, or if no link matches, then ``IndexError`` will be raised. If you give ``verbose`` then messages will be printed about each link, and why it does or doesn't match. If you use ``app.click(verbose=True)`` you'll see a list of all the links. You can use multiple criteria to essentially assert multiple aspects about the link, e.g., where the link's destination is. """ found_html, found_desc, found_attrs = self._find_element( tag='a', href_attr='href', href_extract=None, content=description, id=linkid, href_pattern=href, index=index, verbose=verbose) extra_environ = extra_environ or {} extra_environ.setdefault('HTTP_REFERER', str(self.request.url)) return self.goto(str(found_attrs['uri']), extra_environ=extra_environ) def clickbutton(self, description=None, buttonid=None, href=None, index=None, verbose=False): """ Like :meth:`~webtest.response.TestResponse.click`, except looks for link-like buttons. This kind of button should look like `` WebTest-2.0.28/tests/test_authorisation.py0000644000175000017500000000432013140117112021032 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals from webtest.debugapp import DebugApp from tests.compat import unittest from base64 import b64decode from webtest.compat import to_bytes import webtest class TestAuthorization(unittest.TestCase): def callFUT(self): return webtest.TestApp(DebugApp()) def test_basic_authorization(self): app = self.callFUT() authorization = ('Basic', ['gawel', 'passwd']) app.authorization = authorization self.assertIn('HTTP_AUTHORIZATION', app.extra_environ) self.assertEquals(app.authorization, authorization) resp = app.get('/') resp.mustcontain('HTTP_AUTHORIZATION: Basic Z2F3ZWw6cGFzc3dk') header = resp.request.environ['HTTP_AUTHORIZATION'] self.assertTrue(header.startswith('Basic ')) authtype, value = header.split(' ') auth = (authtype, b64decode(to_bytes(value)).decode('latin1').split(':')) self.assertEquals(authorization, auth) app.authorization = None self.assertNotIn('HTTP_AUTHORIZATION', app.extra_environ) def test_bearer_authorization(self): app = self.callFUT() authorization = ('Bearer', '2588409761fcfa3e378bff4fb766e2e2') app.authorization = authorization self.assertIn('HTTP_AUTHORIZATION', app.extra_environ) self.assertEquals(app.authorization, authorization) resp = app.get('/') resp.mustcontain('HTTP_AUTHORIZATION: Bearer 2588409761fcfa3e378bff4fb766e2e2') header = resp.request.environ['HTTP_AUTHORIZATION'] self.assertTrue(header.startswith('Bearer ')) app.authorization = None self.assertNotIn('HTTP_AUTHORIZATION', app.extra_environ) def test_invalid(self): app = self.callFUT() self.assertRaises(ValueError, app.set_authorization, ()) self.assertRaises(ValueError, app.set_authorization, '') self.assertRaises(ValueError, app.set_authorization, ('Basic', '')) self.assertRaises(ValueError, app.set_authorization, ('Basic', ())) self.assertRaises(ValueError, app.set_authorization, ('Bearer', ())) self.assertRaises(ValueError, app.set_authorization, ('Bearer', [])) WebTest-2.0.28/tests/test_response.py0000644000175000017500000003615513140117112020012 0ustar gawelgawel00000000000000#coding: utf-8 from __future__ import unicode_literals import sys import webtest from webtest.debugapp import debug_app from webob import Request from webob.response import gzip_app_iter from webtest.compat import PY3 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', str('text/html')), ('Content-Length', str(len(body))) ] if req.path_info in utf8_paths: headers[0] = ('Content-Type', str('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 gzipped_app(environ, start_response): status = "200 OK" encoded_body = list(gzip_app_iter([b'test'])) headers = [ ('Content-Type', str('text/html')), ('Content-Encoding', str('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') if not PY3: # No need to deal with that in Py3 self.assertIn("Тестовая страница".encode('utf8'), resp) self.assertIn("Тестовая страница", resp, resp) target = 'Менделеев'.encode('utf8') self.assertIn('This is foo.', resp.click(target, verbose=True)) 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.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 @unittest.skipIf('PyPy' in sys.version, 'skip lxml tests on pypy') 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_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('/') if not PY3: unicode(resp) 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', str('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) WebTest-2.0.28/tests/__init__.py0000644000175000017500000000000213140117112016632 0ustar gawelgawel00000000000000# WebTest-2.0.28/tests/test_utils.py0000644000175000017500000001053313140117112017304 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import re import json from .compat import unittest from webtest import utils class NoDefaultTest(unittest.TestCase): def test_nodefault(self): from webtest.utils import NoDefault self.assertEquals(repr(NoDefault), '') class encode_paramsTest(unittest.TestCase): def test_encode_params_None(self): self.assertEquals(utils.encode_params(None, None), None) def test_encode_params_NoDefault(self): self.assertEquals(utils.encode_params(utils.NoDefault, None), '') def test_encode_params_dict_or_list(self): self.assertEquals(utils.encode_params({'foo': 'bar'}, None), utils.encode_params([('foo', 'bar')], None)) def test_encode_params_no_charset(self): # no content_type at all self.assertEquals(utils.encode_params({'foo': 'bar'}, None), 'foo=bar') # content_type without "charset=xxxx" self.assertEquals(utils.encode_params({'foo': 'bar'}, 'ba'), 'foo=bar') def test_encode_params_charset_utf8(self): # charset is using inconsistent casing on purpose, it should still work self.assertEquals(utils.encode_params({'f': '€'}, ' CHARset=uTF-8; '), 'f=%E2%82%AC') class make_patternTest(unittest.TestCase): def call_FUT(self, obj): from webtest.utils import make_pattern return make_pattern(obj) def test_make_pattern_None(self): self.assertEquals(self.call_FUT(None), None) def test_make_pattern_regex(self): regex = re.compile(r'foobar') self.assertEquals(self.call_FUT(regex), regex.search) def test_make_pattern_function(self): func = lambda x: x self.assertEquals(self.call_FUT(func), func) def test_make_pattern_bytes(self): # if we pass a string, it will get compiled into a regex # that we can later call and match a string self.assertEqual(self.call_FUT('a')('a').string, 'a') def test_make_pattern_invalid(self): self.assertRaises(ValueError, self.call_FUT, 0) class stringifyTest(unittest.TestCase): def test_stringify_text(self): self.assertEquals(utils.stringify("foo"), "foo") def test_stringify_binary(self): self.assertEquals(utils.stringify(b"foo"), "foo") def test_stringify_other(self): self.assertEquals(utils.stringify(123), "123") class json_methodTest(unittest.TestCase): class MockTestApp(object): """Mock TestApp used to test the json_object decorator.""" from webtest.utils import json_method JSONEncoder = json.JSONEncoder foo_json = json_method('FOO') def _gen_request(self, method, url, **kw): return (method, url, kw) mock = MockTestApp() def test_json_method_request_calls(self): from webtest.utils import NoDefault # no params self.assertEquals(self.mock.foo_json('url', params=NoDefault, c='c'), ('FOO', 'url', {'content_type': 'application/json', 'c': 'c', 'params': NoDefault, 'upload_files': None})) # params dumped to json self.assertEquals(self.mock.foo_json('url', params={'a': 'b'}, c='c'), ('FOO', 'url', {'content_type': 'application/json', 'c': 'c', 'params': json.dumps({'a': 'b'}), 'upload_files': None})) def test_json_method_request_respects_content_type_argument(self): self.assertEquals(self.mock.foo_json('url', params={'a': 'b'}, c='c', content_type='application/vnd.api+json;charset=utf-8'), ('FOO', 'url', {'content_type': 'application/vnd.api+json;charset=utf-8', 'c': 'c', 'params': json.dumps({'a': 'b'}), 'upload_files': None})) def test_json_method_doc(self): self.assertIn('FOO request', self.mock.foo_json.__doc__) self.assertIn('TestApp.foo', self.mock.foo_json.__doc__) def test_json_method_name(self): self.assertEqual(self.mock.foo_json.__name__, 'foo_json') WebTest-2.0.28/tests/test_lint.py0000644000175000017500000002563513140117112017123 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals from six import PY3 from six import StringIO from tests.compat import unittest from webob import Request, Response import warnings import mock from webtest import TestApp from webtest.compat import to_bytes from webtest.lint import check_headers from webtest.lint import check_content_type from webtest.lint import check_environ from webtest.lint import IteratorWrapper from webtest.lint import WriteWrapper from webtest.lint import ErrorWrapper from webtest.lint import InputWrapper from webtest.lint import to_string from webtest.lint import middleware from six import BytesIO def application(environ, start_response): req = Request(environ) resp = Response() env_input = environ['wsgi.input'] len_body = len(req.body) env_input.input.seek(0) if req.path_info == '/read': resp.body = env_input.read(len_body) elif req.path_info == '/read_line': resp.body = env_input.readline(len_body) elif req.path_info == '/read_lines': resp.body = b'-'.join(env_input.readlines(len_body)) elif req.path_info == '/close': resp.body = env_input.close() return resp(environ, start_response) class TestToString(unittest.TestCase): def test_to_string(self): self.assertEqual(to_string('foo'), 'foo') self.assertEqual(to_string(b'foo'), 'foo') class TestMiddleware(unittest.TestCase): def test_lint_too_few_args(self): linter = middleware(application) with self.assertRaisesRegexp(AssertionError, "Two arguments required"): linter() with self.assertRaisesRegexp(AssertionError, "Two arguments required"): linter({}) def test_lint_no_keyword_args(self): linter = middleware(application) with self.assertRaisesRegexp(AssertionError, "No keyword arguments " "allowed"): linter({}, 'foo', baz='baz') #TODO: test start_response_wrapper @mock.patch.multiple('webtest.lint', check_environ=lambda x: True, # don't block too early InputWrapper=lambda x: True) def test_lint_iterator_returned(self): linter = middleware(lambda x, y: None) # None is not an iterator msg = "The application must return an iterator, if only an empty list" with self.assertRaisesRegexp(AssertionError, msg): linter({'wsgi.input': 'foo', 'wsgi.errors': 'foo'}, 'foo') class TestInputWrapper(unittest.TestCase): def test_read(self): app = TestApp(application) resp = app.post('/read', 'hello') self.assertEqual(resp.body, b'hello') def test_readline(self): app = TestApp(application) resp = app.post('/read_line', 'hello\n') self.assertEqual(resp.body, b'hello\n') def test_readlines(self): app = TestApp(application) resp = app.post('/read_lines', 'hello\nt\n') self.assertEqual(resp.body, b'hello\n-t\n') def test_close(self): input_wrapper = InputWrapper(None) self.assertRaises(AssertionError, input_wrapper.close) def test_iter(self): data = to_bytes("A line\nAnother line\nA final line\n") input_wrapper = InputWrapper(BytesIO(data)) self.assertEquals(to_bytes("").join(input_wrapper), data, '') def test_seek(self): data = to_bytes("A line\nAnother line\nA final line\n") input_wrapper = InputWrapper(BytesIO(data)) input_wrapper.seek(0) self.assertEquals(to_bytes("").join(input_wrapper), data, '') class TestMiddleware2(unittest.TestCase): def test_exc_info(self): def application_exc_info(environ, start_response): body = to_bytes('body stuff') headers = [ ('Content-Type', 'text/plain; charset=utf-8'), ('Content-Length', str(len(body)))] # PEP 3333 requires native strings: headers = [(str(k), str(v)) for k, v in headers] start_response(to_bytes('200 OK'), headers, ('stuff',)) return [body] app = TestApp(application_exc_info) app.get('/') # don't know what to assert here... a bit cheating, just covers code class TestCheckContentType(unittest.TestCase): def test_no_content(self): status = "204 No Content" headers = [ ('Content-Type', 'text/plain; charset=utf-8'), ('Content-Length', '4') ] self.assertRaises(AssertionError, check_content_type, status, headers) def test_no_content_type(self): status = "200 OK" headers = [ ('Content-Length', '4') ] self.assertRaises(AssertionError, check_content_type, status, headers) class TestCheckHeaders(unittest.TestCase): @unittest.skipIf(PY3, 'unicode is str in Python3') def test_header_unicode_name(self): headers = [(u'X-Price', str('100'))] self.assertRaises(AssertionError, check_headers, headers) @unittest.skipIf(PY3, 'unicode is str in Python3') def test_header_unicode_value(self): headers = [(str('X-Price'), u'100')] self.assertRaises(AssertionError, check_headers, headers) @unittest.skipIf(not PY3, 'bytes is str in Python2') def test_header_bytes_name(self): headers = [(b'X-Price', '100')] self.assertRaises(AssertionError, check_headers, headers) @unittest.skipIf(not PY3, 'bytes is str in Python2') def test_header_bytes_value(self): headers = [('X-Price', b'100')] self.assertRaises(AssertionError, check_headers, headers) def test_header_non_latin1_value(self): headers = [(str('X-Price'), '100€')] self.assertRaises(AssertionError, check_headers, headers) def test_header_non_latin1_name(self): headers = [('X-€', str('foo'))] self.assertRaises(AssertionError, check_headers, headers) class TestCheckEnviron(unittest.TestCase): def test_no_query_string(self): environ = { 'REQUEST_METHOD': str('GET'), 'SERVER_NAME': str('localhost'), 'SERVER_PORT': str('80'), 'wsgi.version': (1, 0, 1), 'wsgi.input': StringIO('test'), 'wsgi.errors': StringIO(), 'wsgi.multithread': None, 'wsgi.multiprocess': None, 'wsgi.run_once': None, 'wsgi.url_scheme': 'http', 'PATH_INFO': str('/'), } with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") check_environ(environ) self.assertEqual(len(w), 1, "We should have only one warning") self.assertTrue( "QUERY_STRING" in str(w[-1].message), "The warning message should say something about QUERY_STRING") def test_no_valid_request(self): environ = { 'REQUEST_METHOD': str('PROPFIND'), 'SERVER_NAME': str('localhost'), 'SERVER_PORT': str('80'), 'wsgi.version': (1, 0, 1), 'wsgi.input': StringIO('test'), 'wsgi.errors': StringIO(), 'wsgi.multithread': None, 'wsgi.multiprocess': None, 'wsgi.run_once': None, 'wsgi.url_scheme': 'http', 'PATH_INFO': str('/'), 'QUERY_STRING': str(''), } with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") check_environ(environ) self.assertEqual(len(w), 1, "We should have only one warning") self.assertTrue( "REQUEST_METHOD" in str(w[-1].message), "The warning message should say something " "about REQUEST_METHOD") def test_handles_native_strings_in_variables(self): # "native string" means unicode in py3, but bytes in py2 path = '/umläut' if not PY3: path = path.encode('utf-8') environ = { 'REQUEST_METHOD': str('GET'), 'SERVER_NAME': str('localhost'), 'SERVER_PORT': str('80'), 'wsgi.version': (1, 0, 1), 'wsgi.input': StringIO('test'), 'wsgi.errors': StringIO(), 'wsgi.multithread': None, 'wsgi.multiprocess': None, 'wsgi.run_once': None, 'wsgi.url_scheme': 'http', 'PATH_INFO': path, 'QUERY_STRING': str(''), } with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") check_environ(environ) self.assertEqual(0, len(w), "We should have no warning") class TestIteratorWrapper(unittest.TestCase): def test_close(self): class MockIterator(object): def __init__(self): self.closed = False def __iter__(self): return self def __next__(self): return None next = __next__ def close(self): self.closed = True mock = MockIterator() wrapper = IteratorWrapper(mock, None) wrapper.close() self.assertTrue(mock.closed, "Original iterator has not been closed") class TestWriteWrapper(unittest.TestCase): def test_wrong_type(self): write_wrapper = WriteWrapper(None) self.assertRaises(AssertionError, write_wrapper, 'not a binary') def test_normal(self): class MockWriter(object): def __init__(self): self.written = [] def __call__(self, s): self.written.append(s) data = to_bytes('foo') mock = MockWriter() write_wrapper = WriteWrapper(mock) write_wrapper(data) self.assertEqual( mock.written, [data], "WriterWrapper should call original writer when data is binary " "type") class TestErrorWrapper(unittest.TestCase): def test_dont_close(self): error_wrapper = ErrorWrapper(None) self.assertRaises(AssertionError, error_wrapper.close) class FakeError(object): def __init__(self): self.written = [] self.flushed = False def write(self, s): self.written.append(s) def writelines(self, lines): for line in lines: self.write(line) def flush(self): self.flushed = True def test_writelines(self): fake_error = self.FakeError() error_wrapper = ErrorWrapper(fake_error) data = [to_bytes('a line'), to_bytes('another line')] error_wrapper.writelines(data) self.assertEqual(fake_error.written, data, "ErrorWrapper should call original writer") def test_flush(self): fake_error = self.FakeError() error_wrapper = ErrorWrapper(fake_error) error_wrapper.flush() self.assertTrue( fake_error.flushed, "ErrorWrapper should have called original wsgi_errors's flush") WebTest-2.0.28/tests/test_http.py0000644000175000017500000000414413140117112017124 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from tests.compat import unittest from webob import Request from webtest.debugapp import debug_app from webtest import http class TestServer(unittest.TestCase): def setUp(self): self.s = http.StopableWSGIServer.create(debug_app) def test_server(self): s = self.s s.wait() self.assertEqual(200, http.check_server(s.adj.host, s.adj.port, '/__application__')) self.assertEqual(200, http.check_server(s.adj.host, s.adj.port, '/__file__?__file__=' + __file__)) self.assertEqual(404, http.check_server(s.adj.host, s.adj.port, '/__file__?__file__=XXX')) self.assertEqual(304, http.check_server(s.adj.host, s.adj.port, '/?status=304')) def test_wsgi_wrapper(self): s = self.s s.wait() req = Request.blank('/__application__') resp = req.get_response(s.wrapper) self.assertEqual(resp.status_int, 200) req = Request.blank('/__file__?__file__=' + __file__) resp = req.get_response(s.wrapper) self.assertEqual(resp.status_int, 200) req = Request.blank('/__file__?__file__=XXX') resp = req.get_response(s.wrapper) self.assertEqual(resp.status_int, 404) req = Request.blank('/?status=304') resp = req.get_response(s.wrapper) self.assertEqual(resp.status_int, 304) def tearDown(self): self.s.shutdown() class TestBrokenServer(unittest.TestCase): def test_shutdown_non_running(self): host, port = http.get_free_port() s = http.StopableWSGIServer(debug_app, host=host, port=port) self.assertFalse(s.wait(retries=-1)) self.assertTrue(s.shutdown()) class TestClient(unittest.TestCase): def test_no_server(self): host, port = http.get_free_port() self.assertEqual(0, http.check_server(host, port, retries=2)) WebTest-2.0.28/tests/test_app.py0000644000175000017500000006062513140117112016733 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from six import binary_type from webob import Request from webob import Response from webtest.compat import to_bytes from webtest.compat import PY3 from collections import OrderedDict from webtest.debugapp import debug_app from webtest import http from tests.compat import unittest import os import six import mock import webtest class TestApp(unittest.TestCase): def setUp(self): self.app = webtest.TestApp(debug_app) def test_encode_multipart_relative_to(self): app = webtest.TestApp(debug_app, relative_to=os.path.dirname(__file__)) data = app.encode_multipart( [], [('file', 'html%s404.html' % os.sep)]) self.assertIn(to_bytes('404.html'), data[-1]) def test_encode_multipart(self): data = self.app.encode_multipart( [], [('file', 'data.txt', six.b('data'))]) self.assertIn(to_bytes('data.txt'), data[-1]) data = self.app.encode_multipart( [], [(six.b('file'), six.b('data.txt'), six.b('data'))]) self.assertIn(to_bytes('data.txt'), data[-1]) data = self.app.encode_multipart( [('key', 'value')], []) self.assertIn(to_bytes('name="key"'), data[-1]) data = self.app.encode_multipart( [(six.b('key'), six.b('value'))], []) self.assertIn(to_bytes('name="key"'), data[-1]) def test_encode_multipart_content_type(self): data = self.app.encode_multipart( [], [('file', 'data.txt', six.b('data'), 'text/x-custom-mime-type')]) self.assertIn(to_bytes('Content-Type: text/x-custom-mime-type'), data[-1]) data = self.app.encode_multipart( [('file', webtest.Upload('data.txt', six.b('data'), 'text/x-custom-mime-type'))], []) self.assertIn(to_bytes('Content-Type: text/x-custom-mime-type'), data[-1]) def test_get_params(self): resp = self.app.get('/', 'a=b') resp.mustcontain('a=b') resp = self.app.get('/?a=b', dict(c='d')) resp.mustcontain('a=b', 'c=d') resp = self.app.get('/?a=b&c=d', dict(e='f')) resp.mustcontain('a=b', 'c=d', 'e=f') def test_request_with_testrequest(self): req = webtest.TestRequest.blank('/') resp = self.app.request(req, method='POST') resp.charset = 'ascii' assert 'REQUEST_METHOD: POST' in resp.text def test_patch(self): resp = self.app.patch('/') self.assertIn('PATCH', resp) resp = self.app.patch('/', xhr=True) self.assertIn('PATCH', resp) def test_custom_headers(self): resp = self.app.post('/', headers={'Accept': 'text/plain'}) resp.charset = 'ascii' assert 'HTTP_ACCEPT: text/plain' in resp.text class TestStatus(unittest.TestCase): def setUp(self): self.app = webtest.TestApp(debug_app) def check_status(self, status, awaiting_status=None): resp = Response() resp.request = Request.blank('/') resp.status = status return self.app._check_status(awaiting_status, resp) def test_check_status_asterisk(self): self.assertEqual(self.check_status('200 Ok', '*'), None) def test_check_status_almost_asterisk(self): self.assertEqual(self.check_status('200 Ok', '2*'), None) def test_check_status_tuple(self): self.assertEqual(self.check_status('200 Ok', (200,)), None) self.assertRaises(webtest.AppError, self.check_status, '200 Ok', (400,)) def test_check_status_none(self): self.assertEqual(self.check_status('200 Ok', None), None) self.assertRaises(webtest.AppError, self.check_status, '400 Ok') def test_check_status_with_custom_reason(self): self.assertEqual(self.check_status('200 Ok', '200 Ok'), None) self.assertRaises(webtest.AppError, self.check_status, '200 Ok', '200 Good Response') self.assertRaises(webtest.AppError, self.check_status, '200 Ok', '400 Bad Request') class TestParserFeature(unittest.TestCase): def test_parser_features(self): app = webtest.TestApp(debug_app, parser_features='custom') self.assertEqual(app.RequestClass.ResponseClass.parser_features, 'custom') class TestAppError(unittest.TestCase): def test_app_error(self): resp = Response(to_bytes('blah')) err = webtest.AppError('message %s', resp) self.assertEqual(err.args, ('message blah',)) def test_app_error_with_bytes_message(self): resp = Response(six.u('\xe9').encode('utf8')) resp.charset = 'utf8' err = webtest.AppError(to_bytes('message %s'), resp) self.assertEqual(err.args, (six.u('message \xe9'),)) def test_app_error_with_unicode(self): err = webtest.AppError(six.u('messag\xe9 %s'), six.u('\xe9')) self.assertEqual(err.args, (six.u('messag\xe9 \xe9'),)) def test_app_error_misc(self): resp = Response(six.u('\xe9').encode('utf8')) resp.charset = '' # dont check the output. just make sure it doesn't fail webtest.AppError(to_bytes('message %s'), resp) webtest.AppError(six.u('messag\xe9 %s'), six.b('\xe9')) class TestPasteVariables(unittest.TestCase): def call_FUT(self, **kwargs): def application(environ, start_response): resp = Response() environ['paste.testing_variables'].update(kwargs) return resp(environ, start_response) return webtest.TestApp(application) def test_paste_testing_variables_raises(self): app = self.call_FUT(body='1') req = Request.blank('/') self.assertRaises(ValueError, app.do_request, req, '*', False) def test_paste_testing_variables(self): app = self.call_FUT(check='1') req = Request.blank('/') resp = app.do_request(req, '*', False) self.assertEqual(resp.check, '1') class TestCookies(unittest.TestCase): def test_supports_providing_cookiejar(self): cookiejar = six.moves.http_cookiejar.CookieJar() app = webtest.TestApp(debug_app, cookiejar=cookiejar) self.assertIs(cookiejar, app.cookiejar) def test_set_cookie(self): def cookie_app(environ, start_response): req = Request(environ) self.assertEqual(req.cookies['foo'], 'bar') self.assertEqual(req.cookies['fizz'], ';bar=baz') status = to_bytes("200 OK") body = '' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ] start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) app.set_cookie('foo', 'bar') app.set_cookie('fizz', ';bar=baz') # Make sure we're escaping. app.get('/') app.reset() app = webtest.TestApp(cookie_app, extra_environ={'HTTP_HOST': 'testserver'}) app.set_cookie('foo', 'bar') app.set_cookie('fizz', ';bar=baz') # Make sure we're escaping. app.get('/') app.reset() def test_preserves_cookies(self): def cookie_app(environ, start_response): req = Request(environ) status = "200 OK" body = 'go' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ] if req.path_info != '/go/': headers.extend([ ('Set-Cookie', 'spam=eggs'), ('Set-Cookie', 'foo=bar;baz'), ]) else: self.assertEquals(dict(req.cookies), {'spam': 'eggs', 'foo': 'bar'}) self.assertIn('foo=bar', environ['HTTP_COOKIE']) self.assertIn('spam=eggs', environ['HTTP_COOKIE']) start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) self.assertTrue(not app.cookiejar, 'App should initially contain no cookies') self.assertFalse(app.cookies) res = app.get('/') self.assertEqual(app.cookies['spam'], 'eggs') self.assertEqual(app.cookies['foo'], 'bar') res = res.click('go') self.assertEqual(app.cookies['spam'], 'eggs') self.assertEqual(app.cookies['foo'], 'bar') app.reset() self.assertFalse(bool(app.cookies)) def test_secure_cookies(self): def cookie_app(environ, start_response): req = Request(environ) status = "200 OK" body = 'go' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ] if req.path_info != '/go/': headers.extend([ ('Set-Cookie', 'spam=eggs; secure'), ('Set-Cookie', 'foo=bar;baz; secure'), ]) else: self.assertEquals(dict(req.cookies), {'spam': 'eggs', 'foo': 'bar'}) self.assertIn('foo=bar', environ['HTTP_COOKIE']) self.assertIn('spam=eggs', environ['HTTP_COOKIE']) start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) self.assertFalse(app.cookies) res = app.get('https://localhost/') self.assertEqual(app.cookies['spam'], 'eggs') self.assertEqual(app.cookies['foo'], 'bar') res = res.click('go') self.assertEqual(app.cookies['spam'], 'eggs') self.assertEqual(app.cookies['foo'], 'bar') def test_cookies_readonly(self): app = webtest.TestApp(debug_app) try: app.cookies = {} except: pass else: self.fail('testapp.cookies should be read-only') @mock.patch('six.moves.http_cookiejar.time.time') def test_expires_cookies(self, mock_time): def cookie_app(environ, start_response): status = to_bytes("200 OK") body = '' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ('Set-Cookie', 'spam=eggs; Expires=Tue, 21-Feb-2013 17:45:00 GMT;'), ] start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) self.assertTrue(not app.cookiejar, 'App should initially contain no cookies') mock_time.return_value = 1361464946.0 app.get('/') self.assertTrue(app.cookies, 'Response should have set cookies') mock_time.return_value = 1461464946.0 app.get('/') self.assertFalse(app.cookies, 'Response should have unset cookies') def test_http_cookie(self): def cookie_app(environ, start_response): req = Request(environ) status = to_bytes("200 OK") body = 'Cookie.' assert dict(req.cookies) == {'spam': 'eggs'} assert environ['HTTP_COOKIE'] == 'spam=eggs' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ] start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) self.assertTrue(not app.cookies, 'App should initially contain no cookies') res = app.get('/', headers=[('Cookie', 'spam=eggs')]) self.assertFalse(app.cookies, 'Response should not have set cookies') self.assertEqual(res.request.environ['HTTP_COOKIE'], 'spam=eggs') self.assertEqual(dict(res.request.cookies), {'spam': 'eggs'}) def test_http_localhost_cookie(self): def cookie_app(environ, start_response): status = to_bytes("200 OK") body = 'Cookie.' headers = [ ('Content-Type', 'text/html'), ('Content-Length', str(len(body))), ('Set-Cookie', 'spam=eggs; Domain=localhost;'), ] start_response(status, headers) return [to_bytes(body)] app = webtest.TestApp(cookie_app) self.assertTrue(not app.cookies, 'App should initially contain no cookies') res = app.get('/') res = app.get('/') self.assertTrue(app.cookies, 'Response should not have set cookies') self.assertEqual(res.request.environ['HTTP_COOKIE'], 'spam=eggs') self.assertEqual(dict(res.request.cookies), {'spam': 'eggs'}) def test_cookie_policy(self): from six.moves import http_cookiejar def cookie_app(environ, start_response): status = to_bytes("200 OK") body = 'Cookie.' headers = [ ('Content-Type', 'text/plain'), ('Content-Length', str(len(body))), ('Set-Cookie', 'spam=eggs; secure; Domain=.example.org;'), ] start_response(status, headers) return [to_bytes(body)] policy = webtest.app.CookiePolicy() flags = ( policy.DomainStrictNoDots | policy.DomainRFC2965Match | policy.DomainStrictNonDomain) policy.strict_ns_domain |= flags cookiejar = http_cookiejar.CookieJar(policy=policy) app = webtest.TestApp( cookie_app, cookiejar=cookiejar, extra_environ={'HTTP_HOST': 'example.org'}) res = app.get('/') res = app.get('/') self.assertFalse(app.cookies, 'Response should not have set cookies') self.assertNotIn('HTTP_COOKIE', res.request.environ) self.assertEqual(dict(res.request.cookies), {}) class TestEnviron(unittest.TestCase): def test_get_extra_environ(self): app = webtest.TestApp(debug_app, extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru', 'foo': 'bar'}) res = app.get('http://localhost/') self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'bar'", res, res) res = app.get('http://localhost/', extra_environ={'foo': 'baz'}) self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'baz'", res, res) def test_post_extra_environ(self): app = webtest.TestApp(debug_app, extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru', 'foo': 'bar'}) res = app.post('http://localhost/') self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'bar'", res, res) res = app.post('http://localhost/', extra_environ={'foo': 'baz'}) self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'baz'", res, res) def test_request_extra_environ(self): app = webtest.TestApp(debug_app, extra_environ={'HTTP_ACCEPT_LANGUAGE': 'ru', 'foo': 'bar'}) res = app.request('http://localhost/', method='GET') self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'bar'", res, res) res = app.request('http://localhost/', method='GET', environ={'foo': 'baz'}) self.assertIn('HTTP_ACCEPT_LANGUAGE: ru', res, res) self.assertIn("foo: 'baz'", res, res) deform_upload_fields_text = """ """ def get_submit_app(form_id, form_fields_text): def submit_app(environ, start_response): req = Request(environ) status = "200 OK" if req.method == "GET": body = """ form page
%s
""" % (form_id, form_fields_text) else: body_head = """ display page """ body_parts = [] for (name, value) in req.POST.items(): if hasattr(value, 'filename'): body_parts.append("%s:%s:%s\n" % ( name, value.filename, value.value.decode('ascii'))) else: body_parts.append("%s:%s\n" % ( name, value)) body_foot = """ """ body = body_head + "".join(body_parts) + body_foot if not isinstance(body, binary_type): body = body.encode('utf8') headers = [ ('Content-Type', 'text/html; charset=utf-8'), ('Content-Length', str(len(body)))] start_response(status, headers) return [body] return submit_app class TestFieldOrder(unittest.TestCase): def test_submit_with_file_upload(self): uploaded_file_name = 'test.txt' uploaded_file_contents = 'test content file upload' if PY3: uploaded_file_contents = to_bytes(uploaded_file_contents) deform_upload_file_app = get_submit_app('deform', deform_upload_fields_text) app = webtest.TestApp(deform_upload_file_app) res = app.get('/') self.assertEqual(res.status_int, 200) self.assertEqual( res.headers['content-type'], 'text/html; charset=utf-8') self.assertEqual(res.content_type, 'text/html') self.assertEqual(res.charset, 'utf-8') single_form = res.forms["deform"] single_form.set("title", "testtitle") single_form.set("fileupload", (uploaded_file_name, uploaded_file_contents)) single_form.set("description", "testdescription") display = single_form.submit("Submit") self.assertIn(""" _charset_: __formid__:deform title:testtitle __start__:fileupload:mapping fileupload:test.txt:test content file upload __end__:fileupload:mapping description:testdescription Submit:Submit """.strip(), display, display) def test_post_with_file_upload(self): uploaded_file_name = 'test.txt' uploaded_file_contents = 'test content file upload' if PY3: uploaded_file_contents = to_bytes(uploaded_file_contents) deform_upload_file_app = get_submit_app('deform', deform_upload_fields_text) app = webtest.TestApp(deform_upload_file_app) display = app.post("/", OrderedDict([ ('_charset_', ''), ('__formid__', 'deform'), ('title', 'testtitle'), ('__start__', 'fileupload:mapping'), ('fileupload', webtest.Upload(uploaded_file_name, uploaded_file_contents)), ('__end__', 'fileupload:mapping'), ('description', 'testdescription'), ('Submit', 'Submit')])) self.assertIn(""" _charset_: __formid__:deform title:testtitle __start__:fileupload:mapping fileupload:test.txt:test content file upload __end__:fileupload:mapping description:testdescription Submit:Submit""".strip(), display, display) def test_field_order_is_across_all_fields(self): fields = """ """ submit_app = get_submit_app('test', fields) app = webtest.TestApp(submit_app) get_res = app.get("/") # Submit the form with the second submit button. display = get_res.forms[0].submit('save', 1) self.assertIn(""" letter:a letter:b number:1 letter:c number:2 letter:d save:Save 2 letter:e""".strip(), display, display) class TestFragments(unittest.TestCase): def test_url_without_fragments(self): app = webtest.TestApp(debug_app) res = app.get('http://localhost/') self.assertEqual(res.status_int, 200) def test_url_with_fragments(self): app = webtest.TestApp(debug_app) res = app.get('http://localhost/#ananchor') self.assertEqual(res.status_int, 200) def application(environ, start_response): req = Request(environ) if req.path_info == '/redirect': req.path_info = '/path' resp = Response() resp.status = '302 Found' resp.location = req.path else: resp = Response() resp.body = to_bytes( 'link' % req.path) return resp(environ, start_response) class TestScriptName(unittest.TestCase): def test_script_name(self): app = webtest.TestApp(application) resp = app.get('/script', extra_environ={'SCRIPT_NAME': '/script'}) resp.mustcontain('href="/script"') resp = app.get('/script/redirect', extra_environ={'SCRIPT_NAME': '/script'}) self.assertEqual(resp.status_int, 302) self.assertEqual(resp.location, 'http://localhost/script/path', resp.location) resp = resp.follow(extra_environ={'SCRIPT_NAME': '/script'}) resp.mustcontain('href="/script/path"') resp = resp.click('link') resp.mustcontain('href="/script/path"') def test_app_script_name(self): app = webtest.TestApp(application, extra_environ={'SCRIPT_NAME': '/script'}) resp = app.get('/script/redirect') self.assertEqual(resp.status_int, 302) self.assertEqual(resp.location, 'http://localhost/script/path', resp.location) resp = resp.follow() resp.mustcontain('href="/script/path"') resp = resp.click('link') resp.mustcontain('href="/script/path"') def test_script_name_doesnt_match(self): app = webtest.TestApp(application) resp = app.get('/path', extra_environ={'SCRIPT_NAME': '/script'}) resp.mustcontain('href="/script/path"') class TestWSGIProxy(unittest.TestCase): def setUp(self): self.s = http.StopableWSGIServer.create(debug_app) self.s.wait() def test_proxy_with_url(self): app = webtest.TestApp(self.s.application_url) resp = app.get('/') self.assertEqual(resp.status_int, 200) def test_proxy_with_environ(self): def app(environ, start_response): pass os.environ['WEBTEST_TARGET_URL'] = self.s.application_url app = webtest.TestApp(app) del os.environ['WEBTEST_TARGET_URL'] resp = app.get('/') self.assertEqual(resp.status_int, 200) def tearDown(self): self.s.shutdown() class TestAppXhrParam(unittest.TestCase): def setUp(self): self.app = webtest.TestApp(debug_app) def test_xhr_param_change_headers(self): app = self.app # FIXME: this test isn`t work for head request # now I don't know how to test head request functions = (app.get, app.post, app.delete, app.put, app.options) # app.head for func in functions: resp = func('/', xhr=True) resp.charset = 'ascii' self.assertIn('HTTP_X_REQUESTED_WITH: XMLHttpRequest', resp.text) WebTest-2.0.28/tests/deploy.ini0000644000175000017500000000012413140117112016523 0ustar gawelgawel00000000000000[app:main] paste.app_factory = webtest.debugapp:make_debug_app form =
WebTest-2.0.28/tests/test_forms.py0000644000175000017500000011517013140117112017275 0ustar gawelgawel00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import cgi import os.path import struct import sys import webtest import six from six import binary_type from six import PY3 from webob import Request from webtest.debugapp import DebugApp from webtest.compat import to_bytes from webtest.forms import NoValue, Submit, Upload from tests.compat import unittest from tests.compat import u class TestForms(unittest.TestCase): def callFUT(self, filename='form_inputs.html', formid='simple_form'): dirname = os.path.join(os.path.dirname(__file__), 'html') app = DebugApp(form=os.path.join(dirname, filename), show_form=True) resp = webtest.TestApp(app).get('/form.html') return resp.forms[formid] def test_set_submit_field(self): form = self.callFUT() self.assertRaises( AttributeError, form['submit'].value__set, 'foo' ) def test_button(self): form = self.callFUT() button = form['button'] self.assertTrue(isinstance(button, Submit), "