cookie will expire when a near expiration time is provided response httpresponse there s a timing weakness in this test the expected result for maxage requires that there be a very slight difference between the evaluated expiration time and the time evaluated in setcookie 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 nowtztimezone utc replacetzinfonone timedelta seconds10 time sleep0 001 response setcookiedatetime expiresexpires datetimecookie response cookiesdatetime self assertequaldatetimecookiemaxage 10 def testawareexpirationself setting a cookie after deletion clears the expiry date response httpresponse response setcookiec oldvalue self assertequalresponse cookiescexpires response deletecookiec self assertequal response cookiescexpires thu 01 jan 1970 00 00 00 gmt response setcookiec newvalue self assertequalresponse cookiescexpires def testfarexpirationself assertin accounts for slight time dependency 23450 cookie will expire if maxage is provided response httpresponse setcookietime time time with freezetimesetcookietime response setcookiemaxage maxage10 maxagecookie response cookiesmaxage self assertequalmaxagecookiemaxage 10 self assertequalmaxagecookieexpires httpdatesetcookietime 10 def testmaxageintself response httpresponse response setcookiemaxage maxage10 6 self assertequalresponse cookiesmaxagemaxage 10 def testmaxagetimedeltaself response httpresponse response setcookiemaxage maxagetimedeltahours1 self assertequalresponse cookiesmaxagemaxage 3600 def testmaxagewithexpiresself response httpresponse msg expires and maxage can t be used together with self assertraisesmessagevalueerror msg response setcookie maxage expiresdatetime2000 1 1 maxagetimedeltahours1 def testhttponlycookieself response httpresponse response setcookieexample httponlytrue examplecookie response cookiesexample self assertin s cookies morsel reservedhttponly strexamplecookie self assertisexamplecookiehttponly true def testunicodecookieself deletecookie sets the secure flag if the cookie name starts with host or secure without that browsers ignore cookies with those prefixes deletecookie sets the secure flag if samesite none cookie will expire when a near expiration time is provided 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 set_cookie accepts an aware datetime as expiration time setting a cookie after deletion clears the expiry date cookie will expire when a distant expiration time is provided assertin accounts for slight time dependency 23450 cookie will expire if max_age is provided httpresponse set_cookie works with unicode data delete_cookie sets the secure flag if the cookie name starts with __host or __secure without that browsers ignore cookies with those prefixes delete_cookie sets the secure flag if samesite none
import time
from datetime import date, datetime, timedelta, timezone
from email.utils import format_datetime as format_datetime_rfc5322
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


class SetCookieTests(SimpleTestCase):
    def test_near_expiration(self):
        
        response = HttpResponse()
        
        
        
        
        
        expires = datetime.now(tz=timezone.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):
        
        response = HttpResponse()
        expires = datetime.now(tz=timezone.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):
        
        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):
        
        response = HttpResponse()
        future_datetime = datetime(
            date.today().year + 2, 1, 1, 4, 5, 6, tzinfo=timezone.utc
        )
        response.set_cookie("datetime", expires=future_datetime)
        datetime_cookie = response.cookies["datetime"]
        self.assertIn(
            datetime_cookie["expires"],
            
            (
                format_datetime_rfc5322(future_datetime, usegmt=True),
                format_datetime_rfc5322(future_datetime.replace(second=7), usegmt=True),
            ),
        )

    def test_max_age_expiration(self):
        
        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_max_age_with_expires(self):
        response = HttpResponse()
        msg = "'expires' and 'max_age' can't be used together."
        with self.assertRaisesMessage(ValueError, msg):
            response.set_cookie(
                "max_age", expires=datetime(2000, 1, 1), max_age=timedelta(hours=1)
            )

    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):
        
        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):
        
        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):
        
        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")