. */ namespace SP\Tests\Core\Acl; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\MockObject\MockObject; use SP\Core\Acl\Actions; use SP\Core\Context\ContextException; use SP\Domain\Core\Acl\ActionNotFoundException; use SP\Domain\Core\Models\Action; use SP\Domain\Storage\Ports\FileCacheService; use SP\Domain\Storage\Ports\XmlFileStorageService; use SP\Infrastructure\File\FileException; use SP\Tests\UnitaryTestCase; use function PHPUnit\Framework\once; /** * Class ActionsTest */ #[Group('unitary')] class ActionsTest extends UnitaryTestCase { private FileCacheService|MockObject $fileCache; private XmlFileStorageService|MockObject $xmlFileStorage; private Actions $actions; public static function expirationDataProvider(): array { return [ [false, true], [true, false], [true, true] ]; } /** * @throws FileException * @throws Exception * @throws ActionNotFoundException */ #[DataProvider('expirationDataProvider')] public function testResetAndExpired(bool $expiredCache, bool $expiredDate) { $fileTime = self::$faker->randomNumber(); $this->fileCache ->expects(self::once()) ->method('isExpired') ->with(Actions::CACHE_EXPIRE) ->willReturn($expiredCache); if (!$expiredCache) { $this->xmlFileStorage ->expects(self::once()) ->method('getFileTime') ->willReturn($fileTime); $this->fileCache ->expects(self::once()) ->method('isExpiredDate') ->with($fileTime) ->willReturn($expiredDate); } $actionsMapped = $this->checkLoadAndSave(); $this->actions->reset(); $action = current($actionsMapped); $out = $this->actions->getActionById(array_key_first($actionsMapped)); self::assertEquals($action, $out); } /** * @return Action[] */ private function checkLoadAndSave(): array { $actions = $this->getActions(); $this->xmlFileStorage ->expects(once()) ->method('load') ->with('actions') ->willReturn($actions); $actionsMapped = array_map( static fn(array $a) => new Action($a['id'], $a['name'], $a['text'], $a['route']), $actions ); $this->fileCache ->expects(once()) ->method('save') ->with($actionsMapped); return $actionsMapped; } /** * @return array|array[] */ private function getActions(): array { $actionsId = array_map(static fn() => self::$faker->unixTime, range(0, 10)); $actions = array_map( static fn(int $id) => [ 'id' => $id, 'name' => self::$faker->colorName, 'text' => self::$faker->city, 'route' => self::$faker->url ], $actionsId ); return array_combine($actionsId, $actions); } /** * @throws FileException * @throws Exception * @throws ActionNotFoundException */ public function testResetAndNotExpired() { $this->fileCache ->expects(self::once()) ->method('isExpired') ->with(Actions::CACHE_EXPIRE) ->willReturn(false); $actions = $this->getActions(); $actionsMapped = array_map( static fn(array $a) => new Action($a['id'], $a['name'], $a['text'], $a['route']), $actions ); $this->fileCache ->expects(self::once()) ->method('load') ->willReturn($actionsMapped); $this->actions->reset(); $action = current($actionsMapped); $out = $this->actions->getActionById(array_key_first($actions)); self::assertEquals($action, $out); } /** * @throws ActionNotFoundException * @throws FileException */ public function testResetWithCacheFileException() { $this->fileCache ->expects(self::once()) ->method('isExpired') ->with(Actions::CACHE_EXPIRE) ->willThrowException(new FileException('TestException')); $actionsMapped = $this->checkLoadAndSave(); $this->actions->reset(); $action = current($actionsMapped); $out = $this->actions->getActionById(array_key_first($actionsMapped)); self::assertEquals($action, $out); } /** * @throws ActionNotFoundException * @throws FileException * @throws Exception */ public function testResetWithXmlFileException() { $this->fileCache ->expects(self::once()) ->method('isExpired') ->with(Actions::CACHE_EXPIRE) ->willReturn(false); $this->xmlFileStorage ->expects(self::once()) ->method('getFileTime') ->willThrowException(new FileException('TestException')); $actionsMapped = $this->checkLoadAndSave(); $this->actions->reset(); $action = current($actionsMapped); $out = $this->actions->getActionById(array_key_first($actionsMapped)); self::assertEquals($action, $out); } /** * @throws FileException */ public function testResetWithSaveException() { $this->fileCache ->expects(self::once()) ->method('isExpired') ->with(Actions::CACHE_EXPIRE) ->willReturn(true); $actions = $this->getActions(); $this->xmlFileStorage ->expects(once()) ->method('load') ->with('actions') ->willReturn($actions); $actionsMapped = array_map( static fn(array $a) => new Action($a['id'], $a['name'], $a['text'], $a['route']), $actions ); $this->fileCache ->expects(once()) ->method('save') ->with($actionsMapped) ->willThrowException(new FileException('TestException')); $this->actions->reset(); } /** * @throws ActionNotFoundException * @throws FileException */ public function testGetActionById() { $actionsMapped = array_map( static fn(array $a) => new Action($a['id'], $a['name'], $a['text'], $a['route']), $this->getActions() ); $this->fileCache ->expects(self::once()) ->method('load') ->willReturn($actionsMapped); $actions = new Actions($this->fileCache, $this->xmlFileStorage); $out = $actions->getActionById(array_key_first($actionsMapped)); self::assertEquals(current($actionsMapped), $out); } /** * @throws ActionNotFoundException */ public function testGetActionByIdWithNotFound() { $this->expectException(ActionNotFoundException::class); $this->expectExceptionMessage('Action not found'); $this->actions->getActionById(self::$faker->randomNumber()); } /** * @throws ContextException * @throws Exception * @throws FileException */ protected function setUp(): void { parent::setUp(); $this->fileCache = $this->createMock(FileCacheService::class); $this->xmlFileStorage = $this->createMock(XmlFileStorageService::class); $this->actions = new Actions($this->fileCache, $this->xmlFileStorage); } }