17db96d56Sopenharmony_ci# Simple test suite for http/cookies.py 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ciimport copy 47db96d56Sopenharmony_ciimport unittest 57db96d56Sopenharmony_ciimport doctest 67db96d56Sopenharmony_cifrom http import cookies 77db96d56Sopenharmony_ciimport pickle 87db96d56Sopenharmony_ci 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_ciclass CookieTests(unittest.TestCase): 117db96d56Sopenharmony_ci 127db96d56Sopenharmony_ci def test_basic(self): 137db96d56Sopenharmony_ci cases = [ 147db96d56Sopenharmony_ci {'data': 'chips=ahoy; vienna=finger', 157db96d56Sopenharmony_ci 'dict': {'chips':'ahoy', 'vienna':'finger'}, 167db96d56Sopenharmony_ci 'repr': "<SimpleCookie: chips='ahoy' vienna='finger'>", 177db96d56Sopenharmony_ci 'output': 'Set-Cookie: chips=ahoy\nSet-Cookie: vienna=finger'}, 187db96d56Sopenharmony_ci 197db96d56Sopenharmony_ci {'data': 'keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"', 207db96d56Sopenharmony_ci 'dict': {'keebler' : 'E=mc2; L="Loves"; fudge=\012;'}, 217db96d56Sopenharmony_ci 'repr': '''<SimpleCookie: keebler='E=mc2; L="Loves"; fudge=\\n;'>''', 227db96d56Sopenharmony_ci 'output': 'Set-Cookie: keebler="E=mc2; L=\\"Loves\\"; fudge=\\012;"'}, 237db96d56Sopenharmony_ci 247db96d56Sopenharmony_ci # Check illegal cookies that have an '=' char in an unquoted value 257db96d56Sopenharmony_ci {'data': 'keebler=E=mc2', 267db96d56Sopenharmony_ci 'dict': {'keebler' : 'E=mc2'}, 277db96d56Sopenharmony_ci 'repr': "<SimpleCookie: keebler='E=mc2'>", 287db96d56Sopenharmony_ci 'output': 'Set-Cookie: keebler=E=mc2'}, 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci # Cookies with ':' character in their name. Though not mentioned in 317db96d56Sopenharmony_ci # RFC, servers / browsers allow it. 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ci {'data': 'key:term=value:term', 347db96d56Sopenharmony_ci 'dict': {'key:term' : 'value:term'}, 357db96d56Sopenharmony_ci 'repr': "<SimpleCookie: key:term='value:term'>", 367db96d56Sopenharmony_ci 'output': 'Set-Cookie: key:term=value:term'}, 377db96d56Sopenharmony_ci 387db96d56Sopenharmony_ci # issue22931 - Adding '[' and ']' as valid characters in cookie 397db96d56Sopenharmony_ci # values as defined in RFC 6265 407db96d56Sopenharmony_ci { 417db96d56Sopenharmony_ci 'data': 'a=b; c=[; d=r; f=h', 427db96d56Sopenharmony_ci 'dict': {'a':'b', 'c':'[', 'd':'r', 'f':'h'}, 437db96d56Sopenharmony_ci 'repr': "<SimpleCookie: a='b' c='[' d='r' f='h'>", 447db96d56Sopenharmony_ci 'output': '\n'.join(( 457db96d56Sopenharmony_ci 'Set-Cookie: a=b', 467db96d56Sopenharmony_ci 'Set-Cookie: c=[', 477db96d56Sopenharmony_ci 'Set-Cookie: d=r', 487db96d56Sopenharmony_ci 'Set-Cookie: f=h' 497db96d56Sopenharmony_ci )) 507db96d56Sopenharmony_ci } 517db96d56Sopenharmony_ci ] 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci for case in cases: 547db96d56Sopenharmony_ci C = cookies.SimpleCookie() 557db96d56Sopenharmony_ci C.load(case['data']) 567db96d56Sopenharmony_ci self.assertEqual(repr(C), case['repr']) 577db96d56Sopenharmony_ci self.assertEqual(C.output(sep='\n'), case['output']) 587db96d56Sopenharmony_ci for k, v in sorted(case['dict'].items()): 597db96d56Sopenharmony_ci self.assertEqual(C[k].value, v) 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci def test_load(self): 627db96d56Sopenharmony_ci C = cookies.SimpleCookie() 637db96d56Sopenharmony_ci C.load('Customer="WILE_E_COYOTE"; Version=1; Path=/acme') 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE') 667db96d56Sopenharmony_ci self.assertEqual(C['Customer']['version'], '1') 677db96d56Sopenharmony_ci self.assertEqual(C['Customer']['path'], '/acme') 687db96d56Sopenharmony_ci 697db96d56Sopenharmony_ci self.assertEqual(C.output(['path']), 707db96d56Sopenharmony_ci 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') 717db96d56Sopenharmony_ci self.assertEqual(C.js_output(), r""" 727db96d56Sopenharmony_ci <script type="text/javascript"> 737db96d56Sopenharmony_ci <!-- begin hiding 747db96d56Sopenharmony_ci document.cookie = "Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1"; 757db96d56Sopenharmony_ci // end hiding --> 767db96d56Sopenharmony_ci </script> 777db96d56Sopenharmony_ci """) 787db96d56Sopenharmony_ci self.assertEqual(C.js_output(['path']), r""" 797db96d56Sopenharmony_ci <script type="text/javascript"> 807db96d56Sopenharmony_ci <!-- begin hiding 817db96d56Sopenharmony_ci document.cookie = "Customer=\"WILE_E_COYOTE\"; Path=/acme"; 827db96d56Sopenharmony_ci // end hiding --> 837db96d56Sopenharmony_ci </script> 847db96d56Sopenharmony_ci """) 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci def test_extended_encode(self): 877db96d56Sopenharmony_ci # Issue 9824: some browsers don't follow the standard; we now 887db96d56Sopenharmony_ci # encode , and ; to keep them from tripping up. 897db96d56Sopenharmony_ci C = cookies.SimpleCookie() 907db96d56Sopenharmony_ci C['val'] = "some,funky;stuff" 917db96d56Sopenharmony_ci self.assertEqual(C.output(['val']), 927db96d56Sopenharmony_ci 'Set-Cookie: val="some\\054funky\\073stuff"') 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci def test_special_attrs(self): 957db96d56Sopenharmony_ci # 'expires' 967db96d56Sopenharmony_ci C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') 977db96d56Sopenharmony_ci C['Customer']['expires'] = 0 987db96d56Sopenharmony_ci # can't test exact output, it always depends on current date/time 997db96d56Sopenharmony_ci self.assertTrue(C.output().endswith('GMT')) 1007db96d56Sopenharmony_ci 1017db96d56Sopenharmony_ci # loading 'expires' 1027db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1037db96d56Sopenharmony_ci C.load('Customer="W"; expires=Wed, 01 Jan 2010 00:00:00 GMT') 1047db96d56Sopenharmony_ci self.assertEqual(C['Customer']['expires'], 1057db96d56Sopenharmony_ci 'Wed, 01 Jan 2010 00:00:00 GMT') 1067db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1077db96d56Sopenharmony_ci C.load('Customer="W"; expires=Wed, 01 Jan 98 00:00:00 GMT') 1087db96d56Sopenharmony_ci self.assertEqual(C['Customer']['expires'], 1097db96d56Sopenharmony_ci 'Wed, 01 Jan 98 00:00:00 GMT') 1107db96d56Sopenharmony_ci 1117db96d56Sopenharmony_ci # 'max-age' 1127db96d56Sopenharmony_ci C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') 1137db96d56Sopenharmony_ci C['Customer']['max-age'] = 10 1147db96d56Sopenharmony_ci self.assertEqual(C.output(), 1157db96d56Sopenharmony_ci 'Set-Cookie: Customer="WILE_E_COYOTE"; Max-Age=10') 1167db96d56Sopenharmony_ci 1177db96d56Sopenharmony_ci def test_set_secure_httponly_attrs(self): 1187db96d56Sopenharmony_ci C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') 1197db96d56Sopenharmony_ci C['Customer']['secure'] = True 1207db96d56Sopenharmony_ci C['Customer']['httponly'] = True 1217db96d56Sopenharmony_ci self.assertEqual(C.output(), 1227db96d56Sopenharmony_ci 'Set-Cookie: Customer="WILE_E_COYOTE"; HttpOnly; Secure') 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_ci def test_samesite_attrs(self): 1257db96d56Sopenharmony_ci samesite_values = ['Strict', 'Lax', 'strict', 'lax'] 1267db96d56Sopenharmony_ci for val in samesite_values: 1277db96d56Sopenharmony_ci with self.subTest(val=val): 1287db96d56Sopenharmony_ci C = cookies.SimpleCookie('Customer="WILE_E_COYOTE"') 1297db96d56Sopenharmony_ci C['Customer']['samesite'] = val 1307db96d56Sopenharmony_ci self.assertEqual(C.output(), 1317db96d56Sopenharmony_ci 'Set-Cookie: Customer="WILE_E_COYOTE"; SameSite=%s' % val) 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1347db96d56Sopenharmony_ci C.load('Customer="WILL_E_COYOTE"; SameSite=%s' % val) 1357db96d56Sopenharmony_ci self.assertEqual(C['Customer']['samesite'], val) 1367db96d56Sopenharmony_ci 1377db96d56Sopenharmony_ci def test_secure_httponly_false_if_not_present(self): 1387db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1397db96d56Sopenharmony_ci C.load('eggs=scrambled; Path=/bacon') 1407db96d56Sopenharmony_ci self.assertFalse(C['eggs']['httponly']) 1417db96d56Sopenharmony_ci self.assertFalse(C['eggs']['secure']) 1427db96d56Sopenharmony_ci 1437db96d56Sopenharmony_ci def test_secure_httponly_true_if_present(self): 1447db96d56Sopenharmony_ci # Issue 16611 1457db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1467db96d56Sopenharmony_ci C.load('eggs=scrambled; httponly; secure; Path=/bacon') 1477db96d56Sopenharmony_ci self.assertTrue(C['eggs']['httponly']) 1487db96d56Sopenharmony_ci self.assertTrue(C['eggs']['secure']) 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci def test_secure_httponly_true_if_have_value(self): 1517db96d56Sopenharmony_ci # This isn't really valid, but demonstrates what the current code 1527db96d56Sopenharmony_ci # is expected to do in this case. 1537db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1547db96d56Sopenharmony_ci C.load('eggs=scrambled; httponly=foo; secure=bar; Path=/bacon') 1557db96d56Sopenharmony_ci self.assertTrue(C['eggs']['httponly']) 1567db96d56Sopenharmony_ci self.assertTrue(C['eggs']['secure']) 1577db96d56Sopenharmony_ci # Here is what it actually does; don't depend on this behavior. These 1587db96d56Sopenharmony_ci # checks are testing backward compatibility for issue 16611. 1597db96d56Sopenharmony_ci self.assertEqual(C['eggs']['httponly'], 'foo') 1607db96d56Sopenharmony_ci self.assertEqual(C['eggs']['secure'], 'bar') 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci def test_extra_spaces(self): 1637db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1647db96d56Sopenharmony_ci C.load('eggs = scrambled ; secure ; path = bar ; foo=foo ') 1657db96d56Sopenharmony_ci self.assertEqual(C.output(), 1667db96d56Sopenharmony_ci 'Set-Cookie: eggs=scrambled; Path=bar; Secure\r\nSet-Cookie: foo=foo') 1677db96d56Sopenharmony_ci 1687db96d56Sopenharmony_ci def test_quoted_meta(self): 1697db96d56Sopenharmony_ci # Try cookie with quoted meta-data 1707db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1717db96d56Sopenharmony_ci C.load('Customer="WILE_E_COYOTE"; Version="1"; Path="/acme"') 1727db96d56Sopenharmony_ci self.assertEqual(C['Customer'].value, 'WILE_E_COYOTE') 1737db96d56Sopenharmony_ci self.assertEqual(C['Customer']['version'], '1') 1747db96d56Sopenharmony_ci self.assertEqual(C['Customer']['path'], '/acme') 1757db96d56Sopenharmony_ci 1767db96d56Sopenharmony_ci self.assertEqual(C.output(['path']), 1777db96d56Sopenharmony_ci 'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme') 1787db96d56Sopenharmony_ci self.assertEqual(C.js_output(), r""" 1797db96d56Sopenharmony_ci <script type="text/javascript"> 1807db96d56Sopenharmony_ci <!-- begin hiding 1817db96d56Sopenharmony_ci document.cookie = "Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1"; 1827db96d56Sopenharmony_ci // end hiding --> 1837db96d56Sopenharmony_ci </script> 1847db96d56Sopenharmony_ci """) 1857db96d56Sopenharmony_ci self.assertEqual(C.js_output(['path']), r""" 1867db96d56Sopenharmony_ci <script type="text/javascript"> 1877db96d56Sopenharmony_ci <!-- begin hiding 1887db96d56Sopenharmony_ci document.cookie = "Customer=\"WILE_E_COYOTE\"; Path=/acme"; 1897db96d56Sopenharmony_ci // end hiding --> 1907db96d56Sopenharmony_ci </script> 1917db96d56Sopenharmony_ci """) 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_ci def test_invalid_cookies(self): 1947db96d56Sopenharmony_ci # Accepting these could be a security issue 1957db96d56Sopenharmony_ci C = cookies.SimpleCookie() 1967db96d56Sopenharmony_ci for s in (']foo=x', '[foo=x', 'blah]foo=x', 'blah[foo=x', 1977db96d56Sopenharmony_ci 'Set-Cookie: foo=bar', 'Set-Cookie: foo', 1987db96d56Sopenharmony_ci 'foo=bar; baz', 'baz; foo=bar', 1997db96d56Sopenharmony_ci 'secure;foo=bar', 'Version=1;foo=bar'): 2007db96d56Sopenharmony_ci C.load(s) 2017db96d56Sopenharmony_ci self.assertEqual(dict(C), {}) 2027db96d56Sopenharmony_ci self.assertEqual(C.output(), '') 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci def test_pickle(self): 2057db96d56Sopenharmony_ci rawdata = 'Customer="WILE_E_COYOTE"; Path=/acme; Version=1' 2067db96d56Sopenharmony_ci expected_output = 'Set-Cookie: %s' % rawdata 2077db96d56Sopenharmony_ci 2087db96d56Sopenharmony_ci C = cookies.SimpleCookie() 2097db96d56Sopenharmony_ci C.load(rawdata) 2107db96d56Sopenharmony_ci self.assertEqual(C.output(), expected_output) 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 2137db96d56Sopenharmony_ci with self.subTest(proto=proto): 2147db96d56Sopenharmony_ci C1 = pickle.loads(pickle.dumps(C, protocol=proto)) 2157db96d56Sopenharmony_ci self.assertEqual(C1.output(), expected_output) 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_ci def test_illegal_chars(self): 2187db96d56Sopenharmony_ci rawdata = "a=b; c,d=e" 2197db96d56Sopenharmony_ci C = cookies.SimpleCookie() 2207db96d56Sopenharmony_ci with self.assertRaises(cookies.CookieError): 2217db96d56Sopenharmony_ci C.load(rawdata) 2227db96d56Sopenharmony_ci 2237db96d56Sopenharmony_ci def test_comment_quoting(self): 2247db96d56Sopenharmony_ci c = cookies.SimpleCookie() 2257db96d56Sopenharmony_ci c['foo'] = '\N{COPYRIGHT SIGN}' 2267db96d56Sopenharmony_ci self.assertEqual(str(c['foo']), 'Set-Cookie: foo="\\251"') 2277db96d56Sopenharmony_ci c['foo']['comment'] = 'comment \N{COPYRIGHT SIGN}' 2287db96d56Sopenharmony_ci self.assertEqual( 2297db96d56Sopenharmony_ci str(c['foo']), 2307db96d56Sopenharmony_ci 'Set-Cookie: foo="\\251"; Comment="comment \\251"' 2317db96d56Sopenharmony_ci ) 2327db96d56Sopenharmony_ci 2337db96d56Sopenharmony_ci 2347db96d56Sopenharmony_ciclass MorselTests(unittest.TestCase): 2357db96d56Sopenharmony_ci """Tests for the Morsel object.""" 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci def test_defaults(self): 2387db96d56Sopenharmony_ci morsel = cookies.Morsel() 2397db96d56Sopenharmony_ci self.assertIsNone(morsel.key) 2407db96d56Sopenharmony_ci self.assertIsNone(morsel.value) 2417db96d56Sopenharmony_ci self.assertIsNone(morsel.coded_value) 2427db96d56Sopenharmony_ci self.assertEqual(morsel.keys(), cookies.Morsel._reserved.keys()) 2437db96d56Sopenharmony_ci for key, val in morsel.items(): 2447db96d56Sopenharmony_ci self.assertEqual(val, '', key) 2457db96d56Sopenharmony_ci 2467db96d56Sopenharmony_ci def test_reserved_keys(self): 2477db96d56Sopenharmony_ci M = cookies.Morsel() 2487db96d56Sopenharmony_ci # tests valid and invalid reserved keys for Morsels 2497db96d56Sopenharmony_ci for i in M._reserved: 2507db96d56Sopenharmony_ci # Test that all valid keys are reported as reserved and set them 2517db96d56Sopenharmony_ci self.assertTrue(M.isReservedKey(i)) 2527db96d56Sopenharmony_ci M[i] = '%s_value' % i 2537db96d56Sopenharmony_ci for i in M._reserved: 2547db96d56Sopenharmony_ci # Test that valid key values come out fine 2557db96d56Sopenharmony_ci self.assertEqual(M[i], '%s_value' % i) 2567db96d56Sopenharmony_ci for i in "the holy hand grenade".split(): 2577db96d56Sopenharmony_ci # Test that invalid keys raise CookieError 2587db96d56Sopenharmony_ci self.assertRaises(cookies.CookieError, 2597db96d56Sopenharmony_ci M.__setitem__, i, '%s_value' % i) 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci def test_setter(self): 2627db96d56Sopenharmony_ci M = cookies.Morsel() 2637db96d56Sopenharmony_ci # tests the .set method to set keys and their values 2647db96d56Sopenharmony_ci for i in M._reserved: 2657db96d56Sopenharmony_ci # Makes sure that all reserved keys can't be set this way 2667db96d56Sopenharmony_ci self.assertRaises(cookies.CookieError, 2677db96d56Sopenharmony_ci M.set, i, '%s_value' % i, '%s_value' % i) 2687db96d56Sopenharmony_ci for i in "thou cast _the- !holy! ^hand| +*grenade~".split(): 2697db96d56Sopenharmony_ci # Try typical use case. Setting decent values. 2707db96d56Sopenharmony_ci # Check output and js_output. 2717db96d56Sopenharmony_ci M['path'] = '/foo' # Try a reserved key as well 2727db96d56Sopenharmony_ci M.set(i, "%s_val" % i, "%s_coded_val" % i) 2737db96d56Sopenharmony_ci self.assertEqual(M.key, i) 2747db96d56Sopenharmony_ci self.assertEqual(M.value, "%s_val" % i) 2757db96d56Sopenharmony_ci self.assertEqual(M.coded_value, "%s_coded_val" % i) 2767db96d56Sopenharmony_ci self.assertEqual( 2777db96d56Sopenharmony_ci M.output(), 2787db96d56Sopenharmony_ci "Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i)) 2797db96d56Sopenharmony_ci expected_js_output = """ 2807db96d56Sopenharmony_ci <script type="text/javascript"> 2817db96d56Sopenharmony_ci <!-- begin hiding 2827db96d56Sopenharmony_ci document.cookie = "%s=%s; Path=/foo"; 2837db96d56Sopenharmony_ci // end hiding --> 2847db96d56Sopenharmony_ci </script> 2857db96d56Sopenharmony_ci """ % (i, "%s_coded_val" % i) 2867db96d56Sopenharmony_ci self.assertEqual(M.js_output(), expected_js_output) 2877db96d56Sopenharmony_ci for i in ["foo bar", "foo@bar"]: 2887db96d56Sopenharmony_ci # Try some illegal characters 2897db96d56Sopenharmony_ci self.assertRaises(cookies.CookieError, 2907db96d56Sopenharmony_ci M.set, i, '%s_value' % i, '%s_value' % i) 2917db96d56Sopenharmony_ci 2927db96d56Sopenharmony_ci def test_set_properties(self): 2937db96d56Sopenharmony_ci morsel = cookies.Morsel() 2947db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 2957db96d56Sopenharmony_ci morsel.key = '' 2967db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 2977db96d56Sopenharmony_ci morsel.value = '' 2987db96d56Sopenharmony_ci with self.assertRaises(AttributeError): 2997db96d56Sopenharmony_ci morsel.coded_value = '' 3007db96d56Sopenharmony_ci 3017db96d56Sopenharmony_ci def test_eq(self): 3027db96d56Sopenharmony_ci base_case = ('key', 'value', '"value"') 3037db96d56Sopenharmony_ci attribs = { 3047db96d56Sopenharmony_ci 'path': '/', 3057db96d56Sopenharmony_ci 'comment': 'foo', 3067db96d56Sopenharmony_ci 'domain': 'example.com', 3077db96d56Sopenharmony_ci 'version': 2, 3087db96d56Sopenharmony_ci } 3097db96d56Sopenharmony_ci morsel_a = cookies.Morsel() 3107db96d56Sopenharmony_ci morsel_a.update(attribs) 3117db96d56Sopenharmony_ci morsel_a.set(*base_case) 3127db96d56Sopenharmony_ci morsel_b = cookies.Morsel() 3137db96d56Sopenharmony_ci morsel_b.update(attribs) 3147db96d56Sopenharmony_ci morsel_b.set(*base_case) 3157db96d56Sopenharmony_ci self.assertTrue(morsel_a == morsel_b) 3167db96d56Sopenharmony_ci self.assertFalse(morsel_a != morsel_b) 3177db96d56Sopenharmony_ci cases = ( 3187db96d56Sopenharmony_ci ('key', 'value', 'mismatch'), 3197db96d56Sopenharmony_ci ('key', 'mismatch', '"value"'), 3207db96d56Sopenharmony_ci ('mismatch', 'value', '"value"'), 3217db96d56Sopenharmony_ci ) 3227db96d56Sopenharmony_ci for case_b in cases: 3237db96d56Sopenharmony_ci with self.subTest(case_b): 3247db96d56Sopenharmony_ci morsel_b = cookies.Morsel() 3257db96d56Sopenharmony_ci morsel_b.update(attribs) 3267db96d56Sopenharmony_ci morsel_b.set(*case_b) 3277db96d56Sopenharmony_ci self.assertFalse(morsel_a == morsel_b) 3287db96d56Sopenharmony_ci self.assertTrue(morsel_a != morsel_b) 3297db96d56Sopenharmony_ci 3307db96d56Sopenharmony_ci morsel_b = cookies.Morsel() 3317db96d56Sopenharmony_ci morsel_b.update(attribs) 3327db96d56Sopenharmony_ci morsel_b.set(*base_case) 3337db96d56Sopenharmony_ci morsel_b['comment'] = 'bar' 3347db96d56Sopenharmony_ci self.assertFalse(morsel_a == morsel_b) 3357db96d56Sopenharmony_ci self.assertTrue(morsel_a != morsel_b) 3367db96d56Sopenharmony_ci 3377db96d56Sopenharmony_ci # test mismatched types 3387db96d56Sopenharmony_ci self.assertFalse(cookies.Morsel() == 1) 3397db96d56Sopenharmony_ci self.assertTrue(cookies.Morsel() != 1) 3407db96d56Sopenharmony_ci self.assertFalse(cookies.Morsel() == '') 3417db96d56Sopenharmony_ci self.assertTrue(cookies.Morsel() != '') 3427db96d56Sopenharmony_ci items = list(cookies.Morsel().items()) 3437db96d56Sopenharmony_ci self.assertFalse(cookies.Morsel() == items) 3447db96d56Sopenharmony_ci self.assertTrue(cookies.Morsel() != items) 3457db96d56Sopenharmony_ci 3467db96d56Sopenharmony_ci # morsel/dict 3477db96d56Sopenharmony_ci morsel = cookies.Morsel() 3487db96d56Sopenharmony_ci morsel.set(*base_case) 3497db96d56Sopenharmony_ci morsel.update(attribs) 3507db96d56Sopenharmony_ci self.assertTrue(morsel == dict(morsel)) 3517db96d56Sopenharmony_ci self.assertFalse(morsel != dict(morsel)) 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci def test_copy(self): 3547db96d56Sopenharmony_ci morsel_a = cookies.Morsel() 3557db96d56Sopenharmony_ci morsel_a.set('foo', 'bar', 'baz') 3567db96d56Sopenharmony_ci morsel_a.update({ 3577db96d56Sopenharmony_ci 'version': 2, 3587db96d56Sopenharmony_ci 'comment': 'foo', 3597db96d56Sopenharmony_ci }) 3607db96d56Sopenharmony_ci morsel_b = morsel_a.copy() 3617db96d56Sopenharmony_ci self.assertIsInstance(morsel_b, cookies.Morsel) 3627db96d56Sopenharmony_ci self.assertIsNot(morsel_a, morsel_b) 3637db96d56Sopenharmony_ci self.assertEqual(morsel_a, morsel_b) 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ci morsel_b = copy.copy(morsel_a) 3667db96d56Sopenharmony_ci self.assertIsInstance(morsel_b, cookies.Morsel) 3677db96d56Sopenharmony_ci self.assertIsNot(morsel_a, morsel_b) 3687db96d56Sopenharmony_ci self.assertEqual(morsel_a, morsel_b) 3697db96d56Sopenharmony_ci 3707db96d56Sopenharmony_ci def test_setitem(self): 3717db96d56Sopenharmony_ci morsel = cookies.Morsel() 3727db96d56Sopenharmony_ci morsel['expires'] = 0 3737db96d56Sopenharmony_ci self.assertEqual(morsel['expires'], 0) 3747db96d56Sopenharmony_ci morsel['Version'] = 2 3757db96d56Sopenharmony_ci self.assertEqual(morsel['version'], 2) 3767db96d56Sopenharmony_ci morsel['DOMAIN'] = 'example.com' 3777db96d56Sopenharmony_ci self.assertEqual(morsel['domain'], 'example.com') 3787db96d56Sopenharmony_ci 3797db96d56Sopenharmony_ci with self.assertRaises(cookies.CookieError): 3807db96d56Sopenharmony_ci morsel['invalid'] = 'value' 3817db96d56Sopenharmony_ci self.assertNotIn('invalid', morsel) 3827db96d56Sopenharmony_ci 3837db96d56Sopenharmony_ci def test_setdefault(self): 3847db96d56Sopenharmony_ci morsel = cookies.Morsel() 3857db96d56Sopenharmony_ci morsel.update({ 3867db96d56Sopenharmony_ci 'domain': 'example.com', 3877db96d56Sopenharmony_ci 'version': 2, 3887db96d56Sopenharmony_ci }) 3897db96d56Sopenharmony_ci # this shouldn't override the default value 3907db96d56Sopenharmony_ci self.assertEqual(morsel.setdefault('expires', 'value'), '') 3917db96d56Sopenharmony_ci self.assertEqual(morsel['expires'], '') 3927db96d56Sopenharmony_ci self.assertEqual(morsel.setdefault('Version', 1), 2) 3937db96d56Sopenharmony_ci self.assertEqual(morsel['version'], 2) 3947db96d56Sopenharmony_ci self.assertEqual(morsel.setdefault('DOMAIN', 'value'), 'example.com') 3957db96d56Sopenharmony_ci self.assertEqual(morsel['domain'], 'example.com') 3967db96d56Sopenharmony_ci 3977db96d56Sopenharmony_ci with self.assertRaises(cookies.CookieError): 3987db96d56Sopenharmony_ci morsel.setdefault('invalid', 'value') 3997db96d56Sopenharmony_ci self.assertNotIn('invalid', morsel) 4007db96d56Sopenharmony_ci 4017db96d56Sopenharmony_ci def test_update(self): 4027db96d56Sopenharmony_ci attribs = {'expires': 1, 'Version': 2, 'DOMAIN': 'example.com'} 4037db96d56Sopenharmony_ci # test dict update 4047db96d56Sopenharmony_ci morsel = cookies.Morsel() 4057db96d56Sopenharmony_ci morsel.update(attribs) 4067db96d56Sopenharmony_ci self.assertEqual(morsel['expires'], 1) 4077db96d56Sopenharmony_ci self.assertEqual(morsel['version'], 2) 4087db96d56Sopenharmony_ci self.assertEqual(morsel['domain'], 'example.com') 4097db96d56Sopenharmony_ci # test iterable update 4107db96d56Sopenharmony_ci morsel = cookies.Morsel() 4117db96d56Sopenharmony_ci morsel.update(list(attribs.items())) 4127db96d56Sopenharmony_ci self.assertEqual(morsel['expires'], 1) 4137db96d56Sopenharmony_ci self.assertEqual(morsel['version'], 2) 4147db96d56Sopenharmony_ci self.assertEqual(morsel['domain'], 'example.com') 4157db96d56Sopenharmony_ci # test iterator update 4167db96d56Sopenharmony_ci morsel = cookies.Morsel() 4177db96d56Sopenharmony_ci morsel.update((k, v) for k, v in attribs.items()) 4187db96d56Sopenharmony_ci self.assertEqual(morsel['expires'], 1) 4197db96d56Sopenharmony_ci self.assertEqual(morsel['version'], 2) 4207db96d56Sopenharmony_ci self.assertEqual(morsel['domain'], 'example.com') 4217db96d56Sopenharmony_ci 4227db96d56Sopenharmony_ci with self.assertRaises(cookies.CookieError): 4237db96d56Sopenharmony_ci morsel.update({'invalid': 'value'}) 4247db96d56Sopenharmony_ci self.assertNotIn('invalid', morsel) 4257db96d56Sopenharmony_ci self.assertRaises(TypeError, morsel.update) 4267db96d56Sopenharmony_ci self.assertRaises(TypeError, morsel.update, 0) 4277db96d56Sopenharmony_ci 4287db96d56Sopenharmony_ci def test_pickle(self): 4297db96d56Sopenharmony_ci morsel_a = cookies.Morsel() 4307db96d56Sopenharmony_ci morsel_a.set('foo', 'bar', 'baz') 4317db96d56Sopenharmony_ci morsel_a.update({ 4327db96d56Sopenharmony_ci 'version': 2, 4337db96d56Sopenharmony_ci 'comment': 'foo', 4347db96d56Sopenharmony_ci }) 4357db96d56Sopenharmony_ci for proto in range(pickle.HIGHEST_PROTOCOL + 1): 4367db96d56Sopenharmony_ci with self.subTest(proto=proto): 4377db96d56Sopenharmony_ci morsel_b = pickle.loads(pickle.dumps(morsel_a, proto)) 4387db96d56Sopenharmony_ci self.assertIsInstance(morsel_b, cookies.Morsel) 4397db96d56Sopenharmony_ci self.assertEqual(morsel_b, morsel_a) 4407db96d56Sopenharmony_ci self.assertEqual(str(morsel_b), str(morsel_a)) 4417db96d56Sopenharmony_ci 4427db96d56Sopenharmony_ci def test_repr(self): 4437db96d56Sopenharmony_ci morsel = cookies.Morsel() 4447db96d56Sopenharmony_ci self.assertEqual(repr(morsel), '<Morsel: None=None>') 4457db96d56Sopenharmony_ci self.assertEqual(str(morsel), 'Set-Cookie: None=None') 4467db96d56Sopenharmony_ci morsel.set('key', 'val', 'coded_val') 4477db96d56Sopenharmony_ci self.assertEqual(repr(morsel), '<Morsel: key=coded_val>') 4487db96d56Sopenharmony_ci self.assertEqual(str(morsel), 'Set-Cookie: key=coded_val') 4497db96d56Sopenharmony_ci morsel.update({ 4507db96d56Sopenharmony_ci 'path': '/', 4517db96d56Sopenharmony_ci 'comment': 'foo', 4527db96d56Sopenharmony_ci 'domain': 'example.com', 4537db96d56Sopenharmony_ci 'max-age': 0, 4547db96d56Sopenharmony_ci 'secure': 0, 4557db96d56Sopenharmony_ci 'version': 1, 4567db96d56Sopenharmony_ci }) 4577db96d56Sopenharmony_ci self.assertEqual(repr(morsel), 4587db96d56Sopenharmony_ci '<Morsel: key=coded_val; Comment=foo; Domain=example.com; ' 4597db96d56Sopenharmony_ci 'Max-Age=0; Path=/; Version=1>') 4607db96d56Sopenharmony_ci self.assertEqual(str(morsel), 4617db96d56Sopenharmony_ci 'Set-Cookie: key=coded_val; Comment=foo; Domain=example.com; ' 4627db96d56Sopenharmony_ci 'Max-Age=0; Path=/; Version=1') 4637db96d56Sopenharmony_ci morsel['secure'] = True 4647db96d56Sopenharmony_ci morsel['httponly'] = 1 4657db96d56Sopenharmony_ci self.assertEqual(repr(morsel), 4667db96d56Sopenharmony_ci '<Morsel: key=coded_val; Comment=foo; Domain=example.com; ' 4677db96d56Sopenharmony_ci 'HttpOnly; Max-Age=0; Path=/; Secure; Version=1>') 4687db96d56Sopenharmony_ci self.assertEqual(str(morsel), 4697db96d56Sopenharmony_ci 'Set-Cookie: key=coded_val; Comment=foo; Domain=example.com; ' 4707db96d56Sopenharmony_ci 'HttpOnly; Max-Age=0; Path=/; Secure; Version=1') 4717db96d56Sopenharmony_ci 4727db96d56Sopenharmony_ci morsel = cookies.Morsel() 4737db96d56Sopenharmony_ci morsel.set('key', 'val', 'coded_val') 4747db96d56Sopenharmony_ci morsel['expires'] = 0 4757db96d56Sopenharmony_ci self.assertRegex(repr(morsel), 4767db96d56Sopenharmony_ci r'<Morsel: key=coded_val; ' 4777db96d56Sopenharmony_ci r'expires=\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+>') 4787db96d56Sopenharmony_ci self.assertRegex(str(morsel), 4797db96d56Sopenharmony_ci r'Set-Cookie: key=coded_val; ' 4807db96d56Sopenharmony_ci r'expires=\w+, \d+ \w+ \d+ \d+:\d+:\d+ \w+') 4817db96d56Sopenharmony_ci 4827db96d56Sopenharmony_ci 4837db96d56Sopenharmony_cidef load_tests(loader, tests, pattern): 4847db96d56Sopenharmony_ci tests.addTest(doctest.DocTestSuite(cookies)) 4857db96d56Sopenharmony_ci return tests 4867db96d56Sopenharmony_ci 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_ciif __name__ == '__main__': 4897db96d56Sopenharmony_ci unittest.main() 490