chore(fixtures) : make AppFixtures idempotent on --append
admin / alice / bob sont desormais resolus via un lookup par username (ensureUser) avant creation, sur le modele de ensureSystemRole (meme fichier) et RbacDemoFixtures::ensureDemoUsers. Sans ce lookup, doctrine:fixtures:load --append (sans purge) violait l'unicite de username en recreant ces comptes. Resultat : tout le jeu de fixtures est rejouable en --append sans erreur ni doublon (verifie : 2 runs consecutifs -> 7 users stables). Le flow canonical make db-reset (purge + load) est inchange.
This commit is contained in:
@@ -28,6 +28,11 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
* systeme de maniere idempotente avant de rattacher les utilisateurs, afin
|
||||
* que le workflow "make db-reset && make fixtures" reste one-shot.
|
||||
*
|
||||
* Idempotence complete (y compris `doctrine:fixtures:load --append`, sans
|
||||
* purge) : roles via ensureSystemRole, utilisateurs via ensureUser (lookup par
|
||||
* username). Rejouer la fixture ne cree donc aucun doublon ni violation
|
||||
* d'unicite de username.
|
||||
*
|
||||
* Dependance explicite a SitesFixtures (ticket 2) : les 3 sites Chatellerault,
|
||||
* Saint-Jean et Pommevic doivent etre presents en base avant d'etre rattaches
|
||||
* aux users. L'inversion volontaire de l'ordre (AppFixtures ← SitesFixtures)
|
||||
@@ -75,8 +80,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
||||
$saintJean = $this->requireSite('Saint-Jean');
|
||||
$pommevic = $this->requireSite('Pommevic');
|
||||
|
||||
$admin = new User();
|
||||
$admin->setUsername('admin');
|
||||
$admin = $this->ensureUser($manager, 'admin');
|
||||
$admin->setIsAdmin(true);
|
||||
$admin->setPassword($this->passwordHasher->hashPassword($admin, 'admin'));
|
||||
$admin->addRbacRole($adminRole);
|
||||
@@ -87,8 +91,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
||||
$admin->setCurrentSite($chatellerault);
|
||||
$manager->persist($admin);
|
||||
|
||||
$alice = new User();
|
||||
$alice->setUsername('alice');
|
||||
$alice = $this->ensureUser($manager, 'alice');
|
||||
$alice->setPassword($this->passwordHasher->hashPassword($alice, 'alice'));
|
||||
$alice->addRbacRole($userRole);
|
||||
// Alice : un seul site, site courant = ce site.
|
||||
@@ -96,8 +99,7 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
||||
$alice->setCurrentSite($chatellerault);
|
||||
$manager->persist($alice);
|
||||
|
||||
$bob = new User();
|
||||
$bob->setUsername('bob');
|
||||
$bob = $this->ensureUser($manager, 'bob');
|
||||
$bob->setPassword($this->passwordHasher->hashPassword($bob, 'bob'));
|
||||
$bob->addRbacRole($userRole);
|
||||
// Bob : site different de Alice, pour prouver le filtrage par site
|
||||
@@ -135,6 +137,27 @@ class AppFixtures extends Fixture implements DependentFixtureInterface
|
||||
return $role;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne l'utilisateur correspondant au username, en le creant s'il
|
||||
* n'existe pas encore. Rend la fixture idempotente y compris en
|
||||
* `doctrine:fixtures:load --append` (sans purge) : sans ce lookup, recreer
|
||||
* « admin » / « alice » / « bob » violerait l'unicite de username. Meme
|
||||
* esprit que ensureSystemRole ci-dessus et RbacDemoFixtures::ensureDemoUsers.
|
||||
*/
|
||||
private function ensureUser(ObjectManager $manager, string $username): User
|
||||
{
|
||||
$user = $manager->getRepository(User::class)->findOneBy(['username' => $username]);
|
||||
|
||||
if (null !== $user) {
|
||||
return $user;
|
||||
}
|
||||
|
||||
$user = new User();
|
||||
$user->setUsername($username);
|
||||
|
||||
return $user;
|
||||
}
|
||||
|
||||
private function requireSite(string $name): SiteInterface
|
||||
{
|
||||
$site = $this->siteProvider->findByName($name);
|
||||
|
||||
Reference in New Issue
Block a user