fix(sites) : referentiel /sites complet pour les roles read_ref (ERP-102)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 1m50s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m21s

Le cloisonnement par site rattache (SiteCollectionScopedExtension) tronquait
encore la collection /sites pour les roles metier :  ouvrait la
security mais le filtre IN sur les sites de l'utilisateur reduisait le select
d'adresse client a son seul site rattache (voire a rien sans site) — le bug
"selects vides" d'ERP-102 etait deplace du 403 vers une liste vide.

- SiteCollectionScopedExtension :  neutralise le scope (lecture
  du referentiel complet), au meme titre que . Lecture seule.
- ClientRBACMatrixTest : l'assertion ne se contente plus du 200, elle verifie
  que les roles metier voient la TOTALITE du referentiel sites (totalItems ==
  nombre de sites en base), pas seulement leur site rattache.
This commit is contained in:
Matthieu
2026-06-03 14:52:06 +02:00
parent 54fe48993f
commit efdbfa5673
2 changed files with 32 additions and 1 deletions
@@ -6,6 +6,7 @@ namespace App\Tests\Module\Commercial\Api;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\Module\Core\Infrastructure\DataFixtures\RbacDemoFixtures;
use App\Module\Sites\Domain\Entity\Site;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\NullOutput;
@@ -281,14 +282,32 @@ final class ClientRBACMatrixTest extends AbstractCommercialApiTestCase
// / sites.read_ref) attachee par la matrice § 2.7 — sans pour autant porter
// la permission d'administration `.view`. Usine, sans aucune permission,
// reste interdit.
// Le referentiel /sites est TRANSVERSE et COMPLET : le cloisonnement par
// site rattache (SiteCollectionScopedExtension) est neutralise par
// `sites.read_ref` (ERP-102). Les comptes demo ne sont rattaches qu'a un
// seul site (Chatellerault) alors que la base en compte plusieurs : on
// verifie donc que le role voit la TOTALITE du referentiel, pas son seul
// site rattache. Sans le bypass de scope, totalItems vaudrait 1.
$totalSites = $this->getEm()->getRepository(Site::class)->count([]);
self::assertGreaterThan(
1,
$totalSites,
'Pre-requis du test : la base doit contenir plusieurs sites pour distinguer scope et bypass.',
);
foreach (['bureau', 'compta', 'commerciale'] as $role) {
$client = $this->authAs($role);
$client->request('GET', '/api/categories', ['headers' => ['Accept' => self::LD]]);
self::assertResponseStatusCodeSame(200, sprintf('Le role %s doit pouvoir lister /categories', $role));
$client->request('GET', '/api/sites', ['headers' => ['Accept' => self::LD]]);
$response = $client->request('GET', '/api/sites', ['headers' => ['Accept' => self::LD]]);
self::assertResponseStatusCodeSame(200, sprintf('Le role %s doit pouvoir lister /sites', $role));
self::assertSame(
$totalSites,
$response->toArray()['totalItems'] ?? null,
sprintf('Le role %s doit voir tout le referentiel sites (%d), pas seulement son site rattache', $role, $totalSites),
);
}
// Usine : aucune permission -> reste a 403 sur les referentiels.