diff --git a/src/admin/tables.py b/src/admin/tables.py index c49221c..d19d2cd 100644 --- a/src/admin/tables.py +++ b/src/admin/tables.py @@ -1,3 +1,4 @@ +import sqlite3 from dataclasses import dataclass from typing import Callable @@ -134,9 +135,19 @@ def set_cell(table: str, pk_value, column: str, value) -> None: raise ValueError(f"Table inconnue : {table}") cfg = TABLES[table] coerced = _coerce_value(table, column, value) - get_conn().execute( - f"UPDATE {table} SET {column} = ? WHERE {cfg.pk} = ?", (coerced, pk_value) - ) + try: + cursor = get_conn().execute( + f"UPDATE {table} SET {column} = ? WHERE {cfg.pk} = ?", (coerced, pk_value) + ) + except sqlite3.IntegrityError as exc: + raise ValueError( + f"Écriture refusée pour {column} (contrainte violée) : {value!r}" + ) from exc + if cursor.rowcount == 0: + raise ValueError( + f"Ligne introuvable (table={table}, {cfg.pk}={pk_value!r}) — " + "probablement supprimée entre-temps." + ) def find_changed_cell( diff --git a/tests/admin/test_tables.py b/tests/admin/test_tables.py index bf55ce7..3ca7382 100644 --- a/tests/admin/test_tables.py +++ b/tests/admin/test_tables.py @@ -68,6 +68,28 @@ def test_set_cell_writes_valid_value(users_db_path): assert rows[0]["siret"] == "12345678900011" +def test_set_cell_raises_valueerror_on_unique_constraint_violation(users_db_path): + from src.auth import db as auth_db + + auth_db.init_schema() + auth_db.create_user("first@ex.fr", "hash") + second_uid = auth_db.create_user("second@ex.fr", "hash") + + with pytest.raises(ValueError): + tables.set_cell("users", second_uid, "email", "first@ex.fr") + + +def test_set_cell_raises_valueerror_when_row_missing(users_db_path): + from src.auth import db as auth_db + + auth_db.init_schema() + uid = auth_db.create_user("a@ex.fr", "hash") + auth_db.delete_user(uid) + + with pytest.raises(ValueError): + tables.set_cell("users", uid, "email", "new@ex.fr") + + def test_set_cell_coerces_numeric_type(users_db_path): from src.auth import db as auth_db from src.subscriptions import db as sub_db