17db96d56Sopenharmony_ciimport copy 27db96d56Sopenharmony_ciimport os 37db96d56Sopenharmony_ciimport sys 47db96d56Sopenharmony_ciimport test.support 57db96d56Sopenharmony_ciimport unittest 67db96d56Sopenharmony_ciimport warnings 77db96d56Sopenharmony_cifrom test.support import os_helper 87db96d56Sopenharmony_cifrom test.support import warnings_helper 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ci 117db96d56Sopenharmony_cimailcap = warnings_helper.import_deprecated('mailcap') 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci# Location of mailcap file 157db96d56Sopenharmony_ciMAILCAPFILE = test.support.findfile("mailcap.txt") 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci# Dict to act as mock mailcap entry for this test 187db96d56Sopenharmony_ci# The keys and values should match the contents of MAILCAPFILE 197db96d56Sopenharmony_ciMAILCAPDICT = { 207db96d56Sopenharmony_ci 'application/x-movie': 217db96d56Sopenharmony_ci [{'compose': 'moviemaker %s', 227db96d56Sopenharmony_ci 'x11-bitmap': '"/usr/lib/Zmail/bitmaps/movie.xbm"', 237db96d56Sopenharmony_ci 'description': '"Movie"', 247db96d56Sopenharmony_ci 'view': 'movieplayer %s', 257db96d56Sopenharmony_ci 'lineno': 4}], 267db96d56Sopenharmony_ci 'application/*': 277db96d56Sopenharmony_ci [{'copiousoutput': '', 287db96d56Sopenharmony_ci 'view': 'echo "This is \\"%t\\" but is 50 \\% Greek to me" \\; cat %s', 297db96d56Sopenharmony_ci 'lineno': 5}], 307db96d56Sopenharmony_ci 'audio/basic': 317db96d56Sopenharmony_ci [{'edit': 'audiocompose %s', 327db96d56Sopenharmony_ci 'compose': 'audiocompose %s', 337db96d56Sopenharmony_ci 'description': '"An audio fragment"', 347db96d56Sopenharmony_ci 'view': 'showaudio %s', 357db96d56Sopenharmony_ci 'lineno': 6}], 367db96d56Sopenharmony_ci 'video/mpeg': 377db96d56Sopenharmony_ci [{'view': 'mpeg_play %s', 'lineno': 13}], 387db96d56Sopenharmony_ci 'application/postscript': 397db96d56Sopenharmony_ci [{'needsterminal': '', 'view': 'ps-to-terminal %s', 'lineno': 1}, 407db96d56Sopenharmony_ci {'compose': 'idraw %s', 'view': 'ps-to-terminal %s', 'lineno': 2}], 417db96d56Sopenharmony_ci 'application/x-dvi': 427db96d56Sopenharmony_ci [{'view': 'xdvi %s', 'lineno': 3}], 437db96d56Sopenharmony_ci 'message/external-body': 447db96d56Sopenharmony_ci [{'composetyped': 'extcompose %s', 457db96d56Sopenharmony_ci 'description': '"A reference to data stored in an external location"', 467db96d56Sopenharmony_ci 'needsterminal': '', 477db96d56Sopenharmony_ci 'view': 'showexternal %s %{access-type} %{name} %{site} %{directory} %{mode} %{server}', 487db96d56Sopenharmony_ci 'lineno': 10}], 497db96d56Sopenharmony_ci 'text/richtext': 507db96d56Sopenharmony_ci [{'test': 'test "`echo %{charset} | tr \'[A-Z]\' \'[a-z]\'`" = iso-8859-8', 517db96d56Sopenharmony_ci 'copiousoutput': '', 527db96d56Sopenharmony_ci 'view': 'shownonascii iso-8859-8 -e richtext -p %s', 537db96d56Sopenharmony_ci 'lineno': 11}], 547db96d56Sopenharmony_ci 'image/x-xwindowdump': 557db96d56Sopenharmony_ci [{'view': 'display %s', 'lineno': 9}], 567db96d56Sopenharmony_ci 'audio/*': 577db96d56Sopenharmony_ci [{'view': '/usr/local/bin/showaudio %t', 'lineno': 7}], 587db96d56Sopenharmony_ci 'video/*': 597db96d56Sopenharmony_ci [{'view': 'animate %s', 'lineno': 12}], 607db96d56Sopenharmony_ci 'application/frame': 617db96d56Sopenharmony_ci [{'print': '"cat %s | lp"', 'view': 'showframe %s', 'lineno': 0}], 627db96d56Sopenharmony_ci 'image/rgb': 637db96d56Sopenharmony_ci [{'view': 'display %s', 'lineno': 8}] 647db96d56Sopenharmony_ci} 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci# For backwards compatibility, readmailcapfile() and lookup() still support 677db96d56Sopenharmony_ci# the old version of mailcapdict without line numbers. 687db96d56Sopenharmony_ciMAILCAPDICT_DEPRECATED = copy.deepcopy(MAILCAPDICT) 697db96d56Sopenharmony_cifor entry_list in MAILCAPDICT_DEPRECATED.values(): 707db96d56Sopenharmony_ci for entry in entry_list: 717db96d56Sopenharmony_ci entry.pop('lineno') 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ciclass HelperFunctionTest(unittest.TestCase): 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci def test_listmailcapfiles(self): 777db96d56Sopenharmony_ci # The return value for listmailcapfiles() will vary by system. 787db96d56Sopenharmony_ci # So verify that listmailcapfiles() returns a list of strings that is of 797db96d56Sopenharmony_ci # non-zero length. 807db96d56Sopenharmony_ci mcfiles = mailcap.listmailcapfiles() 817db96d56Sopenharmony_ci self.assertIsInstance(mcfiles, list) 827db96d56Sopenharmony_ci for m in mcfiles: 837db96d56Sopenharmony_ci self.assertIsInstance(m, str) 847db96d56Sopenharmony_ci with os_helper.EnvironmentVarGuard() as env: 857db96d56Sopenharmony_ci # According to RFC 1524, if MAILCAPS env variable exists, use that 867db96d56Sopenharmony_ci # and only that. 877db96d56Sopenharmony_ci if "MAILCAPS" in env: 887db96d56Sopenharmony_ci env_mailcaps = env["MAILCAPS"].split(os.pathsep) 897db96d56Sopenharmony_ci else: 907db96d56Sopenharmony_ci env_mailcaps = ["/testdir1/.mailcap", "/testdir2/mailcap"] 917db96d56Sopenharmony_ci env["MAILCAPS"] = os.pathsep.join(env_mailcaps) 927db96d56Sopenharmony_ci mcfiles = mailcap.listmailcapfiles() 937db96d56Sopenharmony_ci self.assertEqual(env_mailcaps, mcfiles) 947db96d56Sopenharmony_ci 957db96d56Sopenharmony_ci def test_readmailcapfile(self): 967db96d56Sopenharmony_ci # Test readmailcapfile() using test file. It should match MAILCAPDICT. 977db96d56Sopenharmony_ci with open(MAILCAPFILE, 'r') as mcf: 987db96d56Sopenharmony_ci with self.assertWarns(DeprecationWarning): 997db96d56Sopenharmony_ci d = mailcap.readmailcapfile(mcf) 1007db96d56Sopenharmony_ci self.assertDictEqual(d, MAILCAPDICT_DEPRECATED) 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci def test_lookup(self): 1037db96d56Sopenharmony_ci # Test without key 1047db96d56Sopenharmony_ci expected = [{'view': 'animate %s', 'lineno': 12}, 1057db96d56Sopenharmony_ci {'view': 'mpeg_play %s', 'lineno': 13}] 1067db96d56Sopenharmony_ci actual = mailcap.lookup(MAILCAPDICT, 'video/mpeg') 1077db96d56Sopenharmony_ci self.assertListEqual(expected, actual) 1087db96d56Sopenharmony_ci 1097db96d56Sopenharmony_ci # Test with key 1107db96d56Sopenharmony_ci key = 'compose' 1117db96d56Sopenharmony_ci expected = [{'edit': 'audiocompose %s', 1127db96d56Sopenharmony_ci 'compose': 'audiocompose %s', 1137db96d56Sopenharmony_ci 'description': '"An audio fragment"', 1147db96d56Sopenharmony_ci 'view': 'showaudio %s', 1157db96d56Sopenharmony_ci 'lineno': 6}] 1167db96d56Sopenharmony_ci actual = mailcap.lookup(MAILCAPDICT, 'audio/basic', key) 1177db96d56Sopenharmony_ci self.assertListEqual(expected, actual) 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_ci # Test on user-defined dicts without line numbers 1207db96d56Sopenharmony_ci expected = [{'view': 'mpeg_play %s'}, {'view': 'animate %s'}] 1217db96d56Sopenharmony_ci actual = mailcap.lookup(MAILCAPDICT_DEPRECATED, 'video/mpeg') 1227db96d56Sopenharmony_ci self.assertListEqual(expected, actual) 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci def test_subst(self): 1257db96d56Sopenharmony_ci plist = ['id=1', 'number=2', 'total=3'] 1267db96d56Sopenharmony_ci # test case: ([field, MIMEtype, filename, plist=[]], <expected string>) 1277db96d56Sopenharmony_ci test_cases = [ 1287db96d56Sopenharmony_ci (["", "audio/*", "foo.txt"], ""), 1297db96d56Sopenharmony_ci (["echo foo", "audio/*", "foo.txt"], "echo foo"), 1307db96d56Sopenharmony_ci (["echo %s", "audio/*", "foo.txt"], "echo foo.txt"), 1317db96d56Sopenharmony_ci (["echo %t", "audio/*", "foo.txt"], None), 1327db96d56Sopenharmony_ci (["echo %t", "audio/wav", "foo.txt"], "echo audio/wav"), 1337db96d56Sopenharmony_ci (["echo \\%t", "audio/*", "foo.txt"], "echo %t"), 1347db96d56Sopenharmony_ci (["echo foo", "audio/*", "foo.txt", plist], "echo foo"), 1357db96d56Sopenharmony_ci (["echo %{total}", "audio/*", "foo.txt", plist], "echo 3") 1367db96d56Sopenharmony_ci ] 1377db96d56Sopenharmony_ci for tc in test_cases: 1387db96d56Sopenharmony_ci self.assertEqual(mailcap.subst(*tc[0]), tc[1]) 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci 1417db96d56Sopenharmony_ciclass GetcapsTest(unittest.TestCase): 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci def test_mock_getcaps(self): 1447db96d56Sopenharmony_ci # Test mailcap.getcaps() using mock mailcap file in this dir. 1457db96d56Sopenharmony_ci # Temporarily override any existing system mailcap file by pointing the 1467db96d56Sopenharmony_ci # MAILCAPS environment variable to our mock file. 1477db96d56Sopenharmony_ci with os_helper.EnvironmentVarGuard() as env: 1487db96d56Sopenharmony_ci env["MAILCAPS"] = MAILCAPFILE 1497db96d56Sopenharmony_ci caps = mailcap.getcaps() 1507db96d56Sopenharmony_ci self.assertDictEqual(caps, MAILCAPDICT) 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci def test_system_mailcap(self): 1537db96d56Sopenharmony_ci # Test mailcap.getcaps() with mailcap file(s) on system, if any. 1547db96d56Sopenharmony_ci caps = mailcap.getcaps() 1557db96d56Sopenharmony_ci self.assertIsInstance(caps, dict) 1567db96d56Sopenharmony_ci mailcapfiles = mailcap.listmailcapfiles() 1577db96d56Sopenharmony_ci existingmcfiles = [mcf for mcf in mailcapfiles if os.path.exists(mcf)] 1587db96d56Sopenharmony_ci if existingmcfiles: 1597db96d56Sopenharmony_ci # At least 1 mailcap file exists, so test that. 1607db96d56Sopenharmony_ci for (k, v) in caps.items(): 1617db96d56Sopenharmony_ci self.assertIsInstance(k, str) 1627db96d56Sopenharmony_ci self.assertIsInstance(v, list) 1637db96d56Sopenharmony_ci for e in v: 1647db96d56Sopenharmony_ci self.assertIsInstance(e, dict) 1657db96d56Sopenharmony_ci else: 1667db96d56Sopenharmony_ci # No mailcap files on system. getcaps() should return empty dict. 1677db96d56Sopenharmony_ci self.assertEqual({}, caps) 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ciclass FindmatchTest(unittest.TestCase): 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ci def test_findmatch(self): 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_ci # default findmatch arguments 1757db96d56Sopenharmony_ci c = MAILCAPDICT 1767db96d56Sopenharmony_ci fname = "foo.txt" 1777db96d56Sopenharmony_ci plist = ["access-type=default", "name=john", "site=python.org", 1787db96d56Sopenharmony_ci "directory=/tmp", "mode=foo", "server=bar"] 1797db96d56Sopenharmony_ci audio_basic_entry = { 1807db96d56Sopenharmony_ci 'edit': 'audiocompose %s', 1817db96d56Sopenharmony_ci 'compose': 'audiocompose %s', 1827db96d56Sopenharmony_ci 'description': '"An audio fragment"', 1837db96d56Sopenharmony_ci 'view': 'showaudio %s', 1847db96d56Sopenharmony_ci 'lineno': 6 1857db96d56Sopenharmony_ci } 1867db96d56Sopenharmony_ci audio_entry = {"view": "/usr/local/bin/showaudio %t", 'lineno': 7} 1877db96d56Sopenharmony_ci video_entry = {'view': 'animate %s', 'lineno': 12} 1887db96d56Sopenharmony_ci message_entry = { 1897db96d56Sopenharmony_ci 'composetyped': 'extcompose %s', 1907db96d56Sopenharmony_ci 'description': '"A reference to data stored in an external location"', 'needsterminal': '', 1917db96d56Sopenharmony_ci 'view': 'showexternal %s %{access-type} %{name} %{site} %{directory} %{mode} %{server}', 1927db96d56Sopenharmony_ci 'lineno': 10, 1937db96d56Sopenharmony_ci } 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci # test case: (findmatch args, findmatch keyword args, expected output) 1967db96d56Sopenharmony_ci # positional args: caps, MIMEtype 1977db96d56Sopenharmony_ci # keyword args: key="view", filename="/dev/null", plist=[] 1987db96d56Sopenharmony_ci # output: (command line, mailcap entry) 1997db96d56Sopenharmony_ci cases = [ 2007db96d56Sopenharmony_ci ([{}, "video/mpeg"], {}, (None, None)), 2017db96d56Sopenharmony_ci ([c, "foo/bar"], {}, (None, None)), 2027db96d56Sopenharmony_ci ([c, "video/mpeg"], {}, ('animate /dev/null', video_entry)), 2037db96d56Sopenharmony_ci ([c, "audio/basic", "edit"], {}, ("audiocompose /dev/null", audio_basic_entry)), 2047db96d56Sopenharmony_ci ([c, "audio/basic", "compose"], {}, ("audiocompose /dev/null", audio_basic_entry)), 2057db96d56Sopenharmony_ci ([c, "audio/basic", "description"], {}, ('"An audio fragment"', audio_basic_entry)), 2067db96d56Sopenharmony_ci ([c, "audio/basic", "foobar"], {}, (None, None)), 2077db96d56Sopenharmony_ci ([c, "video/*"], {"filename": fname}, ("animate %s" % fname, video_entry)), 2087db96d56Sopenharmony_ci ([c, "audio/basic", "compose"], 2097db96d56Sopenharmony_ci {"filename": fname}, 2107db96d56Sopenharmony_ci ("audiocompose %s" % fname, audio_basic_entry)), 2117db96d56Sopenharmony_ci ([c, "audio/basic"], 2127db96d56Sopenharmony_ci {"key": "description", "filename": fname}, 2137db96d56Sopenharmony_ci ('"An audio fragment"', audio_basic_entry)), 2147db96d56Sopenharmony_ci ([c, "audio/*"], 2157db96d56Sopenharmony_ci {"filename": fname}, 2167db96d56Sopenharmony_ci (None, None)), 2177db96d56Sopenharmony_ci ([c, "audio/wav"], 2187db96d56Sopenharmony_ci {"filename": fname}, 2197db96d56Sopenharmony_ci ("/usr/local/bin/showaudio audio/wav", audio_entry)), 2207db96d56Sopenharmony_ci ([c, "message/external-body"], 2217db96d56Sopenharmony_ci {"plist": plist}, 2227db96d56Sopenharmony_ci ("showexternal /dev/null default john python.org /tmp foo bar", message_entry)) 2237db96d56Sopenharmony_ci ] 2247db96d56Sopenharmony_ci self._run_cases(cases) 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci @unittest.skipUnless(os.name == "posix", "Requires 'test' command on system") 2277db96d56Sopenharmony_ci @unittest.skipIf(sys.platform == "vxworks", "'test' command is not supported on VxWorks") 2287db96d56Sopenharmony_ci @unittest.skipUnless( 2297db96d56Sopenharmony_ci test.support.has_subprocess_support, 2307db96d56Sopenharmony_ci "'test' command needs process support." 2317db96d56Sopenharmony_ci ) 2327db96d56Sopenharmony_ci def test_test(self): 2337db96d56Sopenharmony_ci # findmatch() will automatically check any "test" conditions and skip 2347db96d56Sopenharmony_ci # the entry if the check fails. 2357db96d56Sopenharmony_ci caps = {"test/pass": [{"test": "test 1 -eq 1"}], 2367db96d56Sopenharmony_ci "test/fail": [{"test": "test 1 -eq 0"}]} 2377db96d56Sopenharmony_ci # test case: (findmatch args, findmatch keyword args, expected output) 2387db96d56Sopenharmony_ci # positional args: caps, MIMEtype, key ("test") 2397db96d56Sopenharmony_ci # keyword args: N/A 2407db96d56Sopenharmony_ci # output: (command line, mailcap entry) 2417db96d56Sopenharmony_ci cases = [ 2427db96d56Sopenharmony_ci # findmatch will return the mailcap entry for test/pass because it evaluates to true 2437db96d56Sopenharmony_ci ([caps, "test/pass", "test"], {}, ("test 1 -eq 1", {"test": "test 1 -eq 1"})), 2447db96d56Sopenharmony_ci # findmatch will return None because test/fail evaluates to false 2457db96d56Sopenharmony_ci ([caps, "test/fail", "test"], {}, (None, None)) 2467db96d56Sopenharmony_ci ] 2477db96d56Sopenharmony_ci self._run_cases(cases) 2487db96d56Sopenharmony_ci 2497db96d56Sopenharmony_ci def _run_cases(self, cases): 2507db96d56Sopenharmony_ci for c in cases: 2517db96d56Sopenharmony_ci self.assertEqual(mailcap.findmatch(*c[0], **c[1]), c[2]) 2527db96d56Sopenharmony_ci 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ciif __name__ == '__main__': 2557db96d56Sopenharmony_ci unittest.main() 256