From ec561ef0a10d910031441e9018b67eeaaa95083a Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 10 Dec 2025 11:49:15 +0100 Subject: [PATCH] Test for action service --- tests/Service/ActionServiceTest.php | 193 ++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tests/Service/ActionServiceTest.php diff --git a/tests/Service/ActionServiceTest.php b/tests/Service/ActionServiceTest.php new file mode 100644 index 0000000..3f6ef0e --- /dev/null +++ b/tests/Service/ActionServiceTest.php @@ -0,0 +1,193 @@ +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'); + } +} \ No newline at end of file