fix(settings): Notifications opens on first visit — no second begin on an autobegun session
CI / lint (push) Successful in 2s
CI / integration (push) Failing after 59s
CI / unit (push) Successful in 1m24s
CI / publish (push) Skipped

Reading the settings autobegins the session's transaction, so the
nested db.begin() that saves the first admin's zone as smtp.tz raised
InvalidRequestError and every visit 500'd until a zone was saved. The
integration test signed in without a zone, so that path never ran;
it now has a test of its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-08 15:34:19 -04:00
co-authored by Claude Opus 5.5
parent 22090b02d8
commit 7ae6f85032
2 changed files with 24 additions and 2 deletions
+3 -2
View File
@@ -222,8 +222,9 @@ async def notifications():
settings = await get_all_settings(db)
if not settings["smtp.tz"] and session.get("tz"):
# "Also send to" reads times in the first admin's zone until one is chosen.
async with db.begin():
await set_setting(db, "smtp.tz", session["tz"])
# Reading the settings already began this session's transaction.
await set_setting(db, "smtp.tz", session["tz"])
await db.commit()
settings["smtp.tz"] = session["tz"]
await _reload_app_config()
who = await audience(db)
+21
View File
@@ -198,3 +198,24 @@ def test_an_account_sets_its_own_address_and_switches_and_an_admin_can_too(app):
assert "Who gets email" in page and 'name="notify.alerts.viewer"' in page and "Also send to" in page
asyncio.run(_go())
def test_the_first_admin_to_open_notifications_sets_the_also_send_to_zone(app):
async def _go():
from steward.core.settings import get_setting, set_setting
async def _tz():
async with app.db_sessionmaker() as s:
return await get_setting(s, "smtp.tz")
async with app.db_sessionmaker() as s:
async with s.begin():
await set_setting(s, "smtp.tz", "")
for zone in ("America/Chicago", "Asia/Tokyo"):
admin, _ = await _client(app)
async with admin.session_transaction() as sess:
sess["tz"] = zone
assert (await admin.get("/settings/notifications/")).status_code == 200
assert await _tz() == "America/Chicago" # the second admin's zone changes nothing
asyncio.run(_go())