tests/test_http.py
author Tero Marttila <terom@fixme.fi>
Mon, 16 Feb 2009 20:02:28 +0200
changeset 80 94c493b7c046
parent 75 f94c06cfcc0e
permissions -rw-r--r--
start writing urltree tests
# :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(), '')