tests/test_http.py
changeset 75 f94c06cfcc0e
parent 74 406cf77d23f9
equal deleted inserted replaced
74:406cf77d23f9 75:f94c06cfcc0e
       
     1 # :set encoding=utf8
       
     2 
       
     3 """
       
     4     Unit tests for qmsk.web.http
       
     5 """
       
     6 
       
     7 import unittest
       
     8 from cStringIO import StringIO
       
     9 
       
    10 import http
       
    11 
       
    12 class TestHttpUtil (unittest.TestCase) :
       
    13     def test_request_url (self) :
       
    14         for env, url in (
       
    15             ({
       
    16                 'wsgi.url_scheme':  "https",
       
    17                 'HTTP_HOST':        "testhost",
       
    18                 'REQUEST_URI':      "/test"
       
    19             }, "https://testhost/test"),
       
    20             ({
       
    21                 'HTTP_HOST':        "-"
       
    22             }, "[???]://-[???]")
       
    23         ) :
       
    24             self.assertEqual(http.request_url(env), url)
       
    25 
       
    26 class TestHttpRequest (unittest.TestCase) :
       
    27     def build_request (self, env_dict={}, **env_kw) :
       
    28         env = {
       
    29             'wsgi.url_scheme':      "http",
       
    30             'HTTP_HOST':            "testhost",
       
    31             'REQUEST_METHOD':       "GET",
       
    32         }
       
    33         env.update(env_dict)
       
    34         env.update(env_kw)
       
    35 
       
    36         return http.Request(env)
       
    37     
       
    38     def test_site_host (self) :
       
    39         self.assertEqual(self.build_request(HTTP_HOST='testhost').site_host, "testhost")
       
    40         self.assertEqual(self.build_request(HTTP_HOST='testhost:13').site_host, "testhost:13")
       
    41     
       
    42     def test_site_root (self) :
       
    43         for script_name, site_root in (
       
    44             ('',            ""         ),
       
    45             ('/foo',        ""         ),
       
    46             ('/foo/bar/',   "/foo/bar"  ),
       
    47         ) :
       
    48             self.assertEqual(self.build_request(SCRIPT_NAME=script_name).site_root, site_root)
       
    49     
       
    50     def test_get_page_name (self) :
       
    51         for path_info, page_name in (
       
    52             ('',                ""),
       
    53             ('/',               ""),
       
    54             ('/foo1/bar',       "foo1/bar"),
       
    55             ('/foo2/bar/',      "foo2/bar/"),
       
    56             ('/foo3/bar/../',   "foo3/"),
       
    57             ('/foo4/bar/..',    "foo4"),
       
    58             ('//',              ""),
       
    59         ) :
       
    60             self.assertEqual(self.build_request(PATH_INFO=path_info).get_page_name(), page_name)
       
    61     
       
    62     def _test_page_prefix (self, request_uri, path_info, page_prefix) :
       
    63         self.assertEqual(self.build_request(REQUEST_URI=request_uri, PATH_INFO=path_info).page_prefix, page_prefix)
       
    64 
       
    65     def test_page_prefix_empty (self) :
       
    66         self._test_page_prefix('', '', "")
       
    67 
       
    68     def test_page_prefix_root_dir (self) :
       
    69         self._test_page_prefix('/foo/', '/foo/', "")
       
    70     
       
    71     def test_page_prefix_cgi (self) :
       
    72         self._test_page_prefix('/foo.cgi/quux', '/quux', "/foo.cgi")
       
    73 
       
    74     def test_page_prefix_qargs (self) :
       
    75         self._test_page_prefix('/foo.cgi/?foo', '/', "/foo.cgi")
       
    76     
       
    77     def test_get_arg (self) :
       
    78         for query_string, key, value in (
       
    79             ('',                'foo',      None),
       
    80             ('foo',             'foo',      ''),
       
    81             ('foo=',            'foo',      ''),
       
    82             ('foo=bar',         'foo',      'bar'),
       
    83             ('foo=&bar=.',      'bar',      '.'),
       
    84         ) :
       
    85             self.assertEqual(self.build_request(QUERY_STRING=query_string).get_arg(key, None), value)
       
    86     
       
    87     def test_get_args (self) :
       
    88         for query_string, keyvals in (
       
    89             ('',                []),
       
    90             ('foo1=&bar',       [('foo1', ''), ('bar', '')]),
       
    91             ('foo2=bar',        [('foo2', 'bar')]),
       
    92             ('foo3=bar&foo3',   [('foo3', 'bar'), ('foo3', '')]),
       
    93         ) :
       
    94             self.assertEqual(self.build_request(QUERY_STRING=query_string).get_args(), keyvals)
       
    95     
       
    96     def _build_post (self, method='POST', **vals) :
       
    97         data = '&'.join('%s=%s' % kv for kv in vals.iteritems())
       
    98 
       
    99         return self.build_request({'wsgi.input': StringIO(data)}, REQUEST_METHOD=method, CONTENT_TYPE='application/x-www-form-urlencoded')
       
   100 
       
   101     def test_is_post (self) :
       
   102         for request_method, bool in (
       
   103             ('GET',             False),
       
   104             ('POST',            True),
       
   105             ('post',            True),
       
   106         ) :
       
   107             self.assertEqual(self._build_post(method=request_method).is_post(), bool)
       
   108         
       
   109     def _test_post (self, **vals) :
       
   110         req = self._build_post(**vals)
       
   111     
       
   112     def test_post_empty (self) :
       
   113         req = self._build_post()
       
   114 
       
   115         self.assertTrue(req.is_post())
       
   116         self.assertEqual(req.get_post('foo', None), None)
       
   117     
       
   118     def test_post_simple (self) :
       
   119         req = self._build_post(foo='bar')
       
   120 
       
   121         self.assertTrue(req.is_post())
       
   122         self.assertEqual(req.get_post('foo', None), 'bar')
       
   123 
       
   124 class TestHttpResponse (unittest.TestCase) :
       
   125     def test_status (self) :
       
   126         response = http.Response(None, status='100 Continue')
       
   127 
       
   128         self.assertEqual(response.get_status(), '100 Continue')
       
   129     
       
   130     def test_data_empty (self) :
       
   131         self.assertEqual(http.Response(None).get_data(), '')
       
   132 
       
   133     def test_data_str (self) :
       
   134         self.assertEqual(http.Response('foo').get_data(), 'foo')
       
   135     
       
   136     def test_data_utf8 (self) :
       
   137         data = u'föö'
       
   138 
       
   139         self.assertEqual(http.Response(data).get_data(), data.encode('utf8'))
       
   140 
       
   141     def test_data_utf16 (self) :
       
   142         data = u'fåå'
       
   143 
       
   144         self.assertEqual(http.Response(data, charset='utf16').get_data(), data.encode('utf16'))
       
   145     
       
   146     def test_data_invalid (self) :
       
   147         data = 'fää'
       
   148 
       
   149         self.assertRaises(UnicodeDecodeError, http.Response(data).get_data)
       
   150 
       
   151     def test_data_binary (self) :
       
   152         data = '\x01\x00'
       
   153 
       
   154         self.assertEqual(http.Response(data, charset=None).get_data(), data)
       
   155     
       
   156     def test_content_type_none (self) :
       
   157         response = http.Response(None, content_type=None)
       
   158 
       
   159         self.assertEqual(response.get_headers(), [])
       
   160     
       
   161     def test_content_type_default (self) :
       
   162         self.assertEqual(http.Response(None).get_headers(), [('Content-type', "text/html; charset=\"UTF-8\"")])
       
   163 
       
   164     def test_content_type_weird (self) :
       
   165         self.assertEqual(http.Response(None, content_type="foo/x-bar").get_headers(), [('Content-type', "foo/x-bar; charset=\"UTF-8\"")])
       
   166 
       
   167     def test_content_type_charset (self) :
       
   168         self.assertEqual(http.Response(None, content_type="foo/x-bar", charset="---").get_headers(), [('Content-type', "foo/x-bar; charset=\"---\"")])
       
   169     
       
   170     def _build_headers (self, tlist=None, **map) :
       
   171         response = http.Response(None)
       
   172 
       
   173         if tlist :
       
   174             for name, value, params in tlist :
       
   175                 response.add_header(name, value, **params)
       
   176         
       
   177         for name, value in map.iteritems() :
       
   178             response.add_header(name, value)
       
   179        
       
   180         return response
       
   181         
       
   182     def test_headers_simple (self) :
       
   183         self.assertEqual(self._build_headers(**{'X-Foo': 'bar, never'}).get_headers(), [
       
   184             ('Content-type', "text/html; charset=\"UTF-8\""),
       
   185             ('X-Foo', "bar, never")
       
   186         ])
       
   187 
       
   188     def test_headers_params (self) :
       
   189         self.assertEqual(self._build_headers([('X-Bar', 'bar', dict(never='yes'))]).get_headers(), [
       
   190             ('Content-type', "text/html; charset=\"UTF-8\""),
       
   191             ('X-Bar', "bar; never=\"yes\"")
       
   192         ])
       
   193 
       
   194     def test_headers_multi (self) :
       
   195         self.assertEqual(self._build_headers([('X-Bar', 'bar', {}), ('X-bar', 'foo', {})]).get_headers(), [
       
   196             ('Content-type', "text/html; charset=\"UTF-8\""),
       
   197             ('X-Bar', "bar"),
       
   198             ('X-bar', "foo"),
       
   199         ])
       
   200 
       
   201 class TestHttpRedirect (unittest.TestCase) :
       
   202     def test_redirect (self) :
       
   203         response = http.Redirect('http://test/bar')
       
   204 
       
   205         self.assertEquals(response.get_status(), '302 Found')
       
   206         self.assertEquals(response.get_headers(), [('Location', 'http://test/bar')])
       
   207         self.assertEquals(response.get_data(), '')
       
   208 
       
   209