test_cgi.py 6.25 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
import cgi
import os
import sys

class HackedSysModule:
    # The regression test will have real values in sys.argv, which
    # will completely confuse the test of the cgi module 
    argv = []
    stdin = sys.stdin

cgi.sys = HackedSysModule()

try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO

class ComparableException:
    def __init__(self, err):
        self.err = err

    def __str__(self):
        return str(self.err)

    def __cmp__(self, anExc):
        if not isinstance(anExc, Exception):
            return -1
        x = cmp(self.err.__class__, anExc.__class__)
        if x != 0:
            return x
        return cmp(self.err.args, anExc.args)

    def __getattr__(self, attr):
        return getattr(self, self.err)

def do_test(buf, method):
    env = {}
    if method == "GET":
        fp = None
        env['REQUEST_METHOD'] = 'GET'
        env['QUERY_STRING'] = buf
    elif method == "POST":
        fp = StringIO(buf)
        env['REQUEST_METHOD'] = 'POST'
        env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'
        env['CONTENT_LENGTH'] = str(len(buf))
    else:
        raise ValueError, "unknown method: %s" % method
    try:
        return cgi.parse(fp, env, strict_parsing=1)
    except StandardError, err:
        return ComparableException(err)

# A list of test cases.  Each test case is a a two-tuple that contains
# a string with the query and a dictionary with the expected result.
    
parse_test_cases = [
    ("", ValueError("bad query field: ''")),
    ("&", ValueError("bad query field: ''")),
    ("&&", ValueError("bad query field: ''")),
61 62
    (";", ValueError("bad query field: ''")),
    (";&;", ValueError("bad query field: ''")),
63 64 65
    # Should the next few really be valid?
    ("=", {}),
    ("=&=", {}),
66
    ("=;=", {}),
67 68 69 70 71 72 73 74 75 76 77 78 79 80
    # This rest seem to make sense
    ("=a", {'': ['a']}),
    ("&=a", ValueError("bad query field: ''")),
    ("=a&", ValueError("bad query field: ''")),
    ("=&a", ValueError("bad query field: 'a'")),
    ("b=a", {'b': ['a']}),
    ("b+=a", {'b ': ['a']}),
    ("a=b=a", {'a': ['b=a']}),
    ("a=+b=a", {'a': [' b=a']}),
    ("&b=a", ValueError("bad query field: ''")),
    ("b&=a", ValueError("bad query field: 'b'")),
    ("a=a+b&b=b+c", {'a': ['a b'], 'b': ['b c']}),
    ("a=a+b&a=b+a", {'a': ['a b', 'b a']}),
    ("x=1&y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
81 82
    ("x=1;y=2.0&z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
    ("x=1;y=2.0;z=2-3.%2b0", {'x': ['1'], 'y': ['2.0'], 'z': ['2-3.+0']}),
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
    ("Hbc5161168c542333633315dee1182227:key_store_seqid=400006&cuyer=r&view=bustomer&order_id=0bb2e248638833d48cb7fed300000f1b&expire=964546263&lobale=en-US&kid=130003.300038&ss=env",
     {'Hbc5161168c542333633315dee1182227:key_store_seqid': ['400006'],
      'cuyer': ['r'],
      'expire': ['964546263'],
      'kid': ['130003.300038'],
      'lobale': ['en-US'],
      'order_id': ['0bb2e248638833d48cb7fed300000f1b'],
      'ss': ['env'],
      'view': ['bustomer'],
      }),
    
    ("group_id=5470&set=custom&_assigned_to=31392&_status=1&_category=100&SUBMIT=Browse",
     {'SUBMIT': ['Browse'],
      '_assigned_to': ['31392'],
      '_category': ['100'],
      '_status': ['1'],
      'group_id': ['5470'],
      'set': ['custom'],
      })
    ]

def norm(list):
    if type(list) == type([]):
        list.sort()
    return list

def first_elts(list):
    return map(lambda x:x[0], list)

def first_second_elts(list):
    return map(lambda p:(p[0], p[1][0]), list)

def main():
    for orig, expect in parse_test_cases:
        # Test basic parsing
        print repr(orig)
        d = do_test(orig, "GET")
        assert d == expect, "Error parsing %s" % repr(orig)
        d = do_test(orig, "POST")
        assert d == expect, "Error parsing %s" % repr(orig)

124 125 126 127
        env = {'QUERY_STRING': orig}
        fcd = cgi.FormContentDict(env)
        sd = cgi.SvFormContentDict(env)
        fs = cgi.FieldStorage(environ=env)
128 129 130 131 132 133
        if type(expect) == type({}):
            # test dict interface
            assert len(expect) == len(fcd)
            assert norm(expect.keys()) == norm(fcd.keys())
            assert norm(expect.values()) == norm(fcd.values())
            assert norm(expect.items()) == norm(fcd.items())
134 135 136 137 138
            assert fcd.get("nonexistent field", "default") == "default"
            assert len(sd) == len(fs)
            assert norm(sd.keys()) == norm(fs.keys())
            assert fs.getvalue("nonexistent field", "default") == "default"
            # test individual fields
139 140 141 142
            for key in expect.keys():
                expect_val = expect[key]
                assert fcd.has_key(key)
                assert norm(fcd[key]) == norm(expect[key])
143 144
                assert fcd.get(key, "default") == fcd[key]
                assert fs.has_key(key)
145 146 147 148 149 150 151 152
                if len(expect_val) > 1:
                    single_value = 0
                else:
                    single_value = 1
                try:
                    val = sd[key]
                except IndexError:
                    assert not single_value
153
                    assert fs.getvalue(key) == expect_val
154 155 156
                else:
                    assert single_value
                    assert val == expect_val[0]
157
                    assert fs.getvalue(key) == expect_val[0]
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
                assert norm(sd.getlist(key)) == norm(expect_val)
                if single_value:
                    assert norm(sd.values()) == \
                           first_elts(norm(expect.values()))
                    assert norm(sd.items()) == \
                           first_second_elts(norm(expect.items()))

    # Test the weird FormContentDict classes
    env = {'QUERY_STRING': "x=1&y=2.0&z=2-3.%2b0&1=1abc"}
    expect = {'x': 1, 'y': 2.0, 'z': '2-3.+0', '1': '1abc'}
    d = cgi.InterpFormContentDict(env)
    for k, v in expect.items():
        assert d[k] == v
    for k, v in d.items():
        assert expect[k] == v
    assert norm(expect.values()) == norm(d.values())

    print "Testing log"
    cgi.initlog()
    cgi.log("Testing")
    cgi.logfp = sys.stdout
    cgi.initlog("%s", "Testing initlog 1")
    cgi.log("%s", "Testing log 2")
    if os.path.exists("/dev/null"):
        cgi.logfp = None
        cgi.logfile = "/dev/null"
        cgi.initlog("%s", "Testing log 3")
        cgi.log("Testing log 4")

main()