Corriger la revue finale : onglets non tronqués, fiche de dalle à jour, clics et lien fiables
Onglet Dalle libellé fixe (col·row dans le title), Affichage/Export PDF/ Génération raccourcis pour tenir dans le panneau ; fiche de dalle rechargée après un run sans désélection et dès que /api/status révèle le bouton Régénérer ; double-clic et réponses en retard ignorés sur la sélection ; curseur d'intensité visible hors mode précision ; lien complet sans &I remis à 1× ; applyCompareClip sort tôt hors mode Comparer ; docs/MAPS.md et AGENTS.md à jour (modes Comparer, &I=, « Comment lire »). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -1694,3 +1694,96 @@ def test_ui_panel_restores_tab_and_ignores_collapse_on_phone():
|
||||
assert "PANEL.collapsed && !isPhone()" in render
|
||||
assert "toggle('collapsed', PANEL.collapsed)" not in render
|
||||
assert "toggle('panel-collapsed', PANEL.collapsed)" not in render
|
||||
|
||||
|
||||
def test_ui_tile_tab_label_stays_dalle_col_row_in_title():
|
||||
"""Revue finale (finding 2) : 5 onglets dans 340 px — le libellé de
|
||||
l'onglet Dalle reste toujours « Dalle » (jamais tronqué), col · row va
|
||||
dans le title de l'onglet (survol) et #tileTitle (déjà dans la fiche).
|
||||
Affichage/Export PDF/Génération raccourcis pour tenir, Partager gardé."""
|
||||
from lidar_pipeline.mapui import _MAP_HTML, _MAP_JS
|
||||
assert '<span class="tab-lbl">Vue</span>' in _MAP_HTML
|
||||
assert '<span class="tab-lbl">PDF</span>' in _MAP_HTML
|
||||
assert '<span class="tab-lbl">Générer</span>' in _MAP_HTML
|
||||
assert '<span class="tab-lbl" id="tileTabLbl">Dalle</span>' in _MAP_HTML
|
||||
assert 'data-tab="share"' in _MAP_HTML and '>Partager</span>' in _MAP_HTML
|
||||
# Le title complet (survol) reste explicite malgré le libellé court
|
||||
assert 'title="Affichage (1)"' in _MAP_HTML
|
||||
assert 'title="Export PDF (3)"' in _MAP_HTML
|
||||
assert 'title="Génération (4)"' in _MAP_HTML
|
||||
assert "function tileTabTitle(" in _MAP_JS
|
||||
assert "textContent = tileTabLabel" not in _MAP_JS # plus de libellé dynamique
|
||||
assert "button[data-tab=\"tile\"]').title = tileTabTitle()" in _MAP_JS
|
||||
|
||||
|
||||
def test_ui_tile_card_refetched_after_gen_run():
|
||||
"""Finding 3 : la fiche de dalle sélectionnée avant/pendant un run devient
|
||||
périmée (résolution, date, couches...) — genAfterRun la recharge par
|
||||
api/map/tile sans jamais désélectionner (pas de clearTileSelection)."""
|
||||
from lidar_pipeline.mapui import _MAP_JS
|
||||
fn = _MAP_JS[_MAP_JS.index("function genAfterRun("):_MAP_JS.index("function genUpdateStatus(")]
|
||||
assert "SELECTED_TILE" in fn and "lastTileQuery" in fn
|
||||
assert "api/map/tile?lat=" in fn
|
||||
assert "selectTile(d, lastTileQuery)" in fn
|
||||
assert "clearTileSelection" not in fn
|
||||
|
||||
|
||||
def test_ui_double_click_and_stale_click_response_ignored():
|
||||
"""M1/M2 : un double-clic (zoom Leaflet, deux clics simples dont le
|
||||
second a detail > 1) ne doit pas re-basculer la sélection posée par le
|
||||
premier ; une réponse arrivée après un clic plus récent (jeton de
|
||||
séquence) est ignorée plutôt que d'écraser l'état."""
|
||||
from lidar_pipeline.mapui import _MAP_JS
|
||||
click = _MAP_JS[_MAP_JS.index("map.on('click'"):]
|
||||
body = click[:click.index("});") + 3]
|
||||
assert "e.originalEvent && e.originalEvent.detail > 1" in body
|
||||
assert "let tileClickSeq = 0;" in _MAP_JS
|
||||
assert "const seq = ++tileClickSeq;" in body
|
||||
assert "if (seq !== tileClickSeq) return;" in body
|
||||
|
||||
|
||||
def test_ui_regen_button_appears_when_gen_status_resolves_late():
|
||||
"""M3 : une dalle sélectionnée avant que /api/status ne réponde ne doit
|
||||
pas rester sans bouton Régénérer — la fiche est ré-émise dès que GEN est
|
||||
connu, dans le même bloc qui pose GEN.available/allowed."""
|
||||
from lidar_pipeline.mapui import _MAP_JS
|
||||
boot = _MAP_JS[_MAP_JS.index("fetch('api/map/meta').then(r => r.json()).then(meta => {"):]
|
||||
status_block = boot[:boot.index("}).catch(() => {\n toast('Serveur de tuiles injoignable.'")]
|
||||
assert "GEN.available = !!d.available;" in status_block
|
||||
assert "if (SELECTED_TILE) renderTabTile();" in status_block
|
||||
|
||||
|
||||
def test_ui_intensity_row_visible_outside_precision_block():
|
||||
"""M4 (liaison de spec) : #intensityRow est un frère de #precBlock, pas un
|
||||
enfant — visible dès l'onglet Affichage même sans couche de précision,
|
||||
masqué seulement en mode précision (renderPanel)."""
|
||||
from lidar_pipeline.mapui import _MAP_HTML
|
||||
assert '<div id="precBlock" hidden>' in _MAP_HTML
|
||||
# #intensityRow ouvre juste après la fermeture de #precBlock (frère, pas
|
||||
# enfant) : rien de precBlock (modeSeg/compareCtl/precLegend) ne le suit.
|
||||
after_prec_close = _MAP_HTML[_MAP_HTML.index('<div class="prec-legend" id="precLegend"'):]
|
||||
close_idx = after_prec_close.index("</div>\n </div>")
|
||||
between = after_prec_close[:close_idx]
|
||||
assert 'id="intensityRow"' not in between
|
||||
assert '<div class="row" id="intensityRow">' in after_prec_close[close_idx:close_idx + 200]
|
||||
|
||||
|
||||
def test_ui_full_shared_link_without_intensity_resets_to_one():
|
||||
"""M5 : un lien complet (couche ou mode dans le hash) sans &I signifie
|
||||
1× (viewHash n'écrit &I que si ≠ 1), jamais l'intensité restée dans le
|
||||
localStorage de ce navigateur."""
|
||||
from lidar_pipeline.mapui import _MAP_JS
|
||||
load = _MAP_JS[_MAP_JS.index("function loadState("):_MAP_JS.index("function saveState(")]
|
||||
assert "else if (hash.main || hash.view) st.intensity = 1;" in load
|
||||
|
||||
|
||||
def test_ui_compare_clip_skips_when_already_off():
|
||||
"""M7 : applyCompareClip sort tôt quand le mode n'est pas Comparer et que
|
||||
les calques sont déjà sans découpe — évite de relire/réécrire le style de
|
||||
tous les calques à chaque déplacement de carte alors que Comparer n'a
|
||||
jamais été ouvert."""
|
||||
from lidar_pipeline.mapui import _MAP_JS
|
||||
clip = _MAP_JS[_MAP_JS.index("function applyCompareClip("):_MAP_JS.index("(function compareDrag(")]
|
||||
assert "let compareClipsCleared = true;" in _MAP_JS
|
||||
assert "if (!on && compareClipsCleared) { el('compareBar').hidden = true; return; }" in clip
|
||||
assert "compareClipsCleared = !on;" in clip
|
||||
|
||||
Reference in New Issue
Block a user