from http import cookiejar as http_cookiejar from webob import Request from webob import Response from webtest.compat import to_bytes from collections import OrderedDict from webtest.debugapp import debug_app from webtest import http from tests.compat import unittest import os from unittest import mock import webtest class TestApp(unittest.TestCase): def setUp(self): self.app = webtest.TestApp(debug_app) def test_pytest_collection_disabled(self): self.assertFalse(webtest.TestApp.__test__) 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', b'data')]) self.assertIn(to_bytes('data.txt'), data[-1]) data = self.app.encode_multipart( [], [(b'file', b'data.txt', 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( [(b'key', 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', 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', 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('\xe9'.encode('utf8')) resp.charset = 'utf8' err = webtest.AppError(to_bytes('message %s'), resp) self.assertEqual(err.args, ('message \xe9',)) def test_app_error_with_unicode(self): err = webtest.AppError('messag\xe9 %s', '\xe9') self.assertEqual(err.args, ('messag\xe9 \xe9',)) def test_app_error_misc(self): resp = Response('\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('messag\xe9 %s', 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 = 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('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): 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 = """