A refused session keeps its cookie, so the cancel branch, keyed on the cookie's account, sent a signed-out browser to the in-app toast the login page never shows: it now asks whether the session holds. The probe's log line named every refusal 'its account no longer holds'; it now carries the reason. The pruning docstring says again that a renewal may land a request's time after the revoke, and the test pins the day of margin. The test clock clamps in the zone asked for.
75 lines
3.0 KiB
Python
75 lines
3.0 KiB
Python
"""The suite's clock (conftest `_clock_never_goes_back`), DB-lane.
|
|
|
|
The wall clock of the docker VM the suite runs in steps BACK now and then (measured: up to 0.5 s).
|
|
These hold the two places that read it besides the app: the session cookie's signature, and a test
|
|
comparing a stamp the app wrote with "now".
|
|
"""
|
|
|
|
import time
|
|
from datetime import datetime, timezone
|
|
from types import SimpleNamespace
|
|
|
|
import itsdangerous.timed
|
|
|
|
_PW = "correct horse battery"
|
|
|
|
|
|
def test_a_cookie_signed_just_before_the_clock_steps_back_still_signs_in(
|
|
client, make_user, monkeypatch
|
|
):
|
|
# The signature carries whole seconds and itsdangerous refuses one from the future: a step back
|
|
# across a second boundary refused the cookie a sign-in had just set (a 401 at random).
|
|
clock = [int(time.time()) + 0.2]
|
|
monkeypatch.setattr(itsdangerous.timed, "time", SimpleNamespace(time=lambda: clock[0]))
|
|
make_user(email="clock@example.com", password=_PW)
|
|
r = client.post("/auth/password-login", json={"email": "clock@example.com", "password": _PW})
|
|
assert r.status_code == 200
|
|
clock[0] -= 0.5
|
|
assert client.get("/api/me/notifications").status_code == 200
|
|
|
|
|
|
def test_a_test_reads_the_clock_the_app_stamps_with(monkeypatch):
|
|
# A test asserting "the app's stamp is not in the future" compared it with the wall clock, which
|
|
# may have stepped back since the app read its own.
|
|
import conftest
|
|
from app import diagnostics
|
|
|
|
# The app reads 12:00:01, then the wall clock steps back half a second (a time past any real one,
|
|
# so a test reading the wall clock instead is behind the stamp).
|
|
later = datetime(2099, 1, 1, 12, 0, 1, tzinfo=timezone.utc)
|
|
stepped_back = datetime(2099, 1, 1, 12, 0, 0, 500000, tzinfo=timezone.utc)
|
|
readings = iter([later])
|
|
|
|
class Stepping(datetime):
|
|
@classmethod
|
|
def now(cls, tz=None):
|
|
return next(readings, stepped_back)
|
|
|
|
monkeypatch.setattr(conftest._NeverBack, "clock", Stepping)
|
|
monkeypatch.setattr(conftest._NeverBack, "last", None)
|
|
stamped = diagnostics.datetime.now(timezone.utc)
|
|
assert datetime.now(timezone.utc) >= stamped
|
|
|
|
|
|
def test_a_clamped_reading_is_in_the_zone_asked_for(monkeypatch):
|
|
# The Pacific quota day read through a clamp came back in UTC: its date was the next day's.
|
|
from zoneinfo import ZoneInfo
|
|
|
|
import conftest
|
|
|
|
pacific = ZoneInfo("America/Los_Angeles")
|
|
utc_reading = datetime(2099, 1, 2, 3, 0, 0, tzinfo=timezone.utc) # 1 January 19:00 in Pacific
|
|
stepped_back = datetime(2099, 1, 1, 18, 59, 59, tzinfo=pacific) # a second earlier
|
|
|
|
class Stepping(datetime):
|
|
@classmethod
|
|
def now(cls, tz=None):
|
|
return utc_reading if tz is timezone.utc else stepped_back
|
|
|
|
monkeypatch.setattr(conftest._NeverBack, "clock", Stepping)
|
|
monkeypatch.setattr(conftest._NeverBack, "last", None)
|
|
conftest._NeverBack.now(timezone.utc)
|
|
clamped = conftest._NeverBack.now(pacific)
|
|
assert clamped.tzinfo is pacific
|
|
assert clamped.date().isoformat() == "2099-01-01"
|