<?php

declare(strict_types=1);

namespace App\Tests\Module\Technique;

use App\Module\Technique\TechniqueModule;
use PHPUnit\Framework\TestCase;

/**
 * Tests structurels du module Technique (M3) : identite et contrat
 * `permissions()`.
 *
 * @internal
 */
final class TechniqueModuleTest extends TestCase
{
    public function testModuleIdentity(): void
    {
        self::assertSame('technique', TechniqueModule::ID);
        self::assertSame('Technique', TechniqueModule::LABEL);
        self::assertFalse(TechniqueModule::REQUIRED);
    }

    public function testPermissionsSetContainsExactlyFiveCodes(): void
    {
        // Garde-fou : le jeu de permissions du module est fige par ce test. Si
        // quelqu'un ajoute / retire une permission sans ajuster la spec (§ 5.1)
        // ni la matrice RBAC, le test casse explicitement.
        $codes = array_column(TechniqueModule::permissions(), 'code');
        sort($codes);

        self::assertSame(
            [
                'technique.providers.accounting.manage',
                'technique.providers.accounting.view',
                'technique.providers.archive',
                'technique.providers.manage',
                'technique.providers.view',
            ],
            $codes,
        );
    }

    public function testEveryPermissionCodeIsPrefixedByModuleId(): void
    {
        // Convention de nommage `module.resource[.sub].action` : le prefixe doit
        // correspondre exactement a l'ID du module (verifie aussi par
        // app:sync-permissions).
        foreach (TechniqueModule::permissions() as $permission) {
            self::assertStringStartsWith(
                TechniqueModule::ID.'.',
                $permission['code'],
                'Chaque code de permission doit etre prefixe par l\'ID du module.',
            );
            self::assertNotSame('', $permission['label'], 'Chaque permission doit porter un label.');
        }
    }
}
