Améliorations sur le style de l'ag grid, ajout nb marchés uniques #47
This commit is contained in:
+94
-10
@@ -5,7 +5,12 @@ import pytest
|
||||
import src.app # noqa: F401 # instancie l'app → register_page() des pages
|
||||
from src.pages.tableau import get_rows_tableau, reset_view
|
||||
from src.utils import grid as grid_module
|
||||
from src.utils.grid import export_dataframe, fetch_grid_page, grid_column_defs
|
||||
from src.utils.grid import (
|
||||
apply_persisted_layout,
|
||||
export_dataframe,
|
||||
fetch_grid_page,
|
||||
grid_column_defs,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
@@ -52,25 +57,27 @@ def test_column_defs_hidden_flag():
|
||||
|
||||
|
||||
def test_fetch_grid_page_returns_rows_and_count():
|
||||
rows, total = fetch_grid_page(None, None, 0, 20)
|
||||
rows, total, total_unique = fetch_grid_page(None, None, 0, 20)
|
||||
assert isinstance(rows, list)
|
||||
assert isinstance(total, int)
|
||||
assert total >= len(rows)
|
||||
assert total_unique <= total
|
||||
|
||||
if rows:
|
||||
# postprocess_page ajoute une colonne 'marche' avec un lien
|
||||
assert "marche" in rows[0]
|
||||
|
||||
|
||||
def test_fetch_grid_page_filter_reduces_count():
|
||||
_, total_all = fetch_grid_page(None, None, 0, 1)
|
||||
_, total_all, _ = fetch_grid_page(None, None, 0, 1)
|
||||
fm = {"objet": {"filterType": "text", "type": "contains", "filter": "zzzzzznope"}}
|
||||
rows, total_filtered = fetch_grid_page(fm, None, 0, 20)
|
||||
rows, total_filtered, _ = fetch_grid_page(fm, None, 0, 20)
|
||||
assert total_filtered <= total_all
|
||||
assert rows == [] and total_filtered == 0
|
||||
|
||||
|
||||
def test_fetch_grid_page_offset_slicing():
|
||||
rows, _ = fetch_grid_page(None, None, 0, 5)
|
||||
rows, _, _ = fetch_grid_page(None, None, 0, 5)
|
||||
assert len(rows) <= 5
|
||||
|
||||
|
||||
@@ -113,9 +120,9 @@ def test_fetch_grid_page_caches_count_across_scroll_blocks(flask_app, monkeypatc
|
||||
|
||||
fm = {"objet": {"filterType": "text", "type": "contains", "filter": "route"}}
|
||||
with flask_app.app_context():
|
||||
_, total1 = fetch_grid_page(fm, None, 0, 20)
|
||||
_, total2 = fetch_grid_page(fm, None, 20, 40)
|
||||
_, total3 = fetch_grid_page(fm, None, 40, 60)
|
||||
_, total1, _ = fetch_grid_page(fm, None, 0, 20)
|
||||
_, total2, _ = fetch_grid_page(fm, None, 20, 40)
|
||||
_, total3, _ = fetch_grid_page(fm, None, 40, 60)
|
||||
|
||||
assert call_count["n"] == 1
|
||||
assert total1 == total2 == total3
|
||||
@@ -124,6 +131,83 @@ def test_fetch_grid_page_caches_count_across_scroll_blocks(flask_app, monkeypatc
|
||||
def test_reset_view_clears_filter_and_sort():
|
||||
"""Régression : le bouton Réinitialiser ('Supprime tous les filtres et les
|
||||
tris') ne remettait à zéro que filterModel, jamais le tri (#41)."""
|
||||
filter_model, reset_column_state = reset_view(1)
|
||||
column_state = [{"colId": "objet", "sort": "asc", "sortIndex": 0, "width": 200}]
|
||||
filter_model, new_column_state = reset_view(1, column_state)
|
||||
assert filter_model == {}
|
||||
assert reset_column_state is True
|
||||
assert new_column_state == [
|
||||
{"colId": "objet", "sort": None, "sortIndex": None, "width": 200}
|
||||
]
|
||||
|
||||
|
||||
def test_reset_view_preserves_column_width():
|
||||
"""Le bouton Réinitialiser ne doit remettre à zéro que les filtres et les
|
||||
tris, pas la largeur (ni le pinning/ordre) des colonnes."""
|
||||
column_state = [
|
||||
{"colId": "objet", "sort": "asc", "sortIndex": 0, "width": 350, "hide": True},
|
||||
{
|
||||
"colId": "montant",
|
||||
"sort": None,
|
||||
"sortIndex": None,
|
||||
"width": 120,
|
||||
"hide": False,
|
||||
},
|
||||
]
|
||||
_, new_column_state = reset_view(1, column_state)
|
||||
assert [c["width"] for c in new_column_state] == [350, 120]
|
||||
assert [c["hide"] for c in new_column_state] == [True, False]
|
||||
assert all(c["sort"] is None and c["sortIndex"] is None for c in new_column_state)
|
||||
|
||||
|
||||
def test_apply_persisted_layout_restores_width_and_order():
|
||||
"""Régression : la largeur et l'ordre des colonnes choisis par
|
||||
l'utilisateur étaient perdus au rechargement de la page, écrasés par les
|
||||
columnDefs régénérés par apply_hidden_columns à chaque chargement (#47)."""
|
||||
defs = [
|
||||
{"field": "marche", "width": 60},
|
||||
{"field": "objet", "minWidth": 360},
|
||||
{"field": "montant", "width": 150},
|
||||
{"field": "acheteur_nom", "width": 200},
|
||||
]
|
||||
# L'utilisateur a redimensionné "montant" et déplacé "acheteur_nom" avant "objet"
|
||||
column_state = [
|
||||
{"colId": "marche", "width": 60},
|
||||
{"colId": "acheteur_nom", "width": 200},
|
||||
{"colId": "objet", "width": 500},
|
||||
{"colId": "montant", "width": 320},
|
||||
]
|
||||
result = apply_persisted_layout(defs, column_state)
|
||||
assert [d["field"] for d in result] == [
|
||||
"marche",
|
||||
"acheteur_nom",
|
||||
"objet",
|
||||
"montant",
|
||||
]
|
||||
assert next(d for d in result if d["field"] == "montant")["width"] == 320
|
||||
# "objet" n'a pas de clé "width" dans columnDefs (minWidth seulement, cf.
|
||||
# grid_column_defs) : columnState en fournit une, elle doit être reprise.
|
||||
assert next(d for d in result if d["field"] == "objet")["width"] == 500
|
||||
|
||||
|
||||
def test_apply_persisted_layout_places_unknown_columns_last():
|
||||
"""Une colonne absente du columnState persisté (jamais vue par
|
||||
l'utilisateur, ex. ajout au schéma) doit rester à la fin plutôt que de
|
||||
faire planter le tri."""
|
||||
defs = [
|
||||
{"field": "marche", "width": 60},
|
||||
{"field": "objet", "minWidth": 360},
|
||||
{"field": "nouvelle_colonne", "width": 130},
|
||||
]
|
||||
column_state = [
|
||||
{"colId": "objet", "width": 400},
|
||||
{"colId": "marche", "width": 60},
|
||||
]
|
||||
result = apply_persisted_layout(defs, column_state)
|
||||
assert [d["field"] for d in result] == ["objet", "marche", "nouvelle_colonne"]
|
||||
|
||||
|
||||
def test_apply_persisted_layout_noop_without_prior_state():
|
||||
"""Premier chargement (jamais de columnState persisté) : columnDefs
|
||||
inchangés, pas d'erreur sur None/[]."""
|
||||
defs = [{"field": "marche", "width": 60}, {"field": "objet", "minWidth": 360}]
|
||||
assert apply_persisted_layout(defs, None) == defs
|
||||
assert apply_persisted_layout(defs, []) == defs
|
||||
|
||||
Reference in New Issue
Block a user