# :set encoding=utf8
"""
Unit tests for qmsk.web.http
"""
import unittest
from cStringIO import StringIO
import http
class TestHttpUtil (unittest.TestCase) :
def test_request_url (self) :
for env, url in (
({
'wsgi.url_scheme': "https",
'HTTP_HOST': "testhost",
'REQUEST_URI': "/test"
}, "https://testhost/test"),
({
'HTTP_HOST': "-"
}, "[???]://-[???]")
) :
self.assertEqual(http.request_url(env), url)
class TestHttpRequest (unittest.TestCase) :
def build_request (self, env_dict={}, **env_kw) :
env = {
'wsgi.url_scheme': "http",
'HTTP_HOST': "testhost",
'REQUEST_METHOD': "GET",
}
env.update(env_dict)
env.update(env_kw)
return http.Request(env)
def test_site_host (self) :
self.assertEqual(self.build_request(HTTP_HOST='testhost').site_host, "testhost")
self.assertEqual(self.build_request(HTTP_HOST='testhost:13').site_host, "testhost:13")
def test_site_root (self) :
for script_name, site_root in (
('', "" ),
('/foo', "" ),
('/foo/bar/', "/foo/bar" ),
) :
self.assertEqual(self.build_request(SCRIPT_NAME=script_name).site_root, site_root)
def test_get_page_name (self) :
for path_info, page_name in (
('', ""),
('/', ""),
('/foo1/bar', "foo1/bar"),
('/foo2/bar/', "foo2/bar/"),
('/foo3/bar/../', "foo3/"),
('/foo4/bar/..', "foo4"),
('//', ""),
) :
self.assertEqual(self.build_request(PATH_INFO=path_info).get_page_name(), page_name)
def _test_page_prefix (self, request_uri, path_info, page_prefix) :
self.assertEqual(self.build_request(REQUEST_URI=request_uri, PATH_INFO=path_info).page_prefix, page_prefix)
def test_page_prefix_empty (self) :
self._test_page_prefix('', '', "")
def test_page_prefix_root_dir (self) :
self._test_page_prefix('/foo/', '/foo/', "")
def test_page_prefix_cgi (self) :
self._test_page_prefix('/foo.cgi/quux', '/quux', "/foo.cgi")
def test_page_prefix_qargs (self) :
self._test_page_prefix('/foo.cgi/?foo', '/', "/foo.cgi")
def test_get_arg (self) :
for query_string, key, value in (
('', 'foo', None),
('foo', 'foo', ''),
('foo=', 'foo', ''),
('foo=bar', 'foo', 'bar'),
('foo=&bar=.', 'bar', '.'),
) :
self.assertEqual(self.build_request(QUERY_STRING=query_string).get_arg(key, None), value)
def test_get_args (self) :
for query_string, keyvals in (
('', []),
('foo1=&bar', [('foo1', ''), ('bar', '')]),
('foo2=bar', [('foo2', 'bar')]),
('foo3=bar&foo3', [('foo3', 'bar'), ('foo3', '')]),
) :
self.assertEqual(self.build_request(QUERY_STRING=query_string).get_args(), keyvals)
def _build_post (self, method='POST', **vals) :
data = '&'.join('%s=%s' % kv for kv in vals.iteritems())
return self.build_request({'wsgi.input': StringIO(data)}, REQUEST_METHOD=method, CONTENT_TYPE='application/x-www-form-urlencoded')
def test_is_post (self) :
for request_method, bool in (
('GET', False),
('POST', True),
('post', True),
) :
self.assertEqual(self._build_post(method=request_method).is_post(), bool)
def _test_post (self, **vals) :
req = self._build_post(**vals)
def test_post_empty (self) :
req = self._build_post()
self.assertTrue(req.is_post())
self.assertEqual(req.get_post('foo', None), None)
def test_post_simple (self) :
req = self._build_post(foo='bar')
self.assertTrue(req.is_post())
self.assertEqual(req.get_post('foo', None), 'bar')
class TestHttpResponse (unittest.TestCase) :
def test_status (self) :
response = http.Response(None, status='100 Continue')
self.assertEqual(response.get_status(), '100 Continue')
def test_data_empty (self) :
self.assertEqual(http.Response(None).get_data(), '')
def test_data_str (self) :
self.assertEqual(http.Response('foo').get_data(), 'foo')
def test_data_utf8 (self) :
data = u'föö'
self.assertEqual(http.Response(data).get_data(), data.encode('utf8'))
def test_data_utf16 (self) :
data = u'fåå'
self.assertEqual(http.Response(data, charset='utf16').get_data(), data.encode('utf16'))
def test_data_invalid (self) :
data = 'fää'
self.assertRaises(UnicodeDecodeError, http.Response(data).get_data)
def test_data_binary (self) :
data = '\x01\x00'
self.assertEqual(http.Response(data, charset=None).get_data(), data)
def test_content_type_none (self) :
response = http.Response(None, content_type=None)
self.assertEqual(response.get_headers(), [])
def test_content_type_default (self) :
self.assertEqual(http.Response(None).get_headers(), [('Content-type', "text/html; charset=\"UTF-8\"")])
def test_content_type_weird (self) :
self.assertEqual(http.Response(None, content_type="foo/x-bar").get_headers(), [('Content-type', "foo/x-bar; charset=\"UTF-8\"")])
def test_content_type_charset (self) :
self.assertEqual(http.Response(None, content_type="foo/x-bar", charset="---").get_headers(), [('Content-type', "foo/x-bar; charset=\"---\"")])
def _build_headers (self, tlist=None, **map) :
response = http.Response(None)
if tlist :
for name, value, params in tlist :
response.add_header(name, value, **params)
for name, value in map.iteritems() :
response.add_header(name, value)
return response
def test_headers_simple (self) :
self.assertEqual(self._build_headers(**{'X-Foo': 'bar, never'}).get_headers(), [
('Content-type', "text/html; charset=\"UTF-8\""),
('X-Foo', "bar, never")
])
def test_headers_params (self) :
self.assertEqual(self._build_headers([('X-Bar', 'bar', dict(never='yes'))]).get_headers(), [
('Content-type', "text/html; charset=\"UTF-8\""),
('X-Bar', "bar; never=\"yes\"")
])
def test_headers_multi (self) :
self.assertEqual(self._build_headers([('X-Bar', 'bar', {}), ('X-bar', 'foo', {})]).get_headers(), [
('Content-type', "text/html; charset=\"UTF-8\""),
('X-Bar', "bar"),
('X-bar', "foo"),
])
class TestHttpRedirect (unittest.TestCase) :
def test_redirect (self) :
response = http.Redirect('http://test/bar')
self.assertEquals(response.get_status(), '302 Found')
self.assertEquals(response.get_headers(), [('Location', 'http://test/bar')])
self.assertEquals(response.get_data(), '')