fix(admin): retire les liens de nav vers des pages non construites
All checks were successful
CI / php-lint (push) Successful in 20s
CI / secret-scan (pull_request) Successful in 8s
CI / static-tests (pull_request) Successful in 33s
CI / auto-merge (push) Has been skipped
CI / auto-merge (pull_request) Successful in 4s
CI / secret-scan (push) Successful in 8s
CI / static-tests (push) Successful in 35s
CI / php-lint (pull_request) Successful in 19s

Le shell admin (layout.php) exposait, conditionnes par permission, 4 liens de
navigation vers des routes inexistantes : /admin/menus, /admin/orders,
/admin/users, /admin/roles. Un clic renvoyait un 404 JSON brut (le seed admin
detient les 4 permissions, donc l'admin voyait les 4 liens morts).

Liens retires tant que leur page n'existe pas ; les sections Operations et
Administration disparaissent (leurs seuls items etaient morts), Menus quitte la
section Catalogue. Un commentaire documente comment/quand les reactiver (avec
leur route, P3 suite / P4). Dashboard / Categories / Produits (pages reelles)
restent, la demo RBAC reste portee par le gating de Produits.

Test : DashboardControllerTest assertait le rendu du lien /admin/users (mort) ;
mis a jour en assertStringNotContainsString. Suite verte (188, 13 DB skip).
This commit is contained in:
Imugiii 2026-06-16 11:46:24 +00:00
parent ad5203d3fc
commit ca64e5037f
2 changed files with 14 additions and 26 deletions

View file

@ -94,7 +94,7 @@ $navClass = static function (string $code, string $current): string {
<a href="/admin/dashboard" class="<?= $navClass('dashboard', $active) ?>">Tableau de bord</a> <a href="/admin/dashboard" class="<?= $navClass('dashboard', $active) ?>">Tableau de bord</a>
</div> </div>
<?php if ($can('product.read') || $can('menu.read') || $can('category.manage')): ?> <?php if ($can('category.manage') || $can('product.read')): ?>
<div class="sidebar-section"> <div class="sidebar-section">
<div class="sidebar-section-label">Catalogue</div> <div class="sidebar-section-label">Catalogue</div>
<?php if ($can('category.manage')): ?> <?php if ($can('category.manage')): ?>
@ -103,30 +103,15 @@ $navClass = static function (string $code, string $current): string {
<?php if ($can('product.read')): ?> <?php if ($can('product.read')): ?>
<a href="/admin/products" class="<?= $navClass('products', $active) ?>">Produits</a> <a href="/admin/products" class="<?= $navClass('products', $active) ?>">Produits</a>
<?php endif; ?> <?php endif; ?>
<?php if ($can('menu.read')): ?>
<a href="/admin/menus" class="<?= $navClass('menus', $active) ?>">Menus</a>
<?php endif; ?>
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php if ($can('order.read')): ?> <?php /*
<div class="sidebar-section"> Items de nav volontairement absents tant que leur page n'existe pas
<div class="sidebar-section-label">Operations</div> (un lien vers une route non enregistree renvoie un 404). A reactiver
<a href="/admin/orders" class="<?= $navClass('orders', $active) ?>">Commandes</a> avec leur route respective : Menus (menu.read), Commandes (order.read),
</div> Utilisateurs (user.read), Roles (role.manage) -- P3 suite / P4.
<?php endif; ?> */ ?>
<?php if ($can('user.read') || $can('role.manage')): ?>
<div class="sidebar-section">
<div class="sidebar-section-label">Administration</div>
<?php if ($can('user.read')): ?>
<a href="/admin/users" class="<?= $navClass('users', $active) ?>">Utilisateurs</a>
<?php endif; ?>
<?php if ($can('role.manage')): ?>
<a href="/admin/roles" class="<?= $navClass('roles', $active) ?>">Roles</a>
<?php endif; ?>
</div>
<?php endif; ?>
</nav> </nav>
<main class="content"> <main class="content">

View file

@ -150,10 +150,13 @@ final class DashboardControllerTest extends TestCase
// Marqueur present UNIQUEMENT dans le fragment dashboard (absent du layout) : // Marqueur present UNIQUEMENT dans le fragment dashboard (absent du layout) :
// verifie que le contenu est bien compose DANS le shell (pas un $content vide). // verifie que le contenu est bien compose DANS le shell (pas un $content vide).
self::assertStringContainsString('Bienvenue, Corentin J', $body); self::assertStringContainsString('Bienvenue, Corentin J', $body);
// Navigation conditionnee aux permissions. // Navigation conditionnee aux permissions : un lien n'apparait que si la
self::assertStringContainsString('/admin/products', $body); // product.read present // permission est presente ET la page existe.
self::assertStringContainsString('/admin/users', $body); // user.read present self::assertStringContainsString('/admin/products', $body); // product.read present + page existante
self::assertStringNotContainsString('/admin/roles', $body); // role.manage absent // user.read est present, mais la page /admin/users n'existe pas encore :
// le lien est retire pour ne pas exposer un 404 (cf. layout.php).
self::assertStringNotContainsString('/admin/users', $body);
self::assertStringNotContainsString('/admin/roles', $body); // pas de page + role.manage absent
// Deconnexion = formulaire POST avec CSRF. // Deconnexion = formulaire POST avec CSRF.
self::assertStringContainsString('action="/logout"', $body); self::assertStringContainsString('action="/logout"', $body);
self::assertStringContainsString('name="_csrf"', $body); self::assertStringContainsString('name="_csrf"', $body);