From 46a301652bdee1ca231df42a1217f853769d858a Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 8 Oct 2026 17:28:19 -0400 Subject: [PATCH] test(sessions): fake users carry sessions_since; a reset ends older sessions (#5427) Co-Authored-By: Claude Opus 5.5 --- tests/test_sessions.py | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/tests/test_sessions.py b/tests/test_sessions.py index db8d4ff..a3e7b8f 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -101,10 +101,13 @@ class _DB: @pytest.mark.parametrize("user,login_age_s,keeps,role", [ # demoted, and a time zone set on the Account page since (milestone 490) - (SimpleNamespace(is_active=True, role=UserRole.viewer, time_zone="Europe/London"), 60, True, "viewer"), - (SimpleNamespace(is_active=False, role=UserRole.admin, time_zone=None), 60, False, None), # deactivated + (SimpleNamespace(is_active=True, role=UserRole.viewer, time_zone="Europe/London", sessions_since=None), + 60, True, "viewer"), + (SimpleNamespace(is_active=False, role=UserRole.admin, time_zone=None, sessions_since=None), + 60, False, None), # deactivated (None, 60, False, None), # deleted - (SimpleNamespace(is_active=True, role=UserRole.admin, time_zone=None), 9 * 3600, False, None), # expired + (SimpleNamespace(is_active=True, role=UserRole.admin, time_zone=None, sessions_since=None), + 9 * 3600, False, None), # expired ]) async def test_session_speaks_for_the_user_as_they_are(app, user, login_age_s, keeps, role): app.db_sessionmaker = lambda: _DB(user) @@ -116,3 +119,19 @@ async def test_session_speaks_for_the_user_as_they_are(app, user, login_age_s, k assert ("user_id" in session) is keeps assert session.get("user_role") == role assert session.get("tz") == (user.time_zone if keeps else None) + + +@pytest.mark.parametrize("reset_ago_s,keeps", [(30, False), (120, True)]) +async def test_a_password_reset_ends_the_sessions_begun_before_it(app, reset_ago_s, keeps): + """#5427: signed in a minute ago; a reset 30 s ago ends the session, one + two minutes ago (before this sign-in) doesn't.""" + from datetime import datetime, timezone + now = time.time() + user = SimpleNamespace(is_active=True, role=UserRole.viewer, time_zone=None, + sessions_since=datetime.fromtimestamp(now - reset_ago_s, timezone.utc)) + app.db_sessionmaker = lambda: _DB(user) + app.config["PERMANENT_SESSION_LIFETIME"] = timedelta(hours=8) + async with app.test_request_context("/"): + session.update(user_id="u", user_role="viewer", username="a", login_at=now - 60) + await refresh_session_user() + assert ("user_id" in session) is keeps