feat(modules): harden module platform with event constants, validation checks, and CLI improvements
- Add ModuleEvents constants class with all 8 event strings; update dispatch call sites - ValidateCommand: check AuthorizationPolicy container registration (check 20) - ValidateCommand: warn on unknown event_listeners keys (check 21) - make:module --simple flag for minimal manifests - module:deactivate reverse-dependency warning - 12 new PHPUnit tests covering all improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
69
tests/App/Module/ModuleEventsTest.php
Normal file
69
tests/App/Module/ModuleEventsTest.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Tests\App\Module;
|
||||
|
||||
use MintyPHP\App\Module\ModuleEvents;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class ModuleEventsTest extends TestCase
|
||||
{
|
||||
public function testAllConstantsAreReturnedByAll(): void
|
||||
{
|
||||
$reflection = new \ReflectionClass(ModuleEvents::class);
|
||||
$constants = $reflection->getConstants();
|
||||
|
||||
self::assertNotEmpty($constants, 'ModuleEvents should define at least one constant');
|
||||
self::assertSame(
|
||||
array_values($constants),
|
||||
ModuleEvents::all(),
|
||||
'ModuleEvents::all() must return exactly the values of all class constants'
|
||||
);
|
||||
}
|
||||
|
||||
public function testConstantValuesMatchExpectedEventStrings(): void
|
||||
{
|
||||
self::assertSame('user.login', ModuleEvents::USER_LOGIN);
|
||||
self::assertSame('user.logout', ModuleEvents::USER_LOGOUT);
|
||||
self::assertSame('user.created', ModuleEvents::USER_CREATED);
|
||||
self::assertSame('user.deleted', ModuleEvents::USER_DELETED);
|
||||
self::assertSame('user.activated', ModuleEvents::USER_ACTIVATED);
|
||||
self::assertSame('user.deactivated', ModuleEvents::USER_DEACTIVATED);
|
||||
self::assertSame('user.assignment_changed', ModuleEvents::USER_ASSIGNMENT_CHANGED);
|
||||
self::assertSame('scheduler.job_failed', ModuleEvents::SCHEDULER_JOB_FAILED);
|
||||
}
|
||||
|
||||
public function testAllReturnsUniqueValues(): void
|
||||
{
|
||||
$all = ModuleEvents::all();
|
||||
self::assertSame($all, array_unique($all), 'ModuleEvents::all() must not contain duplicates');
|
||||
}
|
||||
|
||||
public function testClassIsNotInstantiable(): void
|
||||
{
|
||||
$reflection = new \ReflectionClass(ModuleEvents::class);
|
||||
self::assertFalse($reflection->isInstantiable(), 'ModuleEvents should not be instantiable');
|
||||
}
|
||||
|
||||
public function testDispatchCallSitesUseConstants(): void
|
||||
{
|
||||
$root = dirname(__DIR__, 3);
|
||||
$files = [
|
||||
$root . '/core/Service/Auth/AuthService.php',
|
||||
$root . '/core/Service/User/UserAccountService.php',
|
||||
$root . '/core/Service/Scheduler/SchedulerRunService.php',
|
||||
];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$content = file_get_contents($file);
|
||||
self::assertIsString($content, "Could not read {$file}");
|
||||
|
||||
// Ensure no raw string dispatch calls remain (except in ternaries which use constants)
|
||||
preg_match_all('/->dispatch\(\s*[\'"]([^"\']+)[\'"]\s*,/', $content, $matches);
|
||||
self::assertSame(
|
||||
[],
|
||||
$matches[1],
|
||||
basename($file) . ' still uses raw string event names: ' . implode(', ', $matches[1])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user