<?php

declare(strict_types=1);

namespace App\Tests\Module\Sites;

use App\Module\Sites\Infrastructure\ApiPlatform\State\Processor\SiteAwareInjectionProcessor;
use App\Module\Sites\SitesModule;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * Tests structurels du module Sites : contrat `permissions()` et
 * invariants d'enregistrement des services.
 *
 * @internal
 */
final class SitesModuleTest extends KernelTestCase
{
    public function testPermissionsSetContainsExactlyFourCodes(): void
    {
        // Garde-fou : si quelqu'un ajoute une permission sans ajuster les
        // tests ou la doc, ce test casse explicitement. Si au contraire une
        // permission disparait (ex: bypass_scope retire par erreur), meme
        // effet. Le set de permissions est fige par ce test.
        // `sites.read_ref` ajoutee en ERP-102 (lecture-referentiel transverse).
        $codes = array_column(SitesModule::permissions(), 'code');
        sort($codes);

        self::assertSame(
            ['sites.bypass_scope', 'sites.manage', 'sites.read_ref', 'sites.view'],
            $codes,
        );
    }

    public function testSiteAwareInjectionProcessorIsRegisteredAsDecoratorOfPersistProcessor(): void
    {
        // Garde d'integration : le ticket 4 compte sur le fait que tous
        // les processors existants qui deleguent au persist processor
        // (UserRbacProcessor, RoleProcessor, etc.) passent par notre
        // decorator SiteAwareInjectionProcessor. Si un refactor Symfony
        // change la resolution du service decore, ce test cassera en
        // amont des regressions invisibles dans les tests metier.
        self::bootKernel();
        $container = self::getContainer();

        $persistProcessor = $container->get('api_platform.doctrine.orm.state.persist_processor');

        self::assertInstanceOf(
            SiteAwareInjectionProcessor::class,
            $persistProcessor,
            'Le service api_platform.doctrine.orm.state.persist_processor doit etre decore par SiteAwareInjectionProcessor (#[AsDecorator]).',
        );
    }
}
