Test for action service
This commit is contained in:
parent
eeb82277f7
commit
ec561ef0a1
|
|
@ -0,0 +1,193 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Service;
|
||||||
|
|
||||||
|
use App\Entity\Actions;
|
||||||
|
use App\Entity\Organizations;
|
||||||
|
use App\Entity\User;
|
||||||
|
use App\Service\ActionService;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class ActionServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
private ActionService $service;
|
||||||
|
private MockObject|EntityManagerInterface $entityManager;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
||||||
|
$this->service = new ActionService($this->entityManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to set private ID properties on entities without setters
|
||||||
|
*/
|
||||||
|
private function setEntityId(object $entity, int $id): void
|
||||||
|
{
|
||||||
|
$reflection = new \ReflectionClass($entity);
|
||||||
|
if ($reflection->hasProperty('id')) {
|
||||||
|
$property = $reflection->getProperty('id');
|
||||||
|
// $property->setAccessible(true); // Uncomment for PHP < 8.1
|
||||||
|
$property->setValue($entity, $id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// TEST: getActivityColor
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
public function testGetActivityColorRecent(): void
|
||||||
|
{
|
||||||
|
// Less than 15 minutes ago
|
||||||
|
$date = new \DateTimeImmutable('-10 minutes');
|
||||||
|
$color = $this->service->getActivityColor($date);
|
||||||
|
$this->assertEquals('#086572', $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetActivityColorMedium(): void
|
||||||
|
{
|
||||||
|
// Between 15 and 60 minutes ago
|
||||||
|
$date = new \DateTimeImmutable('-30 minutes');
|
||||||
|
$color = $this->service->getActivityColor($date);
|
||||||
|
$this->assertEquals('#247208', $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetActivityColorOld(): void
|
||||||
|
{
|
||||||
|
// Older than 1 hour
|
||||||
|
$date = new \DateTimeImmutable('-2 hours');
|
||||||
|
$color = $this->service->getActivityColor($date);
|
||||||
|
$this->assertEquals('#cc664c', $color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// TEST: formatActivities
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
public function testFormatActivities(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$org = new Organizations();
|
||||||
|
|
||||||
|
$action1 = new Actions();
|
||||||
|
$action1->setDate(new \DateTimeImmutable('-5 minutes')); // Recent
|
||||||
|
$action1->setActionType('LOGIN');
|
||||||
|
$action1->setUsers($user);
|
||||||
|
$action1->setOrganization($org);
|
||||||
|
$action1->setDescription('User logged in');
|
||||||
|
|
||||||
|
$action2 = new Actions();
|
||||||
|
$action2->setDate(new \DateTimeImmutable('-2 hours')); // Old
|
||||||
|
$action2->setActionType('LOGOUT');
|
||||||
|
|
||||||
|
$activities = [$action1, $action2];
|
||||||
|
|
||||||
|
$result = $this->service->formatActivities($activities);
|
||||||
|
|
||||||
|
$this->assertCount(2, $result);
|
||||||
|
|
||||||
|
// Check first activity (Recent)
|
||||||
|
$this->assertEquals('#086572', $result[0]['color']);
|
||||||
|
$this->assertEquals('LOGIN', $result[0]['actionType']);
|
||||||
|
$this->assertSame($user, $result[0]['users']);
|
||||||
|
$this->assertSame($org, $result[0]['organization']);
|
||||||
|
|
||||||
|
// Check second activity (Old)
|
||||||
|
$this->assertEquals('#cc664c', $result[1]['color']);
|
||||||
|
$this->assertEquals('LOGOUT', $result[1]['actionType']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// TEST: createAction
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
public function testCreateActionBasic(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setEmail('user@test.com');
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->once())
|
||||||
|
->method('persist')
|
||||||
|
->with($this->callback(function (Actions $action) use ($user) {
|
||||||
|
return $action->getActionType() === 'LOGIN'
|
||||||
|
&& $action->getUsers() === $user
|
||||||
|
&& $action->getOrganization() === null
|
||||||
|
&& $action->getDescription() === null;
|
||||||
|
}));
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->once())->method('flush');
|
||||||
|
|
||||||
|
$this->service->createAction('LOGIN', $user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateActionWithOrganizationAndTarget(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setEmail('admin@test.com');
|
||||||
|
|
||||||
|
$org = new Organizations();
|
||||||
|
$this->setEntityId($org, 99);
|
||||||
|
|
||||||
|
// Expect persist with full details
|
||||||
|
$this->entityManager->expects($this->once())
|
||||||
|
->method('persist')
|
||||||
|
->with($this->callback(function (Actions $action) use ($user, $org) {
|
||||||
|
return $action->getActionType() === 'UPDATE'
|
||||||
|
&& $action->getUsers() === $user
|
||||||
|
&& $action->getOrganization() === $org
|
||||||
|
// Check description generated by descriptionAction
|
||||||
|
&& str_contains($action->getDescription(), 'UPDATE by admin@test.com onto Settings');
|
||||||
|
}));
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->once())->method('flush');
|
||||||
|
|
||||||
|
$this->service->createAction('UPDATE', $user, $org, 'Settings');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// TEST: descriptionAction
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
public function testDescriptionActionSuccess(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->setEmail('jane@doe.com');
|
||||||
|
|
||||||
|
$action = new Actions();
|
||||||
|
$action->setActionType('DELETE');
|
||||||
|
$action->setUsers($user);
|
||||||
|
|
||||||
|
// Pass by reference
|
||||||
|
$this->service->descriptionAction($action, 'Document.pdf');
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
'DELETE by jane@doe.com onto Document.pdf',
|
||||||
|
$action->getDescription()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDescriptionActionThrowsIfNoUser(): void
|
||||||
|
{
|
||||||
|
$action = new Actions();
|
||||||
|
$action->setActionType('DELETE');
|
||||||
|
// No user set
|
||||||
|
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Action must have a user set');
|
||||||
|
|
||||||
|
$this->service->descriptionAction($action, 'Target');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDescriptionActionThrowsIfInvalidType(): void
|
||||||
|
{
|
||||||
|
$invalidObject = new \stdClass();
|
||||||
|
|
||||||
|
$this->expectException(\InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionMessage('Action must be an instance of Actions');
|
||||||
|
|
||||||
|
// Pass an object that is NOT an instance of Actions entity
|
||||||
|
$this->service->descriptionAction($invalidObject, 'Target');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue