Test for action service

This commit is contained in:
Charles 2025-12-10 11:49:15 +01:00
parent eeb82277f7
commit ec561ef0a1
1 changed files with 193 additions and 0 deletions

View File

@ -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');
}
}