"""PUT /api/me/preferences merges the keys it is sent into the stored ones, DB-lane. A client saves its preferences a key at a time, and several at once on the boot that moves this browser's copies to the account. Each merge must start from the row as stored when it runs, not as the request first read it — two merges over the same earlier read keep only the last one's keys. """ from fastapi import Depends, Request from sqlalchemy import update from sqlalchemy.orm import Session from app.auth import current_user from app.db import SessionLocal, get_db from app.models import User _PW = "correct horse battery" def test_a_save_keeps_a_key_another_save_stored_after_this_one_read_the_account( client, db, make_user, override_dep ): user = make_user(email="prefs@example.com", password=_PW) assert ( client.post("/auth/password-login", json={"email": "prefs@example.com", "password": _PW}) ).status_code == 200 def read_then_another_save(request: Request, session: Session = Depends(get_db)) -> User: # The account as this request reads it, then a second save committing in the meantime. caller = current_user(request, session) with SessionLocal() as other: other.execute( update(User) .where(User.id == caller.id) .values(preferences={"seenVersion": "1.2.3"}) ) other.commit() return caller override_dep(current_user, read_then_another_save) r = client.put("/api/me/preferences", json={"startOnHome": False}) assert r.status_code == 200 db.expire_all() assert db.get(User, user.id).preferences == {"seenVersion": "1.2.3", "startOnHome": False}