1
0
Files
breadcrumb-the-shire/tests/Architecture/ModuleProviderContractTest.php

142 lines
5.7 KiB
PHP
Raw Permalink Normal View History

2026-03-19 18:30:14 +01:00
<?php
namespace MintyPHP\Tests\Architecture;
use MintyPHP\App\Module\Contracts\EventListener;
use MintyPHP\App\Module\Contracts\LayoutContextProvider;
use MintyPHP\App\Module\Contracts\ModuleDeactivationHandler;
use MintyPHP\App\Module\Contracts\SearchResourceProvider;
use MintyPHP\App\Module\Contracts\SessionProvider;
use MintyPHP\Service\Access\AuthorizationPolicyInterface;
final class ModuleProviderContractTest extends AbstractModuleStructureContractTestCase
{
public function testContainerRegistrarClassesExist(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->containerRegistrars as $registrar) {
self::assertTrue(
class_exists($registrar),
"Module '{$module['id']}' declares container_registrar '{$registrar}' but class does not exist"
);
}
}
}
public function testSearchProviderClassesImplementContract(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->searchResources as $providerClass) {
self::assertTrue(
class_exists($providerClass),
"Module '{$module['id']}' search provider '{$providerClass}' class not found"
);
$provider = new $providerClass();
self::assertInstanceOf(
SearchResourceProvider::class,
$provider,
"Module '{$module['id']}' search provider must implement SearchResourceProvider"
);
}
}
}
public function testLayoutContextProviderClassesImplementContract(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->layoutContextProviders as $providerClass) {
self::assertTrue(
class_exists($providerClass),
"Module '{$module['id']}' layout context provider '{$providerClass}' class not found"
);
$provider = new $providerClass();
self::assertInstanceOf(
LayoutContextProvider::class,
$provider,
"Module '{$module['id']}' layout context provider must implement LayoutContextProvider"
);
}
}
}
public function testSessionProviderClassesImplementContract(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->sessionProviders as $providerClass) {
self::assertTrue(
class_exists($providerClass),
"Module '{$module['id']}' session provider '{$providerClass}' class not found"
);
$provider = new $providerClass();
self::assertInstanceOf(
SessionProvider::class,
$provider,
"Module '{$module['id']}' session provider must implement SessionProvider"
);
}
}
}
public function testAuthorizationPolicyClassesImplementContract(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->authorizationPolicies as $policyClass) {
self::assertTrue(
class_exists($policyClass),
"Module '{$module['id']}' authorization policy '{$policyClass}' class not found"
);
self::assertTrue(
is_subclass_of($policyClass, AuthorizationPolicyInterface::class)
|| in_array(AuthorizationPolicyInterface::class, class_implements($policyClass) ?: [], true),
"Module '{$module['id']}' authorization policy must implement AuthorizationPolicyInterface"
);
}
}
}
public function testEventListenerClassesImplementContract(): void
{
foreach (self::$modules as $module) {
foreach ($module['manifest']->eventListeners as $eventName => $handlers) {
foreach ($handlers as $index => $handler) {
$class = $handler['class'];
self::assertTrue(
class_exists($class),
"Module '{$module['id']}' event_listeners['{$eventName}'][{$index}] class '{$class}' not found"
);
self::assertTrue(
is_subclass_of($class, EventListener::class)
|| in_array(EventListener::class, class_implements($class) ?: [], true),
"Module '{$module['id']}' event_listeners['{$eventName}'][{$index}] class '{$class}' "
. "must implement EventListener interface"
);
}
}
}
self::addToAssertionCount(1);
}
public function testDeactivationHandlerClassImplementsContract(): void
{
foreach (self::$modules as $module) {
$handler = $module['manifest']->deactivationHandler;
if ($handler === null) {
continue;
}
self::assertTrue(
class_exists($handler),
"Module '{$module['id']}' deactivation_handler class '{$handler}' not found"
);
self::assertTrue(
is_subclass_of($handler, ModuleDeactivationHandler::class)
|| in_array(ModuleDeactivationHandler::class, class_implements($handler) ?: [], true),
"Module '{$module['id']}' deactivation_handler class '{$handler}' "
. "must implement ModuleDeactivationHandler interface"
);
}
self::addToAssertionCount(1);
}
}