# -*- coding: utf-8 -*- from unittest import TestCase import mimetypes import poster.encode import StringIO import sys def unix2dos(s): return s.replace("\n", "\r\n") class TestEncode_String(TestCase): def test_simple(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 bar """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", "foo", "bar")) def test_quote_name_space(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo baz" Content-Type: text/plain; charset=utf-8 bar """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", "foo baz", "bar")) def test_quote_name_phparray(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="files[]" Content-Type: text/plain; charset=utf-8 bar """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", "files[]", "bar")) def test_quote_unicode_name(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="=?utf-8?b?4piD?=" Content-Type: text/plain; charset=utf-8 bar """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", u"\N{SNOWMAN}", "bar")) def test_quote_value(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 bar baz@bat """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", "foo", "bar baz@bat")) def test_boundary(self): expected = unix2dos("""--ABC+DEF Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 bar """) self.assertEqual(expected, poster.encode.encode_string("ABC DEF", "foo", "bar")) def test_unicode(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 b\xc3\xa1r """) self.assertEqual(expected, poster.encode.encode_string("XXXXXXXXX", "foo", u"bár")) class TestEncode_File(TestCase): def test_simple(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42)) def test_content_type(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo" Content-Type: text/html """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42, filetype="text/html")) def test_filename_simple(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo"; filename="test.txt" Content-Type: text/plain; charset=utf-8 """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42, "test.txt")) def test_quote_filename(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo"; filename="test file.txt" Content-Type: text/plain; charset=utf-8 """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42, "test file.txt")) expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo"; filename="test\\"file.txt" Content-Type: text/plain; charset=utf-8 """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42, "test\"file.txt")) def test_unicode_filename(self): expected = unix2dos("""--XXXXXXXXX Content-Disposition: form-data; name="foo"; filename="☃.txt" Content-Type: text/plain; charset=utf-8 """) self.assertEqual(expected, poster.encode.encode_file_header("XXXXXXXXX", "foo", 42, u"\N{SNOWMAN}.txt")) class TestEncodeAndQuote(TestCase): def test(self): self.assertEqual("foo+bar", poster.encode.encode_and_quote("foo bar")) self.assertEqual("foo%40bar", poster.encode.encode_and_quote("foo@bar")) self.assertEqual("%28%C2%A9%29+2008", poster.encode.encode_and_quote(u"(©) 2008")) class TestMultiparam(TestCase): def test_from_params(self): fp = open("tests/test_encode.py") expected = [poster.encode.MultipartParam("foo", "bar"), poster.encode.MultipartParam("baz", fileobj=fp, filename=fp.name, filetype=mimetypes.guess_type(fp.name)[0])] self.assertEqual(poster.encode.MultipartParam.from_params( [("foo", "bar"), ("baz", fp)]), expected) self.assertEqual(poster.encode.MultipartParam.from_params( (("foo", "bar"), ("baz", fp))), expected) self.assertEqual(poster.encode.MultipartParam.from_params( {"foo": "bar", "baz": fp}), expected) self.assertEqual(poster.encode.MultipartParam.from_params( [expected[0], expected[1]]), expected) def test_from_params_dict(self): p = poster.encode.MultipartParam('file', fileobj=open("tests/test_encode.py")) params = {"foo": "bar", "file": p} expected = [poster.encode.MultipartParam("foo", "bar"), p] retval = poster.encode.MultipartParam.from_params(params) expected.sort() retval.sort() self.assertEqual(retval, expected) def test_from_params_assertion(self): p = poster.encode.MultipartParam('file', fileobj=open("tests/test_encode.py")) params = {"foo": "bar", "baz": p} self.assertRaises(AssertionError, poster.encode.MultipartParam.from_params, params) def test_simple(self): p = poster.encode.MultipartParam("foo", "bar") boundary = "XYZXYZXYZ" expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 bar --XYZXYZXYZ-- """) self.assertEqual(p.encode(boundary), expected[:-len(boundary)-6]) self.assertEqual(p.get_size(boundary), len(expected)-len(boundary)-6) self.assertEqual(poster.encode.get_body_size([p], boundary), len(expected)) self.assertEqual(poster.encode.get_headers([p], boundary), {'Content-Length': str(len(expected)), 'Content-Type': 'multipart/form-data; boundary=%s' % boundary}) datagen, headers = poster.encode.multipart_encode([p], boundary) self.assertEqual(headers, {'Content-Length': str(len(expected)), 'Content-Type': 'multipart/form-data; boundary=%s' % boundary}) self.assertEqual("".join(datagen), expected) def test_multiple_keys(self): params = poster.encode.MultipartParam.from_params( [("key", "value1"), ("key", "value2")]) boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode(params, boundary) encoded = "".join(datagen) expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="key" Content-Type: text/plain; charset=utf-8 value1 --XYZXYZXYZ Content-Disposition: form-data; name="key" Content-Type: text/plain; charset=utf-8 value2 --XYZXYZXYZ-- """) self.assertEqual(encoded, expected) def test_stringio(self): fp = StringIO.StringIO("file data") params = poster.encode.MultipartParam.from_params( [("foo", fp)] ) boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode(params, boundary) encoded = "".join(datagen) expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 file data --XYZXYZXYZ-- """) self.assertEqual(encoded, expected) def test_reset_string(self): p = poster.encode.MultipartParam("foo", "bar") boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode([p], boundary) expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 bar --XYZXYZXYZ-- """) self.assertEquals("".join(datagen), expected) datagen.reset() self.assertEquals("".join(datagen), expected) def test_reset_multiple_keys(self): params = poster.encode.MultipartParam.from_params( [("key", "value1"), ("key", "value2")]) boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode(params, boundary) expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="key" Content-Type: text/plain; charset=utf-8 value1 --XYZXYZXYZ Content-Disposition: form-data; name="key" Content-Type: text/plain; charset=utf-8 value2 --XYZXYZXYZ-- """) encoded = "".join(datagen) self.assertEqual(encoded, expected) datagen.reset() encoded = "".join(datagen) self.assertEqual(encoded, expected) def test_reset_file(self): fp = StringIO.StringIO("file data") params = poster.encode.MultipartParam.from_params( [("foo", fp)] ) boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode(params, boundary) expected = unix2dos("""--XYZXYZXYZ Content-Disposition: form-data; name="foo" Content-Type: text/plain; charset=utf-8 file data --XYZXYZXYZ-- """) encoded = "".join(datagen) self.assertEqual(encoded, expected) datagen.reset() encoded = "".join(datagen) self.assertEqual(encoded, expected) def test_MultipartParam_cb(self): log = [] def cb(p, current, total): log.append( (p, current, total) ) p = poster.encode.MultipartParam("foo", "bar", cb=cb) boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode([p], boundary) "".join(datagen) l = p.get_size(boundary) self.assertEquals(log[-1], (p, l, l)) def test_MultipartParam_file_cb(self): log = [] def cb(p, current, total): log.append( (p, current, total) ) p = poster.encode.MultipartParam("foo", fileobj=open("tests/test_encode.py"), cb=cb) boundary = poster.encode.gen_boundary() list(p.iter_encode(boundary)) l = p.get_size(boundary) self.assertEquals(log[-1], (p, l, l)) def test_multipart_encode_cb(self): log = [] def cb(p, current, total): log.append( (p, current, total) ) p = poster.encode.MultipartParam("foo", "bar") boundary = "XYZXYZXYZ" datagen, headers = poster.encode.multipart_encode([p], boundary, cb=cb) "".join(datagen) l = int(headers['Content-Length']) self.assertEquals(log[-1], (None, l, l)) class TestGenBoundary(TestCase): def testGenBoundary(self): boundary1 = poster.encode.gen_boundary() boundary2 = poster.encode.gen_boundary() self.assertNotEqual(boundary1, boundary2) self.assert_(len(boundary1) > 0) class TestBackupGenBoundary(TestGenBoundary): _orig_import = __import__ def setUp(self): # Make import uuid fail def my_import(name, *args, **kwargs): if name == 'uuid': raise ImportError("Disabled for testing") return self._orig_import(name, *args, **kwargs) __builtins__['__import__'] = my_import reload(poster.encode) def tearDown(self): __builtins__['__import__'] = self._orig_import reload(poster.encode)