python-2.5.2/win32/Lib/test/test_cgi.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 from test.test_support import verify, verbose
       
     2 import cgi
       
     3 import os
       
     4 import sys
       
     5 import tempfile
       
     6 from StringIO import StringIO
       
     7 
       
     8 class HackedSysModule:
       
     9     # The regression test will have real values in sys.argv, which
       
    10     # will completely confuse the test of the cgi module
       
    11     argv = []
       
    12     stdin = sys.stdin
       
    13 
       
    14 cgi.sys = HackedSysModule()
       
    15 
       
    16 try:
       
    17     from cStringIO import StringIO
       
    18 except ImportError:
       
    19     from StringIO import StringIO
       
    20 
       
    21 class ComparableException:
       
    22     def __init__(self, err):
       
    23         self.err = err
       
    24 
       
    25     def __str__(self):
       
    26         return str(self.err)
       
    27 
       
    28     def __cmp__(self, anExc):
       
    29         if not isinstance(anExc, Exception):
       
    30             return -1
       
    31         x = cmp(self.err.__class__, anExc.__class__)
       
    32         if x != 0:
       
    33             return x
       
    34         return cmp(self.err.args, anExc.args)
       
    35 
       
    36     def __getattr__(self, attr):
       
    37         return getattr(self.err, attr)
       
    38 
       
    39 def do_test(buf, method):
       
    40     env = {}
       
    41     if method == "GET":
       
    42         fp = None
       
    43         env['REQUEST_METHOD'] = 'GET'
       
    44         env['QUERY_STRING'] = buf
       
    45     elif method == "POST":
       
    46         fp = StringIO(buf)
       
    47         env['REQUEST_METHOD'] = 'POST'
       
    48         env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
       
    49         env['CONTENT_LENGTH'] = str(len(buf))
       
    50     else:
       
    51         raise ValueError, "unknown method: %s" % method
       
    52     try:
       
    53         return cgi.parse(fp, env, strict_parsing=1)
       
    54     except StandardError, err:
       
    55         return ComparableException(err)
       
    56 
       
    57 # A list of test cases.  Each test case is a a two-tuple that contains
       
    58 # a string with the query and a dictionary with the expected result.
       
    59 
       
    60 parse_qsl_test_cases = [
       
    61     ("", []),
       
    62     ("&", []),
       
    63     ("&&", []),
       
    64     ("=", [('', '')]),
       
    65     ("=a", [('', 'a')]),
       
    66     ("a", [('a', '')]),
       
    67     ("a=", [('a', '')]),
       
    68     ("a=", [('a', '')]),
       
    69     ("&a=b", [('a', 'b')]),
       
    70     ("a=a+b&b=b+c", [('a', 'a b'), ('b', 'b c')]),
       
    71     ("a=1&a=2", [('a', '1'), ('a', '2')]),
       
    72 ]
       
    73 
       
    74 parse_strict_test_cases = [
       
    75     ("", ValueError("bad query field: ''")),
       
    76     ("&", ValueError("bad query field: ''")),
       
    77     ("&&", ValueError("bad query field: ''")),
       
    78     (";", ValueError("bad query field: ''")),
       
    79     (";&;", ValueError("bad query field: ''")),
       
    80     # Should the next few really be valid?
       
    81     ("=", {}),
       
    82     ("=&=", {}),
       
    83     ("=;=", {}),
       
    84     # This rest seem to make sense
       
    85     ("=a", {'': ['a']}),
       
    86     ("&=a", ValueError("bad query field: ''")),
       
    87     ("=a&", ValueError("bad query field: ''")),
       
    88     ("=&a", ValueError("bad query field: 'a'")),
       
    89     ("b=a", {'b': ['a']}),
       
    90     ("b+=a", {'b ': ['a']}),
       
    91     ("a=b=a", {'a': ['b=a']}),
       
    92     ("a=+b=a", {'a': [' b=a']}),
       
    93     ("&b=a", ValueError("bad query field: ''")),
       
    94     ("b&=a", ValueError("bad query field: 'b'")),
       
    95     ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}),
       
    96     ("a=a+b&a=b+a", {'a': ['a b', 'b a']}),
       
    97     ("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
       
    98     ("x=1;y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
       
    99     ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
       
   100     ("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env",
       
   101      {'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'],
       
   102       'cuyer': ['r'],
       
   103       'expire': ['964546263'],
       
   104       'kid': ['130003.300038'],
       
   105       'lobale': ['en-US'],
       
   106       'order_id': ['0bb2e248638833d48cb7fed300000f1b'],
       
   107       'ss': ['env'],
       
   108       'view': ['bustomer'],
       
   109       }),
       
   110 
       
   111     ("group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse",
       
   112      {'SUBMIT': ['Browse'],
       
   113       '_assigned_to': ['31392'],
       
   114       '_category': ['100'],
       
   115       '_status': ['1'],
       
   116       'group_id': ['5470'],
       
   117       'set': ['custom'],
       
   118       })
       
   119     ]
       
   120 
       
   121 def norm(list):
       
   122     if type(list) == type([]):
       
   123         list.sort()
       
   124     return list
       
   125 
       
   126 def first_elts(list):
       
   127     return map(lambda x:x[0], list)
       
   128 
       
   129 def first_second_elts(list):
       
   130     return map(lambda p:(p[0], p[1][0]), list)
       
   131 
       
   132 def main():
       
   133     for orig, expect in parse_qsl_test_cases:
       
   134         result = cgi.parse_qsl(orig, keep_blank_values=True)
       
   135         print repr(orig), '=>', result
       
   136         verify(result == expect, "Error parsing %s" % repr(orig))
       
   137 
       
   138     for orig, expect in parse_strict_test_cases:
       
   139         # Test basic parsing
       
   140         print repr(orig)
       
   141         d = do_test(orig, "GET")
       
   142         verify(d == expect, "Error parsing %s" % repr(orig))
       
   143         d = do_test(orig, "POST")
       
   144         verify(d == expect, "Error parsing %s" % repr(orig))
       
   145 
       
   146         env = {'QUERY_STRING': orig}
       
   147         fcd = cgi.FormContentDict(env)
       
   148         sd = cgi.SvFormContentDict(env)
       
   149         fs = cgi.FieldStorage(environ=env)
       
   150         if type(expect) == type({}):
       
   151             # test dict interface
       
   152             verify(len(expect) == len(fcd))
       
   153             verify(norm(expect.keys()) == norm(fcd.keys()))
       
   154             verify(norm(expect.values()) == norm(fcd.values()))
       
   155             verify(norm(expect.items()) == norm(fcd.items()))
       
   156             verify(fcd.get("nonexistent field", "default") == "default")
       
   157             verify(len(sd) == len(fs))
       
   158             verify(norm(sd.keys()) == norm(fs.keys()))
       
   159             verify(fs.getvalue("nonexistent field", "default") == "default")
       
   160             # test individual fields
       
   161             for key in expect.keys():
       
   162                 expect_val = expect[key]
       
   163                 verify(fcd.has_key(key))
       
   164                 verify(norm(fcd[key]) == norm(expect[key]))
       
   165                 verify(fcd.get(key, "default") == fcd[key])
       
   166                 verify(fs.has_key(key))
       
   167                 if len(expect_val) > 1:
       
   168                     single_value = 0
       
   169                 else:
       
   170                     single_value = 1
       
   171                 try:
       
   172                     val = sd[key]
       
   173                 except IndexError:
       
   174                     verify(not single_value)
       
   175                     verify(fs.getvalue(key) == expect_val)
       
   176                 else:
       
   177                     verify(single_value)
       
   178                     verify(val == expect_val[0])
       
   179                     verify(fs.getvalue(key) == expect_val[0])
       
   180                 verify(norm(sd.getlist(key)) == norm(expect_val))
       
   181                 if single_value:
       
   182                     verify(norm(sd.values()) == \
       
   183                            first_elts(norm(expect.values())))
       
   184                     verify(norm(sd.items()) == \
       
   185                            first_second_elts(norm(expect.items())))
       
   186 
       
   187     # Test the weird FormContentDict classes
       
   188     env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
       
   189     expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
       
   190     d = cgi.InterpFormContentDict(env)
       
   191     for k, v in expect.items():
       
   192         verify(d[k] == v)
       
   193     for k, v in d.items():
       
   194         verify(expect[k] == v)
       
   195     verify(norm(expect.values()) == norm(d.values()))
       
   196 
       
   197     print "Testing log"
       
   198     cgi.log("Testing")
       
   199     cgi.logfp = sys.stdout
       
   200     cgi.initlog("%s", "Testing initlog 1")
       
   201     cgi.log("%s", "Testing log 2")
       
   202     if os.path.exists("/dev/null"):
       
   203         cgi.logfp = None
       
   204         cgi.logfile = "/dev/null"
       
   205         cgi.initlog("%s", "Testing log 3")
       
   206         cgi.log("Testing log 4")
       
   207 
       
   208     print "Test FieldStorage methods that use readline"
       
   209     # FieldStorage uses readline, which has the capacity to read all
       
   210     # contents of the input file into memory; we use readline's size argument
       
   211     # to prevent that for files that do not contain any newlines in
       
   212     # non-GET/HEAD requests
       
   213     class TestReadlineFile:
       
   214         def __init__(self, file):
       
   215             self.file = file
       
   216             self.numcalls = 0
       
   217 
       
   218         def readline(self, size=None):
       
   219             self.numcalls += 1
       
   220             if size:
       
   221                 return self.file.readline(size)
       
   222             else:
       
   223                 return self.file.readline()
       
   224 
       
   225         def __getattr__(self, name):
       
   226             file = self.__dict__['file']
       
   227             a = getattr(file, name)
       
   228             if not isinstance(a, int):
       
   229                 setattr(self, name, a)
       
   230             return a
       
   231 
       
   232     f = TestReadlineFile(tempfile.TemporaryFile())
       
   233     f.write('x' * 256 * 1024)
       
   234     f.seek(0)
       
   235     env = {'REQUEST_METHOD':'PUT'}
       
   236     fs = cgi.FieldStorage(fp=f, environ=env)
       
   237     # if we're not chunking properly, readline is only called twice
       
   238     # (by read_binary); if we are chunking properly, it will be called 5 times
       
   239     # as long as the chunksize is 1 << 16.
       
   240     verify(f.numcalls > 2)
       
   241 
       
   242     print "Test basic FieldStorage multipart parsing"
       
   243     env = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':'multipart/form-data; boundary=---------------------------721837373350705526688164684', 'CONTENT_LENGTH':'558'}
       
   244     postdata = """-----------------------------721837373350705526688164684
       
   245 Content-Disposition: form-data; name="id"
       
   246 
       
   247 1234
       
   248 -----------------------------721837373350705526688164684
       
   249 Content-Disposition: form-data; name="title"
       
   250 
       
   251 
       
   252 -----------------------------721837373350705526688164684
       
   253 Content-Disposition: form-data; name="file"; filename="test.txt"
       
   254 Content-Type: text/plain
       
   255 
       
   256 Testing 123.
       
   257 
       
   258 -----------------------------721837373350705526688164684
       
   259 Content-Disposition: form-data; name="submit"
       
   260 
       
   261  Add\x20
       
   262 -----------------------------721837373350705526688164684--
       
   263 """
       
   264     fs = cgi.FieldStorage(fp=StringIO(postdata), environ=env)
       
   265     verify(len(fs.list) == 4)
       
   266     expect = [{'name':'id', 'filename':None, 'value':'1234'},
       
   267               {'name':'title', 'filename':None, 'value':''},
       
   268               {'name':'file', 'filename':'test.txt','value':'Testing 123.\n'},
       
   269               {'name':'submit', 'filename':None, 'value':' Add '}]
       
   270     for x in range(len(fs.list)):
       
   271         for k, exp in expect[x].items():
       
   272             got = getattr(fs.list[x], k)
       
   273             verify(got == exp)
       
   274 
       
   275 main()