From a79705679d7f24a84a2623b18350df8b76880aed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20D?= Date: Mon, 11 Mar 2024 17:40:09 +0100 Subject: [PATCH] chore(tests): UT for Eventlog repository MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rubén D --- .../Controllers/Eventlog/ClearController.php | 8 +- .../Controllers/Eventlog/SearchController.php | 14 +- .../SecurityManager/IndexController.php | 20 +- lib/SP/DataModel/EventlogData.php | 188 ------------------ lib/SP/Domain/Security/Models/Eventlog.php | 82 ++++++++ ...ryInterface.php => EventlogRepository.php} | 18 +- ...rviceInterface.php => EventlogService.php} | 8 +- .../{EventlogService.php => Eventlog.php} | 32 ++- .../Security/Repositories/Eventlog.php | 116 +++++++++++ .../Repositories/EventlogBaseRepository.php | 123 ------------ lib/SP/Providers/Log/DatabaseLogHandler.php | 14 +- tests/SPT/Generators/EventlogGenerator.php | 52 +++++ .../Security/Repositories/EventlogTest.php | 178 +++++++++++++++++ 13 files changed, 481 insertions(+), 372 deletions(-) delete mode 100644 lib/SP/DataModel/EventlogData.php create mode 100644 lib/SP/Domain/Security/Models/Eventlog.php rename lib/SP/Domain/Security/Ports/{EventlogRepositoryInterface.php => EventlogRepository.php} (80%) rename lib/SP/Domain/Security/Ports/{EventlogServiceInterface.php => EventlogService.php} (88%) rename lib/SP/Domain/Security/Services/{EventlogService.php => Eventlog.php} (65%) create mode 100644 lib/SP/Infrastructure/Security/Repositories/Eventlog.php delete mode 100644 lib/SP/Infrastructure/Security/Repositories/EventlogBaseRepository.php create mode 100644 tests/SPT/Generators/EventlogGenerator.php create mode 100644 tests/SPT/Infrastructure/Security/Repositories/EventlogTest.php diff --git a/app/modules/web/Controllers/Eventlog/ClearController.php b/app/modules/web/Controllers/Eventlog/ClearController.php index 2c80a9ef..9c083113 100644 --- a/app/modules/web/Controllers/Eventlog/ClearController.php +++ b/app/modules/web/Controllers/Eventlog/ClearController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -32,7 +32,7 @@ use SP\Core\Events\Event; use SP\Core\Events\EventMessage; use SP\Domain\Auth\Services\AuthException; use SP\Domain\Core\Exceptions\SessionTimeout; -use SP\Domain\Security\Ports\EventlogServiceInterface; +use SP\Domain\Security\Ports\EventlogService; use SP\Http\JsonMessage; use SP\Modules\Web\Controllers\ControllerBase; use SP\Modules\Web\Controllers\Traits\JsonTrait; @@ -45,7 +45,7 @@ final class ClearController extends ControllerBase { use JsonTrait; - private EventlogServiceInterface $eventlogService; + private EventlogService $eventlogService; /** * @throws SessionTimeout @@ -55,7 +55,7 @@ final class ClearController extends ControllerBase public function __construct( Application $application, WebControllerHelper $webControllerHelper, - EventlogServiceInterface $eventlogService + EventlogService $eventlogService ) { parent::__construct($application, $webControllerHelper); diff --git a/app/modules/web/Controllers/Eventlog/SearchController.php b/app/modules/web/Controllers/Eventlog/SearchController.php index 4d8b6e95..10b6b334 100644 --- a/app/modules/web/Controllers/Eventlog/SearchController.php +++ b/app/modules/web/Controllers/Eventlog/SearchController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -30,7 +30,7 @@ use SP\Core\Application; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Security\Ports\EventlogServiceInterface; +use SP\Domain\Security\Ports\EventlogService; use SP\Html\DataGrid\DataGridInterface; use SP\Http\JsonMessage; use SP\Modules\Web\Controllers\ControllerBase; @@ -47,14 +47,14 @@ final class SearchController extends ControllerBase use ItemTrait; use JsonTrait; - private EventlogGrid $eventlogGrid; - private EventlogServiceInterface $eventlogService; + private EventlogGrid $eventlogGrid; + private EventlogService $eventlogService; public function __construct( - Application $application, + Application $application, WebControllerHelper $webControllerHelper, - EventlogServiceInterface $eventlogService, - EventlogGrid $eventlogGrid + EventlogService $eventlogService, + EventlogGrid $eventlogGrid ) { parent::__construct($application, $webControllerHelper); diff --git a/app/modules/web/Controllers/SecurityManager/IndexController.php b/app/modules/web/Controllers/SecurityManager/IndexController.php index 2c451b95..97643bb0 100644 --- a/app/modules/web/Controllers/SecurityManager/IndexController.php +++ b/app/modules/web/Controllers/SecurityManager/IndexController.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -31,7 +31,7 @@ use SP\DataModel\ItemSearchData; use SP\Domain\Core\Acl\AclActionsInterface; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Security\Ports\EventlogServiceInterface; +use SP\Domain\Security\Ports\EventlogService; use SP\Domain\Security\Ports\TrackServiceInterface; use SP\Html\DataGrid\DataGridTab; use SP\Modules\Web\Controllers\ControllerBase; @@ -50,17 +50,17 @@ final class IndexController extends ControllerBase protected ItemSearchData $itemSearchData; protected TabsGridHelper $tabsGridHelper; private EventlogGrid $eventlogGrid; - private TrackGrid $trackGrid; - private EventlogServiceInterface $eventlogService; - private TrackServiceInterface $trackService; + private TrackGrid $trackGrid; + private EventlogService $eventlogService; + private TrackServiceInterface $trackService; public function __construct( - Application $application, + Application $application, WebControllerHelper $webControllerHelper, - TabsGridHelper $tabsGridHelper, - EventlogGrid $eventlogGrid, - TrackGrid $trackGrid, - EventlogServiceInterface $eventlogService, + TabsGridHelper $tabsGridHelper, + EventlogGrid $eventlogGrid, + TrackGrid $trackGrid, + EventlogService $eventlogService, TrackServiceInterface $trackService ) { parent::__construct($application, $webControllerHelper); diff --git a/lib/SP/DataModel/EventlogData.php b/lib/SP/DataModel/EventlogData.php deleted file mode 100644 index 339200e9..00000000 --- a/lib/SP/DataModel/EventlogData.php +++ /dev/null @@ -1,188 +0,0 @@ -. - */ - -namespace SP\DataModel; - -use SP\Domain\Common\Models\Model; - -/** - * Class EventlogData - * - * @package SP\DataModel - */ -class EventlogData extends Model -{ - /** - * @var int - */ - public $id; - /** - * @var int - */ - public $date; - /** - * @var string - */ - public $login; - /** - * @var int - */ - public $userId; - /** - * @var string - */ - public $ipAddress; - /** - * @var string - */ - public $action; - /** - * @var string - */ - public $description; - /** - * @var string - */ - public $level; - - /** - * @return int - */ - public function getId() - { - return $this->id; - } - - /** - * @return int - */ - public function getDate() - { - return $this->date; - } - - /** - * @param int $date - */ - public function setDate($date) - { - $this->date = $date; - } - - /** - * @return string - */ - public function getLogin() - { - return $this->login; - } - - /** - * @param string $login - */ - public function setLogin($login) - { - $this->login = $login; - } - - /** - * @return int - */ - public function getUserId() - { - return $this->userId; - } - - /** - * @param int $userId - */ - public function setUserId($userId) - { - $this->userId = $userId; - } - - /** - * @return string - */ - public function getIpAddress() - { - return $this->ipAddress; - } - - /** - * @param string $ipAddress - */ - public function setIpAddress($ipAddress) - { - $this->ipAddress = $ipAddress; - } - - /** - * @return string - */ - public function getAction() - { - return $this->action; - } - - /** - * @param string $action - */ - public function setAction($action) - { - $this->action = $action; - } - - /** - * @return string - */ - public function getDescription() - { - return $this->description; - } - - /** - * @param string $description - */ - public function setDescription($description) - { - $this->description = $description; - } - - /** - * @return string - */ - public function getLevel() - { - return $this->level; - } - - /** - * @param string $level - */ - public function setLevel($level) - { - $this->level = $level; - } -} diff --git a/lib/SP/Domain/Security/Models/Eventlog.php b/lib/SP/Domain/Security/Models/Eventlog.php new file mode 100644 index 00000000..09b951c6 --- /dev/null +++ b/lib/SP/Domain/Security/Models/Eventlog.php @@ -0,0 +1,82 @@ +. + */ + +namespace SP\Domain\Security\Models; + +use SP\Domain\Common\Models\Model; + +/** + * Class Eventlog + */ +class Eventlog extends Model +{ + protected ?int $id = null; + protected ?int $date = null; + protected ?string $login = null; + protected ?int $userId = null; + protected ?string $ipAddress = null; + protected ?string $action = null; + protected ?string $description = null; + protected ?string $level = null; + + public function getId(): ?int + { + return $this->id; + } + + public function getDate(): ?int + { + return $this->date; + } + + public function getLogin(): ?string + { + return $this->login; + } + + public function getUserId(): ?int + { + return $this->userId; + } + + public function getIpAddress(): ?string + { + return $this->ipAddress; + } + + public function getAction(): ?string + { + return $this->action; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function getLevel(): ?string + { + return $this->level; + } +} diff --git a/lib/SP/Domain/Security/Ports/EventlogRepositoryInterface.php b/lib/SP/Domain/Security/Ports/EventlogRepository.php similarity index 80% rename from lib/SP/Domain/Security/Ports/EventlogRepositoryInterface.php rename to lib/SP/Domain/Security/Ports/EventlogRepository.php index 28411f3b..f6191dd3 100644 --- a/lib/SP/Domain/Security/Ports/EventlogRepositoryInterface.php +++ b/lib/SP/Domain/Security/Ports/EventlogRepository.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -24,18 +24,18 @@ namespace SP\Domain\Security\Ports; -use SP\DataModel\EventlogData; use SP\DataModel\ItemSearchData; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Security\Models\Eventlog as EventlogModel; use SP\Infrastructure\Database\QueryResult; /** * Class EventlogRepository * - * @package SP\Infrastructure\Security\Repositories + * @template T of EventlogModel */ -interface EventlogRepositoryInterface +interface EventlogRepository { /** * Clears the event log @@ -49,20 +49,20 @@ interface EventlogRepositoryInterface /** * Searches for items by a given filter * - * @param ItemSearchData $itemSearchData + * @param ItemSearchData $itemSearchData * - * @return QueryResult + * @return QueryResult * @throws ConstraintException * @throws QueryException */ public function search(ItemSearchData $itemSearchData): QueryResult; /** - * @param EventlogData $eventlogData + * @param EventlogModel $eventlog * - * @return int + * @return QueryResult * @throws ConstraintException * @throws QueryException */ - public function create(EventlogData $eventlogData): int; + public function create(EventlogModel $eventlog): QueryResult; } diff --git a/lib/SP/Domain/Security/Ports/EventlogServiceInterface.php b/lib/SP/Domain/Security/Ports/EventlogService.php similarity index 88% rename from lib/SP/Domain/Security/Ports/EventlogServiceInterface.php rename to lib/SP/Domain/Security/Ports/EventlogService.php index 51c20eaa..9eecf78a 100644 --- a/lib/SP/Domain/Security/Ports/EventlogServiceInterface.php +++ b/lib/SP/Domain/Security/Ports/EventlogService.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -24,11 +24,11 @@ namespace SP\Domain\Security\Ports; -use SP\DataModel\EventlogData; use SP\DataModel\ItemSearchData; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; +use SP\Domain\Security\Models\Eventlog; use SP\Infrastructure\Database\QueryResult; /** @@ -36,7 +36,7 @@ use SP\Infrastructure\Database\QueryResult; * * @package SP\Domain\Common\Services\EventLog */ -interface EventlogServiceInterface +interface EventlogService { /** * @throws ConstraintException @@ -55,5 +55,5 @@ interface EventlogServiceInterface * @throws ConstraintException * @throws QueryException */ - public function create(EventlogData $eventlogData): int; + public function create(Eventlog $eventlogData): int; } diff --git a/lib/SP/Domain/Security/Services/EventlogService.php b/lib/SP/Domain/Security/Services/Eventlog.php similarity index 65% rename from lib/SP/Domain/Security/Services/EventlogService.php rename to lib/SP/Domain/Security/Services/Eventlog.php index a03b488d..ecc3f256 100644 --- a/lib/SP/Domain/Security/Services/EventlogService.php +++ b/lib/SP/Domain/Security/Services/Eventlog.php @@ -25,37 +25,29 @@ namespace SP\Domain\Security\Services; use SP\Core\Application; -use SP\DataModel\EventlogData; use SP\DataModel\ItemSearchData; use SP\Domain\Common\Services\Service; use SP\Domain\Core\Exceptions\ConstraintException; use SP\Domain\Core\Exceptions\QueryException; use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Http\RequestInterface; -use SP\Domain\Security\Ports\EventlogRepositoryInterface; -use SP\Domain\Security\Ports\EventlogServiceInterface; +use SP\Domain\Security\Models\Eventlog as EventlogModel; +use SP\Domain\Security\Ports\EventlogRepository; +use SP\Domain\Security\Ports\EventlogService; use SP\Infrastructure\Database\QueryResult; -use SP\Infrastructure\Security\Repositories\EventlogBaseRepository; /** * Class EventlogService - * - * @package SP\Domain\Common\Services\EventLog */ -final class EventlogService extends Service implements EventlogServiceInterface +final class Eventlog extends Service implements EventlogService { - protected EventlogBaseRepository $eventLogRepository; - protected RequestInterface $request; public function __construct( - Application $application, - EventlogRepositoryInterface $eventLogRepository, - RequestInterface $request + Application $application, + private readonly EventlogRepository $eventLogRepository, + private readonly RequestInterface $request ) { parent::__construct($application); - - $this->eventLogRepository = $eventLogRepository; - $this->request = $request; } /** @@ -81,14 +73,14 @@ final class EventlogService extends Service implements EventlogServiceInterface * @throws ConstraintException * @throws QueryException */ - public function create(EventlogData $eventlogData): int + public function create(EventlogModel $eventlog): int { $userData = $this->context->getUserData(); - $eventlogData->setUserId($userData->getId()); - $eventlogData->setLogin($userData->getLogin() ?: '-'); - $eventlogData->setIpAddress($this->request->getClientAddress()); + $eventlog->setUserId($userData->getId()); + $eventlog->setLogin($userData->getLogin() ?: '-'); + $eventlog->setIpAddress($this->request->getClientAddress()); - return $this->eventLogRepository->create($eventlogData); + return $this->eventLogRepository->create($eventlog); } } diff --git a/lib/SP/Infrastructure/Security/Repositories/Eventlog.php b/lib/SP/Infrastructure/Security/Repositories/Eventlog.php new file mode 100644 index 00000000..6170a262 --- /dev/null +++ b/lib/SP/Infrastructure/Security/Repositories/Eventlog.php @@ -0,0 +1,116 @@ +. + */ + +namespace SP\Infrastructure\Security\Repositories; + +use SP\DataModel\ItemSearchData; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Security\Models\Eventlog as EventlogModel; +use SP\Domain\Security\Ports\EventlogRepository; +use SP\Infrastructure\Common\Repositories\BaseRepository; +use SP\Infrastructure\Database\QueryData; +use SP\Infrastructure\Database\QueryResult; + +use function SP\__u; + +/** + * Class Eventlog + * + * @template T of EventlogModel + */ +final class Eventlog extends BaseRepository implements EventlogRepository +{ + public const TABLE = 'EventLog'; + + /** + * Clears the event log + * + * @return bool con el resultado + * @throws QueryException + * @throws ConstraintException + */ + public function clear(): bool + { + $query = $this->queryFactory + ->newDelete() + ->from(self::TABLE); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while clearing the event log out')); + + return $this->db->doQuery($queryData)->getAffectedNumRows() > 0; + } + + /** + * Searches for items by a given filter + * + * @param ItemSearchData $itemSearchData + * + * @return QueryResult + */ + public function search(ItemSearchData $itemSearchData): QueryResult + { + $query = $this->queryFactory + ->newSelect() + ->from(self::TABLE) + ->cols(EventlogModel::getCols(['date'])) + ->cols(['FROM_UNIXTIME(date)' => 'date']) + ->orderBy(['id DESC']) + ->limit($itemSearchData->getLimitCount()) + ->offset($itemSearchData->getLimitStart()); + + if (!empty($itemSearchData->getSeachString())) { + $query->where('action LIKE :action OR ipAddress LIKE :ipAddress OR description LIKE :description'); + + $search = '%' . $itemSearchData->getSeachString() . '%'; + + $query->bindValues(['action' => $search, 'ipAddress' => $search, 'description' => $search]); + } + + $queryData = QueryData::build($query)->setMapClassName(EventlogModel::class); + + return $this->db->doSelect($queryData, true); + } + + + /** + * @param EventlogModel $eventlog + * + * @return QueryResult + * @throws ConstraintException + * @throws QueryException + */ + public function create(EventlogModel $eventlog): QueryResult + { + $query = $this->queryFactory + ->newInsert() + ->into(self::TABLE) + ->cols($eventlog->toArray(null, ['id', 'date'])) + ->set('date', 'UNIX_TIMESTAMP()'); + + $queryData = QueryData::build($query)->setOnErrorMessage(__u('Error while adding the plugin')); + + return $this->db->doQuery($queryData); + } +} diff --git a/lib/SP/Infrastructure/Security/Repositories/EventlogBaseRepository.php b/lib/SP/Infrastructure/Security/Repositories/EventlogBaseRepository.php deleted file mode 100644 index c24a6a9d..00000000 --- a/lib/SP/Infrastructure/Security/Repositories/EventlogBaseRepository.php +++ /dev/null @@ -1,123 +0,0 @@ -. - */ - -namespace SP\Infrastructure\Security\Repositories; - -use SP\DataModel\EventlogData; -use SP\DataModel\ItemSearchData; -use SP\Domain\Core\Exceptions\ConstraintException; -use SP\Domain\Core\Exceptions\QueryException; -use SP\Domain\Security\Ports\EventlogRepositoryInterface; -use SP\Infrastructure\Common\Repositories\BaseRepository; -use SP\Infrastructure\Database\QueryData; -use SP\Infrastructure\Database\QueryResult; - -/** - * Class EventlogRepository - * - * @package SP\Infrastructure\Security\Repositories - */ -final class EventlogBaseRepository extends BaseRepository implements EventlogRepositoryInterface -{ - /** - * Clears the event log - * - * @return bool con el resultado - * @throws QueryException - * @throws ConstraintException - */ - public function clear(): bool - { - $queryData = new QueryData(); - $queryData->setQuery('TRUNCATE TABLE EventLog'); - $queryData->setOnErrorMessage(__u('Error while clearing the event log out')); - - return $this->db->doQuery($queryData)->getAffectedNumRows() > 0; - } - - /** - * Searches for items by a given filter - * - * @param ItemSearchData $itemSearchData - * - * @return QueryResult - * @throws ConstraintException - * @throws QueryException - */ - public function search(ItemSearchData $itemSearchData): QueryResult - { - $queryData = new QueryData(); - $queryData->setSelect('id, FROM_UNIXTIME(date) AS date, action, level, login, ipAddress, description'); - $queryData->setFrom('EventLog'); - $queryData->setOrder('id DESC'); - - if (!empty($itemSearchData->getSeachString())) { - $queryData->setWhere('action LIKE ? OR login LIKE ? OR ipAddress LIKE ? OR description LIKE ?'); - - $search = '%'.$itemSearchData->getSeachString().'%'; - $queryData->setParams(array_fill(0, 4, $search)); - } - - $queryData->setLimit( - '?,?', - [$itemSearchData->getLimitStart(), $itemSearchData->getLimitCount()] - ); - - return $this->db->doSelect($queryData, true); - } - - - /** - * @param EventlogData $eventlogData - * - * @return int - * @throws ConstraintException - * @throws QueryException - */ - public function create(EventlogData $eventlogData): int - { - $sql = 'INSERT INTO EventLog SET - `date` = UNIX_TIMESTAMP(), - login = ?, - userId = ?, - ipAddress = ?, - `action` = ?, - description = ?, - `level` = ?'; - - $queryData = new QueryData(); - $queryData->setQuery($sql); - $queryData->setParams([ - $eventlogData->getLogin(), - $eventlogData->getUserId(), - $eventlogData->getIpAddress(), - $eventlogData->getAction(), - $eventlogData->getDescription(), - $eventlogData->getLevel(), - ] - ); - - return $this->db->doQuery($queryData)->getLastId(); - } -} diff --git a/lib/SP/Providers/Log/DatabaseLogHandler.php b/lib/SP/Providers/Log/DatabaseLogHandler.php index 9bfe7704..0e94c789 100644 --- a/lib/SP/Providers/Log/DatabaseLogHandler.php +++ b/lib/SP/Providers/Log/DatabaseLogHandler.php @@ -4,7 +4,7 @@ * * @author nuxsmin * @link https://syspass.org - * @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org + * @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. * @@ -27,12 +27,12 @@ namespace SP\Providers\Log; use Exception; use SP\Core\Application; use SP\Core\Events\Event; -use SP\DataModel\EventlogData; use SP\Domain\Core\Events\EventReceiver; use SP\Domain\Core\Exceptions\InvalidClassException; use SP\Domain\Core\Exceptions\SPException; use SP\Domain\Core\LanguageInterface; -use SP\Domain\Security\Ports\EventlogServiceInterface; +use SP\Domain\Security\Models\Eventlog; +use SP\Domain\Security\Ports\EventlogService; use SP\Providers\EventsTrait; use SP\Providers\Provider; @@ -51,9 +51,9 @@ final class DatabaseLogHandler extends Provider implements EventReceiver private string $events; public function __construct( - Application $application, - private readonly EventlogServiceInterface $eventlogService, - private readonly LanguageInterface $language + Application $application, + private readonly EventlogService $eventlogService, + private readonly LanguageInterface $language ) { parent::__construct($application); } @@ -75,7 +75,7 @@ final class DatabaseLogHandler extends Provider implements EventReceiver $this->language->setAppLocales(); - $eventlogData = new EventlogData(); + $eventlogData = new Eventlog(); $eventlogData->setAction($eventType); $eventlogData->setLevel('INFO'); diff --git a/tests/SPT/Generators/EventlogGenerator.php b/tests/SPT/Generators/EventlogGenerator.php new file mode 100644 index 00000000..f17a649e --- /dev/null +++ b/tests/SPT/Generators/EventlogGenerator.php @@ -0,0 +1,52 @@ +. + */ + +namespace SPT\Generators; + +use SP\Domain\Security\Models\Eventlog; + +/** + * Class EventlogGenerator + */ +final class EventlogGenerator extends DataGenerator +{ + public function buildEventlog(): Eventlog + { + return new Eventlog($this->eventlogProperties()); + } + + private function eventlogProperties(): array + { + return [ + 'id' => $this->faker->randomNumber(3), + 'date' => $this->faker->unixTime(), + 'login' => $this->faker->colorName(), + 'userId' => $this->faker->randomNumber(3), + 'ipAddress' => $this->faker->ipv4(), + 'action' => $this->faker->jobTitle(), + 'description' => $this->faker->text(), + 'level' => $this->faker->colorName() + ]; + } +} diff --git a/tests/SPT/Infrastructure/Security/Repositories/EventlogTest.php b/tests/SPT/Infrastructure/Security/Repositories/EventlogTest.php new file mode 100644 index 00000000..57f46f4f --- /dev/null +++ b/tests/SPT/Infrastructure/Security/Repositories/EventlogTest.php @@ -0,0 +1,178 @@ +. + */ + +namespace SPT\Infrastructure\Security\Repositories; + +use Aura\SqlQuery\Common\DeleteInterface; +use Aura\SqlQuery\Common\InsertInterface; +use Aura\SqlQuery\Common\SelectInterface; +use Aura\SqlQuery\QueryFactory; +use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Constraint\Callback; +use PHPUnit\Framework\MockObject\MockObject; +use SP\DataModel\ItemSearchData; +use SP\Domain\Core\Exceptions\ConstraintException; +use SP\Domain\Core\Exceptions\QueryException; +use SP\Domain\Security\Models\Eventlog as EventlogModel; +use SP\Infrastructure\Database\DatabaseInterface; +use SP\Infrastructure\Database\QueryData; +use SP\Infrastructure\Database\QueryResult; +use SP\Infrastructure\Security\Repositories\Eventlog; +use SPT\Generators\EventlogGenerator; +use SPT\UnitaryTestCase; + +/** + * Class EventlogTest + */ +#[Group('unitary')] +class EventlogTest extends UnitaryTestCase +{ + + private Eventlog $eventlog; + private DatabaseInterface|MockObject $database; + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testClear() + { + $callback = new Callback( + static function (QueryData $arg) { + $query = $arg->getQuery(); + + return count($query->getBindValues()) === 0 + && is_a($query, DeleteInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database->expects(self::once())->method('doQuery')->with($callback); + + $this->eventlog->clear(); + } + + /** + * @throws ConstraintException + * @throws QueryException + */ + public function testCreate() + { + $eventlog = EventlogGenerator::factory()->buildEventlog(); + + $callbackCreate = new Callback( + static function (QueryData $arg) use ($eventlog) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + + return count($params) === 6 + && $params['description'] === $eventlog->getDescription() + && $params['login'] === $eventlog->getLogin() + && $params['action'] === $eventlog->getAction() + && $params['userId'] === $eventlog->getUserId() + && $params['ipAddress'] === $eventlog->getIpAddress() + && $params['level'] === $eventlog->getLevel() + && is_a($query, InsertInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::exactly(1)) + ->method('doQuery') + ->with($callbackCreate) + ->willReturn(new QueryResult([])); + + $this->eventlog->create($eventlog); + } + + public function testSearch() + { + $item = new ItemSearchData(self::$faker->name); + + $callback = new Callback( + static function (QueryData $arg) use ($item) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + $searchStringLike = '%' . $item->getSeachString() . '%'; + + return count($params) === 3 + && $params['action'] === $searchStringLike + && $params['ipAddress'] === $searchStringLike + && $params['description'] === $searchStringLike + && $arg->getMapClassName() === EventlogModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback, true); + + $this->eventlog->search($item); + } + + public function testSearchWithEmptyString() + { + $item = new ItemSearchData(); + + $callback = new Callback( + static function (QueryData $arg) use ($item) { + $query = $arg->getQuery(); + $params = $query->getBindValues(); + $searchStringLike = '%' . $item->getSeachString() . '%'; + + return count($params) === 0 + && $arg->getMapClassName() === EventlogModel::class + && is_a($query, SelectInterface::class) + && !empty($query->getStatement()); + } + ); + + $this->database + ->expects(self::once()) + ->method('doSelect') + ->with($callback, true); + + $this->eventlog->search($item); + } + + + protected function setUp(): void + { + parent::setUp(); + + $this->database = $this->createMock(DatabaseInterface::class); + $queryFactory = new QueryFactory('mysql'); + + $this->eventlog = new Eventlog( + $this->database, + $this->context, + $this->application->getEventDispatcher(), + $queryFactory, + ); + } +}