feat: make event state constructor-only and immutable
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace KTXT\Unit\Event;
|
||||
|
||||
use KTXF\Event\Event;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\TestDox;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class EventTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
#[TestDox('Event data and context are supplied during construction')]
|
||||
public function constructsCompleteEventState(): void
|
||||
{
|
||||
$event = new Event(
|
||||
'test.event',
|
||||
['nested' => ['value' => 'original']],
|
||||
'tenant-a',
|
||||
'identity-a',
|
||||
);
|
||||
|
||||
$copy = $event->getData();
|
||||
$copy['nested']['value'] = 'changed';
|
||||
|
||||
self::assertSame('original', $event->get('nested')['value']);
|
||||
self::assertSame('tenant-a', $event->getTenantId());
|
||||
self::assertSame('identity-a', $event->getIdentityId());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[TestDox('Event data rejects mutable object references')]
|
||||
public function rejectsMutablePayloadValues(): void
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
|
||||
new Event('test.event', ['mutable' => new \stdClass()]);
|
||||
}
|
||||
}
|
||||
@@ -34,13 +34,35 @@ final class SecurityEventTest extends TestCase
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[TestDox('Explicit severity can override the event type default')]
|
||||
#[TestDox('Construction can override the event type default severity')]
|
||||
public function allowsSeverityOverride(): void
|
||||
{
|
||||
$event = new SecurityEvent(SecurityEvent::AUTH_FAILURE);
|
||||
|
||||
$event->setSeverity(SecurityEvent::SEVERITY_CRITICAL);
|
||||
$event = new SecurityEvent(
|
||||
SecurityEvent::AUTH_FAILURE,
|
||||
severity: SecurityEvent::SEVERITY_CRITICAL,
|
||||
);
|
||||
|
||||
self::assertSame(SecurityEvent::SEVERITY_CRITICAL, $event->getSeverity());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[TestDox('Event state exposes no mutation methods')]
|
||||
public function exposesNoMutationMethods(): void
|
||||
{
|
||||
foreach ([
|
||||
'set',
|
||||
'setTenantId',
|
||||
'setIdentityId',
|
||||
'setIpAddress',
|
||||
'setDeviceFingerprint',
|
||||
'setUserAgent',
|
||||
'setRequestPath',
|
||||
'setRequestMethod',
|
||||
'setUserId',
|
||||
'setReason',
|
||||
'setSeverity',
|
||||
] as $method) {
|
||||
self::assertFalse(method_exists(SecurityEvent::class, $method));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,9 +215,9 @@ class FirewallServiceTest extends TestCase
|
||||
null,
|
||||
'tenant-rule',
|
||||
FirewallRuleObject::SCOPE_TENANT,
|
||||
'Tenant block'
|
||||
'Tenant block',
|
||||
'tenant-a',
|
||||
);
|
||||
$event->setTenantId('tenant-a');
|
||||
|
||||
$this->service->logSecurityEvent($event);
|
||||
}
|
||||
@@ -275,9 +275,9 @@ class FirewallServiceTest extends TestCase
|
||||
'203.0.113.10',
|
||||
101,
|
||||
60,
|
||||
'/login'
|
||||
'/login',
|
||||
'tenant-a',
|
||||
);
|
||||
$event->setTenantId('tenant-a');
|
||||
|
||||
$this->service->logSecurityEvent($event);
|
||||
}
|
||||
@@ -300,11 +300,11 @@ class FirewallServiceTest extends TestCase
|
||||
\KTXC\Security\Event\SecurityEvent::SUSPICIOUS_ACTIVITY,
|
||||
'203.0.113.20',
|
||||
null,
|
||||
['detector' => 'payload-signature']
|
||||
['detector' => 'payload-signature'],
|
||||
tenantId: 'tenant-a',
|
||||
requestPath: '/admin',
|
||||
requestMethod: 'POST',
|
||||
);
|
||||
$event->setTenantId('tenant-a')
|
||||
->setRequestPath('/admin')
|
||||
->setRequestMethod('POST');
|
||||
|
||||
$this->service->logSecurityEvent($event);
|
||||
}
|
||||
@@ -329,9 +329,9 @@ class FirewallServiceTest extends TestCase
|
||||
'ruleId' => 'rule-123',
|
||||
'ruleScope' => FirewallRuleObject::SCOPE_SYSTEM,
|
||||
'origin' => FirewallRuleManager::ORIGIN_MANUAL,
|
||||
]
|
||||
],
|
||||
identityId: 'operator',
|
||||
);
|
||||
$event->setIdentityId('operator');
|
||||
|
||||
$this->service->logSecurityEvent($event);
|
||||
}
|
||||
@@ -351,9 +351,10 @@ class FirewallServiceTest extends TestCase
|
||||
->willReturnArgument(0);
|
||||
$event = new \KTXC\Security\Event\SecurityEvent(
|
||||
\KTXC\Security\Event\SecurityEvent::FIREWALL_SETTINGS_UPDATED,
|
||||
['changeReason' => 'Tighten controls']
|
||||
['changeReason' => 'Tighten controls'],
|
||||
tenantId: 'tenant-a',
|
||||
identityId: 'operator',
|
||||
);
|
||||
$event->setTenantId('tenant-a')->setIdentityId('operator');
|
||||
|
||||
$this->service->logSecurityEvent($event);
|
||||
}
|
||||
@@ -376,8 +377,10 @@ class FirewallServiceTest extends TestCase
|
||||
->willReturn(4);
|
||||
$this->events->expects($this->never())->method('dispatch');
|
||||
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure('203.0.113.10');
|
||||
$event->setTenantId('tenant-a');
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure(
|
||||
'203.0.113.10',
|
||||
tenantId: 'tenant-a',
|
||||
);
|
||||
$this->service->handleAuthFailure($event);
|
||||
|
||||
self::assertSame(8, $this->currentConfiguration->firewall()->maxAuthFailures());
|
||||
@@ -400,8 +403,10 @@ class FirewallServiceTest extends TestCase
|
||||
->with('tenant-a', '203.0.113.10', 300)
|
||||
->willReturn(0);
|
||||
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure('203.0.113.10');
|
||||
$event->setTenantId('tenant-a');
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure(
|
||||
'203.0.113.10',
|
||||
tenantId: 'tenant-a',
|
||||
);
|
||||
$this->service->handleAuthFailure($event);
|
||||
}
|
||||
|
||||
@@ -454,8 +459,10 @@ class FirewallServiceTest extends TestCase
|
||||
}
|
||||
});
|
||||
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure('203.0.113.10');
|
||||
$event->setTenantId('tenant-event');
|
||||
$event = \KTXC\Security\Event\SecurityEvent::authFailure(
|
||||
'203.0.113.10',
|
||||
tenantId: 'tenant-event',
|
||||
);
|
||||
$this->service->handleAuthFailure($event);
|
||||
|
||||
self::assertSame(['tenant-event', 'tenant-event', 'tenant-event'], $publishedTenants);
|
||||
|
||||
Reference in New Issue
Block a user