"""Palier 12 (0.15.0 → refonte 0.16.0): layout barre latérale (#16) et wallboard sans défilement parasite.""" import app.main as main def test_sidebar_on_app_pages(client, fake_gitea): for path in ("/", "/focus", "/today", "/briefing", "/forecast", "/rules", "/health", "/standup", "/capture"): page = client.get(path) assert page.status_code == 200, path assert page.text.count('id="sidebar"') == 1, path assert page.text.count('id="nav-burger"') == 1, path assert "with-sidebar" in page.text, path assert "/static/js/nav.js" in page.text, path # Les quatre sections accordéon de la barre latérale. for group in ("Principal", "Rituels", "Pilotage", "Outils"): assert group in page.text, (path, group) for gkey in ("principal", "rituels", "pilotage", "outils"): assert f'data-group-btn="{gkey}"' in page.text, (path, gkey) assert page.text.count('class="side-acc"') == 4, path assert "kanbante-nav-closed" in page.text # bootstrap pré-rendu assert 'href="/health"' in page.text assert 'id="side-collapse"' in page.text # Bouton palette : icône seule, à droite du titre — pas de # libellé texte « Recherche & commandes » visible. assert 'class="side-head"' in page.text assert ">🔍" in page.text # Le libellé de l'ancien bouton palette a disparu (le lien de # navigation « Recherche », lui, existe toujours — c'est le # texte complet « Recherche & commandes » qui doit manquer). assert 'side-label">Recherche & commandes' not in page.text assert "Recherche & commandes" not in page.text def test_sidebar_active_states(client, fake_gitea): home = client.get("/") assert 'href="/" class="side-link active"' in home.text forecast = client.get("/forecast") assert 'href="/forecast" class="side-link active"' in forecast.text today = client.get("/today") assert 'href="/today" class="side-link active"' in today.text def test_board_topbar_crumb_and_gitea_link(client, fake_gitea): board = client.get("/board/Projets/demo") assert board.status_code == 200 assert 'href="/board/Projets/demo"' in board.text # fil d'Ariane topbar assert "Gitea ↗" in board.text assert 'id="sidebar"' in board.text def test_wall_has_no_sidebar(client, fake_gitea): wall = client.get("/wall") assert wall.status_code == 200 assert 'id="sidebar"' not in wall.text # plein écran TV assumé assert "wall-foot" in wall.text def test_nav_js_contract(client, fake_gitea): js = client.get("/static/js/nav.js") assert js.status_code == 200 assert "sidebar-collapsed" in js.text assert "localStorage" in js.text assert "side-backdrop" in js.text assert "Escape" in js.text assert "kanbante-nav-open" in js.text # accordéon exclusif persisté (0.22.0) assert "setOpenGroup" in js.text assert "data-group-btn" in js.text def test_wall_more_cards_line(client, fake_gitea, monkeypatch): async def fake_collect(only_repo, *args, **kwargs): return [{ "full_name": "Projets/demo", "counts": {c: 0 for c in ("backlog", "todo", "in_progress", "qa", "review", "done")}, "open_total": 12, "cards": [ {"number": i, "title": f"Carte {i}", "column": "in_progress", "column_label": "🚧 En cours", "age_days": 2, "aging": False} for i in range(1, 10) ], "cards_total": 12, "closed_today": 1, }] monkeypatch.setattr(main, "_collect_wall_data", fake_collect) page = client.get("/wall") assert page.status_code == 200 assert "+3 autres cartes en vol" in page.text assert "📋 Ouvertes" in page.text