Le super admin (table super_admins, master DB) ne pouvait pas se connecter via /api/login car ce firewall n'utilisait que le provider tenant. De même, le JWT n'était pas enrichi pour les super admins, l'endpoint /api/me/roles les rejetait, et le frontend redirigeait systématiquement vers /dashboard. Un chain provider (super_admin + tenant) résout l'authentification, le JwtPayloadEnricher et MyRolesProvider gèrent désormais les deux types d'utilisateurs, et le frontend redirige selon le rôle après login.
149 lines
5.6 KiB
PHP
149 lines
5.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\SuperAdmin\Domain\Model\Establishment;
|
|
|
|
use App\Shared\Domain\Tenant\TenantId;
|
|
use App\SuperAdmin\Domain\Event\EtablissementCree;
|
|
use App\SuperAdmin\Domain\Event\EtablissementDesactive;
|
|
use App\SuperAdmin\Domain\Exception\EstablishmentDejaInactifException;
|
|
use App\SuperAdmin\Domain\Model\Establishment\Establishment;
|
|
use App\SuperAdmin\Domain\Model\Establishment\EstablishmentId;
|
|
use App\SuperAdmin\Domain\Model\Establishment\EstablishmentStatus;
|
|
use App\SuperAdmin\Domain\Model\SuperAdmin\SuperAdminId;
|
|
use DateTimeImmutable;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class EstablishmentTest extends TestCase
|
|
{
|
|
private const string SUPER_ADMIN_ID = '550e8400-e29b-41d4-a716-446655440001';
|
|
private const string ESTABLISHMENT_NAME = 'École Alpha';
|
|
private const string SUBDOMAIN = 'ecole-alpha';
|
|
|
|
#[Test]
|
|
public function creerCreatesActiveEstablishment(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
|
|
self::assertSame(EstablishmentStatus::ACTIF, $establishment->status);
|
|
self::assertSame(self::ESTABLISHMENT_NAME, $establishment->name);
|
|
self::assertSame(self::SUBDOMAIN, $establishment->subdomain);
|
|
self::assertNull($establishment->lastActivityAt);
|
|
self::assertNotEmpty($establishment->databaseName);
|
|
self::assertStringStartsWith('classeo_tenant_', $establishment->databaseName);
|
|
}
|
|
|
|
#[Test]
|
|
public function creerRecordsEtablissementCreeEvent(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
|
|
$events = $establishment->pullDomainEvents();
|
|
|
|
self::assertCount(1, $events);
|
|
self::assertInstanceOf(EtablissementCree::class, $events[0]);
|
|
self::assertTrue($establishment->id->equals($events[0]->establishmentId));
|
|
self::assertTrue($establishment->tenantId->equals($events[0]->tenantId));
|
|
self::assertSame(self::ESTABLISHMENT_NAME, $events[0]->name);
|
|
self::assertSame(self::SUBDOMAIN, $events[0]->subdomain);
|
|
}
|
|
|
|
#[Test]
|
|
public function creerGeneratesTenantIdAndDatabaseName(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
|
|
self::assertInstanceOf(TenantId::class, $establishment->tenantId);
|
|
self::assertStringStartsWith('classeo_tenant_', $establishment->databaseName);
|
|
}
|
|
|
|
#[Test]
|
|
public function desactiverChangesStatusToInactif(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
|
|
$establishment->desactiver(new DateTimeImmutable('2026-02-16 12:00:00'));
|
|
|
|
self::assertSame(EstablishmentStatus::INACTIF, $establishment->status);
|
|
}
|
|
|
|
#[Test]
|
|
public function desactiverRecordsEtablissementDesactiveEvent(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
$establishment->pullDomainEvents(); // Clear creation event
|
|
|
|
$establishment->desactiver(new DateTimeImmutable('2026-02-16 12:00:00'));
|
|
|
|
$events = $establishment->pullDomainEvents();
|
|
self::assertCount(1, $events);
|
|
self::assertInstanceOf(EtablissementDesactive::class, $events[0]);
|
|
}
|
|
|
|
#[Test]
|
|
public function desactiverThrowsWhenAlreadyInactive(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
$establishment->desactiver(new DateTimeImmutable('2026-02-16 12:00:00'));
|
|
|
|
$this->expectException(EstablishmentDejaInactifException::class);
|
|
$establishment->desactiver(new DateTimeImmutable('2026-02-16 13:00:00'));
|
|
}
|
|
|
|
#[Test]
|
|
public function enregistrerActiviteUpdatesLastActivityAt(): void
|
|
{
|
|
$establishment = $this->createEstablishment();
|
|
$activityAt = new DateTimeImmutable('2026-02-16 15:00:00');
|
|
|
|
$establishment->enregistrerActivite($activityAt);
|
|
|
|
self::assertEquals($activityAt, $establishment->lastActivityAt);
|
|
}
|
|
|
|
#[Test]
|
|
public function reconstituteRestoresAllProperties(): void
|
|
{
|
|
$id = EstablishmentId::generate();
|
|
$tenantId = TenantId::generate();
|
|
$createdBy = SuperAdminId::fromString(self::SUPER_ADMIN_ID);
|
|
$createdAt = new DateTimeImmutable('2026-01-01 10:00:00');
|
|
$lastActivityAt = new DateTimeImmutable('2026-02-16 14:30:00');
|
|
|
|
$establishment = Establishment::reconstitute(
|
|
id: $id,
|
|
tenantId: $tenantId,
|
|
name: self::ESTABLISHMENT_NAME,
|
|
subdomain: self::SUBDOMAIN,
|
|
databaseName: 'classeo_tenant_abc123',
|
|
status: EstablishmentStatus::ACTIF,
|
|
createdAt: $createdAt,
|
|
createdBy: $createdBy,
|
|
lastActivityAt: $lastActivityAt,
|
|
);
|
|
|
|
self::assertTrue($id->equals($establishment->id));
|
|
self::assertTrue($tenantId->equals($establishment->tenantId));
|
|
self::assertSame(self::ESTABLISHMENT_NAME, $establishment->name);
|
|
self::assertSame(self::SUBDOMAIN, $establishment->subdomain);
|
|
self::assertSame('classeo_tenant_abc123', $establishment->databaseName);
|
|
self::assertSame(EstablishmentStatus::ACTIF, $establishment->status);
|
|
self::assertEquals($createdAt, $establishment->createdAt);
|
|
self::assertTrue($createdBy->equals($establishment->createdBy));
|
|
self::assertEquals($lastActivityAt, $establishment->lastActivityAt);
|
|
self::assertEmpty($establishment->pullDomainEvents());
|
|
}
|
|
|
|
private function createEstablishment(): Establishment
|
|
{
|
|
return Establishment::creer(
|
|
name: self::ESTABLISHMENT_NAME,
|
|
subdomain: self::SUBDOMAIN,
|
|
createdBy: SuperAdminId::fromString(self::SUPER_ADMIN_ID),
|
|
createdAt: new DateTimeImmutable('2026-02-16 10:00:00'),
|
|
);
|
|
}
|
|
}
|