123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- import time
- from datetime import datetime, timedelta
- from http import cookies
- from django.http import HttpResponse
- from django.test import SimpleTestCase
- from django.test.utils import freeze_time
- from django.utils.http import http_date
- from django.utils.timezone import utc
- class SetCookieTests(SimpleTestCase):
- def test_near_expiration(self):
- """Cookie will expire when a near expiration time is provided."""
- response = HttpResponse()
- # There's a timing weakness in this test; The expected result for
- # max-age requires that there be a very slight difference between the
- # evaluated expiration time and the time evaluated in set_cookie(). If
- # this difference doesn't exist, the cookie time will be 1 second
- # larger. The sleep guarantees that there will be a time difference.
- expires = datetime.now(tz=utc).replace(tzinfo=None) + timedelta(seconds=10)
- time.sleep(0.001)
- response.set_cookie("datetime", expires=expires)
- datetime_cookie = response.cookies["datetime"]
- self.assertEqual(datetime_cookie["max-age"], 10)
- def test_aware_expiration(self):
- """set_cookie() accepts an aware datetime as expiration time."""
- response = HttpResponse()
- expires = datetime.now(tz=utc) + timedelta(seconds=10)
- time.sleep(0.001)
- response.set_cookie("datetime", expires=expires)
- datetime_cookie = response.cookies["datetime"]
- self.assertEqual(datetime_cookie["max-age"], 10)
- def test_create_cookie_after_deleting_cookie(self):
- """Setting a cookie after deletion clears the expiry date."""
- response = HttpResponse()
- response.set_cookie("c", "old-value")
- self.assertEqual(response.cookies["c"]["expires"], "")
- response.delete_cookie("c")
- self.assertEqual(
- response.cookies["c"]["expires"], "Thu, 01 Jan 1970 00:00:00 GMT"
- )
- response.set_cookie("c", "new-value")
- self.assertEqual(response.cookies["c"]["expires"], "")
- def test_far_expiration(self):
- """Cookie will expire when a distant expiration time is provided."""
- response = HttpResponse()
- response.set_cookie("datetime", expires=datetime(2038, 1, 1, 4, 5, 6))
- datetime_cookie = response.cookies["datetime"]
- self.assertIn(
- datetime_cookie["expires"],
- # assertIn accounts for slight time dependency (#23450)
- ("Fri, 01 Jan 2038 04:05:06 GMT", "Fri, 01 Jan 2038 04:05:07 GMT"),
- )
- def test_max_age_expiration(self):
- """Cookie will expire if max_age is provided."""
- response = HttpResponse()
- set_cookie_time = time.time()
- with freeze_time(set_cookie_time):
- response.set_cookie("max_age", max_age=10)
- max_age_cookie = response.cookies["max_age"]
- self.assertEqual(max_age_cookie["max-age"], 10)
- self.assertEqual(max_age_cookie["expires"], http_date(set_cookie_time + 10))
- def test_max_age_int(self):
- response = HttpResponse()
- response.set_cookie("max_age", max_age=10.6)
- self.assertEqual(response.cookies["max_age"]["max-age"], 10)
- def test_max_age_timedelta(self):
- response = HttpResponse()
- response.set_cookie("max_age", max_age=timedelta(hours=1))
- self.assertEqual(response.cookies["max_age"]["max-age"], 3600)
- def test_httponly_cookie(self):
- response = HttpResponse()
- response.set_cookie("example", httponly=True)
- example_cookie = response.cookies["example"]
- self.assertIn(
- "; %s" % cookies.Morsel._reserved["httponly"], str(example_cookie)
- )
- self.assertIs(example_cookie["httponly"], True)
- def test_unicode_cookie(self):
- """HttpResponse.set_cookie() works with Unicode data."""
- response = HttpResponse()
- cookie_value = "清風"
- response.set_cookie("test", cookie_value)
- self.assertEqual(response.cookies["test"].value, cookie_value)
- def test_samesite(self):
- response = HttpResponse()
- response.set_cookie("example", samesite="None")
- self.assertEqual(response.cookies["example"]["samesite"], "None")
- response.set_cookie("example", samesite="Lax")
- self.assertEqual(response.cookies["example"]["samesite"], "Lax")
- response.set_cookie("example", samesite="strict")
- self.assertEqual(response.cookies["example"]["samesite"], "strict")
- def test_invalid_samesite(self):
- msg = 'samesite must be "lax", "none", or "strict".'
- with self.assertRaisesMessage(ValueError, msg):
- HttpResponse().set_cookie("example", samesite="invalid")
- class DeleteCookieTests(SimpleTestCase):
- def test_default(self):
- response = HttpResponse()
- response.delete_cookie("c")
- cookie = response.cookies["c"]
- self.assertEqual(cookie["expires"], "Thu, 01 Jan 1970 00:00:00 GMT")
- self.assertEqual(cookie["max-age"], 0)
- self.assertEqual(cookie["path"], "/")
- self.assertEqual(cookie["secure"], "")
- self.assertEqual(cookie["domain"], "")
- self.assertEqual(cookie["samesite"], "")
- def test_delete_cookie_secure_prefix(self):
- """
- delete_cookie() sets the secure flag if the cookie name starts with
- __Host- or __Secure- (without that, browsers ignore cookies with those
- prefixes).
- """
- response = HttpResponse()
- for prefix in ("Secure", "Host"):
- with self.subTest(prefix=prefix):
- cookie_name = "__%s-c" % prefix
- response.delete_cookie(cookie_name)
- self.assertIs(response.cookies[cookie_name]["secure"], True)
- def test_delete_cookie_secure_samesite_none(self):
- # delete_cookie() sets the secure flag if samesite='none'.
- response = HttpResponse()
- response.delete_cookie("c", samesite="none")
- self.assertIs(response.cookies["c"]["secure"], True)
- def test_delete_cookie_samesite(self):
- response = HttpResponse()
- response.delete_cookie("c", samesite="lax")
- self.assertEqual(response.cookies["c"]["samesite"], "lax")
|