diff --git a/app/modules/web/Controllers/AccountFavoriteController.php b/app/modules/web/Controllers/AccountFavoriteController.php index 0a3f0926..84252852 100644 --- a/app/modules/web/Controllers/AccountFavoriteController.php +++ b/app/modules/web/Controllers/AccountFavoriteController.php @@ -26,7 +26,7 @@ namespace SP\Modules\Web\Controllers; use SP\Http\JsonResponse; use SP\Modules\Web\Controllers\Traits\JsonTrait; -use SP\Services\Account\AccountFavoriteService; +use SP\Services\Account\AccountToFavoriteService; /** * Class AccountFavoriteController @@ -38,7 +38,7 @@ class AccountFavoriteController extends SimpleControllerBase use JsonTrait; /** - * @var AccountFavoriteService + * @var AccountToFavoriteService */ private $accountFavoriteService; @@ -78,7 +78,7 @@ class AccountFavoriteController extends SimpleControllerBase { $this->checks(); - $this->accountFavoriteService = $this->dic->get(AccountFavoriteService::class); + $this->accountFavoriteService = $this->dic->get(AccountToFavoriteService::class); } } \ No newline at end of file diff --git a/app/modules/web/Controllers/Helpers/ItemsGridHelper.php b/app/modules/web/Controllers/Helpers/ItemsGridHelper.php index af7923c8..6978d5ee 100644 --- a/app/modules/web/Controllers/Helpers/ItemsGridHelper.php +++ b/app/modules/web/Controllers/Helpers/ItemsGridHelper.php @@ -359,7 +359,9 @@ class ItemsGridHelper extends HelperBase $GridData->addDataRowSource('clientName'); $GridData->addDataRowSource('name'); $GridData->addDataRowSource('type'); - $GridData->addDataRowSource('size'); + $GridData->addDataRowSource('size', false, function ($value) { + return sprintf('%.2f KB', $value / 1000); + }); $GridData->setData($queryResult); // Grid diff --git a/lib/SP/Core/Context/ContextInterface.php b/lib/SP/Core/Context/ContextInterface.php index edec1689..1f03d51b 100644 --- a/lib/SP/Core/Context/ContextInterface.php +++ b/lib/SP/Core/Context/ContextInterface.php @@ -25,6 +25,7 @@ namespace SP\Core\Context; use SP\Config\ConfigData; +use SP\DataModel\Dto\AccountCache; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; @@ -109,7 +110,6 @@ interface ContextInterface /** * @param $sk - * @return mixed */ public function setSecurityKey($sk); @@ -154,4 +154,9 @@ interface ContextInterface * @return bool */ public function resetAppStatus(); + + /** + * @return AccountCache[]|null + */ + public function getAccountsCache(); } \ No newline at end of file diff --git a/lib/SP/Core/Context/SessionContext.php b/lib/SP/Core/Context/SessionContext.php index 9c510227..00c6e86b 100644 --- a/lib/SP/Core/Context/SessionContext.php +++ b/lib/SP/Core/Context/SessionContext.php @@ -27,6 +27,7 @@ namespace SP\Core\Context; use SP\Account\AccountSearchFilter; use SP\Config\ConfigData; use SP\Core\Crypt\Vault; +use SP\DataModel\Dto\AccountCache; use SP\DataModel\ProfileData; use SP\Services\User\UserLoginResponse; @@ -87,6 +88,7 @@ class SessionContext extends ContextBase * * @param string $key * @param mixed $default + * * @return mixed */ protected function getContextKey($key, $default = null) @@ -115,6 +117,7 @@ class SessionContext extends ContextBase * * @param string $key El nombre de la variable * @param mixed $value El valor de la variable + * * @return mixed */ protected function setContextKey($key, $value) @@ -292,6 +295,7 @@ class SessionContext extends ContextBase /** * @param $sk + * * @return mixed */ public function setSecurityKey($sk) @@ -343,6 +347,7 @@ class SessionContext extends ContextBase * Establecer el timeout de la sesión * * @param int $timeout El valor en segundos + * * @return int */ public function setSessionTimeout($timeout) @@ -386,6 +391,7 @@ class SessionContext extends ContextBase * Establece la hora de creación del SID * * @param $time int La marca de hora + * * @return int */ public function setSidStartTime($time) @@ -409,6 +415,7 @@ class SessionContext extends ContextBase * Establece la hora de inicio de actividad * * @param $time int La marca de hora + * * @return int */ public function setStartActivity($time) @@ -520,10 +527,12 @@ class SessionContext extends ContextBase /** * Devuelve la cache de cuentas + * + * @return AccountCache[] */ public function getAccountsCache() { - $this->getContextKey('accountsCache'); + return $this->getContextKey('accountsCache'); } /** diff --git a/lib/SP/Core/Context/StatelessContext.php b/lib/SP/Core/Context/StatelessContext.php index d36d1895..f653dbe6 100644 --- a/lib/SP/Core/Context/StatelessContext.php +++ b/lib/SP/Core/Context/StatelessContext.php @@ -50,6 +50,7 @@ class StatelessContext extends ContextBase * * @param string $key El nombre de la variable * @param mixed $value El valor de la variable + * * @return mixed */ protected function setContextKey($key, $value) @@ -90,6 +91,7 @@ class StatelessContext extends ContextBase * * @param string $key * @param mixed $default + * * @return mixed */ protected function getContextKey($key, $default = null) @@ -151,6 +153,7 @@ class StatelessContext extends ContextBase /** * @param $sk + * * @return mixed */ public function setSecurityKey($sk) @@ -246,4 +249,12 @@ class StatelessContext extends ContextBase { return $this->getContextKey('configTime'); } + + /** + * @return null + */ + public function getAccountsCache() + { + return null; + } } \ No newline at end of file diff --git a/lib/SP/Log/LogUtil.php b/lib/SP/Core/Exceptions/InvalidImageException.php similarity index 60% rename from lib/SP/Log/LogUtil.php rename to lib/SP/Core/Exceptions/InvalidImageException.php index 1372af90..9f632ad3 100644 --- a/lib/SP/Log/LogUtil.php +++ b/lib/SP/Core/Exceptions/InvalidImageException.php @@ -22,27 +22,14 @@ * along with sysPass. If not, see . */ -namespace SP\Log; +namespace SP\Core\Exceptions; /** - * Class LogUtil + * Class InvalidImageException * - * @package SP\Log + * @package SP\Core\Exceptions */ -class LogUtil +class InvalidImageException extends SPException { - /** - * Registrar que una extensión no ha sido cargada - * - * @param string $extension La extensión no cargada - * @param string $source El origen del error - * @return Log - * @throws \SP\Core\Exceptions\SPException - */ - public static function extensionNotLoaded($extension, $source = __FUNCTION__) - { - $msg = sprintf(__('Extensión \'%s\' no cargada'), $extension); - return Log::writeNewLog($source, $msg, Log::ERROR); - } } \ No newline at end of file diff --git a/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php b/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php new file mode 100644 index 00000000..366a2805 --- /dev/null +++ b/lib/SP/DataModel/Dto/AccountHistoryCreateDto.php @@ -0,0 +1,99 @@ +. + */ + +namespace SP\DataModel\Dto; + + +/** + * Class AccountHistoryCreateDto + * + * @package SP\DataModel\Dto + */ +class AccountHistoryCreateDto +{ + /** + * @var int + */ + private $accountId; + /** + * @var bool + */ + private $isModify; + /** + * @var bool + */ + private $isDelete; + /** + * @var string + */ + private $masterPassHash; + + /** + * AccountHistoryCreateDto constructor. + * + * @param int $accountId + * @param bool $isModify + * @param bool $isDelete + * @param string $masterPassHash + */ + public function __construct(int $accountId, bool $isModify, bool $isDelete, string $masterPassHash) + { + $this->accountId = $accountId; + $this->isModify = $isModify; + $this->isDelete = $isDelete; + $this->masterPassHash = $masterPassHash; + } + + /** + * @return int + */ + public function getAccountId(): int + { + return $this->accountId; + } + + /** + * @return bool + */ + public function isModify(): bool + { + return $this->isModify; + } + + /** + * @return bool + */ + public function isDelete(): bool + { + return $this->isDelete; + } + + /** + * @return string + */ + public function getMasterPassHash(): string + { + return $this->masterPassHash; + } +} \ No newline at end of file diff --git a/lib/SP/DataModel/FileExtData.php b/lib/SP/DataModel/FileExtData.php index e89ab3e7..b4a7d2b1 100644 --- a/lib/SP/DataModel/FileExtData.php +++ b/lib/SP/DataModel/FileExtData.php @@ -34,7 +34,7 @@ class FileExtData extends FileData /** * @var string */ - public $customerName = ''; + public $clientName = ''; /** * @var string */ @@ -43,17 +43,17 @@ class FileExtData extends FileData /** * @return string */ - public function getCustomerName() + public function getClientName() { - return $this->customerName; + return $this->clientName; } /** - * @param string $customerName + * @param string $clientName */ - public function setCustomerName($customerName) + public function setClientName($clientName) { - $this->customerName = $customerName; + $this->clientName = $clientName; } /** diff --git a/lib/SP/Repositories/Account/AccountFileRepository.php b/lib/SP/Repositories/Account/AccountFileRepository.php index b30a01a0..1ef0b639 100644 --- a/lib/SP/Repositories/Account/AccountFileRepository.php +++ b/lib/SP/Repositories/Account/AccountFileRepository.php @@ -27,11 +27,11 @@ namespace SP\Repositories\Account; use SP\DataModel\FileData; use SP\DataModel\FileExtData; use SP\DataModel\ItemSearchData; -use SP\Repositories\NoSuchItemException; use SP\Repositories\Repository; use SP\Repositories\RepositoryItemInterface; use SP\Repositories\RepositoryItemTrait; use SP\Storage\Database\QueryData; +use SP\Storage\Database\QueryResult; /** * Class AccountFileRepository @@ -94,7 +94,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac /** * @param $id * - * @return FileExtData + * @return \SP\Storage\Database\QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ @@ -118,7 +118,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac $queryData->setQuery($query); $queryData->addParam($id); - return $this->db->doSelect($queryData)->getData(); + return $this->db->doSelect($queryData); } /** @@ -126,7 +126,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac * * @param int $id * - * @return FileExtData + * @return \SP\Storage\Database\QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ @@ -153,7 +153,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac $queryData->setQuery($query); $queryData->addParam($id); - return $this->db->doSelect($queryData)->getData(); + return $this->db->doSelect($queryData); } /** @@ -161,36 +161,37 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac * * @param int $id * - * @return FileData[] + * @return \SP\Storage\Database\QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ public function getByAccountId($id) { $query = /** @lang SQL */ - 'SELECT AF.id, - AF.name, - AF.size, - AF.type, - AF.accountId, - AF.content, - AF.thumb, - AF.extension - FROM AccountFile AF - WHERE accountId = ?'; + 'SELECT id, + `name`, + size, + type, + accountId, + content, + thumb, + extension + FROM AccountFile + WHERE accountId = ? + ORDER BY `name`'; $queryData = new QueryData(); $queryData->setMapClassName(FileData::class); $queryData->setQuery($query); $queryData->addParam($id); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** * Returns all the items * - * @return FileExtData[] + * @return \SP\Storage\Database\QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ @@ -209,13 +210,14 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac C.name AS clientName FROM AccountFile AF INNER JOIN Account A ON A.id = AF.accountId - INNER JOIN Client C ON A.clientId = C.id'; + INNER JOIN Client C ON A.clientId = C.id + ORDER BY AF.name'; $queryData = new QueryData(); $queryData->setMapClassName(FileExtData::class); $queryData->setQuery($query); - return $this->db->doSelect($queryData)->getDataAsArray(); + return $this->db->doSelect($queryData); } /** @@ -223,12 +225,16 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac * * @param array $ids * - * @return array + * @return \SP\Storage\Database\QueryResult * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ public function getByIdBatch(array $ids) { + if (empty($ids)) { + return new QueryResult(); + } + $query = /** @lang SQL */ 'SELECT AF.id, AF.name, @@ -250,7 +256,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac $queryData->setQuery($query); $queryData->setParams($ids); - return $this->db->doQuery($queryData)->getDataAsArray(); + return $this->db->doQuery($queryData); } /** @@ -258,8 +264,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac * * @param $id * - * @return AccountFileRepository - * @throws NoSuchItemException + * @return int * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ @@ -273,11 +278,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac $queryData->addParam($id); $queryData->setOnErrorMessage(__u('Error al eliminar el archivo')); - if ($this->db->doQuery($queryData)->getAffectedNumRows() === 0) { - throw new NoSuchItemException(__u('Archivo no encontrado')); - } - - return $this; + return $this->db->doQuery($queryData)->getAffectedNumRows(); } /** @@ -291,6 +292,10 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac */ public function deleteByIdBatch(array $ids) { + if (empty($ids)) { + return 0; + } + $queryData = new QueryData(); $queryData->setQuery('DELETE FROM AccountFile WHERE id IN (' . $this->getParamsFromArray($ids) . ')'); $queryData->setParams($ids); @@ -342,7 +347,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac { $queryData = new QueryData(); $queryData->setMapClassName(FileExtData::class); - $queryData->setSelect('AF.id, AF.name, CONCAT(ROUND(AF.size/1000, 2), "KB") AS size, AF.thumb, AF.type, A.name as accountName, C.name as clientName'); + $queryData->setSelect('AF.id, AF.accountId, AF.name, AF.size, AF.thumb, AF.type, AF.extension, A.name as accountName, C.name as clientName'); $queryData->setFrom('AccountFile AF INNER JOIN Account A ON A.id = AF.accountId INNER JOIN Client C ON A.clientId = C.id'); $queryData->setOrder('A.name'); diff --git a/lib/SP/Repositories/Account/AccountHistoryRepository.php b/lib/SP/Repositories/Account/AccountHistoryRepository.php index fc9e7f0b..ffced50f 100644 --- a/lib/SP/Repositories/Account/AccountHistoryRepository.php +++ b/lib/SP/Repositories/Account/AccountHistoryRepository.php @@ -30,6 +30,7 @@ use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; use SP\DataModel\AccountHistoryData; use SP\DataModel\AccountPassData; +use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\ItemSearchData; use SP\Repositories\Repository; use SP\Repositories\RepositoryItemInterface; @@ -104,13 +105,13 @@ class AccountHistoryRepository extends Repository implements RepositoryItemInter /** * Crea una nueva cuenta en la BBDD * - * @param array $itemData ['id' => , 'isModify' => ,'isDelete' => , 'masterPassHash' => ] + * @param AccountHistoryCreateDto $dto * * @return int * @throws QueryException * @throws ConstraintException */ - public function create($itemData) + public function create($dto) { $queryData = new QueryData(); $query = /** @lang SQL */ @@ -161,10 +162,10 @@ class AccountHistoryRepository extends Repository implements RepositoryItemInter ?,?,? FROM Account WHERE id = ?'; $queryData->setQuery($query); - $queryData->addParam($itemData['isModify']); - $queryData->addParam($itemData['isDelete']); - $queryData->addParam($itemData['masterPassHash']); - $queryData->addParam($itemData['id']); + $queryData->addParam((int)$dto->isModify()); + $queryData->addParam((int)$dto->isDelete()); + $queryData->addParam($dto->getMasterPassHash()); + $queryData->addParam($dto->getAccountId()); $queryData->setOnErrorMessage(__u('Error al actualizar el historial')); return $this->db->doQuery($queryData)->getLastId(); diff --git a/lib/SP/Repositories/Account/AccountRepository.php b/lib/SP/Repositories/Account/AccountRepository.php index 564f2e0d..af8a435d 100644 --- a/lib/SP/Repositories/Account/AccountRepository.php +++ b/lib/SP/Repositories/Account/AccountRepository.php @@ -641,15 +641,15 @@ class AccountRepository extends Repository implements RepositoryItemInterface $queryJoins = new QueryJoin(); if ($accountSearchFilter->isSearchFavorites() === true) { - $queryJoins->addJoin('INNER JOIN AccountToFavorite AF ON (AF.accountId = Account.id AND AF.userId = ?)', [$this->context->getUserData()->getId()]); + $queryJoins->addJoin('INNER JOIN AccountToFavorite ON (AccountToFavorite.accountId = Account.id AND AccountToFavorite.userId = ?)', [$this->context->getUserData()->getId()]); } if ($accountSearchFilter->hasTags()) { - $queryJoins->addJoin('INNER JOIN AccountToTag AT ON AT.accountId = Account.id'); - $queryFilters->addFilter('AT.tagId IN (' . $this->getParamsFromArray($accountSearchFilter->getTagsId()) . ')', $accountSearchFilter->getTagsId()); + $queryJoins->addJoin('INNER JOIN AccountToTag ON AccountToTag.accountId = Account.id'); + $queryFilters->addFilter('AccountToTag.tagId IN (' . $this->getParamsFromArray($accountSearchFilter->getTagsId()) . ')', $accountSearchFilter->getTagsId()); if (QueryCondition::CONDITION_AND === $accountSearchFilter->getFilterOperator()) { - $queryData->setGroupBy('Account.id HAVING COUNT(DISTINCT AT.tagId) = ' . count($accountSearchFilter->getTagsId())); + $queryData->setGroupBy('Account.id HAVING COUNT(DISTINCT AccountToTag.tagId) = ' . count($accountSearchFilter->getTagsId())); } } diff --git a/lib/SP/Repositories/Account/AccountFavoriteRepository.php b/lib/SP/Repositories/Account/AccountToFavoriteRepository.php similarity index 98% rename from lib/SP/Repositories/Account/AccountFavoriteRepository.php rename to lib/SP/Repositories/Account/AccountToFavoriteRepository.php index e2137725..4969622c 100644 --- a/lib/SP/Repositories/Account/AccountFavoriteRepository.php +++ b/lib/SP/Repositories/Account/AccountToFavoriteRepository.php @@ -32,7 +32,7 @@ use SP\Storage\Database\QueryData; * * @package SP\Repositories\Account */ -class AccountFavoriteRepository extends Repository +class AccountToFavoriteRepository extends Repository { /** * Obtener un array con los Ids de cuentas favoritas diff --git a/lib/SP/Repositories/RepositoryItemTrait.php b/lib/SP/Repositories/RepositoryItemTrait.php index 8ca44c45..88d87d4b 100644 --- a/lib/SP/Repositories/RepositoryItemTrait.php +++ b/lib/SP/Repositories/RepositoryItemTrait.php @@ -24,7 +24,6 @@ namespace SP\Repositories; -use SP\Core\Exceptions\SPException; use SP\DataModel\DataModelInterface; use SP\Storage\Database\DBStorageInterface; use SP\Storage\Database\DBUtil; @@ -52,7 +51,7 @@ trait RepositoryItemTrait foreach ($items as $key => $item) { try { $this->delete($item->getId()); - } catch (SPException $e) { + } catch (\Exception $e) { unset($items[$key]); } } diff --git a/lib/SP/Repositories/User/UserRepository.php b/lib/SP/Repositories/User/UserRepository.php index 811161df..2c4ae74e 100644 --- a/lib/SP/Repositories/User/UserRepository.php +++ b/lib/SP/Repositories/User/UserRepository.php @@ -513,9 +513,8 @@ class UserRepository extends Repository implements RepositoryItemInterface /** * @param $login string * - * @return UserData + * @return QueryResult * @throws ConstraintException - * @throws NoSuchItemException * @throws QueryException */ public function getByLogin($login) @@ -556,13 +555,7 @@ class UserRepository extends Repository implements RepositoryItemInterface $queryData->setParams([$login, $login]); $queryData->setOnErrorMessage(__u('Error al obtener los datos del usuario')); - $result = $this->db->doSelect($queryData); - - if ($result->getNumRows() === 0) { - throw new NoSuchItemException(__u('El usuario no existe')); - } - - return $result->getData(); + return$this->db->doSelect($queryData); } /** diff --git a/lib/SP/Services/Account/AccountFileService.php b/lib/SP/Services/Account/AccountFileService.php index 8a714857..845d6e38 100644 --- a/lib/SP/Services/Account/AccountFileService.php +++ b/lib/SP/Services/Account/AccountFileService.php @@ -2,8 +2,8 @@ /** * sysPass * - * @author nuxsmin - * @link https://syspass.org + * @author nuxsmin + * @link https://syspass.org * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org * * This file is part of sysPass. @@ -29,6 +29,7 @@ use SP\DataModel\FileData; use SP\DataModel\FileExtData; use SP\DataModel\ItemSearchData; use SP\Repositories\Account\AccountFileRepository; +use SP\Repositories\NoSuchItemException; use SP\Services\Service; use SP\Services\ServiceException; use SP\Storage\Database\QueryResult; @@ -47,20 +48,12 @@ class AccountFileService extends Service */ protected $accountFileRepository; - /** - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - */ - public function initialize() - { - $this->accountFileRepository = $this->dic->get(AccountFileRepository::class); - } - /** * Creates an item * * @param FileData $itemData - * @return mixed + * + * @return int * @throws SPException * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException @@ -85,7 +78,7 @@ class AccountFileService extends Service */ public function getInfoById($id) { - return $this->accountFileRepository->getInfoById($id); + return $this->accountFileRepository->getInfoById($id)->getData(); } /** @@ -99,7 +92,7 @@ class AccountFileService extends Service */ public function getById($id) { - return $this->accountFileRepository->getById($id); + return $this->accountFileRepository->getById($id)->getData(); } /** @@ -111,7 +104,7 @@ class AccountFileService extends Service */ public function getAll() { - return $this->accountFileRepository->getAll(); + return $this->accountFileRepository->getAll()->getDataAsArray(); } /** @@ -119,19 +112,20 @@ class AccountFileService extends Service * * @param array $ids * - * @return array + * @return FileExtData[] * @throws \SP\Core\Exceptions\ConstraintException * @throws \SP\Core\Exceptions\QueryException */ public function getByIdBatch(array $ids) { - return $this->accountFileRepository->getByIdBatch($ids); + return $this->accountFileRepository->getByIdBatch($ids)->getDataAsArray(); } /** * Deletes all the items for given ids * * @param array $ids + * * @return int * @throws ServiceException * @throws \SP\Core\Exceptions\ConstraintException @@ -150,14 +144,16 @@ class AccountFileService extends Service * Deletes an item * * @param $id + * * @return AccountFileService - * @throws SPException - * @throws ServiceException + * @throws NoSuchItemException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function delete($id) { if ($this->accountFileRepository->delete($id) === 0) { - throw new ServiceException(__u('Archivo no encontrado'), ServiceException::INFO); + throw new NoSuchItemException(__u('Archivo no encontrado')); } return $this; @@ -188,6 +184,15 @@ class AccountFileService extends Service */ public function getByAccountId($id) { - return $this->accountFileRepository->getByAccountId($id); + return $this->accountFileRepository->getByAccountId($id)->getDataAsArray(); + } + + /** + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface + */ + protected function initialize() + { + $this->accountFileRepository = $this->dic->get(AccountFileRepository::class); } } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountHistoryService.php b/lib/SP/Services/Account/AccountHistoryService.php index ed8ae324..aed43037 100644 --- a/lib/SP/Services/Account/AccountHistoryService.php +++ b/lib/SP/Services/Account/AccountHistoryService.php @@ -27,6 +27,7 @@ namespace SP\Services\Account; use SP\Core\Exceptions\QueryException; use SP\Core\Exceptions\SPException; use SP\DataModel\AccountHistoryData; +use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\ItemData; use SP\DataModel\ItemSearchData; use SP\Repositories\Account\AccountHistoryRepository; @@ -57,17 +58,6 @@ class AccountHistoryService extends Service */ protected $accountToUserRepository; - /** - * @throws \Psr\Container\ContainerExceptionInterface - * @throws \Psr\Container\NotFoundExceptionInterface - */ - public function initialize() - { - $this->accountHistoryRepository = $this->dic->get(AccountHistoryRepository::class); - $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class); - $this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class); - } - /** * Returns the item for given id * @@ -166,16 +156,15 @@ class AccountHistoryService extends Service /** * Crea una nueva cuenta en la BBDD * - * @param array $itemData ['id' => , 'isModify' => ,'isDelete' => , 'masterPassHash' => ] + * @param AccountHistoryCreateDto $dto * * @return bool * @throws QueryException * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException */ - public function create($itemData) + public function create(AccountHistoryCreateDto $dto) { - return $this->accountHistoryRepository->create($itemData); + return $this->accountHistoryRepository->create($dto); } /** @@ -240,6 +229,17 @@ class AccountHistoryService extends Service */ public function getAll() { - return self::mapHistoryForDateSelect($this->accountHistoryRepository->getAll()->getDataAsArray()); + return $this->accountHistoryRepository->getAll()->getDataAsArray(); + } + + /** + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface + */ + protected function initialize() + { + $this->accountHistoryRepository = $this->dic->get(AccountHistoryRepository::class); + $this->accountToUserRepository = $this->dic->get(AccountToUserRepository::class); + $this->accountToUserGroupRepository = $this->dic->get(AccountToUserGroupRepository::class); } } \ No newline at end of file diff --git a/lib/SP/Services/Account/AccountSearchService.php b/lib/SP/Services/Account/AccountSearchService.php index 76a61aff..8794d386 100644 --- a/lib/SP/Services/Account/AccountSearchService.php +++ b/lib/SP/Services/Account/AccountSearchService.php @@ -54,7 +54,7 @@ class AccountSearchService extends Service * Regex filters for special searching */ const FILTERS_REGEX_IS = '#(?(?:is|not):(?:expired|private))#'; - const FILTERS_REGEX = '#(?id|user|group|file|owner|maingroup):"?(?[\w\.]+)"?#'; + const FILTERS_REGEX = '#(?id|user|group|file|owner|maingroup):(?:"(?[\w\s\.]+)"|(?[\w\.]+))#'; const FILTERS_REGEX_OPERATOR = '#op:(?and|or)#'; const COLORS_CACHE_FILE = CACHE_PATH . DIRECTORY_SEPARATOR . 'colors.cache'; @@ -137,7 +137,11 @@ class AccountSearchService extends Service public function processSearchResults(AccountSearchFilter $accountSearchFilter) { $accountSearchFilter->setStringFilters($this->analyzeQueryFilters($accountSearchFilter->getTxtSearch())); - $accountSearchFilter->setFilterOperator($this->filterOperator); + + if ($accountSearchFilter->getFilterOperator() === null) { + $accountSearchFilter->setFilterOperator($this->filterOperator); + } + $accountSearchFilter->setCleanTxtSearch($this->cleanString); $accountSearchResponse = $this->accountRepository->getByFilter($accountSearchFilter); @@ -146,7 +150,7 @@ class AccountSearchService extends Service $maxTextLength = $this->configData->isResultsAsCards() ? 40 : 60; $accountLinkEnabled = $this->context->getUserData()->getPreferences()->isAccountLink() || $this->configData->isAccountLink(); - $favorites = $this->dic->get(AccountFavoriteService::class)->getForUserId($this->context->getUserData()->getId()); + $favorites = $this->dic->get(AccountToFavoriteService::class)->getForUserId($this->context->getUserData()->getId()); $accountAclService = $this->dic->get(AccountAclService::class); @@ -178,7 +182,7 @@ class AccountSearchService extends Service $accountsData[] = $accountsSearchItem; } - return (new QueryResult($accountsData))->setTotalNumRows($accountSearchResponse->getCount()); + return QueryResult::fromResults($accountsData, $accountSearchResponse->getCount()); } /** @@ -202,6 +206,18 @@ class AccountSearchService extends Service return $queryCondition; } + $this->extractFilterOperator($string); + $this->extractFilterIs($string, $queryCondition); + $this->extractFilterItems($string, $queryCondition); + + return $queryCondition; + } + + /** + * @param $string + */ + private function extractFilterOperator($string) + { if (preg_match(self::FILTERS_REGEX_OPERATOR, $string, $matches)) { // Removes the operator from the string to increase regex performance $this->cleanString = trim(str_replace($matches[0], '', $this->cleanString)); @@ -215,7 +231,14 @@ class AccountSearchService extends Service break; } } + } + /** + * @param string $string + * @param QueryCondition $queryCondition + */ + private function extractFilterIs($string, QueryCondition $queryCondition) + { if (preg_match_all(self::FILTERS_REGEX_IS, $string, $matches, PREG_SET_ORDER) > 0) { foreach ($matches as $filter) { // Removes the current filter from the string to increase regex performance @@ -237,21 +260,31 @@ class AccountSearchService extends Service } } } + } + /** + * @param string $string + * @param QueryCondition $queryCondition + */ + private function extractFilterItems($string, QueryCondition $queryCondition) + { if (preg_match_all(self::FILTERS_REGEX, $string, $matches, PREG_SET_ORDER) > 0) { foreach ($matches as $filter) { // Removes the current filter from the string to increase regex performance $this->cleanString = trim(str_replace($filter[0], '', $this->cleanString)); - if (($text = $filter['filter']) !== '') { - try { + $text = !empty($filter['filter_quoted']) ? $filter['filter_quoted'] : $filter['filter']; + if ($text !== '') { + try { switch ($filter['type']) { case 'user': if (is_object(($userData = $this->dic->get(UserService::class)->getByLogin($text)))) { $queryCondition->addFilter( - 'Account.userId = ? OR Account.id IN (SELECT AU.accountId FROM AccountToUser AU WHERE AU.accountId = Account.id AND AU.userId = ? - UNION ALL SELECT AUG.accountId FROM AccountToUserGroup AUG WHERE AUG.accountId = Account.id AND AUG.userGroupId = ?)', + 'Account.userId = ? OR Account.id IN + (SELECT AccountToUser.accountId FROM AccountToUser WHERE AccountToUser.accountId = Account.id AND AccountToUser.userId = ? + UNION ALL + SELECT AccountToUserGroup.accountId FROM AccountToUserGroup WHERE AccountToUserGroup.accountId = Account.id AND AccountToUserGroup.userGroupId = ?)', [$userData->getId(), $userData->getId(), $userData->getUserGroupId()]); } break; @@ -261,15 +294,15 @@ class AccountSearchService extends Service case 'group': if (is_object(($userGroupData = $this->dic->get(UserGroupService::class)->getByName($text)))) { $queryCondition->addFilter( - 'Account.userGroupId = ? OR Account.id IN (SELECT AUG.accountId FROM AccountToUserGroup AUG WHERE AUG.accountId = id AND AUG.userGroupId = ?)', + 'Account.userGroupId = ? OR Account.id IN (SELECT AccountToUserGroup.accountId FROM AccountToUserGroup WHERE AccountToUserGroup.accountId = id AND AccountToUserGroup.userGroupId = ?)', [$userGroupData->getId(), $userGroupData->getId()]); } break; case 'maingroup': - $queryCondition->addFilter('Account.userGroupName = ?', ['%' . $text . '%']); + $queryCondition->addFilter('Account.userGroupName LIKE ?', ['%' . $text . '%']); break; case 'file': - $queryCondition->addFilter('Account.id IN (SELECT AF.accountId FROM AccountFile AF WHERE AF.name LIKE ?)', ['%' . $text . '%']); + $queryCondition->addFilter('Account.id IN (SELECT AccountFile.accountId FROM AccountFile WHERE AccountFile.name LIKE ?)', ['%' . $text . '%']); break; case 'id': $queryCondition->addFilter('Account.id = ?', [(int)$text]); @@ -277,12 +310,11 @@ class AccountSearchService extends Service } } catch (\Exception $e) { + processException($e); } } } } - - return $queryCondition; } /** @@ -301,7 +333,10 @@ class AccountSearchService extends Service /** @var AccountCache[] $cache */ $cache = $this->context->getAccountsCache(); - if (!isset($cache[$accountId]) + $hasCache = $cache !== null; + + if ($cache === false + || !isset($cache[$accountId]) || $cache[$accountId]->getTime() < (int)strtotime($accountSearchData->getDateEdit()) ) { $cache[$accountId] = new AccountCache( @@ -309,7 +344,9 @@ class AccountSearchService extends Service $this->accountToUserRepository->getUsersByAccountId($accountId), $this->accountToUserGroupRepository->getUserGroupsByAccountId($accountId)); - $this->context->setAccountsCache($cache); + if ($hasCache) { + $this->context->setAccountsCache($cache); + } } return $cache[$accountId]; diff --git a/lib/SP/Services/Account/AccountService.php b/lib/SP/Services/Account/AccountService.php index 08adbb6a..1c857c7f 100644 --- a/lib/SP/Services/Account/AccountService.php +++ b/lib/SP/Services/Account/AccountService.php @@ -35,6 +35,7 @@ use SP\Core\Exceptions\SPException; use SP\DataModel\AccountData; use SP\DataModel\AccountPassData; use SP\DataModel\Dto\AccountDetailsResponse; +use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\Dto\AccountSearchResponse; use SP\DataModel\ItemSearchData; use SP\Repositories\Account\AccountRepository; @@ -307,12 +308,12 @@ class AccountService extends Service implements AccountServiceInterface $accountHistoryRepository = $this->dic->get(AccountHistoryService::class); $configService = $this->dic->get(ConfigService::class); - return $accountHistoryRepository->create([ - 'id' => $accountId, - 'isDelete' => (int)$isDelete, - 'isModify' => (int)!$isDelete, - 'masterPassHash' => $configService->getByParam('masterPwd') - ]); + return $accountHistoryRepository->create(new AccountHistoryCreateDto( + $accountId, + $isDelete, + !$isDelete, + $configService->getByParam('masterPwd')) + ); } /** diff --git a/lib/SP/Services/Account/AccountFavoriteService.php b/lib/SP/Services/Account/AccountToFavoriteService.php similarity index 89% rename from lib/SP/Services/Account/AccountFavoriteService.php rename to lib/SP/Services/Account/AccountToFavoriteService.php index ba77c91e..a53207d6 100644 --- a/lib/SP/Services/Account/AccountFavoriteService.php +++ b/lib/SP/Services/Account/AccountToFavoriteService.php @@ -24,7 +24,7 @@ namespace SP\Services\Account; -use SP\Repositories\Account\AccountFavoriteRepository; +use SP\Repositories\Account\AccountToFavoriteRepository; use SP\Services\Service; /** @@ -32,10 +32,10 @@ use SP\Services\Service; * * @package SP\Services\Account */ -class AccountFavoriteService extends Service +class AccountToFavoriteService extends Service { /** - * @var AccountFavoriteRepository + * @var AccountToFavoriteRepository */ protected $accountFavoriteRepository; @@ -60,7 +60,8 @@ class AccountFavoriteService extends Service * @param $userId int El Id del usuario * * @return bool - * @throws \SP\Core\Exceptions\SPException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException */ public function add($accountId, $userId) { @@ -88,6 +89,6 @@ class AccountFavoriteService extends Service */ protected function initialize() { - $this->accountFavoriteRepository = $this->dic->get(AccountFavoriteRepository::class); + $this->accountFavoriteRepository = $this->dic->get(AccountToFavoriteRepository::class); } } \ No newline at end of file diff --git a/lib/SP/Services/Service.php b/lib/SP/Services/Service.php index 3a927e80..da164c5e 100644 --- a/lib/SP/Services/Service.php +++ b/lib/SP/Services/Service.php @@ -28,8 +28,6 @@ use DI\Container; use Psr\Container\ContainerInterface; use SP\Config\Config; use SP\Core\Context\ContextInterface; -use SP\Core\Context\SessionContext; -use SP\Core\Context\StatelessContext; use SP\Core\Events\EventDispatcher; /** @@ -46,7 +44,7 @@ abstract class Service */ protected $config; /** - * @var SessionContext|StatelessContext + * @var ContextInterface */ protected $context; /** diff --git a/lib/SP/Services/User/UserService.php b/lib/SP/Services/User/UserService.php index 65642f23..36eb45d4 100644 --- a/lib/SP/Services/User/UserService.php +++ b/lib/SP/Services/User/UserService.php @@ -32,6 +32,7 @@ use SP\DataModel\ItemSearchData; use SP\DataModel\UserData; use SP\DataModel\UserPreferencesData; use SP\Repositories\DuplicatedItemException; +use SP\Repositories\NoSuchItemException; use SP\Repositories\User\UserRepository; use SP\Services\Service; use SP\Services\ServiceException; @@ -153,7 +154,13 @@ class UserService extends Service */ public function getByLogin($login) { - return $this->userRepository->getByLogin($login); + $result = $this->userRepository->getByLogin($login); + + if ($result->getNumRows() === 0) { + throw new NoSuchItemException(__u('El usuario no existe')); + } + + return $result->getData(); } /** diff --git a/lib/SP/Storage/Database/QueryResult.php b/lib/SP/Storage/Database/QueryResult.php index 17639c6e..52b63ceb 100644 --- a/lib/SP/Storage/Database/QueryResult.php +++ b/lib/SP/Storage/Database/QueryResult.php @@ -34,7 +34,7 @@ class QueryResult /** * @var array */ - private $data = []; + private $data; /** * @var int */ @@ -69,6 +69,23 @@ class QueryResult } } + /** + * @param array $data + * @param null $totalNumRows + * + * @return QueryResult + */ + public static function fromResults(array $data, $totalNumRows = null) + { + $result = new self($data); + + if ($totalNumRows !== null) { + $result->totalNumRows = $totalNumRows; + } + + return $result; + } + /** * @return mixed */ @@ -79,7 +96,7 @@ class QueryResult return $this->data[0]; } - return $this->data; + return null; } /** @@ -89,7 +106,7 @@ class QueryResult */ public function getDataAsArray(): array { - return $this->data; + return (array)$this->data; } /** @@ -179,5 +196,4 @@ class QueryResult return $this; } - } \ No newline at end of file diff --git a/lib/SP/Util/FileUtil.php b/lib/SP/Util/FileUtil.php index c36fd9a3..fb199ec1 100644 --- a/lib/SP/Util/FileUtil.php +++ b/lib/SP/Util/FileUtil.php @@ -68,12 +68,12 @@ class FileUtil } /** - * @param FileData $FileData + * @param FileData $fileData * * @return bool */ - public static function isImage(FileData $FileData) + public static function isImage(FileData $fileData) { - return in_array(mb_strtoupper($FileData->getExtension()), self::$imageExtensions, true); + return in_array(mb_strtoupper($fileData->getExtension()), self::$imageExtensions, true); } } \ No newline at end of file diff --git a/lib/SP/Util/ImageUtil.php b/lib/SP/Util/ImageUtil.php index ac229185..7ea50878 100644 --- a/lib/SP/Util/ImageUtil.php +++ b/lib/SP/Util/ImageUtil.php @@ -24,6 +24,7 @@ namespace SP\Util; +use SP\Core\Exceptions\InvalidImageException; use SP\Log\LogUtil; defined('APP_ROOT') || die(); @@ -39,13 +40,13 @@ class ImageUtil * Convertir un texto a imagen * * @param $text string El texto a convertir + * * @return bool|string - * @throws \SP\Core\Exceptions\SPException */ public static function convertText($text) { if (!Checks::gdIsAvailable()) { - LogUtil::extensionNotLoaded('GD'); + debugLog(sprintf(__('Extensión \'%s\' no cargada'), 'GD')); return false; } @@ -89,18 +90,21 @@ class ImageUtil * Crear miniatura de una imagen * * @param $image string La imagen a redimensionar + * * @return bool|string - * @throws \SP\Core\Exceptions\SPException + * @throws InvalidImageException */ public static function createThumbnail($image) { if (!Checks::gdIsAvailable()) { - LogUtil::extensionNotLoaded('GD', __FUNCTION__); + debugLog(sprintf(__('Extensión \'%s\' no cargada'), 'GD')); return false; } - $im = imagecreatefromstring($image); + if (($im = @imagecreatefromstring($image)) === false) { + throw new InvalidImageException(__u('Imagen no válida')); + } $width = imagesx($im); $height = imagesy($im); diff --git a/lib/SP/Util/Util.php b/lib/SP/Util/Util.php index 4a516010..d28084fa 100644 --- a/lib/SP/Util/Util.php +++ b/lib/SP/Util/Util.php @@ -174,9 +174,9 @@ class Util $ConfigData = Bootstrap::getContainer()->get(ConfigData::class); if (!Checks::curlIsAvailable()) { - $Log = LogUtil::extensionNotLoaded('CURL', __FUNCTION__); + debugLog(sprintf(__('Extensión \'%s\' no cargada'), 'CURL')); - throw new SPException($Log->getDescription(), SPException::WARNING); + throw new SPException(sprintf(__('Extensión \'%s\' no cargada'), 'CURL')); } $ch = curl_init($url); diff --git a/tests/AccountRepositoryTestCase.php b/tests/AccountRepositoryTestCase.php deleted file mode 100644 index a2e5d347..00000000 --- a/tests/AccountRepositoryTestCase.php +++ /dev/null @@ -1,504 +0,0 @@ -. - */ - -namespace SP\Tests; - -use DI\DependencyException; -use SP\Account\AccountRequest; -use SP\Account\AccountSearchFilter; -use SP\Core\Crypt\Crypt; -use SP\Core\Exceptions\SPException; -use SP\DataModel\AccountVData; -use SP\DataModel\Dto\AccountSearchResponse; -use SP\DataModel\ItemSearchData; -use SP\Mvc\Model\QueryCondition; -use SP\Repositories\Account\AccountRepository; -use SP\Services\Account\AccountPasswordRequest; -use SP\Storage\DatabaseConnectionData; - -/** - * Class AccountRepositoryTest - * - * Tests unitarios para comprobar las consultas a la BBDD relativas a las cuentas - * - * @package SP\Tests - */ -class AccountRepositoryTest extends DatabaseBaseTest -{ - const SECURE_KEY_PASSWORD = 'syspass123'; - /** - * @var AccountRepository - */ - private static $accountRepository; - - /** - * @throws DependencyException - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - */ - public static function setUpBeforeClass() - { - $dic = setupContext(); - - // Datos de conexión a la BBDD - self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); - - // Inicializar el repositorio - self::$accountRepository = $dic->get(AccountRepository::class); - } - - /** - * Comprobar la eliminación de registros - * - * @throws SPException - */ - public function testDelete() - { - // Comprobar registros iniciales - $this->assertEquals(2, $this->conn->getRowCount('Account')); - - // Eliminar un registro y comprobar el total de registros - $this->assertEquals(1, self::$accountRepository->delete(1)); - $this->assertEquals(1, $this->conn->getRowCount('Account')); - - // Eliminar un registro no existente - $this->assertEquals(0, self::$accountRepository->delete(100)); - - // Eliminar un registro y comprobar el total de registros - $this->assertEquals(1, self::$accountRepository->delete(2)); - $this->assertEquals(0, $this->conn->getRowCount('Account')); - } - - /** - * No implementado - */ - public function testEditRestore() - { - $this->markTestSkipped(); - } - - /** - * Comprobar la modificación de una clave de cuenta - * - * @covers \SP\Repositories\Account\AccountRepository::getPasswordForId() - * @throws SPException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testEditPassword() - { - $accountRequest = new AccountRequest(); - $accountRequest->key = Crypt::makeSecuredKey(self::SECURE_KEY_PASSWORD); - $accountRequest->pass = Crypt::encrypt('1234', $accountRequest->key, self::SECURE_KEY_PASSWORD); - $accountRequest->id = 2; - $accountRequest->userEditId = 1; - $accountRequest->passDateChange = time() + 3600; - - // Comprobar que la modificación de la clave es correcta - $this->assertTrue(self::$accountRepository->editPassword($accountRequest)); - - $accountPassData = self::$accountRepository->getPasswordForId(2); - $clearPassword = Crypt::decrypt($accountPassData->pass, $accountPassData->key, self::SECURE_KEY_PASSWORD); - - // Comprobar que la clave obtenida es igual a la encriptada anteriormente - $this->assertEquals('1234', $clearPassword); - - // Comprobar que se devuelve un array vacío - $this->assertCount(0, self::$accountRepository->getPasswordForId(10)); - } - - /** - * No implementado - */ - public function testCheckInUse() - { - $this->markTestSkipped(); - } - - /** - * Comprobar la obtención de cuentas - * - * @throws SPException - */ - public function testGetById() - { - $account = self::$accountRepository->getById(1); - - $this->assertInstanceOf(AccountVData::class, $account); - $this->assertEquals(1, $account->getId()); - - $this->expectException(SPException::class); - - self::$accountRepository->getById(100); - } - - /** - * @throws SPException - */ - public function testUpdate() - { - $accountRequest = new AccountRequest(); - $accountRequest->id = 1; - $accountRequest->name = 'Prueba 1'; - $accountRequest->login = 'admin'; - $accountRequest->url = 'http://syspass.org'; - $accountRequest->notes = 'notas'; - $accountRequest->userEditId = 1; - $accountRequest->passDateChange = time() + 3600; - $accountRequest->clientId = 1; - $accountRequest->categoryId = 1; - $accountRequest->isPrivate = 0; - $accountRequest->isPrivateGroup = 0; - $accountRequest->parentId = 0; - $accountRequest->userGroupId = 2; - - $this->assertTrue(self::$accountRepository->update($accountRequest)); - - $account = self::$accountRepository->getById(1); - - $this->assertEquals($accountRequest->name, $account->getName()); - $this->assertEquals($accountRequest->login, $account->getLogin()); - $this->assertEquals($accountRequest->url, $account->getUrl()); - $this->assertEquals($accountRequest->notes, $account->getNotes()); - $this->assertEquals($accountRequest->userEditId, $account->getUserEditId()); - $this->assertEquals($accountRequest->passDateChange, $account->getPassDateChange()); - $this->assertEquals($accountRequest->clientId, $account->getClientId()); - $this->assertEquals($accountRequest->categoryId, $account->getCategoryId()); - $this->assertEquals($accountRequest->isPrivate, $account->getIsPrivate()); - $this->assertEquals($accountRequest->isPrivateGroup, $account->getIsPrivateGroup()); - $this->assertEquals($accountRequest->parentId, $account->getParentId()); - - // El grupo no debe de cambiar si el usuario no tiene permisos - $this->assertNotEquals($accountRequest->userGroupId, $account->getUserGroupId()); - $this->assertEquals(1, $account->getUserGroupId()); - } - - /** - * No implementado - */ - public function testCheckDuplicatedOnAdd() - { - $this->markTestSkipped(); - } - - /** - * Comprobar la eliminación en lotes - * - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - */ - public function testDeleteByIdBatch() - { - // Comprobar registros iniciales - $this->assertEquals(2, $this->conn->getRowCount('Account')); - - $this->assertEquals(2, self::$accountRepository->deleteByIdBatch([1, 2, 100])); - - // Comprobar registros tras eliminación - $this->assertEquals(0, $this->conn->getRowCount('Account')); - } - - /** - * Comprobar la búsqueda de cuentas - */ - public function testSearch() - { - // Comprobar búsqueda con el texto Google Inc - $itemSearchData = new ItemSearchData(); - $itemSearchData->setSeachString('Google'); - $itemSearchData->setLimitCount(10); - - $search = self::$accountRepository->search($itemSearchData); - - $this->assertCount(2, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(1, $search['count']); - $this->assertInstanceOf(\stdClass::class, $search[0]); - $this->assertEquals(1, $search[0]->id); - $this->assertEquals('Google', $search[0]->name); - - // Comprobar búsqueda con el texto Apple - $itemSearchData = new ItemSearchData(); - $itemSearchData->setSeachString('Apple'); - $itemSearchData->setLimitCount(1); - - $search = self::$accountRepository->search($itemSearchData); - $this->assertCount(2, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(1, $search['count']); - $this->assertInstanceOf(\stdClass::class, $search[0]); - $this->assertEquals(2, $search[0]->id); - $this->assertEquals('Apple', $search[0]->name); - } - - /** - * Comprobar las cuentas enlazadas - */ - public function testGetLinked() - { - $filter = new QueryCondition(); - $filter->addFilter('Account.parentId = 1'); - - $this->assertCount(0, self::$accountRepository->getLinked($filter)); - } - - /** - * Comprobar en incremento del contador de vistas - * - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - * @throws SPException - */ - public function testIncrementViewCounter() - { - $accountBefore = self::$accountRepository->getById(1); - - $this->assertTrue(self::$accountRepository->incrementViewCounter(1)); - - $accountAfter = self::$accountRepository->getById(1); - - $this->assertEquals($accountBefore->getCountView() + 1, $accountAfter->getCountView()); - } - - /** - * Obtener todas las cuentas - */ - public function testGetAll() - { - $this->assertCount(2, self::$accountRepository->getAll()); - } - - /** - * @throws SPException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testUpdatePassword() - { - $accountRequest = new AccountPasswordRequest(); - $accountRequest->id = 2; - $accountRequest->key = Crypt::makeSecuredKey(self::SECURE_KEY_PASSWORD); - $accountRequest->pass = Crypt::encrypt('1234', $accountRequest->key, self::SECURE_KEY_PASSWORD); - - // Comprobar que la modificación de la clave es correcta - $this->assertTrue(self::$accountRepository->updatePassword($accountRequest)); - - $accountPassData = self::$accountRepository->getPasswordForId(2); - $clearPassword = Crypt::decrypt($accountPassData->pass, $accountPassData->key, self::SECURE_KEY_PASSWORD); - - // Comprobar que la clave obtenida es igual a la encriptada anteriormente - $this->assertEquals('1234', $clearPassword); - } - - /** - * Comprobar en incremento del contador de desencriptado - * - * @throws SPException - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - */ - public function testIncrementDecryptCounter() - { - $accountBefore = self::$accountRepository->getById(1); - - $this->assertTrue(self::$accountRepository->incrementDecryptCounter(1)); - - $accountAfter = self::$accountRepository->getById(1); - - $this->assertEquals($accountBefore->getCountDecrypt() + 1, $accountAfter->getCountDecrypt()); - } - - /** - * Comprobar el número total de cuentas - */ - public function testGetTotalNumAccounts() - { - $this->assertEquals(2, self::$accountRepository->getTotalNumAccounts()->num); - } - - /** - * No implementado - */ - public function testGetDataForLink() - { - $this->markTestSkipped(); - } - - /** - * Comprobar las cuentas devueltas para un filtro de usuario - */ - public function testGetForUser() - { - $queryCondition = new QueryCondition(); - $queryCondition->addFilter('Account.isPrivate = 1'); - - $this->assertCount(0, self::$accountRepository->getForUser($queryCondition)); - } - - /** - * Comprobar las cuentas devueltas para obtener los datos de las claves - */ - public function testGetAccountsPassData() - { - $this->assertCount(2, self::$accountRepository->getAccountsPassData()); - } - - /** - * Comprobar la creación de una cuenta - * - * @throws SPException - * @throws \Defuse\Crypto\Exception\CryptoException - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - */ - public function testCreate() - { - $accountRequest = new AccountRequest(); - $accountRequest->name = 'Prueba 2'; - $accountRequest->login = 'admin'; - $accountRequest->url = 'http://syspass.org'; - $accountRequest->notes = 'notas'; - $accountRequest->userEditId = 1; - $accountRequest->passDateChange = time() + 3600; - $accountRequest->clientId = 1; - $accountRequest->categoryId = 1; - $accountRequest->isPrivate = 0; - $accountRequest->isPrivateGroup = 0; - $accountRequest->parentId = 0; - $accountRequest->userId = 1; - $accountRequest->userGroupId = 2; - $accountRequest->key = Crypt::makeSecuredKey(self::SECURE_KEY_PASSWORD); - $accountRequest->pass = Crypt::encrypt('1234', $accountRequest->key, self::SECURE_KEY_PASSWORD); - - // Comprobar registros iniciales - $this->assertEquals(2, $this->conn->getRowCount('Account')); - - self::$accountRepository->create($accountRequest); - - // Comprobar registros finales - $this->assertEquals(3, $this->conn->getRowCount('Account')); - } - - /** - * No implementado - */ - public function testGetByIdBatch() - { - $this->markTestSkipped(); - } - - /** - * No implementado - */ - public function testCheckDuplicatedOnUpdate() - { - $this->markTestSkipped(); - } - - /** - * No implementado - */ - public function testGetPasswordHistoryForId() - { - $this->markTestSkipped(); - } - - /** - * Comprobar la búsqueda de cuentas mediante filtros - */ - public function testGetByFilter() - { - $searchFilter = new AccountSearchFilter(); - $searchFilter->setLimitCount(10); - $searchFilter->setCategoryId(1); - - // Comprobar un Id de categoría - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(1, $response->getCount()); - $this->assertCount(1, $response->getData()); - - // Comprobar un Id de categoría no existente - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setCategoryId(10); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(0, $response->getCount()); - $this->assertCount(0, $response->getData()); - - // Comprobar un Id de cliente - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setClientId(1); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(1, $response->getCount()); - $this->assertCount(1, $response->getData()); - - // Comprobar un Id de cliente no existente - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setClientId(10); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(0, $response->getCount()); - $this->assertCount(0, $response->getData()); - - // Comprobar una cadena de texto - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setCleanTxtSearch('apple.com'); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(1, $response->getCount()); - $this->assertCount(1, $response->getData()); - $this->assertEquals(2, $response->getData()[0]->getId()); - - // Comprobar los favoritos - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setSearchFavorites(true); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(0, $response->getCount()); - $this->assertCount(0, $response->getData()); - - // Comprobar las etiquetas - $searchFilter->reset(); - $searchFilter->setLimitCount(10); - $searchFilter->setTagsId([1]); - - $response = self::$accountRepository->getByFilter($searchFilter); - $this->assertInstanceOf(AccountSearchResponse::class, $response); - $this->assertEquals(1, $response->getCount()); - $this->assertCount(1, $response->getData()); - $this->assertEquals(1, $response->getData()[0]->getId()); - } -} diff --git a/tests/CategoryRepositoryTestCase.php b/tests/CategoryRepositoryTestCase.php deleted file mode 100644 index 06bcd432..00000000 --- a/tests/CategoryRepositoryTestCase.php +++ /dev/null @@ -1,276 +0,0 @@ -. - */ - -namespace SP\Tests; - -use SP\Core\Exceptions\QueryException; -use SP\DataModel\CategoryData; -use SP\DataModel\ItemSearchData; -use SP\Repositories\Category\CategoryRepository; -use SP\Repositories\DuplicatedItemException; -use SP\Storage\DatabaseConnectionData; - -/** - * Class CategoryRepositoryTest - * - * @package SP\Tests - */ -class CategoryRepositoryTest extends DatabaseBaseTest -{ - /** - * @var CategoryRepository - */ - private static $categoryRepository; - - /** - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - * @throws \DI\DependencyException - */ - public static function setUpBeforeClass() - { - $dic = setupContext(); - - // Datos de conexión a la BBDD - self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); - - // Inicializar el repositorio - self::$categoryRepository = $dic->get(CategoryRepository::class); - } - - /** - * Comprobar los resultados de obtener las categorías por nombre - */ - public function testGetByName() - { - $category = self::$categoryRepository->getByName('Prueba'); - - $this->assertCount(0, $category); - - $category = self::$categoryRepository->getByName('Web'); - - $this->assertEquals(1, $category->getId()); - $this->assertEquals('Web sites', $category->getDescription()); - - $category = self::$categoryRepository->getByName('Linux'); - - $this->assertEquals(2, $category->getId()); - $this->assertEquals('Linux server', $category->getDescription()); - - // Se comprueba que el hash generado es el mismo en para el nombre 'Web' - $category = self::$categoryRepository->getByName(' web. '); - - $this->assertEquals(1, $category->getId()); - $this->assertEquals('Web sites', $category->getDescription()); - } - - /** - * Comprobar la búsqueda mediante texto - */ - public function testSearch() - { - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('linux'); - - $search = self::$categoryRepository->search($searchItemData); - $this->assertCount(2, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(1, $search['count']); - $this->assertEquals(2, $search[0]->id); - $this->assertEquals('Linux server', $search[0]->description); - - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('prueba'); - - $search = self::$categoryRepository->search($searchItemData); - $this->assertCount(1, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(0, $search['count']); - } - - /** - * Comprobar los resultados de obtener las categorías por Id - */ - public function testGetById() - { - $category = self::$categoryRepository->getById(10); - - $this->assertCount(0, $category); - - $category = self::$categoryRepository->getById(1); - - $this->assertEquals('Web', $category->getName()); - $this->assertEquals('Web sites', $category->getDescription()); - - $category = self::$categoryRepository->getById(2); - - $this->assertEquals('Linux', $category->getName()); - $this->assertEquals('Linux server', $category->getDescription()); - } - - /** - * Comprobar la obtención de todas las categorías - */ - public function testGetAll() - { - $count = $this->conn->getRowCount('Category'); - - $results = self::$categoryRepository->getAll(); - - $this->assertCount($count, $results); - - $this->assertInstanceOf(CategoryData::class, $results[0]); - $this->assertEquals('Linux', $results[0]->getName()); - - $this->assertInstanceOf(CategoryData::class, $results[1]); - $this->assertEquals('SSH', $results[1]->getName()); - - $this->assertInstanceOf(CategoryData::class, $results[2]); - $this->assertEquals('Web', $results[2]->getName()); - } - - /** - * Comprobar la actualización de categorías - * - * @covers \SP\Repositories\Category\CategoryRepository::checkDuplicatedOnUpdate() - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - * @throws \SP\Core\Exceptions\SPException - * @throws \SP\Repositories\DuplicatedItemException - */ - public function testUpdate() - { - $categoryData = new CategoryData(); - $categoryData->id = 1; - $categoryData->name = 'Web prueba'; - $categoryData->description = 'Descripción web prueba'; - - self::$categoryRepository->update($categoryData); - - $category = self::$categoryRepository->getById(1); - - $this->assertEquals($category->getName(), $categoryData->name); - $this->assertEquals($category->getDescription(), $categoryData->description); - - // Comprobar la a actualización con un nombre duplicado comprobando su hash - $categoryData = new CategoryData(); - $categoryData->id = 1; - $categoryData->name = ' linux.'; - - $this->expectException(DuplicatedItemException::class); - - self::$categoryRepository->update($categoryData); - } - - /** - * Comprobar la eliminación de categorías - * - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - */ - public function testDeleteByIdBatch() - { - $countBefore = $this->conn->getRowCount('Category'); - - $this->assertEquals(1, self::$categoryRepository->deleteByIdBatch([3])); - - $countAfter = $this->conn->getRowCount('Category'); - - $this->assertEquals($countBefore - 1, $countAfter); - - // Comprobar que se produce una excepción al tratar de eliminar categorías usadas - $this->expectException(QueryException::class); - - $this->assertEquals(1, self::$categoryRepository->deleteByIdBatch([1, 2, 3])); - } - - /** - * Comprobar la creación de categorías - * - * @covers \SP\Repositories\Category\CategoryRepository::checkDuplicatedOnAdd() - * @throws DuplicatedItemException - * @throws \SP\Core\Exceptions\SPException - */ - public function testCreate() - { - $countBefore = $this->conn->getRowCount('Category'); - - $categoryData = new CategoryData(); - $categoryData->name = 'Categoría prueba'; - $categoryData->description = 'Descripción prueba'; - - $id = self::$categoryRepository->create($categoryData); - - // Comprobar que el Id devuelto corresponde con la categoría creada - $category = self::$categoryRepository->getById($id); - - $this->assertEquals($categoryData->name, $category->getName()); - - $countAfter = $this->conn->getRowCount('Category'); - - $this->assertEquals($countBefore + 1, $countAfter); - } - - /** - * Comprobar la eliminación de categorías por Id - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testDelete() - { - $countBefore = $this->conn->getRowCount('Category'); - - $this->assertEquals(1, self::$categoryRepository->delete(3)); - - $countAfter = $this->conn->getRowCount('Category'); - - $this->assertEquals($countBefore - 1, $countAfter); - - // Comprobar que se produce una excepción al tratar de eliminar categorías usadas - $this->expectException(QueryException::class); - - $this->assertEquals(1, self::$categoryRepository->delete(2)); - } - - /** - * Comprobar la obtención de categorías por Id en lote - */ - public function testGetByIdBatch() - { - $this->assertCount(3, self::$categoryRepository->getByIdBatch([1, 2, 3])); - $this->assertCount(3, self::$categoryRepository->getByIdBatch([1, 2, 3, 4, 5])); - $this->assertCount(0, self::$categoryRepository->getByIdBatch([])); - } - - /** - * No implementado - */ - public function testCheckInUse() - { - $this->markTestSkipped(); - } -} diff --git a/tests/ClientRepositoryTestCase.php b/tests/ClientRepositoryTestCase.php deleted file mode 100644 index 69439f5a..00000000 --- a/tests/ClientRepositoryTestCase.php +++ /dev/null @@ -1,290 +0,0 @@ -. - */ - -namespace SP\Tests; - -use SP\Core\Exceptions\QueryException; -use SP\DataModel\ClientData; -use SP\DataModel\ItemSearchData; -use SP\Mvc\Model\QueryCondition; -use SP\Repositories\Client\ClientRepository; -use SP\Repositories\DuplicatedItemException; -use SP\Storage\DatabaseConnectionData; - -/** - * Class ClientRepositoryTest - * - * @package SP\Tests - */ -class ClientRepositoryTest extends DatabaseBaseTest -{ - /** - * @var ClientRepository - */ - private static $clientRepository; - - /** - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - * @throws \DI\DependencyException - */ - public static function setUpBeforeClass() - { - $dic = setupContext(); - - // Datos de conexión a la BBDD - self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); - - // Inicializar el repositorio - self::$clientRepository = $dic->get(ClientRepository::class); - } - - /** - * Comprobar los resultados de obtener los cliente por nombre - */ - public function testGetByName() - { - $client = self::$clientRepository->getByName('Amazon'); - - $this->assertCount(0, $client); - - $client = self::$clientRepository->getByName('Google'); - - $this->assertEquals(1, $client->getId()); - $this->assertEquals('Google Inc.', $client->getDescription()); - - $client = self::$clientRepository->getByName('Apple'); - - $this->assertEquals(2, $client->getId()); - $this->assertEquals('Apple Inc.', $client->getDescription()); - - // Se comprueba que el hash generado es el mismo en para el nombre 'Web' - $client = self::$clientRepository->getByName(' google. '); - - $this->assertEquals(1, $client->getId()); - $this->assertEquals('Google Inc.', $client->getDescription()); - } - - /** - * Comprobar la búsqueda mediante texto - */ - public function testSearch() - { - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('google'); - - $search = self::$clientRepository->search($searchItemData); - $this->assertCount(2, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(1, $search['count']); - $this->assertEquals(1, $search[0]->id); - $this->assertEquals('Google Inc.', $search[0]->description); - - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('prueba'); - - $search = self::$clientRepository->search($searchItemData); - $this->assertCount(1, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(0, $search['count']); - } - - /** - * Comprobar los resultados de obtener los clientes por Id - */ - public function testGetById() - { - $client = self::$clientRepository->getById(10); - - $this->assertCount(0, $client); - - $client = self::$clientRepository->getById(1); - - $this->assertEquals('Google', $client->getName()); - $this->assertEquals('Google Inc.', $client->getDescription()); - - $client = self::$clientRepository->getById(2); - - $this->assertEquals('Apple', $client->getName()); - $this->assertEquals('Apple Inc.', $client->getDescription()); - } - - /** - * Comprobar la obtención de todas las client - */ - public function testGetAll() - { - $count = $this->conn->getRowCount('Client'); - - $results = self::$clientRepository->getAll(); - - $this->assertCount($count, $results); - - $this->assertInstanceOf(ClientData::class, $results[0]); - $this->assertEquals('Apple', $results[0]->getName()); - - $this->assertInstanceOf(ClientData::class, $results[1]); - $this->assertEquals('Google', $results[1]->getName()); - - $this->assertInstanceOf(ClientData::class, $results[2]); - $this->assertEquals('Microsoft', $results[2]->getName()); - } - - /** - * Comprobar la actualización de clientes - * - * @covers \SP\Repositories\Client\ClientRepository::checkDuplicatedOnUpdate() - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - * @throws \SP\Core\Exceptions\SPException - * @throws \SP\Repositories\DuplicatedItemException - */ - public function testUpdate() - { - $clientData = new ClientData(); - $clientData->id = 1; - $clientData->name = 'Cliente prueba'; - $clientData->description = 'Descripción cliente prueba'; - - self::$clientRepository->update($clientData); - - $category = self::$clientRepository->getById(1); - - $this->assertEquals($category->getName(), $clientData->name); - $this->assertEquals($category->getDescription(), $clientData->description); - - // Comprobar la a actualización con un nombre duplicado comprobando su hash - $clientData = new ClientData(); - $clientData->id = 1; - $clientData->name = ' apple.'; - - $this->expectException(DuplicatedItemException::class); - - self::$clientRepository->update($clientData); - } - - /** - * Comprobar la eliminación de clientes - * - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - */ - public function testDeleteByIdBatch() - { - $countBefore = $this->conn->getRowCount('Client'); - - $this->assertEquals(1, self::$clientRepository->deleteByIdBatch([3])); - - $countAfter = $this->conn->getRowCount('Client'); - - $this->assertEquals($countBefore - 1, $countAfter); - - // Comprobar que se produce una excepción al tratar de eliminar clientes usados - $this->expectException(QueryException::class); - - $this->assertEquals(1, self::$clientRepository->deleteByIdBatch([1, 2, 3])); - } - - /** - * Comprobar la creación de clientes - * - * @covers \SP\Repositories\Client\ClientRepository::checkDuplicatedOnAdd() - * @throws DuplicatedItemException - * @throws \SP\Core\Exceptions\SPException - */ - public function testCreate() - { - $countBefore = $this->conn->getRowCount('Client'); - - $clientData = new ClientData(); - $clientData->name = 'Cliente prueba'; - $clientData->description = 'Descripción prueba'; - $clientData->isGlobal = 1; - - $id = self::$clientRepository->create($clientData); - - // Comprobar que el Id devuelto corresponde con el cliente creado - $client = self::$clientRepository->getById($id); - - $this->assertEquals($clientData->name, $client->getName()); - $this->assertEquals($clientData->isGlobal, $client->getIsGlobal()); - - $countAfter = $this->conn->getRowCount('Client'); - - $this->assertEquals($countBefore + 1, $countAfter); - } - - /** - * Comprobar la eliminación de clientes por Id - * - * @throws \SP\Core\Exceptions\QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testDelete() - { - $countBefore = $this->conn->getRowCount('Client'); - - $this->assertEquals(1, self::$clientRepository->delete(3)); - - $countAfter = $this->conn->getRowCount('Client'); - - $this->assertEquals($countBefore - 1, $countAfter); - - // Comprobar que se produce una excepción al tratar de eliminar clientes usados - $this->expectException(QueryException::class); - - $this->assertEquals(1, self::$clientRepository->delete(2)); - } - - /** - * Comprobar la obtención de clientes por Id en lote - */ - public function testGetByIdBatch() - { - $this->assertCount(3, self::$clientRepository->getByIdBatch([1, 2, 3])); - $this->assertCount(3, self::$clientRepository->getByIdBatch([1, 2, 3, 4, 5])); - $this->assertCount(0, self::$clientRepository->getByIdBatch([])); - } - - /** - * No implementado - */ - public function testCheckInUse() - { - $this->markTestSkipped(); - } - - /** - * @throws QueryException - */ - public function testGetAllForFilter() - { - $filter = new QueryCondition(); - $filter->addFilter('Account.isPrivate = 0'); - - $this->assertCount(3, self::$clientRepository->getAllForFilter($filter)); - } -} diff --git a/tests/Repositories/AccountFileRepositoryTest.php b/tests/Repositories/AccountFileRepositoryTest.php new file mode 100644 index 00000000..6d123b6b --- /dev/null +++ b/tests/Repositories/AccountFileRepositoryTest.php @@ -0,0 +1,315 @@ +. + */ + +namespace SP\Tests\Repositories; + +use PHPUnit\DbUnit\DataSet\IDataSet; +use SP\DataModel\FileData; +use SP\DataModel\FileExtData; +use SP\DataModel\ItemSearchData; +use SP\Repositories\Account\AccountFileRepository; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Tests\DatabaseTestCase; +use function SP\Tests\setupContext; + +/** + * Class AccountFileRepositoryTest + * + * @package SP\Tests\Repositories + */ +class AccountFileRepositoryTest extends DatabaseTestCase +{ + /** + * @var AccountFileRepository + */ + private static $repository; + + /** + * @throws \DI\DependencyException + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el repositorio + self::$repository = $dic->get(AccountFileRepository::class); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testDelete() + { + $this->assertEquals(1, self::$repository->delete(1)); + $this->assertEquals(1, self::$repository->delete(3)); + $this->assertEquals(0, self::$repository->delete(10)); + + $this->assertEquals(1, $this->conn->getRowCount('AccountFile')); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testDeleteByIdBatch() + { + $this->assertEquals(2, self::$repository->deleteByIdBatch([1, 3, 10])); + $this->assertEquals(0, self::$repository->deleteByIdBatch([])); + + $this->assertEquals(1, $this->conn->getRowCount('AccountFile')); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetInfoById() + { + $result = self::$repository->getInfoById(1); + /** @var FileExtData $data */ + $data = $result->getData(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('sysPass.xml', $data->getName()); + $this->assertEquals('text/xml', $data->getType()); + $this->assertEquals('XML', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(1312, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertNull($data->getContent()); + $this->assertNull($data->getThumb()); + + $result = self::$repository->getInfoById(10); + + $this->assertEquals(0, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetById() + { + $result = self::$repository->getById(1); + /** @var FileExtData $data */ + $data = $result->getData(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('sysPass.xml', $data->getName()); + $this->assertEquals('text/xml', $data->getType()); + $this->assertEquals('XML', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(1312, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertEquals(pack('H*', '3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C526F6F743E0A20203C4D6574613E0A202020203C47656E657261746F723E737973506173733C2F47656E657261746F723E0A202020203C56657273696F6E3E312E322E303C2F56657273696F6E3E0A202020203C54696D653E313433393332353330343C2F54696D653E0A202020203C557365722069643D2231223E61646D696E3C2F557365723E0A202020203C47726F75702069643D2231223E41646D696E733C2F47726F75703E0A202020203C486173683E36646232633238323731393136326630663136316531343731653734636531623C2F486173683E0A20203C2F4D6574613E0A20203C43617465676F726965733E0A202020203C43617465676F72792069643D2231223E0A2020202020203C6E616D653E485454503C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F43617465676F72793E0A20203C2F43617465676F726965733E0A20203C437573746F6D6572733E0A202020203C437573746F6D65722069643D2231223E0A2020202020203C6E616D653E476F6F676C6520496E632E3C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A202020203C437573746F6D65722069643D2232223E0A2020202020203C6E616D653E4D6963726F736F667420496E633C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A20203C2F437573746F6D6572733E0A20203C4163636F756E74733E0A202020203C4163636F756E742069643D2231223E0A2020202020203C6E616D653E476F6F676C653C2F6E616D653E0A2020202020203C637573746F6D657249643E313C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E61646D696E3C2F6C6F67696E3E0A2020202020203C75726C3E382E382E382E383C2F75726C3E0A2020202020203C6E6F7465732F3E0A2020202020203C706173733E6C4E66513133634B6A384D592B79434F346652536B4773494334357247454C442F424E69345654614671593D3C2F706173733E0A2020202020203C7061737369763E454E6354743338503265346C643350395A553241767939664C466277386C42473947382F75414D785A6D343D3C2F7061737369763E0A202020203C2F4163636F756E743E0A202020203C4163636F756E742069643D2232223E0A2020202020203C6E616D653E4D6963726F736F66743C2F6E616D653E0A2020202020203C637573746F6D657249643E323C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E726F6F743C2F6C6F67696E3E0A2020202020203C75726C3E342E342E342E343C2F75726C3E0A2020202020203C6E6F7465733E4E6F746173206465206D6963726F66736F66743C2F6E6F7465733E0A2020202020203C706173733E3352394F48632B53335A4E56684D795948352F784C476C76625246662F5367573348527261322B325349453D3C2F706173733E0A2020202020203C7061737369763E763637306A596B43547178635332344C4F65453077672B304330376A734C2F4635342B6E56484963544F773D3C2F7061737369763E0A202020203C2F4163636F756E743E0A20203C2F4163636F756E74733E0A3C2F526F6F743E0A'), $data->getContent()); + $this->assertEquals(pack('H*', '6E6F5F7468756D62'), $data->getThumb()); + + $result = self::$repository->getById(4); + /** @var FileExtData $data */ + $data = $result->getData(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('android.png', $data->getName()); + $this->assertEquals('image/png', $data->getType()); + $this->assertEquals('PNG', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(4295, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertEquals(pack('H*', '89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61CB00000006624B474400FF00FF00FFA0BDA793000000097048597300000B1300000B1301009A9C180000000774494D4507DD011D0E180BE2306F78000010544944415478DAED5D6B745CD575FEBE7DEFC8961F3C0C01EC45480C2B8B0026A1D4206B2CB9C27181F208D074816D59069A16280B92A6246D42520A252D210FD2248426818418C9C63CD264C182BAE1154B1A4960CAB35E506A1E5D26501C9E768464CDDCF3F5C7BDA31796A59135F28CE66C2D594B9A19DF73F7FECEB71F67DF7388329096CCC293C1E997845174D1F2FACE374B7DBCCD1B17CF0F42DDDB1BED58F2E74B9E7DBB94C76AE5000069DA05A2CE8CA8EF94FA587FF6507D1503D71A018757D9EC334A7DBC650100B2E79F4C70B0E0336B338BFEA494C75A352DF70D1AE71AB8F9A5F51DCD1E001320AB163FB159C2CD12663A58D35D1DE9D9A538CE350F351C65C6931D1038B9CBAFBA11F200983016705F96DC9B3077CE4EC7926481B0BAF7F208760C22AD69AAEBEC2A07BD960D001AD39DBF27832F986C3A694DEBDA4F9A5352816A5BC332293CD790450AE115E5A2D7B201000050D10310FE57CC9DEAD47342A98CEBB6473E5585A0F72C3077805C78EDF2FAB6B7CA46A7283359DB9E5E2D6A0DA42E9B3E73C9CA850F6547FBCCBAB69A1991719E219C0146F38420A07400E40218009102BA01F70E2D34C1BD48177457F76CDFF6A7CB9ECE8D9AF6B5A76B403C4CEA8528179D76FE92C75E2F177D86E5060089F793DC08CBFD91EBED5905E0D6E1EFB9E7D7A7A5B6CFD85E47BAE3011C23E02002F300CD00381750086086C86133C0DE8364005E045C774FF5CCDFB574A4B7105107A2E0A5C6FA8EA7771D9FE07A11339C70533919BF2C1900009ADBEACE27A31F928E3DCF1FB5EF5F7CF6E7B907375F17BCF6EE7D75845B29E3498110413A5C4415101B5A1020825072E79404821093BF0CFC4100084A10F09E889728E668EE2E58EFFAC69A27B702C0DAAE450B11059B003D09F0338D8B332F7B004C46D09549B782564FD7773314DE01E3B7441C09A91A04094862FC1322C971F14DE21E10A3062024800ECEDD1B657139A6A183C0C141C4BF5B59DFF1BD72D3A3952B00E8EC3B0E511616FCA5026D70D47110A69348883DB139314EE327E44E80313DC43F6240848E38C7A6BB570D3CCCC4E742CDBCBB2CF5586E035ED75A77906374BA8C5F20B9801A740F1404F6D379516290D871C47048CA3CA2EBA37827841FCEDEE785473FFD8937E5015014DAAF3D9BB02F89AA0110304FC87BF12E84FC10040ADB40AC0F72D13F2F5FF2E81B1E0013286B3A177D3E10AF226C7FF4CF7A09E4DEBD07C59C80981048E07527BD2EBAAFAF4E77FDD203604F23FE478EFF10AAAAEE27834F00AAA228F183095C09E5A94E8441B683DCF9DDC6F4A67FF000182FE5B72F3A8EC0DD8E7604291156168C250146413038E46E545FF4E5D50D9BBA7D1650C8CC6FAF6D20C33B6176841162A2D2B2F0AB141C28C081B2CB2C0C7FBCB6ADE610CF00632EF4D42E03ED76331D085122588E050B498A07EE08173E9072D59F3D77C9035B3D03EC2ED8EB38611189663377A0627F3AC4F8FD2CA0815F94285B93481071553119811497103198A394142008C004BA3FDE99DA7E434BF3D98107C0483EBFB5EEE32985FF06E21080026803D9769EB20827C9D14114639A158C2439192088314711A2E8E020231C1947A7FDC3CDC3564412B352C1593AFCB59B3C007635F3DB3FB91F037C3F6270485C6461BE82C7FE843B9E66204593DD41B15E2E3C09D4CD4E8AE2A430FFAEE2794D4104B25BA19D17059C51A75C7635113DDBBFA4306400C99F62F0A608BB706D7BFA2B3E06F84091E7C46B81F06BCC2B99C290544F8098706EE4AE6BAA7FF4CA217143E6842B89F01A9261D18286643549E4EB51A4D3CEAFEF782AFFD2ADBF39E1A3A954F84B92C78DA45AE54B46D2FF98B4AAB1AEF331CF00009A338B9792C165C984573C69862A50042882C2CBA4EEFAC08D38B600F6BC8A896AC6CB4C14EEDA27D5F7CCE0972E6CD8F40AC9FB04E634E20808023D240E75C0579B5B97CCAE7800AC6B4FCF32E03A80FB4914A8DD509500E27D67DA39FCF569E1F6B71DD58D64E1B758819F20107CF59C458FBBE1AF3BB93700971DF1FA94245553ACA6F1D316642FA8780038D829803B7160E68E40DEFD457FCE35D841C35FEEC91E7244001DC4A252401E08EE9896F6F4B45D14001680563DD200E28549E66F0620AE696E3D69DF8A060019FD24B1B9304A7D3751DB1CCABED9D2567F707FFCB0B1617F0BB2D70236BFA8E19F986F275949E8ACC1AFDD96492F03B814D27BA351D0C00206F767D0FDAD8A0D029B330B2F37567D7FA0B83FDAF41506DE1BBDE5E0EE320494AC01D491717C56D4D5E0A4B813E7F764EE61297C4EEA3B9808FE0CB4FEE2C4686B15493E03D04541943A74457DEBFFED0D1B847B177DC15730A4238BA37E228EC1242A3C80D4250E02E3926BB15B0112C62263E34952B014744B8500A425FD64635B9E8C7B952081E6D8FB8F002EAA2817D0D256BB4AC6B990A9309B09042926052011A42545A1C921B498004832C69CD1125B16967C8A202588567767DBA70EACAC1820D05F518100C74279A33FA1E280CD277B7998838A3CFDDC349EFF8324611FC95ACFD9150380B5AD4B3F02D961B1439F84B0BD644549A518331CDD49150300A57A1B44EE17F75C56AAF1630E50E24688E0D0E6CE051FAA1017A005046654B2E9070702A000B92318EDBF60CA03E017FF716695938E066028970E8FE2C612F1CA91611E2D9AFA0CD03B63DB7E06CC2A853A44E96000824888C7ADED4807531A001686F3011E36100555BA07102832E92F98A149AECD4C7A2128723A90B039A050AEAD5E139E4E524999DB8E256C5F00DBA62C009227B7025478FC3FC2F430208B29CD0002B611F8B58499A477018366468A0A36050A764E6900107A42C205F404F0C1A9A1E939B959EF4FBA0B1AAF34676AE691566F48D508EE9DC8E9A954F7EC8D2B4ED9B0DD1BB438D29CA9F918192E31040B1DDC13514EAF9CBF24F3C0A402E0F68DB587E542DE48E014C6FE3CDFB02331474655B734D6B75DECCD3571B2AE75D127A330F839A5A3498679CE889BA4A26E44A9ABB163EBF71A4F7FC51515002D99DAD341DD06700E6183D6C7014870341111216D0E34FDBC1575BFD93CE4463A6A0E92C27B00D5F81CE003723380CF35A633BD43667DC7A28B41DE4467963C953E68E9537020880890D6079AF6D72BEA5AC7FC6472417580E6B69A1300FE2BC53954DC843F78F95B244C8E94810C8E7196BDBBA5BDF6C8A1AE4E7301DB4FCCB779FBAF415FBDC38BA32DED8B9AA8E0BB2658BE6A3878DD5B204C1211880C973B8BD6B4B4D7CD9A700034671A029A7D9BD487018BA7FDB0199C2C6FF6F7650AEEE3802E5DBB71516AD09B1C2097BC3F590EF25F498A3C24396E6E5F7C04C8AB49552BE993E72EEB08A424C6CF26B953A05CD3C43380BAEB9D6909644967EC983C8C447E2E0A73733DBB17E86A371E1FC8B26788383CAE9891BB2B9C924C1E5931C0ECEB130E005AEA6B26CB33FD989D374104ACBA6C70B6E3650CC158387D9621BC3451B546EF978C275CBCEF19E74C3C00C423FB2D3A16FB73A00D5AD2511393784EE92AC050C3C8428AF30BD43959605F9A1500D143C7B37C1B03D20EF3262E500C018854B197CC0B5B0D1C4FF52E0E08236FD1717242912BA6616103E29EDC8A977169ADB83ED30A9BCA1310DC78348C514FC464044C361938E69EE3A8E282C0C9D29379D5577AACE9C50360D2E9CD4BE500C00781A5AD27EF023C03F82CC067015E3C031417DDDEF157781AE879BF5453279F05946A16E083401F04FA20D08B07809729910578A95800F820B0B4F5E483401F047AF12EC08B07800F023D007C10E883402F9E017C16E0B3002F9E012618DDDEF157781AE879BF5453279F05946A16E083401F04961E00343E64FB495FBAAEA0803D82149F9B5CE8F8E39391426FC98215376E9D178901F842FE1C6C150A5FD9666FD142273E7300DFDFC571E4A3E75C2A0600A8479C84E470BEB182588C8F4369F74160614120C93E119D89CE59B0CE271A0074A95FC5C7DE8E313C91440674CAED10ED1E1F0416E8EAA3AA5E8A1B2C7FA450413AEFDB32E10050D0FD2085F6FCE9DEA3108DE2CD0B2384A8FA494AF686377161B2B2FEE11CADF75780B62001C16E483F09B748288714A65D3FE10068AC7D3C47049713B655D26E0F4A14C47833496D702E77FD7975AD7DDEA4E30041EDE35B8C760DA077F346DEB5778ECF1F4D7692BD75F9E2CC2D454903572E6E7B8AD0192032FD916A12AFF6EF6528C45182C32F9C729736D677FDCE9B72FCB2A236D302B87341BC0A80BBD0B980E4CC6C871B2297FB62510B412BD399670CC1994ED94B1CB955122947894E7410B545C0AA200A2F6CAADBF4F264E7B55325081CC2BEE9AE07082E72CA5EE5C8ED8374DE2B3A8AEC14706A900BBFBABA7ED3DB1375DDDDCA6DED7F405AB585C25CC7F0A326CD065C67CEB4A3A9B663C47D01D7654E3C56A8BA437447D14785C366067F00E06F876F17DFAFF3CC1F32642A05051F1683434DAA8E987B5030D794CEB8F15C75DC059AD5754F0A4004E0D5E47BEC90F32CB06BF38FA6F3C5FF29007D005E4CBE27B310E4652ACA5E0280A7FDCA05804830B2F8D21E0815070029F50E8077095750CD7AEAFA7E258513029069AA03C0FD7EF61B0ED816073D1E01C999C17454CEC936AE1A2103983200683AF5DFFB10F17E38F478F303B1FD01839E03DDD3151104EE089EFF1903BE3470D85C654241884F550201133734A53B5EA808005C9A7EABCF145C02302B89042B120194E448C0D96381E1DB159406022BD2ADED705806228B7C8D5B82244DCD4AD1209E4BFA3BE266293E196571DAB9B51DDBF60A08F7B65A9A1F699887AA9DFF02DA1924AAA87C7E38BC3696EF2E62D29352C0D0E3E316C7F639E52F81E458CC424E4AD1C0F8767529451028D144A72CA52F35D677FE60AFB250A9CC8FE6F68663C0F79752C1C930CC27866544F16F1F1335AD20FB4BC9D1C602C4A74104A3CC53519C25623E871DD23A46A70E88DB40BD81E14BE69203AA9E72DAB921E776DC77E192FFDAEB876C975525666D7BDDB330B7000503C000E4D098EE1AD3A7D6B52D5BE8C2DE4D540E5050200144809B76E5AABA8DD7F942D0441ABFAD9EC0EE67EF44615D8CF619FF550850D5E5A2D78A590CF235870A0780970A07805F76F20CE0C503C08B0780179F0578F141A017EF02BC780078F100F000F041A007800F023D00CA62066B4F66BFA780F20600A9713D56986F3F5701144044C975A67EE37A1901C040322C7432934CFA0C830240D3174285870E713323813D78E8D60360448920445D85FB732528C83D53006CBA18F7111674A97827172188824D1E00132C2B1767E4C88D4326DB581120C031BA77CC1F30ED10A2FFD69877C4CA030D800867D97B3C008A2081C3060AEF8820C4E489128D6475411044120E556EDF9BC67A9D55E92E19F023CA90B40703BB799251F90EE6785FC79F8239E701500479FDB73B5F8BA42B81C8C5BBE7891A21BACB3F73176F5785BF5F5EF7E06B05390EA5D608783ADE0E2BDE7D6FF71C0300DAE622BBA17171973C008A20579CF7B864582F879BD11FA727F6C2E07DB4D4FF9280DB65F6CD42AFB5AAAEED1D0997027815200752102529699E7F92A707A45E29FA22DC2BCFF92CA088727EBAF35DF5CCBA42C87E03021C92FD11E3CDD2E418EF4F2C3AC0E1A786E06F9A6A33E3DAA62E65DD5D70D17952EE29C9C131796A20F9D7E59F0171EE2D38AD9866B6AEA9E1B7659539966D816C4DE7B166D1CCA369EE6263D525CEB9300E0DF43E94BDC55C6AFD4EC3A3172EEED8637FBCA67D416A9AED7F7AD6B9CF9BB98678DE0812B790EE6A396E5855D7F15639EAF1FF015841FD48A44C570F0000000049454E44AE426082'), $data->getContent()); + $this->assertEquals(pack('H*', '6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141414470556C45515652596865315A585567555552512B5A39646358624E4E4C4C4D314E6247303341724B4A585533677167484B336F776968376336442B71682F372F33346F67736A434C364B45777A622B4B54497A6F77536853574E63734C4E61734B4372536367304E79705A437935335477395934732B73366439787252505539444C4E7A7633504F64382B636D5876504C494161584B7A4C557355767461766A44775737387449596D535A7A5645526B6946722F7167316D576730614C516F65387634634636654C546441626F6B4A36653451334C37353075586F453453647A7837475539664D623166704874515941554F6159302F72636E5A67614159546F36344149554F696A72546B504D75614E71616E7347485A424A66597372556244776953674C597675662F37557038712F566857377543354C47344C494E673045584A7762682B423539736A4E5835444A6243696F544E64714E597871524531545A6F354F6D54374B58745046614D4B55665031497A5948544A67414541674C68304B5A6D6A3063676F6B4238416A702F39486E624B7A635149654B30444D4D5357787850515158583072324A49595344713577766D7430376C6A554E6B7171614B7832314E7A3463574E6C4D6941434167446E72346E5868544C48594D685135776E7543524276324A515041366C334A6741457A744742704C4143597A416278536D696F39734B64544A5A59796756523270437049586D7045524743556A455267597844414A7358336E6433667838386E454B476F6D4E304B5068786B4F5642382B55676B4731376F704B566B71425665796571657177474256717A78797153464A614F71544E47457849765253416F65314951394C53704F7A534D7166425A6F4E47716E467030544768786257617033624A323979526549675A4551724B2B31473470735675796C78743968766F6C49304B5A33537065494242736C6F626A35624F4D53574644573450395155413269324F735558667961727033575361696F7279586436353369707A2B3237482F564A723831634B74636E773837733150452F6349694C686D3332517070372B4770706D6A354D623842586D6E61307A512B367355776131676565486646735253424C3956554D445657494C2F47564C43763133554C506866513072346B7A4D55754B3368425749493143386F622B657A51454E385558476D5661724939625A37344B6A4F786F3969373064417A676257586C4D74626C357142306D6750537461704B4F794C617A4E366B434547624F6A6E49306668304F4B57454D327179504771427366722F6350354C756E4A674935696565755348716E4F6C32396E613565663435436F587A392B6F33344E5230732F5975436F4D4F62483250676C6C6B56434F426D7854744647745073432B396D68656B3076397A4B7251676B66514835665650374F64776E55486E2B36317456372F6B496B714B3833696F3338755261376E6E506B6C496A6A78535A704E2B634C703974753148325670582F594638324A464558487548372B57734954576177677269334A73466E6944502B75677878423839626875496843415172714C71345454782F38764354764B536F7172423132415864726E5942454146356A35586E3271576A687A613267446474424C3039777642767351414159454A5365466D397862597477652B504467414138397A6F636F6631784A565A5133502B4138457749412B7133696A634141414141456C46546B5375516D4343'), $data->getThumb()); + + $result = self::$repository->getById(10); + + $this->assertEquals(0, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCreate() + { + $data = new FileData(); + $data->setAccountId(2); + $data->setName('test.jpg'); + $data->setType('image/jpg'); + $data->setExtension('JPG'); + $data->setContent('image'); + $data->setThumb('thumb'); + $data->setSize(1000); + + $this->assertEquals(5, self::$repository->create($data)); + + $result = self::$repository->getById(5); + /** @var FileExtData $resultData */ + $resultData = $result->getData(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(FileExtData::class, $resultData); + $this->assertEquals($data->getName(), $resultData->getName()); + $this->assertEquals($data->getType(), $resultData->getType()); + $this->assertEquals($data->getExtension(), $resultData->getExtension()); + $this->assertEquals($data->getSize(), $resultData->getSize()); + $this->assertEquals($data->getAccountId(), $resultData->getAccountId()); + $this->assertEquals($data->getContent(), $resultData->getContent()); + $this->assertEquals($data->getThumb(), $resultData->getThumb()); + + $this->assertEquals(4, $this->conn->getRowCount('AccountFile')); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetAll() + { + $result = self::$repository->getAll(); + /** @var FileExtData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals(3, $result->getNumRows()); + $this->assertCount(3, $data); + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals(4, $data[0]->getId()); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals('Google', $data[0]->getAccountName()); + $this->assertEquals('Google', $data[0]->getClientName()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + $this->assertEquals(pack('H*', '89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61CB00000006624B474400FF00FF00FFA0BDA793000000097048597300000B1300000B1301009A9C180000000774494D4507DD011D0E180BE2306F78000010544944415478DAED5D6B745CD575FEBE7DEFC8961F3C0C01EC45480C2B8B0026A1D4206B2CB9C27181F208D074816D59069A16280B92A6246D42520A252D210FD2248426818418C9C63CD264C182BAE1154B1A4960CAB35E506A1E5D26501C9E768464CDDCF3F5C7BDA31796A59135F28CE66C2D594B9A19DF73F7FECEB71F67DF7388329096CCC293C1E997845174D1F2FACE374B7DBCCD1B17CF0F42DDDB1BED58F2E74B9E7DBB94C76AE5000069DA05A2CE8CA8EF94FA587FF6507D1503D71A018757D9EC334A7DBC650100B2E79F4C70B0E0336B338BFEA494C75A352DF70D1AE71AB8F9A5F51DCD1E001320AB163FB159C2CD12663A58D35D1DE9D9A538CE350F351C65C6931D1038B9CBAFBA11F200983016705F96DC9B3077CE4EC7926481B0BAF7F208760C22AD69AAEBEC2A07BD960D001AD39DBF27832F986C3A694DEBDA4F9A5352816A5BC332293CD790450AE115E5A2D7B201000050D10310FE57CC9DEAD47342A98CEBB6473E5585A0F72C3077805C78EDF2FAB6B7CA46A7283359DB9E5E2D6A0DA42E9B3E73C9CA850F6547FBCCBAB69A1991719E219C0146F38420A07400E40218009102BA01F70E2D34C1BD48177457F76CDFF6A7CB9ECE8D9AF6B5A76B403C4CEA8528179D76FE92C75E2F177D86E5060089F793DC08CBFD91EBED5905E0D6E1EFB9E7D7A7A5B6CFD85E47BAE3011C23E02002F300CD00381750086086C86133C0DE8364005E045C774FF5CCDFB574A4B7105107A2E0A5C6FA8EA7771D9FE07A11339C70533919BF2C1900009ADBEACE27A31F928E3DCF1FB5EF5F7CF6E7B907375F17BCF6EE7D75845B29E3498110413A5C4415101B5A1020825072E79404821093BF0CFC4100084A10F09E889728E668EE2E58EFFAC69A27B702C0DAAE450B11059B003D09F0338D8B332F7B004C46D09549B782564FD7773314DE01E3B7441C09A91A04094862FC1322C971F14DE21E10A3062024800ECEDD1B657139A6A183C0C141C4BF5B59DFF1BD72D3A3952B00E8EC3B0E511616FCA5026D70D47110A69348883DB139314EE327E44E80313DC43F6240848E38C7A6BB570D3CCCC4E742CDBCBB2CF5586E035ED75A77906374BA8C5F20B9801A740F1404F6D379516290D871C47048CA3CA2EBA37827841FCEDEE785473FFD8937E5015014DAAF3D9BB02F89AA0110304FC87BF12E84FC10040ADB40AC0F72D13F2F5FF2E81B1E0013286B3A177D3E10AF226C7FF4CF7A09E4DEBD07C59C80981048E07527BD2EBAAFAF4E77FDD203604F23FE478EFF10AAAAEE27834F00AAA228F183095C09E5A94E8441B683DCF9DDC6F4A67FF000182FE5B72F3A8EC0DD8E7604291156168C250146413038E46E545FF4E5D50D9BBA7D1650C8CC6FAF6D20C33B6176841162A2D2B2F0AB141C28C081B2CB2C0C7FBCB6ADE610CF00632EF4D42E03ED76331D085122588E050B498A07EE08173E9072D59F3D77C9035B3D03EC2ED8EB38611189663377A0627F3AC4F8FD2CA0815F94285B93481071553119811497103198A394142008C004BA3FDE99DA7E434BF3D98107C0483EBFB5EEE32985FF06E21080026803D9769EB20827C9D14114639A158C2439192088314711A2E8E020231C1947A7FDC3CDC3564412B352C1593AFCB59B3C007635F3DB3FB91F037C3F6270485C6461BE82C7FE843B9E66204593DD41B15E2E3C09D4CD4E8AE2A430FFAEE2794D4104B25BA19D17059C51A75C7635113DDBBFA4306400C99F62F0A608BB706D7BFA2B3E06F84091E7C46B81F06BCC2B99C290544F8098706EE4AE6BAA7FF4CA217143E6842B89F01A9261D18286643549E4EB51A4D3CEAFEF782AFFD2ADBF39E1A3A954F84B92C78DA45AE54B46D2FF98B4AAB1AEF331CF00009A338B9792C165C984573C69862A50042882C2CBA4EEFAC08D38B600F6BC8A896AC6CB4C14EEDA27D5F7CCE0972E6CD8F40AC9FB04E634E20808023D240E75C0579B5B97CCAE7800AC6B4FCF32E03A80FB4914A8DD509500E27D67DA39FCF569E1F6B71DD58D64E1B758819F20107CF59C458FBBE1AF3BB93700971DF1FA94245553ACA6F1D316642FA8780038D829803B7160E68E40DEFD457FCE35D841C35FEEC91E7244001DC4A252401E08EE9896F6F4B45D14001680563DD200E28549E66F0620AE696E3D69DF8A060019FD24B1B9304A7D3751DB1CCABED9D2567F707FFCB0B1617F0BB2D70236BFA8E19F986F275949E8ACC1AFDD96492F03B814D27BA351D0C00206F767D0FDAD8A0D029B330B2F37567D7FA0B83FDAF41506DE1BBDE5E0EE320494AC01D491717C56D4D5E0A4B813E7F764EE61297C4EEA3B9808FE0CB4FEE2C4686B15493E03D04541943A74457DEBFFED0D1B847B177DC15730A4238BA37E228EC1242A3C80D4250E02E3926BB15B0112C62263E34952B014744B8500A425FD64635B9E8C7B952081E6D8FB8F002EAA2817D0D256BB4AC6B990A9309B09042926052011A42545A1C921B498004832C69CD1125B16967C8A202588567767DBA70EACAC1820D05F518100C74279A33FA1E280CD277B7998838A3CFDDC349EFF8324611FC95ACFD9150380B5AD4B3F02D961B1439F84B0BD644549A518331CDD49150300A57A1B44EE17F75C56AAF1630E50E24688E0D0E6CE051FAA1017A005046654B2E9070702A000B92318EDBF60CA03E017FF716695938E066028970E8FE2C612F1CA91611E2D9AFA0CD03B63DB7E06CC2A853A44E96000824888C7ADED4807531A001686F3011E36100555BA07102832E92F98A149AECD4C7A2128723A90B039A050AEAD5E139E4E524999DB8E256C5F00DBA62C009227B7025478FC3FC2F430208B29CD0002B611F8B58499A477018366468A0A36050A764E6900107A42C205F404F0C1A9A1E939B959EF4FBA0B1AAF34676AE691566F48D508EE9DC8E9A954F7EC8D2B4ED9B0DD1BB438D29CA9F918192E31040B1DDC13514EAF9CBF24F3C0A402E0F68DB587E542DE48E014C6FE3CDFB02331474655B734D6B75DECCD3571B2AE75D127A330F839A5A3498679CE889BA4A26E44A9ABB163EBF71A4F7FC51515002D99DAD341DD06700E6183D6C7014870341111216D0E34FDBC1575BFD93CE4463A6A0E92C27B00D5F81CE003723380CF35A633BD43667DC7A28B41DE4467963C953E68E9537020880890D6079AF6D72BEA5AC7FC6472417580E6B69A1300FE2BC53954DC843F78F95B244C8E94810C8E7196BDBBA5BDF6C8A1AE4E7301DB4FCCB779FBAF415FBDC38BA32DED8B9AA8E0BB2658BE6A3878DD5B204C1211880C973B8BD6B4B4D7CD9A700034671A029A7D9BD487018BA7FDB0199C2C6FF6F7650AEEE3802E5DBB71516AD09B1C2097BC3F590EF25F498A3C24396E6E5F7C04C8AB49552BE993E72EEB08A424C6CF26B953A05CD3C43380BAEB9D6909644967EC983C8C447E2E0A73733DBB17E86A371E1FC8B26788383CAE9891BB2B9C924C1E5931C0ECEB130E005AEA6B26CB33FD989D374104ACBA6C70B6E3650CC158387D9621BC3451B546EF978C275CBCEF19E74C3C00C423FB2D3A16FB73A00D5AD2511393784EE92AC050C3C8428AF30BD43959605F9A1500D143C7B37C1B03D20EF3262E500C018854B197CC0B5B0D1C4FF52E0E08236FD1717242912BA6616103E29EDC8A977169ADB83ED30A9BCA1310DC78348C514FC464044C361938E69EE3A8E282C0C9D29379D5577AACE9C50360D2E9CD4BE500C00781A5AD27EF023C03F82CC067015E3C031417DDDEF157781AE879BF5453279F05946A16E083401F04FA20D08B07809729910578A95800F820B0B4F5E483401F047AF12EC08B07800F023D007C10E883402F9E017C16E0B3002F9E012618DDDEF157781AE879BF5453279F05946A16E083401F04961E00343E64FB495FBAAEA0803D82149F9B5CE8F8E39391426FC98215376E9D178901F842FE1C6C150A5FD9666FD142273E7300DFDFC571E4A3E75C2A0600A8479C84E470BEB182588C8F4369F74160614120C93E119D89CE59B0CE271A0074A95FC5C7DE8E313C91440674CAED10ED1E1F0416E8EAA3AA5E8A1B2C7FA450413AEFDB32E10050D0FD2085F6FCE9DEA3108DE2CD0B2384A8FA494AF686377161B2B2FEE11CADF75780B62001C16E483F09B748288714A65D3FE10068AC7D3C47049713B655D26E0F4A14C47833496D702E77FD7975AD7DDEA4E30041EDE35B8C760DA077F346DEB5778ECF1F4D7692BD75F9E2CC2D454903572E6E7B8AD0192032FD916A12AFF6EF6528C45182C32F9C729736D677FDCE9B72FCB2A236D302B87341BC0A80BBD0B980E4CC6C871B2297FB62510B412BD399670CC1994ED94B1CB955122947894E7410B545C0AA200A2F6CAADBF4F264E7B55325081CC2BEE9AE07082E72CA5EE5C8ED8374DE2B3A8AEC14706A900BBFBABA7ED3DB1375DDDDCA6DED7F405AB585C25CC7F0A326CD065C67CEB4A3A9B663C47D01D7654E3C56A8BA437447D14785C366067F00E06F876F17DFAFF3CC1F32642A05051F1683434DAA8E987B5030D794CEB8F15C75DC059AD5754F0A4004E0D5E47BEC90F32CB06BF38FA6F3C5FF29007D005E4CBE27B310E4652ACA5E0280A7FDCA05804830B2F8D21E0815070029F50E8077095750CD7AEAFA7E258513029069AA03C0FD7EF61B0ED816073D1E01C999C17454CEC936AE1A2103983200683AF5DFFB10F17E38F478F303B1FD01839E03DDD3151104EE089EFF1903BE3470D85C654241884F550201133734A53B5EA808005C9A7EABCF145C02302B89042B120194E448C0D96381E1DB159406022BD2ADED705806228B7C8D5B82244DCD4AD1209E4BFA3BE266293E196571DAB9B51DDBF60A08F7B65A9A1F699887AA9DFF02DA1924AAA87C7E38BC3696EF2E62D29352C0D0E3E316C7F639E52F81E458CC424E4AD1C0F8767529451028D144A72CA52F35D677FE60AFB250A9CC8FE6F68663C0F79752C1C930CC27866544F16F1F1335AD20FB4BC9D1C602C4A74104A3CC53519C25623E871DD23A46A70E88DB40BD81E14BE69203AA9E72DAB921E776DC77E192FFDAEB876C975525666D7BDDB330B7000503C000E4D098EE1AD3A7D6B52D5BE8C2DE4D540E5050200144809B76E5AABA8DD7F942D0441ABFAD9EC0EE67EF44615D8CF619FF550850D5E5A2D78A590CF235870A0780970A07805F76F20CE0C503C08B0780179F0578F141A017EF02BC780078F100F000F041A007800F023D00CA62066B4F66BFA780F20600A9713D56986F3F5701144044C975A67EE37A1901C040322C7432934CFA0C830240D3174285870E713323813D78E8D60360448920445D85FB732528C83D53006CBA18F7111674A97827172188824D1E00132C2B1767E4C88D4326DB581120C031BA77CC1F30ED10A2FFD69877C4CA030D800867D97B3C008A2081C3060AEF8820C4E489128D6475411044120E556EDF9BC67A9D55E92E19F023CA90B40703BB799251F90EE6785FC79F8239E701500479FDB73B5F8BA42B81C8C5BBE7891A21BACB3F73176F5785BF5F5EF7E06B05390EA5D608783ADE0E2BDE7D6FF71C0300DAE622BBA17171973C008A20579CF7B864582F879BD11FA727F6C2E07DB4D4FF9280DB65F6CD42AFB5AAAEED1D0997027815200752102529699E7F92A707A45E29FA22DC2BCFF92CA088727EBAF35DF5CCBA42C87E03021C92FD11E3CDD2E418EF4F2C3AC0E1A786E06F9A6A33E3DAA62E65DD5D70D17952EE29C9C131796A20F9D7E59F0171EE2D38AD9866B6AEA9E1B7659539966D816C4DE7B166D1CCA369EE6263D525CEB9300E0DF43E94BDC55C6AFD4EC3A3172EEED8637FBCA67D416A9AED7F7AD6B9CF9BB98678DE0812B790EE6A396E5855D7F15639EAF1FF015841FD48A44C570F0000000049454E44AE426082'), $data[0]->getContent()); + $this->assertEquals(pack('H*', '6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141414470556C45515652596865315A585567555552512B5A39646358624E4E4C4C4D314E6247303341724B4A585533677167484B336F776968376336442B71682F372F33346F67736A434C364B45777A622B4B54497A6F77536853574E63734C4E61734B4372536367304E79705A437935335477395934732B73366439787252505539444C4E7A7633504F64382B636D5876504C494161584B7A4C557355767461766A44775737387449596D535A7A5645526B6946722F7167316D576730614C516F65387634634636654C546441626F6B4A36653451334C37353075586F453453647A7837475539664D623166704874515941554F6159302F72636E5A67614159546F36344149554F696A72546B504D75614E71616E7347485A424A66597372556244776953674C597675662F37557038712F566857377543354C47344C494E673045584A7762682B423539736A4E5835444A6243696F544E64714E597871524531545A6F354F6D54374B58745046614D4B55665031497A5948544A67414541674C68304B5A6D6A3063676F6B4238416A702F39486E624B7A635149654B30444D4D5357787850515158583072324A49595344713577766D7430376C6A554E6B7171614B7832314E7A3463574E6C4D6941434167446E72346E5868544C48594D685135776E7543524276324A515041366C334A6741457A744742704C4143597A416278536D696F39734B64544A5A59796756523270437049586D7045524743556A455267597844414A7358336E6433667838386E454B476F6D4E304B5068786B4F5642382B55676B4731376F704B566B71425665796571657177474256717A78797153464A614F71544E47457849765253416F65314951394C53704F7A534D7166425A6F4E47716E467030544768786257617033624A323979526549675A4551724B2B31473470735675796C78743968766F6C49304B5A33537065494242736C6F626A35624F4D53574644573450395155413269324F735558667961727033575361696F7279586436353369707A2B3237482F564A723831634B74636E773837733150452F6349694C686D3332517070372B4770706D6A354D623842586D6E61307A512B367355776131676565486646735253424C3956554D445657494C2F47564C43763133554C506866513072346B7A4D55754B3368425749493143386F622B657A51454E385558476D5661724939625A37344B6A4F786F3969373064417A676257586C4D74626C357142306D6750537461704B4F794C617A4E366B434547624F6A6E49306668304F4B57454D327179504771427366722F6350354C756E4A674935696565755348716E4F6C32396E613565663435436F587A392B6F33344E5230732F5975436F4D4F62483250676C6C6B56434F426D7854744647745073432B396D68656B3076397A4B7251676B66514835665650374F64776E55486E2B36317456372F6B496B714B3833696F3338755261376E6E506B6C496A6A78535A704E2B634C703974753148325670582F594638324A464558487548372B57734954576177677269334A73466E6944502B75677878423839626875496843415172714C71345454782F38764354764B536F7172423132415864726E5942454146356A35586E3271576A687A613267446474424C3039777642767351414159454A5365466D397862597477652B504467414138397A6F636F6631784A565A5133502B4138457749412B7133696A634141414141456C46546B5375516D4343'), $data[0]->getThumb()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testSearch() + { + $itemSearchData = new ItemSearchData(); + $itemSearchData->setLimitCount(10); + $itemSearchData->setSeachString('android'); + + $result = self::$repository->search($itemSearchData); + /** @var FileExtData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertCount(1, $data); + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals('Google', $data[0]->getAccountName()); + $this->assertEquals('Google', $data[0]->getClientName()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + + $itemSearchData = new ItemSearchData(); + $itemSearchData->setLimitCount(10); + $itemSearchData->setSeachString(''); + + $result = self::$repository->search($itemSearchData); + $this->assertEquals(3, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetByAccountId() + { + $result = self::$repository->getByAccountId(1); + /** @var FileData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals(2, $result->getNumRows()); + $this->assertCount(2, $data); + $this->assertInstanceOf(FileData::class, $data[0]); + $this->assertEquals(4, $data[0]->getId()); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + + $this->assertInstanceOf(FileData::class, $data[1]); + $this->assertEquals(1, $data[1]->getId()); + $this->assertEquals('sysPass.xml', $data[1]->getName()); + $this->assertEquals('text/xml', $data[1]->getType()); + $this->assertEquals('XML', $data[1]->getExtension()); + $this->assertEquals(1312, $data[1]->getSize()); + $this->assertEquals(1, $data[1]->getAccountId()); + $this->assertEquals(pack('H*', '3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C526F6F743E0A20203C4D6574613E0A202020203C47656E657261746F723E737973506173733C2F47656E657261746F723E0A202020203C56657273696F6E3E312E322E303C2F56657273696F6E3E0A202020203C54696D653E313433393332353330343C2F54696D653E0A202020203C557365722069643D2231223E61646D696E3C2F557365723E0A202020203C47726F75702069643D2231223E41646D696E733C2F47726F75703E0A202020203C486173683E36646232633238323731393136326630663136316531343731653734636531623C2F486173683E0A20203C2F4D6574613E0A20203C43617465676F726965733E0A202020203C43617465676F72792069643D2231223E0A2020202020203C6E616D653E485454503C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F43617465676F72793E0A20203C2F43617465676F726965733E0A20203C437573746F6D6572733E0A202020203C437573746F6D65722069643D2231223E0A2020202020203C6E616D653E476F6F676C6520496E632E3C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A202020203C437573746F6D65722069643D2232223E0A2020202020203C6E616D653E4D6963726F736F667420496E633C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A20203C2F437573746F6D6572733E0A20203C4163636F756E74733E0A202020203C4163636F756E742069643D2231223E0A2020202020203C6E616D653E476F6F676C653C2F6E616D653E0A2020202020203C637573746F6D657249643E313C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E61646D696E3C2F6C6F67696E3E0A2020202020203C75726C3E382E382E382E383C2F75726C3E0A2020202020203C6E6F7465732F3E0A2020202020203C706173733E6C4E66513133634B6A384D592B79434F346652536B4773494334357247454C442F424E69345654614671593D3C2F706173733E0A2020202020203C7061737369763E454E6354743338503265346C643350395A553241767939664C466277386C42473947382F75414D785A6D343D3C2F7061737369763E0A202020203C2F4163636F756E743E0A202020203C4163636F756E742069643D2232223E0A2020202020203C6E616D653E4D6963726F736F66743C2F6E616D653E0A2020202020203C637573746F6D657249643E323C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E726F6F743C2F6C6F67696E3E0A2020202020203C75726C3E342E342E342E343C2F75726C3E0A2020202020203C6E6F7465733E4E6F746173206465206D6963726F66736F66743C2F6E6F7465733E0A2020202020203C706173733E3352394F48632B53335A4E56684D795948352F784C476C76625246662F5367573348527261322B325349453D3C2F706173733E0A2020202020203C7061737369763E763637306A596B43547178635332344C4F65453077672B304330376A734C2F4635342B6E56484963544F773D3C2F7061737369763E0A202020203C2F4163636F756E743E0A20203C2F4163636F756E74733E0A3C2F526F6F743E0A'), $data[1]->getContent()); + $this->assertEquals(pack('H*', '6E6F5F7468756D62'), $data[1]->getThumb()); + + $result = self::$repository->getByAccountId(10); + $this->assertEquals(0, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetByIdBatch() + { + $result = self::$repository->getByIdBatch([1, 2, 3]); + /** @var FileData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals(2, $result->getNumRows()); + $this->assertCount(2, $data); + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals(1, $data[0]->getId()); + $this->assertInstanceOf(FileExtData::class, $data[1]); + $this->assertEquals(3, $data[1]->getId()); + + $result = self::$repository->getByIdBatch([]); + $this->assertEquals(0, $result->getNumRows()); + } + + /** + * Returns the test dataset. + * + * @return IDataSet + */ + protected function getDataSet() + { + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountFile.xml'); + } +} diff --git a/tests/Repositories/AccountHistoryRepositoryTest.php b/tests/Repositories/AccountHistoryRepositoryTest.php index ec3ca08a..c7b1e682 100644 --- a/tests/Repositories/AccountHistoryRepositoryTest.php +++ b/tests/Repositories/AccountHistoryRepositoryTest.php @@ -26,6 +26,7 @@ namespace SP\Tests\Repositories; use PHPUnit\DbUnit\DataSet\IDataSet; use SP\DataModel\AccountHistoryData; +use SP\DataModel\Dto\AccountHistoryCreateDto; use SP\DataModel\ItemSearchData; use SP\Repositories\Account\AccountHistoryRepository; use SP\Services\Account\AccountPasswordRequest; @@ -142,13 +143,16 @@ class AccountHistoryRepositoryTest extends DatabaseTestCase */ public function testCreate() { - $result = self::$repository->create(['id' => 2, 'isModify' => 1, 'isDelete' => 0, 'masterPassHash' => Util::generateRandomBytes()]); + $result = self::$repository->create(new AccountHistoryCreateDto(2, true, false, Util::generateRandomBytes())); $this->assertEquals(8, $result); - $result = self::$repository->create(['id' => 10, 'isModify' => 1, 'isDelete' => 0, 'masterPassHash' => Util::generateRandomBytes()]); + $result = self::$repository->create(new AccountHistoryCreateDto(2, true, true, Util::generateRandomBytes())); + $this->assertEquals(9, $result); + + $result = self::$repository->create(new AccountHistoryCreateDto(10, true, false, Util::generateRandomBytes())); $this->assertEquals(0, $result); - $this->assertEquals(6, $this->conn->getRowCount('AccountHistory')); + $this->assertEquals(7, $this->conn->getRowCount('AccountHistory')); } /** diff --git a/tests/Repositories/AccountRepositoryTest.php b/tests/Repositories/AccountRepositoryTest.php index 5ef1d017..4d841861 100644 --- a/tests/Repositories/AccountRepositoryTest.php +++ b/tests/Repositories/AccountRepositoryTest.php @@ -127,7 +127,7 @@ class AccountRepositoryTest extends DatabaseTestCase $this->assertEquals('1234', $clearPassword); // Comprobar que se devuelve un array vacío - $this->assertCount(0, self::$repository->getPasswordForId(10)); + $this->assertNull(self::$repository->getPasswordForId(10)); } /** diff --git a/tests/Repositories/AccountFavoriteRepositoryTest.php b/tests/Repositories/AccountToFavoriteRepositoryTest.php similarity index 90% rename from tests/Repositories/AccountFavoriteRepositoryTest.php rename to tests/Repositories/AccountToFavoriteRepositoryTest.php index b77ab827..aa767406 100644 --- a/tests/Repositories/AccountFavoriteRepositoryTest.php +++ b/tests/Repositories/AccountToFavoriteRepositoryTest.php @@ -27,7 +27,7 @@ namespace SP\Tests\Repositories; use DI\DependencyException; use PHPUnit\DbUnit\DataSet\IDataSet; use SP\Core\Exceptions\ConstraintException; -use SP\Repositories\Account\AccountFavoriteRepository; +use SP\Repositories\Account\AccountToFavoriteRepository; use SP\Storage\Database\DatabaseConnectionData; use SP\Tests\DatabaseTestCase; use function SP\Tests\setupContext; @@ -37,10 +37,10 @@ use function SP\Tests\setupContext; * * @package SP\Tests\Repositories */ -class AccountFavoriteRepositoryTest extends DatabaseTestCase +class AccountToFavoriteRepositoryTest extends DatabaseTestCase { /** - * @var AccountFavoriteRepository + * @var AccountToFavoriteRepository */ private static $repository; @@ -57,7 +57,7 @@ class AccountFavoriteRepositoryTest extends DatabaseTestCase self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); // Inicializar el repositorio - self::$repository = $dic->get(AccountFavoriteRepository::class); + self::$repository = $dic->get(AccountToFavoriteRepository::class); } /** @@ -113,6 +113,6 @@ class AccountFavoriteRepositoryTest extends DatabaseTestCase */ protected function getDataSet() { - return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_favorite.xml'); + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountFavorite.xml'); } } diff --git a/tests/Repositories/CategoryRepositoryTest.php b/tests/Repositories/CategoryRepositoryTest.php index 947413bd..dcd958ca 100644 --- a/tests/Repositories/CategoryRepositoryTest.php +++ b/tests/Repositories/CategoryRepositoryTest.php @@ -72,9 +72,7 @@ class CategoryRepositoryTest extends DatabaseTestCase */ public function testGetByName() { - $category = self::$repository->getByName('Prueba'); - - $this->assertCount(0, $category); + $this->assertNull(self::$repository->getByName('Prueba')); $category = self::$repository->getByName('Web'); @@ -133,9 +131,7 @@ class CategoryRepositoryTest extends DatabaseTestCase */ public function testGetById() { - $category = self::$repository->getById(10); - - $this->assertCount(0, $category); + $this->assertNull(self::$repository->getById(10)); $category = self::$repository->getById(1); diff --git a/tests/Repositories/ClientRepositoryTest.php b/tests/Repositories/ClientRepositoryTest.php index 162b9dfd..60a39ce8 100644 --- a/tests/Repositories/ClientRepositoryTest.php +++ b/tests/Repositories/ClientRepositoryTest.php @@ -73,9 +73,7 @@ class ClientRepositoryTest extends DatabaseTestCase */ public function testGetByName() { - $client = self::$repository->getByName('Amazon'); - - $this->assertCount(0, $client); + $this->assertNull(self::$repository->getByName('Amazon')); $client = self::$repository->getByName('Google'); @@ -133,9 +131,7 @@ class ClientRepositoryTest extends DatabaseTestCase */ public function testGetById() { - $client = self::$repository->getById(10); - - $this->assertCount(0, $client); + $this->assertNull(self::$repository->getById(10)); $client = self::$repository->getById(1); diff --git a/tests/Repositories/TagRepositoryTest.php b/tests/Repositories/TagRepositoryTest.php index b8021989..2e2fa85c 100644 --- a/tests/Repositories/TagRepositoryTest.php +++ b/tests/Repositories/TagRepositoryTest.php @@ -101,9 +101,7 @@ class TagRepositoryTest extends DatabaseTestCase */ public function testGetById() { - $tag = self::$repository->getById(10); - - $this->assertCount(0, $tag); + $this->assertNull(self::$repository->getById(10)); $tag = self::$repository->getById(1); diff --git a/tests/Repositories/UserGroupRepositoryTest.php b/tests/Repositories/UserGroupRepositoryTest.php index da78bd29..4db5a25c 100644 --- a/tests/Repositories/UserGroupRepositoryTest.php +++ b/tests/Repositories/UserGroupRepositoryTest.php @@ -105,8 +105,7 @@ class UserGroupRepositoryTestCase extends DatabaseTestCase $this->assertEquals('Demo', $group->getName()); $this->assertEmpty($group->getDescription()); - $group = self::$repository->getByName('Prueba'); - $this->assertCount(0, $group); + $this->assertNull(self::$repository->getByName('Prueba')); } /** @@ -164,8 +163,7 @@ class UserGroupRepositoryTestCase extends DatabaseTestCase $this->assertEquals('Demo', $group->getName()); $this->assertEmpty($group->getDescription()); - $group = self::$repository->getById(4); - $this->assertCount(0, $group); + $this->assertNull(self::$repository->getById(4)); } /** diff --git a/tests/Repositories/UserProfileRepositoryTest.php b/tests/Repositories/UserProfileRepositoryTest.php index a3229b81..509ae240 100644 --- a/tests/Repositories/UserProfileRepositoryTest.php +++ b/tests/Repositories/UserProfileRepositoryTest.php @@ -212,8 +212,7 @@ class UserProfileRepositoryTest extends DatabaseTestCase $this->assertEquals('Demo', $profile->getName()); $this->assertNotEmpty($profile->getProfile()); - $profile = self::$repository->getById(4); - $this->assertCount(0, $profile); + $this->assertNull(self::$repository->getById(4)); } /** diff --git a/tests/Repositories/UserRepositoryTest.php b/tests/Repositories/UserRepositoryTest.php index a284fbdf..49916448 100644 --- a/tests/Repositories/UserRepositoryTest.php +++ b/tests/Repositories/UserRepositoryTest.php @@ -259,15 +259,18 @@ class UserRepositoryTest extends DatabaseTestCase */ public function testGetByLogin() { - $user = self::$repository->getByLogin('demo'); + $result = self::$repository->getByLogin('demo'); - $this->assertInstanceOf(UserData::class, $user); - $this->assertEquals('sysPass demo', $user->getName()); - $this->assertEquals('demo', $user->getLogin()); + $this->assertEquals(1, $result->getNumRows()); - $this->expectException(NoSuchItemException::class); + /** @var UserData $data */ + $data = $result->getData(); - self::$repository->getByLogin('prueba'); + $this->assertInstanceOf(UserData::class, $data); + $this->assertEquals('sysPass demo', $data->getName()); + $this->assertEquals('demo', $data->getLogin()); + + $this->assertEquals(0, self::$repository->getByLogin('prueba')->getNumRows()); } /** diff --git a/tests/Services/AccountAclServiceTest.php b/tests/Services/AccountAclServiceTest.php index bdbc67ba..482003cf 100644 --- a/tests/Services/AccountAclServiceTest.php +++ b/tests/Services/AccountAclServiceTest.php @@ -789,6 +789,6 @@ class AccountAclServiceTest extends DatabaseTestCase */ protected function getDataSet() { - return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_acl.xml'); + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountAcl.xml'); } } diff --git a/tests/Services/AccountFavoriteServiceTest.php b/tests/Services/AccountFavoriteServiceTest.php new file mode 100644 index 00000000..afa39645 --- /dev/null +++ b/tests/Services/AccountFavoriteServiceTest.php @@ -0,0 +1,113 @@ +. + */ + +namespace SP\Tests\Services; + +use PHPUnit\DbUnit\DataSet\IDataSet; +use SP\Core\Exceptions\ConstraintException; +use SP\Services\Account\AccountToFavoriteService; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Tests\DatabaseTestCase; +use function SP\Tests\setupContext; + +/** + * Class AccountFavoriteServiceTest + * + * @package SP\Tests\Services + */ +class AccountFavoriteServiceTest extends DatabaseTestCase +{ + /** + * @var AccountToFavoriteService + */ + private static $service; + + /** + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \DI\DependencyException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el servicio + self::$service = $dic->get(AccountToFavoriteService::class); + } + + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testDelete() + { + $this->assertEquals(1, self::$service->delete(1, 3)); + $this->assertEquals(0, self::$service->delete(10, 1)); + } + + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetForUserId() + { + $data = self::$service->getForUserId(3); + + $this->assertCount(2, $data); + $this->assertArrayHasKey(1, $data); + $this->assertArrayHasKey(2, $data); + $this->assertEquals(3, $data[1]); + $this->assertEquals(3, $data[2]); + + $this->assertCount(0, self::$service->getForUserId(10)); + } + + /** + * @throws ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testAdd() + { + $this->assertEquals(0, self::$service->add(1, 2)); + + $this->expectException(ConstraintException::class); + + self::$service->add(3, 1); + + self::$service->add(1, 3); + } + + /** + * Returns the test dataset. + * + * @return IDataSet + */ + protected function getDataSet() + { + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountFavorite.xml'); + } +} diff --git a/tests/Services/AccountFileServiceTest.php b/tests/Services/AccountFileServiceTest.php new file mode 100644 index 00000000..e477327b --- /dev/null +++ b/tests/Services/AccountFileServiceTest.php @@ -0,0 +1,335 @@ +. + */ + +namespace SP\Tests\Services; + +use PHPUnit\DbUnit\DataSet\IDataSet; +use SP\Core\Exceptions\InvalidImageException; +use SP\DataModel\FileData; +use SP\DataModel\FileExtData; +use SP\DataModel\ItemSearchData; +use SP\Repositories\NoSuchItemException; +use SP\Services\Account\AccountFileService; +use SP\Services\ServiceException; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Tests\DatabaseTestCase; +use function SP\Tests\setupContext; + +/** + * Class AccountFileServiceTest + * + * @package SP\Tests\Services + */ +class AccountFileServiceTest extends DatabaseTestCase +{ + /** + * @var AccountFileService + */ + private static $service; + + /** + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \DI\DependencyException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el servicio + self::$service = $dic->get(AccountFileService::class); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testCreate() + { + $file = RESOURCE_DIR . DIRECTORY_SEPARATOR . 'imgs' . DIRECTORY_SEPARATOR . 'add.png'; + $image = file_get_contents($file); + + $data = new FileData(); + $data->setAccountId(2); + $data->setName('app.png'); + $data->setType('image/png'); + $data->setExtension('PNG'); + $data->setContent($image); + $data->setSize(filesize($file)); + + $this->assertEquals(5, self::$service->create($data)); + + $resultData = self::$service->getById(5); + + $this->assertInstanceOf(FileExtData::class, $resultData); + $this->assertEquals($data->getName(), $resultData->getName()); + $this->assertEquals($data->getType(), $resultData->getType()); + $this->assertEquals($data->getExtension(), $resultData->getExtension()); + $this->assertEquals($data->getSize(), $resultData->getSize()); + $this->assertEquals($data->getAccountId(), $resultData->getAccountId()); + $this->assertEquals($data->getContent(), $resultData->getContent()); + $this->assertEquals($data->getThumb(), $resultData->getThumb()); + + $data = new FileData(); + $data->setAccountId(2); + $data->setName('app.png'); + $data->setType('image/png'); + $data->setExtension('SVG'); + $data->setContent(''); + $data->setSize(0); + + $this->assertEquals(6, self::$service->create($data)); + + $resultData = self::$service->getById(6); + + $this->assertInstanceOf(FileExtData::class, $resultData); + $this->assertEquals($data->getName(), $resultData->getName()); + $this->assertEquals($data->getType(), $resultData->getType()); + $this->assertEquals($data->getExtension(), $resultData->getExtension()); + $this->assertEquals($data->getSize(), $resultData->getSize()); + $this->assertEquals($data->getAccountId(), $resultData->getAccountId()); + $this->assertEquals($data->getContent(), $resultData->getContent()); + $this->assertEquals('no_thumb', $resultData->getThumb()); + + $this->assertEquals(5, $this->conn->getRowCount('AccountFile')); + + $this->expectException(InvalidImageException::class); + + $data = new FileData(); + $data->setAccountId(2); + $data->setName('app.png'); + $data->setType('image/png'); + $data->setExtension('PNG'); + $data->setContent(''); + $data->setSize(0); + + $this->assertEquals(6, self::$service->create($data)); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testSearch() + { + $itemSearchData = new ItemSearchData(); + $itemSearchData->setLimitCount(10); + $itemSearchData->setSeachString('android'); + + $result = self::$service->search($itemSearchData); + /** @var FileExtData[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals(1, $result->getNumRows()); + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals('Google', $data[0]->getAccountName()); + $this->assertEquals('Google', $data[0]->getClientName()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + + $itemSearchData = new ItemSearchData(); + $itemSearchData->setLimitCount(10); + $itemSearchData->setSeachString(''); + + $result = self::$service->search($itemSearchData); + $this->assertEquals(3, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetById() + { + $data = self::$service->getById(1); + + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('sysPass.xml', $data->getName()); + $this->assertEquals('text/xml', $data->getType()); + $this->assertEquals('XML', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(1312, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertEquals(pack('H*', '3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C526F6F743E0A20203C4D6574613E0A202020203C47656E657261746F723E737973506173733C2F47656E657261746F723E0A202020203C56657273696F6E3E312E322E303C2F56657273696F6E3E0A202020203C54696D653E313433393332353330343C2F54696D653E0A202020203C557365722069643D2231223E61646D696E3C2F557365723E0A202020203C47726F75702069643D2231223E41646D696E733C2F47726F75703E0A202020203C486173683E36646232633238323731393136326630663136316531343731653734636531623C2F486173683E0A20203C2F4D6574613E0A20203C43617465676F726965733E0A202020203C43617465676F72792069643D2231223E0A2020202020203C6E616D653E485454503C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F43617465676F72793E0A20203C2F43617465676F726965733E0A20203C437573746F6D6572733E0A202020203C437573746F6D65722069643D2231223E0A2020202020203C6E616D653E476F6F676C6520496E632E3C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A202020203C437573746F6D65722069643D2232223E0A2020202020203C6E616D653E4D6963726F736F667420496E633C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A20203C2F437573746F6D6572733E0A20203C4163636F756E74733E0A202020203C4163636F756E742069643D2231223E0A2020202020203C6E616D653E476F6F676C653C2F6E616D653E0A2020202020203C637573746F6D657249643E313C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E61646D696E3C2F6C6F67696E3E0A2020202020203C75726C3E382E382E382E383C2F75726C3E0A2020202020203C6E6F7465732F3E0A2020202020203C706173733E6C4E66513133634B6A384D592B79434F346652536B4773494334357247454C442F424E69345654614671593D3C2F706173733E0A2020202020203C7061737369763E454E6354743338503265346C643350395A553241767939664C466277386C42473947382F75414D785A6D343D3C2F7061737369763E0A202020203C2F4163636F756E743E0A202020203C4163636F756E742069643D2232223E0A2020202020203C6E616D653E4D6963726F736F66743C2F6E616D653E0A2020202020203C637573746F6D657249643E323C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E726F6F743C2F6C6F67696E3E0A2020202020203C75726C3E342E342E342E343C2F75726C3E0A2020202020203C6E6F7465733E4E6F746173206465206D6963726F66736F66743C2F6E6F7465733E0A2020202020203C706173733E3352394F48632B53335A4E56684D795948352F784C476C76625246662F5367573348527261322B325349453D3C2F706173733E0A2020202020203C7061737369763E763637306A596B43547178635332344C4F65453077672B304330376A734C2F4635342B6E56484963544F773D3C2F7061737369763E0A202020203C2F4163636F756E743E0A20203C2F4163636F756E74733E0A3C2F526F6F743E0A'), $data->getContent()); + $this->assertEquals(pack('H*', '6E6F5F7468756D62'), $data->getThumb()); + + $data = self::$service->getById(4); + + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('android.png', $data->getName()); + $this->assertEquals('image/png', $data->getType()); + $this->assertEquals('PNG', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(4295, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertEquals(pack('H*', '89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61CB00000006624B474400FF00FF00FFA0BDA793000000097048597300000B1300000B1301009A9C180000000774494D4507DD011D0E180BE2306F78000010544944415478DAED5D6B745CD575FEBE7DEFC8961F3C0C01EC45480C2B8B0026A1D4206B2CB9C27181F208D074816D59069A16280B92A6246D42520A252D210FD2248426818418C9C63CD264C182BAE1154B1A4960CAB35E506A1E5D26501C9E768464CDDCF3F5C7BDA31796A59135F28CE66C2D594B9A19DF73F7FECEB71F67DF7388329096CCC293C1E997845174D1F2FACE374B7DBCCD1B17CF0F42DDDB1BED58F2E74B9E7DBB94C76AE5000069DA05A2CE8CA8EF94FA587FF6507D1503D71A018757D9EC334A7DBC650100B2E79F4C70B0E0336B338BFEA494C75A352DF70D1AE71AB8F9A5F51DCD1E001320AB163FB159C2CD12663A58D35D1DE9D9A538CE350F351C65C6931D1038B9CBAFBA11F200983016705F96DC9B3077CE4EC7926481B0BAF7F208760C22AD69AAEBEC2A07BD960D001AD39DBF27832F986C3A694DEBDA4F9A5352816A5BC332293CD790450AE115E5A2D7B201000050D10310FE57CC9DEAD47342A98CEBB6473E5585A0F72C3077805C78EDF2FAB6B7CA46A7283359DB9E5E2D6A0DA42E9B3E73C9CA850F6547FBCCBAB69A1991719E219C0146F38420A07400E40218009102BA01F70E2D34C1BD48177457F76CDFF6A7CB9ECE8D9AF6B5A76B403C4CEA8528179D76FE92C75E2F177D86E5060089F793DC08CBFD91EBED5905E0D6E1EFB9E7D7A7A5B6CFD85E47BAE3011C23E02002F300CD00381750086086C86133C0DE8364005E045C774FF5CCDFB574A4B7105107A2E0A5C6FA8EA7771D9FE07A11339C70533919BF2C1900009ADBEACE27A31F928E3DCF1FB5EF5F7CF6E7B907375F17BCF6EE7D75845B29E3498110413A5C4415101B5A1020825072E79404821093BF0CFC4100084A10F09E889728E668EE2E58EFFAC69A27B702C0DAAE450B11059B003D09F0338D8B332F7B004C46D09549B782564FD7773314DE01E3B7441C09A91A04094862FC1322C971F14DE21E10A3062024800ECEDD1B657139A6A183C0C141C4BF5B59DFF1BD72D3A3952B00E8EC3B0E511616FCA5026D70D47110A69348883DB139314EE327E44E80313DC43F6240848E38C7A6BB570D3CCCC4E742CDBCBB2CF5586E035ED75A77906374BA8C5F20B9801A740F1404F6D379516290D871C47048CA3CA2EBA37827841FCEDEE785473FFD8937E5015014DAAF3D9BB02F89AA0110304FC87BF12E84FC10040ADB40AC0F72D13F2F5FF2E81B1E0013286B3A177D3E10AF226C7FF4CF7A09E4DEBD07C59C80981048E07527BD2EBAAFAF4E77FDD203604F23FE478EFF10AAAAEE27834F00AAA228F183095C09E5A94E8441B683DCF9DDC6F4A67FF000182FE5B72F3A8EC0DD8E7604291156168C250146413038E46E545FF4E5D50D9BBA7D1650C8CC6FAF6D20C33B6176841162A2D2B2F0AB141C28C081B2CB2C0C7FBCB6ADE610CF00632EF4D42E03ED76331D085122588E050B498A07EE08173E9072D59F3D77C9035B3D03EC2ED8EB38611189663377A0627F3AC4F8FD2CA0815F94285B93481071553119811497103198A394142008C004BA3FDE99DA7E434BF3D98107C0483EBFB5EEE32985FF06E21080026803D9769EB20827C9D14114639A158C2439192088314711A2E8E020231C1947A7FDC3CDC3564412B352C1593AFCB59B3C007635F3DB3FB91F037C3F6270485C6461BE82C7FE843B9E66204593DD41B15E2E3C09D4CD4E8AE2A430FFAEE2794D4104B25BA19D17059C51A75C7635113DDBBFA4306400C99F62F0A608BB706D7BFA2B3E06F84091E7C46B81F06BCC2B99C290544F8098706EE4AE6BAA7FF4CA217143E6842B89F01A9261D18286643549E4EB51A4D3CEAFEF782AFFD2ADBF39E1A3A954F84B92C78DA45AE54B46D2FF98B4AAB1AEF331CF00009A338B9792C165C984573C69862A50042882C2CBA4EEFAC08D38B600F6BC8A896AC6CB4C14EEDA27D5F7CCE0972E6CD8F40AC9FB04E634E20808023D240E75C0579B5B97CCAE7800AC6B4FCF32E03A80FB4914A8DD509500E27D67DA39FCF569E1F6B71DD58D64E1B758819F20107CF59C458FBBE1AF3BB93700971DF1FA94245553ACA6F1D316642FA8780038D829803B7160E68E40DEFD457FCE35D841C35FEEC91E7244001DC4A252401E08EE9896F6F4B45D14001680563DD200E28549E66F0620AE696E3D69DF8A060019FD24B1B9304A7D3751DB1CCABED9D2567F707FFCB0B1617F0BB2D70236BFA8E19F986F275949E8ACC1AFDD96492F03B814D27BA351D0C00206F767D0FDAD8A0D029B330B2F37567D7FA0B83FDAF41506DE1BBDE5E0EE320494AC01D491717C56D4D5E0A4B813E7F764EE61297C4EEA3B9808FE0CB4FEE2C4686B15493E03D04541943A74457DEBFFED0D1B847B177DC15730A4238BA37E228EC1242A3C80D4250E02E3926BB15B0112C62263E34952B014744B8500A425FD64635B9E8C7B952081E6D8FB8F002EAA2817D0D256BB4AC6B990A9309B09042926052011A42545A1C921B498004832C69CD1125B16967C8A202588567767DBA70EACAC1820D05F518100C74279A33FA1E280CD277B7998838A3CFDDC349EFF8324611FC95ACFD9150380B5AD4B3F02D961B1439F84B0BD644549A518331CDD49150300A57A1B44EE17F75C56AAF1630E50E24688E0D0E6CE051FAA1017A005046654B2E9070702A000B92318EDBF60CA03E017FF716695938E066028970E8FE2C612F1CA91611E2D9AFA0CD03B63DB7E06CC2A853A44E96000824888C7ADED4807531A001686F3011E36100555BA07102832E92F98A149AECD4C7A2128723A90B039A050AEAD5E139E4E524999DB8E256C5F00DBA62C009227B7025478FC3FC2F430208B29CD0002B611F8B58499A477018366468A0A36050A764E6900107A42C205F404F0C1A9A1E939B959EF4FBA0B1AAF34676AE691566F48D508EE9DC8E9A954F7EC8D2B4ED9B0DD1BB438D29CA9F918192E31040B1DDC13514EAF9CBF24F3C0A402E0F68DB587E542DE48E014C6FE3CDFB02331474655B734D6B75DECCD3571B2AE75D127A330F839A5A3498679CE889BA4A26E44A9ABB163EBF71A4F7FC51515002D99DAD341DD06700E6183D6C7014870341111216D0E34FDBC1575BFD93CE4463A6A0E92C27B00D5F81CE003723380CF35A633BD43667DC7A28B41DE4467963C953E68E9537020880890D6079AF6D72BEA5AC7FC6472417580E6B69A1300FE2BC53954DC843F78F95B244C8E94810C8E7196BDBBA5BDF6C8A1AE4E7301DB4FCCB779FBAF415FBDC38BA32DED8B9AA8E0BB2658BE6A3878DD5B204C1211880C973B8BD6B4B4D7CD9A700034671A029A7D9BD487018BA7FDB0199C2C6FF6F7650AEEE3802E5DBB71516AD09B1C2097BC3F590EF25F498A3C24396E6E5F7C04C8AB49552BE993E72EEB08A424C6CF26B953A05CD3C43380BAEB9D6909644967EC983C8C447E2E0A73733DBB17E86A371E1FC8B26788383CAE9891BB2B9C924C1E5931C0ECEB130E005AEA6B26CB33FD989D374104ACBA6C70B6E3650CC158387D9621BC3451B546EF978C275CBCEF19E74C3C00C423FB2D3A16FB73A00D5AD2511393784EE92AC050C3C8428AF30BD43959605F9A1500D143C7B37C1B03D20EF3262E500C018854B197CC0B5B0D1C4FF52E0E08236FD1717242912BA6616103E29EDC8A977169ADB83ED30A9BCA1310DC78348C514FC464044C361938E69EE3A8E282C0C9D29379D5577AACE9C50360D2E9CD4BE500C00781A5AD27EF023C03F82CC067015E3C031417DDDEF157781AE879BF5453279F05946A16E083401F04FA20D08B07809729910578A95800F820B0B4F5E483401F047AF12EC08B07800F023D007C10E883402F9E017C16E0B3002F9E012618DDDEF157781AE879BF5453279F05946A16E083401F04961E00343E64FB495FBAAEA0803D82149F9B5CE8F8E39391426FC98215376E9D178901F842FE1C6C150A5FD9666FD142273E7300DFDFC571E4A3E75C2A0600A8479C84E470BEB182588C8F4369F74160614120C93E119D89CE59B0CE271A0074A95FC5C7DE8E313C91440674CAED10ED1E1F0416E8EAA3AA5E8A1B2C7FA450413AEFDB32E10050D0FD2085F6FCE9DEA3108DE2CD0B2384A8FA494AF686377161B2B2FEE11CADF75780B62001C16E483F09B748288714A65D3FE10068AC7D3C47049713B655D26E0F4A14C47833496D702E77FD7975AD7DDEA4E30041EDE35B8C760DA077F346DEB5778ECF1F4D7692BD75F9E2CC2D454903572E6E7B8AD0192032FD916A12AFF6EF6528C45182C32F9C729736D677FDCE9B72FCB2A236D302B87341BC0A80BBD0B980E4CC6C871B2297FB62510B412BD399670CC1994ED94B1CB955122947894E7410B545C0AA200A2F6CAADBF4F264E7B55325081CC2BEE9AE07082E72CA5EE5C8ED8374DE2B3A8AEC14706A900BBFBABA7ED3DB1375DDDDCA6DED7F405AB585C25CC7F0A326CD065C67CEB4A3A9B663C47D01D7654E3C56A8BA437447D14785C366067F00E06F876F17DFAFF3CC1F32642A05051F1683434DAA8E987B5030D794CEB8F15C75DC059AD5754F0A4004E0D5E47BEC90F32CB06BF38FA6F3C5FF29007D005E4CBE27B310E4652ACA5E0280A7FDCA05804830B2F8D21E0815070029F50E8077095750CD7AEAFA7E258513029069AA03C0FD7EF61B0ED816073D1E01C999C17454CEC936AE1A2103983200683AF5DFFB10F17E38F478F303B1FD01839E03DDD3151104EE089EFF1903BE3470D85C654241884F550201133734A53B5EA808005C9A7EABCF145C02302B89042B120194E448C0D96381E1DB159406022BD2ADED705806228B7C8D5B82244DCD4AD1209E4BFA3BE266293E196571DAB9B51DDBF60A08F7B65A9A1F699887AA9DFF02DA1924AAA87C7E38BC3696EF2E62D29352C0D0E3E316C7F639E52F81E458CC424E4AD1C0F8767529451028D144A72CA52F35D677FE60AFB250A9CC8FE6F68663C0F79752C1C930CC27866544F16F1F1335AD20FB4BC9D1C602C4A74104A3CC53519C25623E871DD23A46A70E88DB40BD81E14BE69203AA9E72DAB921E776DC77E192FFDAEB876C975525666D7BDDB330B7000503C000E4D098EE1AD3A7D6B52D5BE8C2DE4D540E5050200144809B76E5AABA8DD7F942D0441ABFAD9EC0EE67EF44615D8CF619FF550850D5E5A2D78A590CF235870A0780970A07805F76F20CE0C503C08B0780179F0578F141A017EF02BC780078F100F000F041A007800F023D00CA62066B4F66BFA780F20600A9713D56986F3F5701144044C975A67EE37A1901C040322C7432934CFA0C830240D3174285870E713323813D78E8D60360448920445D85FB732528C83D53006CBA18F7111674A97827172188824D1E00132C2B1767E4C88D4326DB581120C031BA77CC1F30ED10A2FFD69877C4CA030D800867D97B3C008A2081C3060AEF8820C4E489128D6475411044120E556EDF9BC67A9D55E92E19F023CA90B40703BB799251F90EE6785FC79F8239E701500479FDB73B5F8BA42B81C8C5BBE7891A21BACB3F73176F5785BF5F5EF7E06B05390EA5D608783ADE0E2BDE7D6FF71C0300DAE622BBA17171973C008A20579CF7B864582F879BD11FA727F6C2E07DB4D4FF9280DB65F6CD42AFB5AAAEED1D0997027815200752102529699E7F92A707A45E29FA22DC2BCFF92CA088727EBAF35DF5CCBA42C87E03021C92FD11E3CDD2E418EF4F2C3AC0E1A786E06F9A6A33E3DAA62E65DD5D70D17952EE29C9C131796A20F9D7E59F0171EE2D38AD9866B6AEA9E1B7659539966D816C4DE7B166D1CCA369EE6263D525CEB9300E0DF43E94BDC55C6AFD4EC3A3172EEED8637FBCA67D416A9AED7F7AD6B9CF9BB98678DE0812B790EE6A396E5855D7F15639EAF1FF015841FD48A44C570F0000000049454E44AE426082'), $data->getContent()); + $this->assertEquals(pack('H*', '6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141414470556C45515652596865315A585567555552512B5A39646358624E4E4C4C4D314E6247303341724B4A585533677167484B336F776968376336442B71682F372F33346F67736A434C364B45777A622B4B54497A6F77536853574E63734C4E61734B4372536367304E79705A437935335477395934732B73366439787252505539444C4E7A7633504F64382B636D5876504C494161584B7A4C557355767461766A44775737387449596D535A7A5645526B6946722F7167316D576730614C516F65387634634636654C546441626F6B4A36653451334C37353075586F453453647A7837475539664D623166704874515941554F6159302F72636E5A67614159546F36344149554F696A72546B504D75614E71616E7347485A424A66597372556244776953674C597675662F37557038712F566857377543354C47344C494E673045584A7762682B423539736A4E5835444A6243696F544E64714E597871524531545A6F354F6D54374B58745046614D4B55665031497A5948544A67414541674C68304B5A6D6A3063676F6B4238416A702F39486E624B7A635149654B30444D4D5357787850515158583072324A49595344713577766D7430376C6A554E6B7171614B7832314E7A3463574E6C4D6941434167446E72346E5868544C48594D685135776E7543524276324A515041366C334A6741457A744742704C4143597A416278536D696F39734B64544A5A59796756523270437049586D7045524743556A455267597844414A7358336E6433667838386E454B476F6D4E304B5068786B4F5642382B55676B4731376F704B566B71425665796571657177474256717A78797153464A614F71544E47457849765253416F65314951394C53704F7A534D7166425A6F4E47716E467030544768786257617033624A323979526549675A4551724B2B31473470735675796C78743968766F6C49304B5A33537065494242736C6F626A35624F4D53574644573450395155413269324F735558667961727033575361696F7279586436353369707A2B3237482F564A723831634B74636E773837733150452F6349694C686D3332517070372B4770706D6A354D623842586D6E61307A512B367355776131676565486646735253424C3956554D445657494C2F47564C43763133554C506866513072346B7A4D55754B3368425749493143386F622B657A51454E385558476D5661724939625A37344B6A4F786F3969373064417A676257586C4D74626C357142306D6750537461704B4F794C617A4E366B434547624F6A6E49306668304F4B57454D327179504771427366722F6350354C756E4A674935696565755348716E4F6C32396E613565663435436F587A392B6F33344E5230732F5975436F4D4F62483250676C6C6B56434F426D7854744647745073432B396D68656B3076397A4B7251676B66514835665650374F64776E55486E2B36317456372F6B496B714B3833696F3338755261376E6E506B6C496A6A78535A704E2B634C703974753148325670582F594638324A464558487548372B57734954576177677269334A73466E6944502B75677878423839626875496843415172714C71345454782F38764354764B536F7172423132415864726E5942454146356A35586E3271576A687A613267446474424C3039777642767351414159454A5365466D397862597477652B504467414138397A6F636F6631784A565A5133502B4138457749412B7133696A634141414141456C46546B5375516D4343'), $data->getThumb()); + + $this->assertNull(self::$service->getById(10)); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetByIdBatch() + { + $data = self::$service->getByIdBatch([1, 2, 3]); + + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals(1, $data[0]->getId()); + $this->assertInstanceOf(FileExtData::class, $data[1]); + $this->assertEquals(3, $data[1]->getId()); + + $this->assertCount(0, self::$service->getByIdBatch([])); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetInfoById() + { + $data = self::$service->getInfoById(1); + + $this->assertInstanceOf(FileExtData::class, $data); + $this->assertEquals('sysPass.xml', $data->getName()); + $this->assertEquals('text/xml', $data->getType()); + $this->assertEquals('XML', $data->getExtension()); + $this->assertEquals('Google', $data->getAccountName()); + $this->assertEquals('Google', $data->getClientName()); + $this->assertEquals(1312, $data->getSize()); + $this->assertEquals(1, $data->getAccountId()); + $this->assertNull($data->getContent()); + $this->assertNull($data->getThumb()); + + $this->assertNull(self::$service->getInfoById(10)); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetAll() + { + $data = self::$service->getAll(); + + $this->assertCount(3, $data); + $this->assertInstanceOf(FileExtData::class, $data[0]); + $this->assertEquals(4, $data[0]->getId()); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals('Google', $data[0]->getAccountName()); + $this->assertEquals('Google', $data[0]->getClientName()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + $this->assertEquals(pack('H*', '89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61CB00000006624B474400FF00FF00FFA0BDA793000000097048597300000B1300000B1301009A9C180000000774494D4507DD011D0E180BE2306F78000010544944415478DAED5D6B745CD575FEBE7DEFC8961F3C0C01EC45480C2B8B0026A1D4206B2CB9C27181F208D074816D59069A16280B92A6246D42520A252D210FD2248426818418C9C63CD264C182BAE1154B1A4960CAB35E506A1E5D26501C9E768464CDDCF3F5C7BDA31796A59135F28CE66C2D594B9A19DF73F7FECEB71F67DF7388329096CCC293C1E997845174D1F2FACE374B7DBCCD1B17CF0F42DDDB1BED58F2E74B9E7DBB94C76AE5000069DA05A2CE8CA8EF94FA587FF6507D1503D71A018757D9EC334A7DBC650100B2E79F4C70B0E0336B338BFEA494C75A352DF70D1AE71AB8F9A5F51DCD1E001320AB163FB159C2CD12663A58D35D1DE9D9A538CE350F351C65C6931D1038B9CBAFBA11F200983016705F96DC9B3077CE4EC7926481B0BAF7F208760C22AD69AAEBEC2A07BD960D001AD39DBF27832F986C3A694DEBDA4F9A5352816A5BC332293CD790450AE115E5A2D7B201000050D10310FE57CC9DEAD47342A98CEBB6473E5585A0F72C3077805C78EDF2FAB6B7CA46A7283359DB9E5E2D6A0DA42E9B3E73C9CA850F6547FBCCBAB69A1991719E219C0146F38420A07400E40218009102BA01F70E2D34C1BD48177457F76CDFF6A7CB9ECE8D9AF6B5A76B403C4CEA8528179D76FE92C75E2F177D86E5060089F793DC08CBFD91EBED5905E0D6E1EFB9E7D7A7A5B6CFD85E47BAE3011C23E02002F300CD00381750086086C86133C0DE8364005E045C774FF5CCDFB574A4B7105107A2E0A5C6FA8EA7771D9FE07A11339C70533919BF2C1900009ADBEACE27A31F928E3DCF1FB5EF5F7CF6E7B907375F17BCF6EE7D75845B29E3498110413A5C4415101B5A1020825072E79404821093BF0CFC4100084A10F09E889728E668EE2E58EFFAC69A27B702C0DAAE450B11059B003D09F0338D8B332F7B004C46D09549B782564FD7773314DE01E3B7441C09A91A04094862FC1322C971F14DE21E10A3062024800ECEDD1B657139A6A183C0C141C4BF5B59DFF1BD72D3A3952B00E8EC3B0E511616FCA5026D70D47110A69348883DB139314EE327E44E80313DC43F6240848E38C7A6BB570D3CCCC4E742CDBCBB2CF5586E035ED75A77906374BA8C5F20B9801A740F1404F6D379516290D871C47048CA3CA2EBA37827841FCEDEE785473FFD8937E5015014DAAF3D9BB02F89AA0110304FC87BF12E84FC10040ADB40AC0F72D13F2F5FF2E81B1E0013286B3A177D3E10AF226C7FF4CF7A09E4DEBD07C59C80981048E07527BD2EBAAFAF4E77FDD203604F23FE478EFF10AAAAEE27834F00AAA228F183095C09E5A94E8441B683DCF9DDC6F4A67FF000182FE5B72F3A8EC0DD8E7604291156168C250146413038E46E545FF4E5D50D9BBA7D1650C8CC6FAF6D20C33B6176841162A2D2B2F0AB141C28C081B2CB2C0C7FBCB6ADE610CF00632EF4D42E03ED76331D085122588E050B498A07EE08173E9072D59F3D77C9035B3D03EC2ED8EB38611189663377A0627F3AC4F8FD2CA0815F94285B93481071553119811497103198A394142008C004BA3FDE99DA7E434BF3D98107C0483EBFB5EEE32985FF06E21080026803D9769EB20827C9D14114639A158C2439192088314711A2E8E020231C1947A7FDC3CDC3564412B352C1593AFCB59B3C007635F3DB3FB91F037C3F6270485C6461BE82C7FE843B9E66204593DD41B15E2E3C09D4CD4E8AE2A430FFAEE2794D4104B25BA19D17059C51A75C7635113DDBBFA4306400C99F62F0A608BB706D7BFA2B3E06F84091E7C46B81F06BCC2B99C290544F8098706EE4AE6BAA7FF4CA217143E6842B89F01A9261D18286643549E4EB51A4D3CEAFEF782AFFD2ADBF39E1A3A954F84B92C78DA45AE54B46D2FF98B4AAB1AEF331CF00009A338B9792C165C984573C69862A50042882C2CBA4EEFAC08D38B600F6BC8A896AC6CB4C14EEDA27D5F7CCE0972E6CD8F40AC9FB04E634E20808023D240E75C0579B5B97CCAE7800AC6B4FCF32E03A80FB4914A8DD509500E27D67DA39FCF569E1F6B71DD58D64E1B758819F20107CF59C458FBBE1AF3BB93700971DF1FA94245553ACA6F1D316642FA8780038D829803B7160E68E40DEFD457FCE35D841C35FEEC91E7244001DC4A252401E08EE9896F6F4B45D14001680563DD200E28549E66F0620AE696E3D69DF8A060019FD24B1B9304A7D3751DB1CCABED9D2567F707FFCB0B1617F0BB2D70236BFA8E19F986F275949E8ACC1AFDD96492F03B814D27BA351D0C00206F767D0FDAD8A0D029B330B2F37567D7FA0B83FDAF41506DE1BBDE5E0EE320494AC01D491717C56D4D5E0A4B813E7F764EE61297C4EEA3B9808FE0CB4FEE2C4686B15493E03D04541943A74457DEBFFED0D1B847B177DC15730A4238BA37E228EC1242A3C80D4250E02E3926BB15B0112C62263E34952B014744B8500A425FD64635B9E8C7B952081E6D8FB8F002EAA2817D0D256BB4AC6B990A9309B09042926052011A42545A1C921B498004832C69CD1125B16967C8A202588567767DBA70EACAC1820D05F518100C74279A33FA1E280CD277B7998838A3CFDDC349EFF8324611FC95ACFD9150380B5AD4B3F02D961B1439F84B0BD644549A518331CDD49150300A57A1B44EE17F75C56AAF1630E50E24688E0D0E6CE051FAA1017A005046654B2E9070702A000B92318EDBF60CA03E017FF716695938E066028970E8FE2C612F1CA91611E2D9AFA0CD03B63DB7E06CC2A853A44E96000824888C7ADED4807531A001686F3011E36100555BA07102832E92F98A149AECD4C7A2128723A90B039A050AEAD5E139E4E524999DB8E256C5F00DBA62C009227B7025478FC3FC2F430208B29CD0002B611F8B58499A477018366468A0A36050A764E6900107A42C205F404F0C1A9A1E939B959EF4FBA0B1AAF34676AE691566F48D508EE9DC8E9A954F7EC8D2B4ED9B0DD1BB438D29CA9F918192E31040B1DDC13514EAF9CBF24F3C0A402E0F68DB587E542DE48E014C6FE3CDFB02331474655B734D6B75DECCD3571B2AE75D127A330F839A5A3498679CE889BA4A26E44A9ABB163EBF71A4F7FC51515002D99DAD341DD06700E6183D6C7014870341111216D0E34FDBC1575BFD93CE4463A6A0E92C27B00D5F81CE003723380CF35A633BD43667DC7A28B41DE4467963C953E68E9537020880890D6079AF6D72BEA5AC7FC6472417580E6B69A1300FE2BC53954DC843F78F95B244C8E94810C8E7196BDBBA5BDF6C8A1AE4E7301DB4FCCB779FBAF415FBDC38BA32DED8B9AA8E0BB2658BE6A3878DD5B204C1211880C973B8BD6B4B4D7CD9A700034671A029A7D9BD487018BA7FDB0199C2C6FF6F7650AEEE3802E5DBB71516AD09B1C2097BC3F590EF25F498A3C24396E6E5F7C04C8AB49552BE993E72EEB08A424C6CF26B953A05CD3C43380BAEB9D6909644967EC983C8C447E2E0A73733DBB17E86A371E1FC8B26788383CAE9891BB2B9C924C1E5931C0ECEB130E005AEA6B26CB33FD989D374104ACBA6C70B6E3650CC158387D9621BC3451B546EF978C275CBCEF19E74C3C00C423FB2D3A16FB73A00D5AD2511393784EE92AC050C3C8428AF30BD43959605F9A1500D143C7B37C1B03D20EF3262E500C018854B197CC0B5B0D1C4FF52E0E08236FD1717242912BA6616103E29EDC8A977169ADB83ED30A9BCA1310DC78348C514FC464044C361938E69EE3A8E282C0C9D29379D5577AACE9C50360D2E9CD4BE500C00781A5AD27EF023C03F82CC067015E3C031417DDDEF157781AE879BF5453279F05946A16E083401F04FA20D08B07809729910578A95800F820B0B4F5E483401F047AF12EC08B07800F023D007C10E883402F9E017C16E0B3002F9E012618DDDEF157781AE879BF5453279F05946A16E083401F04961E00343E64FB495FBAAEA0803D82149F9B5CE8F8E39391426FC98215376E9D178901F842FE1C6C150A5FD9666FD142273E7300DFDFC571E4A3E75C2A0600A8479C84E470BEB182588C8F4369F74160614120C93E119D89CE59B0CE271A0074A95FC5C7DE8E313C91440674CAED10ED1E1F0416E8EAA3AA5E8A1B2C7FA450413AEFDB32E10050D0FD2085F6FCE9DEA3108DE2CD0B2384A8FA494AF686377161B2B2FEE11CADF75780B62001C16E483F09B748288714A65D3FE10068AC7D3C47049713B655D26E0F4A14C47833496D702E77FD7975AD7DDEA4E30041EDE35B8C760DA077F346DEB5778ECF1F4D7692BD75F9E2CC2D454903572E6E7B8AD0192032FD916A12AFF6EF6528C45182C32F9C729736D677FDCE9B72FCB2A236D302B87341BC0A80BBD0B980E4CC6C871B2297FB62510B412BD399670CC1994ED94B1CB955122947894E7410B545C0AA200A2F6CAADBF4F264E7B55325081CC2BEE9AE07082E72CA5EE5C8ED8374DE2B3A8AEC14706A900BBFBABA7ED3DB1375DDDDCA6DED7F405AB585C25CC7F0A326CD065C67CEB4A3A9B663C47D01D7654E3C56A8BA437447D14785C366067F00E06F876F17DFAFF3CC1F32642A05051F1683434DAA8E987B5030D794CEB8F15C75DC059AD5754F0A4004E0D5E47BEC90F32CB06BF38FA6F3C5FF29007D005E4CBE27B310E4652ACA5E0280A7FDCA05804830B2F8D21E0815070029F50E8077095750CD7AEAFA7E258513029069AA03C0FD7EF61B0ED816073D1E01C999C17454CEC936AE1A2103983200683AF5DFFB10F17E38F478F303B1FD01839E03DDD3151104EE089EFF1903BE3470D85C654241884F550201133734A53B5EA808005C9A7EABCF145C02302B89042B120194E448C0D96381E1DB159406022BD2ADED705806228B7C8D5B82244DCD4AD1209E4BFA3BE266293E196571DAB9B51DDBF60A08F7B65A9A1F699887AA9DFF02DA1924AAA87C7E38BC3696EF2E62D29352C0D0E3E316C7F639E52F81E458CC424E4AD1C0F8767529451028D144A72CA52F35D677FE60AFB250A9CC8FE6F68663C0F79752C1C930CC27866544F16F1F1335AD20FB4BC9D1C602C4A74104A3CC53519C25623E871DD23A46A70E88DB40BD81E14BE69203AA9E72DAB921E776DC77E192FFDAEB876C975525666D7BDDB330B7000503C000E4D098EE1AD3A7D6B52D5BE8C2DE4D540E5050200144809B76E5AABA8DD7F942D0441ABFAD9EC0EE67EF44615D8CF619FF550850D5E5A2D78A590CF235870A0780970A07805F76F20CE0C503C08B0780179F0578F141A017EF02BC780078F100F000F041A007800F023D00CA62066B4F66BFA780F20600A9713D56986F3F5701144044C975A67EE37A1901C040322C7432934CFA0C830240D3174285870E713323813D78E8D60360448920445D85FB732528C83D53006CBA18F7111674A97827172188824D1E00132C2B1767E4C88D4326DB581120C031BA77CC1F30ED10A2FFD69877C4CA030D800867D97B3C008A2081C3060AEF8820C4E489128D6475411044120E556EDF9BC67A9D55E92E19F023CA90B40703BB799251F90EE6785FC79F8239E701500479FDB73B5F8BA42B81C8C5BBE7891A21BACB3F73176F5785BF5F5EF7E06B05390EA5D608783ADE0E2BDE7D6FF71C0300DAE622BBA17171973C008A20579CF7B864582F879BD11FA727F6C2E07DB4D4FF9280DB65F6CD42AFB5AAAEED1D0997027815200752102529699E7F92A707A45E29FA22DC2BCFF92CA088727EBAF35DF5CCBA42C87E03021C92FD11E3CDD2E418EF4F2C3AC0E1A786E06F9A6A33E3DAA62E65DD5D70D17952EE29C9C131796A20F9D7E59F0171EE2D38AD9866B6AEA9E1B7659539966D816C4DE7B166D1CCA369EE6263D525CEB9300E0DF43E94BDC55C6AFD4EC3A3172EEED8637FBCA67D416A9AED7F7AD6B9CF9BB98678DE0812B790EE6A396E5855D7F15639EAF1FF015841FD48A44C570F0000000049454E44AE426082'), $data[0]->getContent()); + $this->assertEquals(pack('H*', '6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141414470556C45515652596865315A585567555552512B5A39646358624E4E4C4C4D314E6247303341724B4A585533677167484B336F776968376336442B71682F372F33346F67736A434C364B45777A622B4B54497A6F77536853574E63734C4E61734B4372536367304E79705A437935335477395934732B73366439787252505539444C4E7A7633504F64382B636D5876504C494161584B7A4C557355767461766A44775737387449596D535A7A5645526B6946722F7167316D576730614C516F65387634634636654C546441626F6B4A36653451334C37353075586F453453647A7837475539664D623166704874515941554F6159302F72636E5A67614159546F36344149554F696A72546B504D75614E71616E7347485A424A66597372556244776953674C597675662F37557038712F566857377543354C47344C494E673045584A7762682B423539736A4E5835444A6243696F544E64714E597871524531545A6F354F6D54374B58745046614D4B55665031497A5948544A67414541674C68304B5A6D6A3063676F6B4238416A702F39486E624B7A635149654B30444D4D5357787850515158583072324A49595344713577766D7430376C6A554E6B7171614B7832314E7A3463574E6C4D6941434167446E72346E5868544C48594D685135776E7543524276324A515041366C334A6741457A744742704C4143597A416278536D696F39734B64544A5A59796756523270437049586D7045524743556A455267597844414A7358336E6433667838386E454B476F6D4E304B5068786B4F5642382B55676B4731376F704B566B71425665796571657177474256717A78797153464A614F71544E47457849765253416F65314951394C53704F7A534D7166425A6F4E47716E467030544768786257617033624A323979526549675A4551724B2B31473470735675796C78743968766F6C49304B5A33537065494242736C6F626A35624F4D53574644573450395155413269324F735558667961727033575361696F7279586436353369707A2B3237482F564A723831634B74636E773837733150452F6349694C686D3332517070372B4770706D6A354D623842586D6E61307A512B367355776131676565486646735253424C3956554D445657494C2F47564C43763133554C506866513072346B7A4D55754B3368425749493143386F622B657A51454E385558476D5661724939625A37344B6A4F786F3969373064417A676257586C4D74626C357142306D6750537461704B4F794C617A4E366B434547624F6A6E49306668304F4B57454D327179504771427366722F6350354C756E4A674935696565755348716E4F6C32396E613565663435436F587A392B6F33344E5230732F5975436F4D4F62483250676C6C6B56434F426D7854744647745073432B396D68656B3076397A4B7251676B66514835665650374F64776E55486E2B36317456372F6B496B714B3833696F3338755261376E6E506B6C496A6A78535A704E2B634C703974753148325670582F594638324A464558487548372B57734954576177677269334A73466E6944502B75677878423839626875496843415172714C71345454782F38764354764B536F7172423132415864726E5942454146356A35586E3271576A687A613267446474424C3039777642767351414159454A5365466D397862597477652B504467414138397A6F636F6631784A565A5133502B4138457749412B7133696A634141414141456C46546B5375516D4343'), $data[0]->getThumb()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetByAccountId() + { + $data = self::$service->getByAccountId(1); + + $this->assertCount(2, $data); + $this->assertInstanceOf(FileData::class, $data[0]); + $this->assertEquals(4, $data[0]->getId()); + $this->assertEquals('android.png', $data[0]->getName()); + $this->assertEquals('image/png', $data[0]->getType()); + $this->assertEquals('PNG', $data[0]->getExtension()); + $this->assertEquals(4295, $data[0]->getSize()); + $this->assertEquals(1, $data[0]->getAccountId()); + + $this->assertInstanceOf(FileData::class, $data[1]); + $this->assertEquals(1, $data[1]->getId()); + $this->assertEquals('sysPass.xml', $data[1]->getName()); + $this->assertEquals('text/xml', $data[1]->getType()); + $this->assertEquals('XML', $data[1]->getExtension()); + $this->assertEquals(1312, $data[1]->getSize()); + $this->assertEquals(1, $data[1]->getAccountId()); + $this->assertEquals(pack('H*', '3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C526F6F743E0A20203C4D6574613E0A202020203C47656E657261746F723E737973506173733C2F47656E657261746F723E0A202020203C56657273696F6E3E312E322E303C2F56657273696F6E3E0A202020203C54696D653E313433393332353330343C2F54696D653E0A202020203C557365722069643D2231223E61646D696E3C2F557365723E0A202020203C47726F75702069643D2231223E41646D696E733C2F47726F75703E0A202020203C486173683E36646232633238323731393136326630663136316531343731653734636531623C2F486173683E0A20203C2F4D6574613E0A20203C43617465676F726965733E0A202020203C43617465676F72792069643D2231223E0A2020202020203C6E616D653E485454503C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F43617465676F72793E0A20203C2F43617465676F726965733E0A20203C437573746F6D6572733E0A202020203C437573746F6D65722069643D2231223E0A2020202020203C6E616D653E476F6F676C6520496E632E3C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A202020203C437573746F6D65722069643D2232223E0A2020202020203C6E616D653E4D6963726F736F667420496E633C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A20203C2F437573746F6D6572733E0A20203C4163636F756E74733E0A202020203C4163636F756E742069643D2231223E0A2020202020203C6E616D653E476F6F676C653C2F6E616D653E0A2020202020203C637573746F6D657249643E313C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E61646D696E3C2F6C6F67696E3E0A2020202020203C75726C3E382E382E382E383C2F75726C3E0A2020202020203C6E6F7465732F3E0A2020202020203C706173733E6C4E66513133634B6A384D592B79434F346652536B4773494334357247454C442F424E69345654614671593D3C2F706173733E0A2020202020203C7061737369763E454E6354743338503265346C643350395A553241767939664C466277386C42473947382F75414D785A6D343D3C2F7061737369763E0A202020203C2F4163636F756E743E0A202020203C4163636F756E742069643D2232223E0A2020202020203C6E616D653E4D6963726F736F66743C2F6E616D653E0A2020202020203C637573746F6D657249643E323C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E726F6F743C2F6C6F67696E3E0A2020202020203C75726C3E342E342E342E343C2F75726C3E0A2020202020203C6E6F7465733E4E6F746173206465206D6963726F66736F66743C2F6E6F7465733E0A2020202020203C706173733E3352394F48632B53335A4E56684D795948352F784C476C76625246662F5367573348527261322B325349453D3C2F706173733E0A2020202020203C7061737369763E763637306A596B43547178635332344C4F65453077672B304330376A734C2F4635342B6E56484963544F773D3C2F7061737369763E0A202020203C2F4163636F756E743E0A20203C2F4163636F756E74733E0A3C2F526F6F743E0A'), $data[1]->getContent()); + $this->assertEquals(pack('H*', '6E6F5F7468756D62'), $data[1]->getThumb()); + + $this->assertCount(0, self::$service->getByAccountId(10)); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Repositories\NoSuchItemException + */ + public function testDelete() + { + self::$service + ->delete(1) + ->delete(3); + + $this->assertEquals(1, $this->conn->getRowCount('AccountFile')); + + $this->expectException(NoSuchItemException::class); + + self::$service->delete(10); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException + */ + public function testDeleteByIdBatch() + { + $this->assertEquals(2, self::$service->deleteByIdBatch([1, 3])); + $this->assertEquals(0, self::$service->deleteByIdBatch([])); + + $this->assertEquals(1, $this->conn->getRowCount('AccountFile')); + + $this->expectException(ServiceException::class); + + self::$service->deleteByIdBatch([10]); + } + + /** + * Returns the test dataset. + * + * @return IDataSet + */ + protected function getDataSet() + { + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountFile.xml'); + } +} diff --git a/tests/Services/AccountHistoryServiceTest.php b/tests/Services/AccountHistoryServiceTest.php new file mode 100644 index 00000000..b59273c7 --- /dev/null +++ b/tests/Services/AccountHistoryServiceTest.php @@ -0,0 +1,250 @@ +. + */ + +namespace SP\Tests\Services; + +use PHPUnit\DbUnit\DataSet\IDataSet; +use SP\DataModel\AccountHistoryData; +use SP\DataModel\Dto\AccountHistoryCreateDto; +use SP\DataModel\ItemSearchData; +use SP\Repositories\NoSuchItemException; +use SP\Services\Account\AccountHistoryService; +use SP\Services\Account\AccountPasswordRequest; +use SP\Services\ServiceException; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Tests\DatabaseTestCase; +use SP\Util\Util; +use function SP\Tests\setupContext; + +/** + * Class AccountHistoryServiceTest + * + * @package SP\Tests\Services + */ +class AccountHistoryServiceTest extends DatabaseTestCase +{ + /** + * @var AccountHistoryService + */ + private static $service; + + /** + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \DI\DependencyException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el servicio + self::$service = $dic->get(AccountHistoryService::class); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetAll() + { + $data = self::$service->getAll(); + + $this->assertCount(5, $data); + $this->assertEquals(7, $data[0]->id); + $this->assertEquals('2018-06-13 20:14:23', $data[0]->dateEdit); + $this->assertEquals('2018-06-05 22:11:40', $data[0]->dateAdd); + $this->assertEquals('admin', $data[0]->userAdd); + $this->assertEquals('admin', $data[0]->userEdit); + } + + /** + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testCreate() + { + $result = self::$service->create(new AccountHistoryCreateDto(2, true, false, Util::generateRandomBytes())); + $this->assertEquals(8, $result); + + $result = self::$service->create(new AccountHistoryCreateDto(2, true, true, Util::generateRandomBytes())); + $this->assertEquals(9, $result); + + $result = self::$service->create(new AccountHistoryCreateDto(10, true, false, Util::generateRandomBytes())); + $this->assertEquals(0, $result); + + $this->assertEquals(7, $this->conn->getRowCount('AccountHistory')); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testSearch() + { + $itemSearchData = new ItemSearchData(); + $itemSearchData->setLimitCount(10); + $itemSearchData->setSeachString('Google'); + + $result = self::$service->search($itemSearchData); + $data = $result->getDataAsArray(); + + $this->assertEquals(5, $result->getNumRows()); + $this->assertCount(5, $data); + $this->assertEquals(7, $data[0]->id); + + $itemSearchData->setSeachString('test'); + $result = self::$service->search($itemSearchData); + + $this->assertEquals(0, $result->getNumRows()); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetHistoryForAccount() + { + $data = self::$service->getHistoryForAccount(2); + + $this->assertCount(1, $data); + $this->assertArrayHasKey(3, $data); + $this->assertEquals('2018-06-06 22:20:29 - admin', $data[3]); + + $data = self::$service->getHistoryForAccount(1); + + $this->assertCount(4, $data); + $this->assertArrayHasKey(4, $data); + $this->assertArrayHasKey(5, $data); + $this->assertArrayHasKey(6, $data); + $this->assertArrayHasKey(7, $data); + $this->assertEquals('2018-06-05 22:11:40 - admin', $data[4]); + + $this->assertCount(0, self::$service->getHistoryForAccount(10)); + } + + /** + * @throws \SP\Core\Exceptions\SPException + */ + public function testGetById() + { + $data = self::$service->getById(3); + /** @var AccountHistoryData $data */ + + $this->assertInstanceOf(AccountHistoryData::class, $data); + $this->assertEquals(3, $data->getId()); + $this->assertEquals('2018-06-06 22:20:29', $data->getDateEdit()); + $this->assertEquals('2018-06-05 22:49:34', $data->getDateAdd()); + $this->assertEquals(1, $data->getUserId()); + $this->assertEquals(1, $data->getUserEditId()); + + $this->expectException(NoSuchItemException::class); + + self::$service->getById(1); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Services\ServiceException + */ + public function testDelete() + { + self::$service->delete(3); + self::$service->delete(4); + + $this->expectException(ServiceException::class); + + self::$service->delete(1); + + $this->assertEquals(3, $this->conn->getRowCount('AccountHistory')); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testDeleteByIdBatch() + { + $this->assertEquals(3, self::$service->deleteByIdBatch([1, 3, 4, 5])); + $this->assertEquals(0, self::$service->deleteByIdBatch([])); + + $this->assertEquals(2, $this->conn->getRowCount('AccountHistory')); + } + + /** + * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException + * @throws \SP\Core\Exceptions\SPException + */ + public function testUpdatePasswordMasterPass() + { + $request = new AccountPasswordRequest(); + $request->id = 3; + $request->pass = Util::generateRandomBytes(); + $request->key = Util::generateRandomBytes(); + $request->hash = Util::generateRandomBytes(); + + self::$service->updatePasswordMasterPass($request); + + $data = self::$service->getById(3); + + $this->assertEquals($request->pass, $data->getPass()); + $this->assertEquals($request->key, $data->getKey()); + + $this->expectException(ServiceException::class); + + $request->id = 10; + + self::$service->updatePasswordMasterPass($request); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + */ + public function testGetAccountsPassData() + { + $data = self::$service->getAccountsPassData(); + + $this->assertCount(5, $data); + $this->assertEquals(3, $data[0]->id); + $this->assertEquals('Google', $data[0]->name); + $this->assertEquals(pack('H*', '646566353032303064396362643366376662646536326637663732663861383732623430613839386131643134333933663662623033316664343362366461643762626564643634386437363964346634616234386638336636653236396166623734636261383134313363626162326461393733343934613231653934666331616664633637313732316562356666396562646132613665313937626233333563613632383830393934333863643731333230383132316430366433303838'), $data[0]->pass); + $this->assertEquals(pack('H*', '6465663130303030646566353032303032636635623034396437656539356531653838663166613438643061616132663133613163663766346238316165663837326134373665316461653661353865316666626438346130383166303062633138646136373265653935643234626564336565303063333262646262303433336633356534323263616337613238363532336233313666316137333462616337343839346631333632643863376430373861373862396135633064396239653061353537626562666336636566623766363166376330393734356461623536373762303436313865343936383434663932666364303634316330303935636239363938336361336631363161623134663339643536636233653938333833613062396464356365383736333334376364363933313563306436343362623937366139383831376632346431303364316533353133306262393862353034353262346334663934663162323531383632356530653331346438343430323362666334306264616265376437386238663632326535353338636537663431626261616461613138646333333662623762636565333030656565333734616537356365303131363731323239383132383964346634383661376635303136303835336138663335653366393230383632386162373332343335633037656432616234'), $data[0]->key); + $this->assertEquals(pack('H*', '24327924313024787473754E325055766753482F306D7266426C73624F4163745667436A596371447143364C3354395172614E785A43345258475961'), $data[0]->mPassHash); + } + + /** + * Returns the test dataset. + * + * @return IDataSet + */ + protected function getDataSet() + { + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountHistory.xml'); + } +} diff --git a/tests/Services/AccountSearchServiceTest.php b/tests/Services/AccountSearchServiceTest.php new file mode 100644 index 00000000..16137825 --- /dev/null +++ b/tests/Services/AccountSearchServiceTest.php @@ -0,0 +1,503 @@ +. + */ + +namespace SP\Tests\Services; + +use PHPUnit\DbUnit\DataSet\IDataSet; +use SP\Account\AccountSearchFilter; +use SP\Account\AccountSearchItem; +use SP\Core\Context\ContextInterface; +use SP\DataModel\UserPreferencesData; +use SP\Mvc\Model\QueryCondition; +use SP\Services\Account\AccountSearchService; +use SP\Services\User\UserLoginResponse; +use SP\Storage\Database\DatabaseConnectionData; +use SP\Storage\Database\QueryResult; +use SP\Tests\DatabaseTestCase; +use function SP\Tests\setupContext; + +/** + * Class AccountSearchServiceTest + * + * @package SP\Tests\Services + */ +class AccountSearchServiceTest extends DatabaseTestCase +{ + /** + * @var AccountSearchService + */ + private static $service; + /** + * @var \Closure + */ + private static $setUpUser; + + /** + * @throws \DI\NotFoundException + * @throws \SP\Core\Context\ContextException + * @throws \DI\DependencyException + */ + public static function setUpBeforeClass() + { + $dic = setupContext(); + + // Datos de conexión a la BBDD + self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); + + // Inicializar el servicio + self::$service = $dic->get(AccountSearchService::class); + + $context = $dic->get(ContextInterface::class); + + self::$setUpUser = function (UserLoginResponse $response) use ($context) { + $response->setLastUpdate(time()); + + $context->setUserData($response); + }; + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testProcessSearchResultsForUserAdmin() + { + $userData = new UserLoginResponse(); + $userData->setId(1); + $userData->setUserGroupId(1); + $userData->setIsAdminApp(1); + $userData->setPreferences(new UserPreferencesData()); + + self::$setUpUser->call($this, $userData); + + $this->checkCategoryById(1, [1]); + $this->checkNonExistantCategory(); + $this->checkClientById(1, [1]); + $this->checkClientById(2, [2]); + $this->checkClientAndCategory(2, 2, [2]); + $this->checkClientAndCategory(2, 1, [2, 1], QueryCondition::CONDITION_OR); + $this->checkNonExistantClient(); + $this->checkString('apple.com', [2]); + $this->checkString('aaaa', [1]); + $this->checkString('github'); + $this->checkString('google', [1]); + $this->checkString('slack'); + $this->checkString('is:private'); + $this->checkString('not:private', [2, 1]); + $this->checkString('user:admin', [2, 1]); + $this->checkString('user:user_a', [2, 1]); + $this->checkString('owner:user_a'); + $this->checkString('owner:user_b'); + $this->checkString('group:Admins', [2, 1]); + $this->checkString('group:Usuarios', [2]); + $this->checkString('maingroup:Admins', [2, 1]); + $this->checkString('maingroup:Usuarios'); + $this->checkString('file:"Clock 3"', [2]); + $this->checkString('file:"syspass"', [1]); + $this->checkString('id:1', [1]); + $this->checkString('id:3'); + $this->checkFavorites(1, [1]); + $this->checkTags([1, 3], [2]); + $this->checkTags([1, 3], [2, 1], QueryCondition::CONDITION_OR); + $this->checkTags([2], [1]); + } + + /** + * @param int $id Category Id + * @param array $accountsId + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkCategoryById($id, array $accountsId = []) + { + $rows = count($accountsId); + + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setCategoryId($id); + + // Comprobar un Id de categoría + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + + if ($rows > 0) { + /** @var AccountSearchItem[] $data */ + $data = $result->getDataAsArray(); + + $i = 0; + + foreach ($data as $searchItem) { + $this->assertEquals($accountsId[$i], $searchItem->getAccountSearchVData()->getId()); + $i++; + } + } + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkNonExistantCategory() + { + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setCategoryId(10); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + $this->assertEquals(0, $result->getNumRows()); + $this->assertCount(0, $result->getDataAsArray()); + } + + /** + * @param int $id Client Id + * @param array $accountsId + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkClientById($id, array $accountsId = []) + { + $rows = count($accountsId); + + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setClientId($id); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + $this->assertEquals($rows, $result->getNumRows()); + + if ($rows > 0) { + /** @var AccountSearchItem[] $data */ + $data = $result->getDataAsArray(); + + $i = 0; + + foreach ($data as $searchItem) { + $this->assertEquals($accountsId[$i], $searchItem->getAccountSearchVData()->getId()); + $i++; + } + } + } + + /** + * @param int $clientId + * @param int $categoryId + * @param array $accountsId + * @param string $operator + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkClientAndCategory($clientId, $categoryId, array $accountsId = [], $operator = null) + { + $rows = count($accountsId); + + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setFilterOperator($operator); + $searchFilter->setClientId($clientId); + $searchFilter->setCategoryId($categoryId); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + $this->assertEquals($rows, $result->getNumRows()); + + $i = 0; + + /** @var AccountSearchItem $item */ + foreach ($result->getDataAsArray() as $item) { + $this->assertEquals($accountsId[$i], $item->getAccountSearchVData()->getId()); + $i++; + } + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkNonExistantClient() + { + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setClientId(10); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + $this->assertEquals(0, $result->getNumRows()); + $this->assertCount(0, $result->getDataAsArray()); + } + + /** + * @param string $string + * @param array $accountsId + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkString($string, array $accountsId = []) + { + $rows = count($accountsId); + + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setTxtSearch($string); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + + $this->assertEquals($rows, $result->getNumRows()); + + $i = 0; + + /** @var AccountSearchItem $item */ + foreach ($result->getDataAsArray() as $item) { + $this->assertEquals($accountsId[$i], $item->getAccountSearchVData()->getId()); + + $i++; + } + } + + /** + * @param int $rows Expected rows + * @param array $accountsId + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkFavorites($rows, array $accountsId = []) + { + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setSearchFavorites(true); + + $result = self::$service->processSearchResults($searchFilter); + + $this->assertInstanceOf(QueryResult::class, $result); + $this->assertEquals($rows, $result->getNumRows()); + + $i = 0; + + /** @var AccountSearchItem $item */ + foreach ($result->getDataAsArray() as $item) { + $this->assertEquals($accountsId[$i], $item->getAccountSearchVData()->getId()); + $i++; + } + } + + /** + * @param array $tagsId + * @param array $accountsId + * @param string $operator + * + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + private function checkTags(array $tagsId, array $accountsId = [], $operator = null) + { + $rows = count($accountsId); + + $searchFilter = new AccountSearchFilter(); + $searchFilter->setLimitCount(10); + $searchFilter->setFilterOperator($operator); + $searchFilter->setTagsId($tagsId); + + $result = self::$service->processSearchResults($searchFilter); + $this->assertInstanceOf(QueryResult::class, $result); + + /** @var AccountSearchItem[] $data */ + $data = $result->getDataAsArray(); + + $this->assertEquals($rows, $result->getNumRows()); + $this->assertCount($rows, $data); + + $i = 0; + + foreach ($data as $item) { + $this->assertEquals($accountsId[$i], $item->getAccountSearchVData()->getId()); + $i++; + } + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testProcessSearchResultsForUserDemo() + { + AccountSearchItem::$publicLinkEnabled = false; + + $userData = new UserLoginResponse(); + $userData->setId(2); + $userData->setUserGroupId(2); + $userData->setPreferences(new UserPreferencesData()); + + self::$setUpUser->call($this, $userData); + + $this->checkCategoryById(1, [1]); + $this->checkNonExistantCategory(); + $this->checkClientById(1, [1]); + $this->checkClientById(2, [2]); + $this->checkClientAndCategory(2, 2, [2]); + $this->checkClientAndCategory(2, 1, [2, 1], QueryCondition::CONDITION_OR); + $this->checkNonExistantClient(); + $this->checkString('apple.com', [2]); + $this->checkString('github'); + $this->checkString('google', [1]); + $this->checkString('slack'); + $this->checkString('is:private'); + $this->checkString('not:private', [2, 1]); + $this->checkString('user:admin', [2, 1]); + $this->checkString('user:user_a', [2, 1]); + $this->checkString('owner:user_a'); + $this->checkString('owner:user_b'); + $this->checkString('group:Admins', [2, 1]); + $this->checkString('group:Usuarios', [2]); + $this->checkString('maingroup:Admins', [2, 1]); + $this->checkString('maingroup:Usuarios'); + $this->checkString('file:"Clock 3"', [2]); + $this->checkString('file:"syspass"', [1]); + $this->checkString('id:1', [1]); + $this->checkString('id:3'); + $this->checkFavorites(1, [2]); + $this->checkTags([1, 3], [2]); + $this->checkTags([1, 3], [2, 1], QueryCondition::CONDITION_OR); + $this->checkTags([2], [1]); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testProcessSearchResultsForUserA() + { + AccountSearchItem::$publicLinkEnabled = false; + + $userData = new UserLoginResponse(); + $userData->setId(3); + $userData->setUserGroupId(3); + $userData->setPreferences(new UserPreferencesData()); + + self::$setUpUser->call($this, $userData); + + $this->checkCategoryById(1, [1]); + $this->checkNonExistantCategory(); + $this->checkClientById(1, [1]); + $this->checkClientById(2, [2, 3]); + $this->checkClientAndCategory(2, 2, [2, 3]); + $this->checkClientAndCategory(2, 1, [2, 3, 1], QueryCondition::CONDITION_OR); + $this->checkNonExistantClient(); + $this->checkString('apple.com', [2]); + $this->checkString('github', [3]); + $this->checkString('google', [1]); + $this->checkString('slack', [4]); + $this->checkString('is:private', [3, 4]); + $this->checkString('user:admin', [2, 1]); + $this->checkString('user:user_a', [2, 3, 1, 4]); + $this->checkString('owner:user_a', [3, 4]); + $this->checkString('owner:user_b'); + $this->checkString('group:Admins', [2, 1]); + $this->checkString('group:Usuarios', [2, 3, 4]); + $this->checkString('maingroup:Admins', [2, 1]); + $this->checkString('maingroup:Usuarios', [3, 4]); + $this->checkString('file:"Clock 3"', [2]); + $this->checkString('file:"syspass"', [1]); + $this->checkString('id:1', [1]); + $this->checkString('id:3', [3]); + $this->checkFavorites(2, [2, 1]); + $this->checkTags([1, 3], [2]); + $this->checkTags([1, 3], [2, 1], QueryCondition::CONDITION_OR); + $this->checkTags([2], [1]); + } + + /** + * @throws \SP\Core\Exceptions\ConstraintException + * @throws \SP\Core\Exceptions\QueryException + * @throws \SP\Core\Exceptions\SPException + */ + public function testProcessSearchResultsForUserB() + { + AccountSearchItem::$publicLinkEnabled = false; + + $userData = new UserLoginResponse(); + $userData->setId(4); + $userData->setUserGroupId(3); + $userData->setPreferences(new UserPreferencesData()); + + self::$setUpUser->call($this, $userData); + + $this->checkCategoryById(1); + $this->checkNonExistantCategory(); + $this->checkClientById(1); + $this->checkClientById(2, [2]); + $this->checkClientAndCategory(2, 2, [2]); + $this->checkClientAndCategory(2, 1, [2], QueryCondition::CONDITION_OR); + $this->checkNonExistantClient(); + $this->checkString('apple.com', [2]); + $this->checkString('github'); + $this->checkString('google'); + $this->checkString('slack', [4]); + $this->checkString('is:private', [4]); + $this->checkString('not:private', [2]); + $this->checkString('user:admin', [2]); + $this->checkString('user:user_a', [2, 4]); + $this->checkString('owner:user_a', [4]); + $this->checkString('owner:user_b'); + $this->checkString('group:Admins', [2]); + $this->checkString('group:Usuarios', [2, 4]); + $this->checkString('maingroup:Admins', [2]); + $this->checkString('maingroup:Usuarios', [4]); + $this->checkString('file:"Clock 3"', [2]); + $this->checkString('file:"syspass"'); + $this->checkString('id:1'); + $this->checkString('id:3'); + $this->checkFavorites(0); + $this->checkTags([1, 3], [2]); + $this->checkTags([1, 3], [2], QueryCondition::CONDITION_OR); + $this->checkTags([2]); + } + + /** + * Returns the test dataset. + * + * @return IDataSet + */ + protected function getDataSet() + { + return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_accountSearch.xml'); + } +} diff --git a/tests/TagRepositoryTestCase.php b/tests/TagRepositoryTestCase.php deleted file mode 100644 index 64175fef..00000000 --- a/tests/TagRepositoryTestCase.php +++ /dev/null @@ -1,233 +0,0 @@ -. - */ - -namespace SP\Tests; - -use SP\Core\Exceptions\QueryException; -use SP\DataModel\ItemSearchData; -use SP\DataModel\TagData; -use SP\Repositories\DuplicatedItemException; -use SP\Repositories\Tag\TagRepository; -use SP\Storage\DatabaseConnectionData; - -/** - * Class TagRepositoryTest - * - * @package SP\Tests - */ -class TagRepositoryTest extends DatabaseBaseTest -{ - /** - * @var TagRepository - */ - private static $tagRepository; - - /** - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - * @throws \DI\DependencyException - */ - public static function setUpBeforeClass() - { - $dic = setupContext(); - - // Datos de conexión a la BBDD - self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); - - // Inicializar el repositorio - self::$tagRepository = $dic->get(TagRepository::class); - } - - /** - * Comprobar la búsqueda mediante texto - */ - public function testSearch() - { - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('www'); - - $search = self::$tagRepository->search($searchItemData); - $this->assertCount(2, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(1, $search['count']); - $this->assertEquals(1, $search[0]->id); - - $searchItemData = new ItemSearchData(); - $searchItemData->setLimitCount(10); - $searchItemData->setSeachString('prueba'); - - $search = self::$tagRepository->search($searchItemData); - $this->assertCount(1, $search); - $this->assertArrayHasKey('count', $search); - $this->assertEquals(0, $search['count']); - } - - /** - * Comprobar los resultados de obtener las etiquetas por Id - */ - public function testGetById() - { - $tag = self::$tagRepository->getById(10); - - $this->assertCount(0, $tag); - - $tag = self::$tagRepository->getById(1); - - $this->assertEquals('www', $tag->getName()); - - $tag = self::$tagRepository->getById(2); - - $this->assertEquals('windows', $tag->getName()); - } - - /** - * Comprobar la obtención de todas las etiquetas - */ - public function testGetAll() - { - $count = $this->conn->getRowCount('Tag'); - - $results = self::$tagRepository->getAll(); - - $this->assertCount($count, $results); - - $this->assertInstanceOf(TagData::class, $results[0]); - $this->assertEquals('Linux', $results[0]->getName()); - - $this->assertInstanceOf(TagData::class, $results[1]); - $this->assertEquals('windows', $results[1]->getName()); - - $this->assertInstanceOf(TagData::class, $results[2]); - $this->assertEquals('www', $results[2]->getName()); - } - - /** - * Comprobar la actualización de etiquetas - * - * @covers \SP\Repositories\Category\CategoryRepository::checkDuplicatedOnUpdate() - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - * @throws \SP\Core\Exceptions\SPException - */ - public function testUpdate() - { - $tagData = new TagData(); - $tagData->id = 1; - $tagData->name = 'Servidor'; - - self::$tagRepository->update($tagData); - - $category = self::$tagRepository->getById(1); - - $this->assertEquals($category->getName(), $tagData->name); - - // Comprobar la a actualización con un nombre duplicado comprobando su hash - $tagData = new TagData(); - $tagData->id = 1; - $tagData->name = ' linux.'; - - $this->expectException(DuplicatedItemException::class); - - self::$tagRepository->update($tagData); - } - - /** - * Comprobar la eliminación de etiquetas - * - * @throws \SP\Core\Exceptions\SPException - */ - public function testDeleteByIdBatch() - { - $this->assertEquals(0, self::$tagRepository->deleteByIdBatch([4])); - $this->assertEquals(3, self::$tagRepository->deleteByIdBatch([1, 2, 3])); - - $this->assertEquals(0, $this->conn->getRowCount('Tag')); - } - - /** - * Comprobar la creación de etiquetas - * - * @covers \SP\Repositories\Category\CategoryRepository::checkDuplicatedOnAdd() - * @throws DuplicatedItemException - * @throws \SP\Core\Exceptions\SPException - */ - public function testCreate() - { - $countBefore = $this->conn->getRowCount('Tag'); - - $tagData = new TagData(); - $tagData->name = 'Core'; - - $id = self::$tagRepository->create($tagData); - - // Comprobar que el Id devuelto corresponde con la etiqueta creada - $tag = self::$tagRepository->getById($id); - - $this->assertEquals($tagData->name, $tag->getName()); - - $countAfter = $this->conn->getRowCount('Tag'); - - $this->assertEquals($countBefore + 1, $countAfter); - } - - /** - * Comprobar la eliminación de etiquetas por Id - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testDelete() - { - $countBefore = $this->conn->getRowCount('Tag'); - - $this->assertEquals(1, self::$tagRepository->delete(3)); - - $countAfter = $this->conn->getRowCount('Tag'); - - $this->assertEquals($countBefore - 1, $countAfter); - - // Comprobar la eliminación de etiquetas usadas - $this->assertEquals(1, self::$tagRepository->delete(1)); - } - - /** - * Comprobar la obtención de etiquetas por Id en lote - */ - public function testGetByIdBatch() - { - $this->assertCount(3, self::$tagRepository->getByIdBatch([1, 2, 3])); - $this->assertCount(3, self::$tagRepository->getByIdBatch([1, 2, 3, 4, 5])); - $this->assertCount(0, self::$tagRepository->getByIdBatch([])); - } - - /** - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testCheckInUse() - { - $this->assertTrue(self::$tagRepository->checkInUse(1)); - } -} diff --git a/tests/UserRepositoryTestCase.php b/tests/UserRepositoryTestCase.php deleted file mode 100644 index d1edca38..00000000 --- a/tests/UserRepositoryTestCase.php +++ /dev/null @@ -1,306 +0,0 @@ -. - */ - -namespace SP\Tests; - -use DI\DependencyException; -use SP\Core\Crypt\Hash; -use SP\Core\Exceptions\ConstraintException; -use SP\Core\Exceptions\QueryException; -use SP\DataModel\UserData; -use SP\DataModel\UserPreferencesData; -use SP\Repositories\NoSuchItemException; -use SP\Repositories\User\UserRepository; -use SP\Services\User\UpdatePassRequest; -use SP\Storage\DatabaseConnectionData; - -/** - * Class UserRepositoryTest - * - * @package SP\Tests - */ -class UserRepositoryTest extends DatabaseBaseTest -{ - - /** - * @var UserRepository - */ - private static $userRepository; - - /** - * @throws DependencyException - * @throws \DI\NotFoundException - * @throws \SP\Core\Context\ContextException - */ - public static function setUpBeforeClass() - { - $dic = setupContext(); - - // Datos de conexión a la BBDD - self::$databaseConnectionData = $dic->get(DatabaseConnectionData::class); - - // Inicializar el repositorio - self::$userRepository = $dic->get(UserRepository::class); - } - - /** - * Comprobar la actualización de usuarios - * - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\QueryException - * @throws \SP\Core\Exceptions\SPException - */ - public function testUpdate() - { - $userData = new UserData(); - $userData->setId(2); - $userData->setName('Usuario Demo'); - $userData->setLogin('demo'); - $userData->setEmail('demo@syspass.org'); - $userData->setNotes('Usuario Demo'); - $userData->setUserGroupId(1); - $userData->setUserProfileId(1); - $userData->setIsAdminApp(1); - $userData->setIsAdminAcc(1); - $userData->setIsDisabled(1); - $userData->setIsChangePass(1); - $userData->setIsLdap(0); - - $this->assertEquals(1, self::$userRepository->update($userData)); - - $userData = new UserData(); - $userData->setId(10); - - $this->expectException(QueryException::class); - - self::$userRepository->update($userData); - } - - /** - * Comprobar la modificación de las preferencias de usuario - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testUpdatePreferencesById() - { - $preferences = new UserPreferencesData(); - $preferences->setLang('es_ED'); - $preferences->setAccountLink(true); - $preferences->setOptionalActions(true); - $preferences->setResultsAsCards(true); - $preferences->setResultsPerPage(10); - - $this->assertTrue(self::$userRepository->updatePreferencesById(2, $preferences)); - } - - /** - * Comprobar la obtención de los datos de un usuario - * - * @throws \SP\Core\Exceptions\SPException - */ - public function testGetById() - { - $user = self::$userRepository->getById(2); - - $this->assertInstanceOf(UserData::class, $user); - $this->assertEquals('sysPass Demo', $user->getName()); - $this->assertEquals('demo', $user->getLogin()); - - $this->expectException(NoSuchItemException::class); - - self::$userRepository->getById(3); - } - - /** - * Comprobar si existe un usuario - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testCheckExistsByLogin() - { - $this->assertTrue(self::$userRepository->checkExistsByLogin('demo')); - $this->assertFalse(self::$userRepository->checkExistsByLogin('usuario')); - } - - /** - * Comprobar los datos de uso de un usuario - */ - public function testGetUsageForUser() - { - $this->assertCount(1, self::$userRepository->getUsageForUser(2)); - } - - /** - * Comprobar la actualización de la clave de un usuario por Id - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - * @throws \SP\Core\Exceptions\SPException - */ - public function testUpdatePassById() - { - $result = self::$userRepository->updatePassById(2, new UpdatePassRequest(Hash::hashKey('prueba123'))); - - $this->assertTrue($result); - } - - /** - * Obtener los datos de los usuarios por Id en lote - */ - public function testGetByIdBatch() - { - $users = self::$userRepository->getByIdBatch([1, 2, 5]); - - $this->assertCount(2, $users); - $this->assertInstanceOf(UserData::class, $users[0]); - $this->assertEquals('admin', $users[0]->getName()); - $this->assertInstanceOf(UserData::class, $users[1]); - } - - /** - * Obtener los datos de todos los usuarios - */ - public function testGetAll() - { - $users = self::$userRepository->getAll(); - - $this->assertCount(4, $users); - $this->assertInstanceOf(UserData::class, $users[0]); - $this->assertEquals('admin', $users[0]->getName()); - } - - /** - * Actualizar un usuario desde el proceso de login - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testUpdateOnLogin() - { - $userData = new UserData(); - $userData->setPass(Hash::hashKey('prueba123')); - $userData->setName('prueba'); - $userData->setEmail('prueba@syspass.org'); - $userData->setIsLdap(1); - $userData->setLogin('demo'); - - $result = self::$userRepository->updateOnLogin($userData); - - $this->assertTrue($result); - } - - /** - * Eliminar usuarios en lote - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testDeleteByIdBatch() - { - $result = self::$userRepository->deleteByIdBatch([1, 2, 5]); - - $this->assertCount(2, $result); - } - - /** - * Comprobar la obtención de los datos de un usuario - * - * @throws \SP\Core\Exceptions\SPException - */ - public function testGetByLogin() - { - $user = self::$userRepository->getByLogin('demo'); - - $this->assertInstanceOf(UserData::class, $user); - $this->assertEquals('sysPass Demo', $user->getName()); - $this->assertEquals('demo', $user->getLogin()); - - $this->expectException(NoSuchItemException::class); - - self::$userRepository->getByLogin('prueba'); - } - - /** - * Comprobar la eliminación de un usuario - * - * @throws QueryException - * @throws \SP\Core\Exceptions\ConstraintException - */ - public function testDelete() - { - $result = self::$userRepository->delete(2); - - $this->assertEquals(1, $result); - - $this->expectException(ConstraintException::class); - - self::$userRepository->delete(1); - } - - /** - * Comprobar la obtención de los datos de usuarios - */ - public function testGetBasicInfo() - { - $users = self::$userRepository->getBasicInfo(); - - $this->assertCount(4, $users); - $this->assertInstanceOf(UserData::class, $users[0]); - } - - /** - * Comprobar la modificación de los datos del último login - * - * @throws ConstraintException - * @throws QueryException - */ - public function testUpdateLastLoginById() - { - $result = self::$userRepository->updateLastLoginById(2); - - $this->assertTrue($result); - } - - public function testSearch() - { - - } - - public function testUpdateMasterPassById() - { - - } - - public function testCreate() - { - - } - - public function testGetUserEmailForGroup() - { - - } -} diff --git a/tests/res/datasets/syspass_acl.xml b/tests/res/datasets/syspass_accountAcl.xml similarity index 100% rename from tests/res/datasets/syspass_acl.xml rename to tests/res/datasets/syspass_accountAcl.xml diff --git a/tests/res/datasets/syspass_favorite.xml b/tests/res/datasets/syspass_accountFavorite.xml similarity index 100% rename from tests/res/datasets/syspass_favorite.xml rename to tests/res/datasets/syspass_accountFavorite.xml diff --git a/tests/res/datasets/syspass_accountFile.xml b/tests/res/datasets/syspass_accountFile.xml new file mode 100644 index 00000000..56057624 --- /dev/null +++ b/tests/res/datasets/syspass_accountFile.xml @@ -0,0 +1,37 @@ + + + + + + 1 + 1 + sysPass.xml + text/xml + 1312 + 3C3F786D6C2076657273696F6E3D22312E302220656E636F64696E673D225554462D38223F3E0A3C526F6F743E0A20203C4D6574613E0A202020203C47656E657261746F723E737973506173733C2F47656E657261746F723E0A202020203C56657273696F6E3E312E322E303C2F56657273696F6E3E0A202020203C54696D653E313433393332353330343C2F54696D653E0A202020203C557365722069643D2231223E61646D696E3C2F557365723E0A202020203C47726F75702069643D2231223E41646D696E733C2F47726F75703E0A202020203C486173683E36646232633238323731393136326630663136316531343731653734636531623C2F486173683E0A20203C2F4D6574613E0A20203C43617465676F726965733E0A202020203C43617465676F72792069643D2231223E0A2020202020203C6E616D653E485454503C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F43617465676F72793E0A20203C2F43617465676F726965733E0A20203C437573746F6D6572733E0A202020203C437573746F6D65722069643D2231223E0A2020202020203C6E616D653E476F6F676C6520496E632E3C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A202020203C437573746F6D65722069643D2232223E0A2020202020203C6E616D653E4D6963726F736F667420496E633C2F6E616D653E0A2020202020203C6465736372697074696F6E2F3E0A202020203C2F437573746F6D65723E0A20203C2F437573746F6D6572733E0A20203C4163636F756E74733E0A202020203C4163636F756E742069643D2231223E0A2020202020203C6E616D653E476F6F676C653C2F6E616D653E0A2020202020203C637573746F6D657249643E313C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E61646D696E3C2F6C6F67696E3E0A2020202020203C75726C3E382E382E382E383C2F75726C3E0A2020202020203C6E6F7465732F3E0A2020202020203C706173733E6C4E66513133634B6A384D592B79434F346652536B4773494334357247454C442F424E69345654614671593D3C2F706173733E0A2020202020203C7061737369763E454E6354743338503265346C643350395A553241767939664C466277386C42473947382F75414D785A6D343D3C2F7061737369763E0A202020203C2F4163636F756E743E0A202020203C4163636F756E742069643D2232223E0A2020202020203C6E616D653E4D6963726F736F66743C2F6E616D653E0A2020202020203C637573746F6D657249643E323C2F637573746F6D657249643E0A2020202020203C63617465676F727949643E313C2F63617465676F727949643E0A2020202020203C6C6F67696E3E726F6F743C2F6C6F67696E3E0A2020202020203C75726C3E342E342E342E343C2F75726C3E0A2020202020203C6E6F7465733E4E6F746173206465206D6963726F66736F66743C2F6E6F7465733E0A2020202020203C706173733E3352394F48632B53335A4E56684D795948352F784C476C76625246662F5367573348527261322B325349453D3C2F706173733E0A2020202020203C7061737369763E763637306A596B43547178635332344C4F65453077672B304330376A734C2F4635342B6E56484963544F773D3C2F7061737369763E0A202020203C2F4163636F756E743E0A20203C2F4163636F756E74733E0A3C2F526F6F743E0A + XML + 6E6F5F7468756D62 + + + 3 + 2 + Clock 3.jpg + image/jpeg + 4273 + FFD8FFE000104A46494600010100000100010000FFDB0043000A07070807060A0808080B0A0A0B0E18100E0D0D0E1D15161118231F2524221F2221262B372F26293429212230413134393B3E3E3E252E4449433C48373D3E3BFFDB0043010A0B0B0E0D0E1C10101C3B2822283B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3B3BFFC00011080073007303012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFC4001F0100030101010101010101010000000000000102030405060708090A0BFFC400B51100020102040403040705040400010277000102031104052131061241510761711322328108144291A1B1C109233352F0156272D10A162434E125F11718191A262728292A35363738393A434445464748494A535455565758595A636465666768696A737475767778797A82838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE2E3E4E5E6E7E8E9EAF2F3F4F5F6F7F8F9FAFFDA000C03010002110311003F00F1C44A9D12BACF86FE12B1F17EBF3E9FA84B711451DAB4CAD032AB6E0E8BDC1E30C6BD2C7C12F0C000FDBB5500F1CCB1F1FF008E500787A254E895EC137C29F09DB90BF6FD50B63BCB1E3FF40AA73FC3AF0D41D2F35138EDE6479FFD0281D8F3244A9D12BB997C1DA0424E2E6F40C1C6F91013FF008ED556F0FE8A84013DDB7246EDE981FA5016672E8953A256F1D1F498B21A69C7A7EF1791F9542B6FA57DA4C6AF70CA7852AEB953EA723A7F9ED82AE87CACCD44A9D12B6B4EB1D0E598C5793DC459C91209515540073BB238E9D7DFB77EA60F0169B23604978BFEF3A8FF00D96AD46EAE886ECEC7068953A2577CFE05D1221C5CDE7E2EBFFC4D2C3E0BD19DB027BCEBFDF4FF00E2693562ACCE1D12A744AEFE3F0168CCA3175779CF4DEBFF00C4D55D6FC23A7697A4CF7704D72D247B76891971CB01FDD1D8D211C784E28A9C271450064FC13017C5F779FF00A07BFF00E8C8EBD86FEF42444062A082339AF1FF0083C7CBF145E1F5B071FF009123AF45D718C876C4FB5D8F504F3DF3FA552571AEE655F6AA88C4EFC633DF9F4FF38AE72F75B9240543003773838ACBD73519AD55A5C79B133E0313D320F07F0CFEB5956167AD7886EA386C6DD9D64380501007A93EC3B9E82A5E9A2354BA9A7FDA924D3C7089BCC9A421515392C4F0001EA4D741A5783B53D59E28E5BCB7B21E63C522C7FE90C85319562A76AB73F74907827B576BE16F06693A069B6D24D6292EA18579669955E44908E42B738C72383F89AE5FC65E2DD1B4ABFBBB0D2E04BBBDBA3B2E859B7D9CC52A7219A540199B2402B9E3675539C9EA4277D8E8A4F87FE1AD8229ADE6B865EA5EE9C16FC88FD07F3AAE7C37A3A46E936956B09CE17C82D961EA4F1CFB74F7AF32D4FC69E24D6AE45C3EA725AE06D16FA73344871D4E4364FE24D64DC5AEA13E6799EEA4719E4CC493F98CD3524BA072F767A3EB9A269B65A734F6DA64B2EC23885D8C817FBC149C3638C8E38C9CF18A5D0EFF00504D303D85E5CEA16800D914D0B46EA0F20A33FDE5C718048E38C6307CDE2BDD5AD98449A9DFDB803210C8D8F5E0719FCAB7AC7C79A9DAC4A751B58AEADD005F3231B24278E4F38F4E303AF5A7CD17BAB1493E8CEE135F0EBF31646FEE30DAC3F02339FF00EB54B69AB02411267273C9C71D7FC2B8BD66E86A96B1EA9A44A9208D8AC9C152401D31F8FEA39F5ABA7F88964216401243C9EC3F3FCE9C9A295AC7AFE9DAB2B3E03A9EDEB9FF0038A7F89984BE1DBA2B9FE0E0741F3AD709A56AE721771C67DEBA6BDBE175A15C26EDD90B8E7FDA159A77339239609C515384E28A641CC7C2F6F27C4374C7FE7C9C7FE3E95D6788EF1E3F2E68E4C79520270718078CFF002AE3FC00DE56B172C0E3368C33FF00034ADBF115D99B4DB800E020DC467D083F8F4FD6A1CF9648DE11BC59CB5E5E99079780CA87A63A1F5FE7D2BD2FE1E6893D8E8F7926A901B77BD508A03324CAA3209CF55CE723041E33E98F30D1A279BC4C891DB8BA11CBBD9791B4671B8903800906BD16DFC6A24D5F5AB1F21A5874F412ACD0AE4B85505D0FFB5B836DF5C1E9B79DA2BAF7329B6F4441F113C5E34BB54F0DE8526C99D7FD22447667863C03B41EECD9EE49C11C65811C0E9FA5C6D6E4CCA5636FB88A705871827F4FE9C7599A39350D6EFAF5A21E6199A568FCE620BE49500E395CE4FE38C56EE8BA7CFA9195A5CA44AD90EC854631DB3E98E4D6136EF6467527CAAC8C2B6BA996ED628ECF6C6CA37F929C2C873C9EE38EB91D6B527D3B519E35104332EE71BCAE54E3D8E3D7F4CD7571580B5B23736D0111821C1050171904B658E147A93CF7F63A90D843241E62C73191B19591CA3020F207B8E71D8FAE306972DCC1BBEA91C29D3AFD6206E2D5C1DB97C2961D39AC2FB3C5A8C456D5D6DE58F21515970F1E7861C1E318FC735E81E2C33C76B6FA158999E5D537A33800AA460FCDB8F5F9B2147A024F6E6FDB681A635B2A0815664528C594292091938C74F9473D7803B5096BA0E2DC55D1E48967A8593B5EDA26C92303CD89548565EE303AF6E3DC1F4AAB72F079A2E6DD888E53C29C6548E307F9D7A06AFA525A4AD3DACB1DC3443FE59B6E7423271B723E6C838CF5E41C026B9BD6B4448DA19E3B79218351195B764E6DE451C8273DF923F1E2ABE2475D3A8A5B95F4AD41D1F05BDB935DFE9F7C6E2C1D3767701DFAF22BCB210D6F3946006D6C0AF4FD00E9EFA5E123FF004908BFBC0C704F1938CFF4A94ED63471BA2C84E28A9C271456A60709E0F668B529D97FE7D9B3FF007D2D5FD6C97B1B80A40CC47A8CFE03F3AABE141B2FE76C6716EDC7AFCCB56756007C99E3695248C8238E3D6B09FC475D27EE18DE149FCBD7C48A18F9B190483DBA93C7B815D26B9345A5787AE174D8961762A1B6E32E4B724FA9233C9F5AE2FC317BF66BE313B6CF3700673CE39C574B1CEDAC6911ACF0B40D2B2175739C6187F4CF5F6AE98BF70C64AD222D122B6B68079930D8A58C8CC4F453B71F98C01EA7DEBAB9F51D3A3B388ADE4769672B32B5C3BA84CC6FB4A61BAE5B2323A81D7BD57D2B4B4BE82789CB44F1CDB448002C854E415ED9CAA904E7A0E0D686A7A2D96A09069B3A36C91A4932589DAF907233EFCE3A707F1C36670BB735D9A7A75D473CB3CD6B7115DDAB287DF03F98030FBC0618E33F2E140EC4924B55F5DAC5C2BAFCBC3E1BEEF1DEB9883C07A34128789668E41C099362B7D72AA2B3FC41E15D43EC05EDB539EEB64AB2C91DCCACE190039072724727E5070413C669DC768B66BE876716ADA9DFEB971133ADCB7976E246253CA5C85214F40465B18EB21EE2B66F0C904C6EA286326300B313CB8C1CA0F43CA91D41EF8C0359FA035EC3A7D9C7E741796CB02076C95983E3E627390F93939F94F5FBD9AD2BD69C2AF9621F236389C312180DBF295C0C1E78EDC1F6C53889BD463E8B6324CD288143BAB2EEC6400D82481D3248049EA48EB5C9EB1671AE87A942CEE5ADD44DB0C646C08416F98F5CA9DBC76EBC9ADB96EB5B86DB4A4B2B4498BC71E7CD942EF22362C8C4E483F748201FBAD9C719A7E275945F6A08AD0FD9DB4D99A4C93E6670C0103A05C0E7BE40FC348EA690D25A1E6FA9DB3978E68D372B7DE715D1784E666B98E3C9DA4118FC0D518E3FF47891C00CA8A0827BE3A55CF07A63518863A0393FF0135125AA3AAFA1DB04E28A9C271455191C0F84E22DA84E07FCFBB7F35A9B538CF23F848E303353782E012EA770A549FF00456E3FE04B5A1ABD8853B994F049C63A0CF5AC66B5B9D149E963CAEDD92D3520CD8D8AC4648E9D466BAD8A78EEAD7FBEB282383D45739ADD93457AD9FE23BBF33EBF5CD555656884447DDE4EF63C607200E858FF00F5BDEAE32E812573D5744D4D1187971F9F35CC241DAB8FDEC6BCEF2385DDD466B56D5EEB55D28B4AD1C72B7EF2DA48D1B0B91953F30EA32467B8F98019C0E0FC2BA87F67CF1ADC305826DA30836F9583F21E4FF0F7FA91CD7A5DACC970AB8910C840390DF2C83FBC9EA0F5A6D7538AA4395E857B79E1B2D3D8AC53280CA0C288CEE3903200C9C720FD2B499D6352CEE14A8E598E001DCFB573735ECD75AD79715ABC535AF90BF3232EFF0033F89581F9828272A54721B046091B53DB5CCF0C96D22412C1226D6CB15CE7AF1838F6EB5266FCC9EE16D43C6F395462E12362DB4963D141F524553BF7B996F5ACA1B8245C28565E3302F24B8E3BF0307232467038365E0BEB95DA4C11AF0CAC3F7877020838207F9FA731691756B2CF2C10C7718015D6EA52196E72A0EE5209246307A01E9C53B0245F86EE16BDFB202C64D8640429DA406DA46EE9907A8EA3F1AC9F103DA4BA45FCCA1A65997C862A41187211B07D8296FA1CD6A9B38E395E6822DB712E43480918C84527382B9C2A751D17F3E3BC5FA844F15BDBB49E798010933F04E47CF230C0033D0638C138E0D6B15646B4E3AA67217C1DB524BA5CBC681891D94E38FE95BBE108C9BE89B6E0053EF9F96B1A43E6C691A9C87E49EBC5759E18B52B3A3E3B1ED8ED59BD59D2F63A709C515384E28AA3238FF87B0F99ADDC02323EC8DFFA125749AC5817048046327803FCF7AC3F875F2EBB3FBDA37FE8495DDDEDB89D58AF6E83DEA64AE8719599E3BE22D1FCC80944CB263803FAD71534263915C0C60FE15ED3AA69BF293D72781906B84D57409BCE0218C9573D1467DBA0E959EC6FCD7D4E7EDEF43210E76B28CFB56FE93E2A9ADAD5AD999E48882A8F1BE2587231FBB639C71ED8ACB97C31A9A056FB148075181CD236977969F2C96CEA18E7705E2AD484E299EB3A55F59EA519B9B2DB70D200B2C80059303270C0F279638038F9B8A9B559A16B54517BF660D345B9CB18C905C7CBBB8DA4F4F53C8182723C6F75C5B7EF632E1BAA953D0FAD6AD9F8BF5F8576AEA33B6C3D1E46603F5AABC5983A1AE87AE59CC2DED6DEDA59D9E458C2199D0AF98CA30493D33D4D538E04B1962BC796778CCCE33733BE22460CDFBB8C020904800E3217233800579ECFE3AF10CB095FB5AC60F24A2E08ACB9751D42FB1E75D4B264E797273EFCD3BC50952EACEE75CF19C30CA6CED1D4C8C7A0072E30072D93853B795E49E327A8AE4E667BC6796E1CBB483E625B939E302A82DAE4A796C43746C13D3B7D6B7EC34D92E6452FD8F1CF007A52736CD5251D86695A7B4CE18A119030A7B0F4AEEB4AB0F2D4498C6D1C67834DD2749DA8BBA31F980738AE8C5A88AD19B1CE001CFB8A4913265309C515384E28AA24E2FC0436EB731FFA766FFD096BD1490A84B0E4F53FD3F4AF1D44A9912811EA3716514EC0608EF8154DF4B8D633B10018E95C0A254E8949AB949B474B7164493F2671541F4F62DCAF1F9D5044A9D12A79116AA3436E3C3F6F70C1A58096EC7241F6E4566DE782D5D09B77287D1FA71F856DA254E894F9439EE7152785EE616FDE424AA9EBB78FE54F87C38E5C7C84AFE35DCA254E894B945CC72D63E1D20062A793926BA8D3B4658994ED23073D38AB08953A25525626E694168B1A804608E7AF14B72C0208C60E4FE9EB54912A744A6210271454E138A2803C95054E828A280274153A0A28A009D054C828A280274153A0A28A009D054E828A280274153A0A28A009D054E828A28025038A28A2803FFFD9 + JPG + 6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141415666306C455156525968573135655A4263785A6C6E58692F7A6E58565864565631645864317477375575745553516B4C494C43435075415A387749793932494D78342F44456A4866483242473249326248472B50593849364E675448446D4C553961786A593951786A504D455944474B4E774A4B4D6B4953454C6D6970686270623671377572753771756C36392B37334D2F614E6141724F626B6645694D372B582B66752B373533352B304541414D595959347751516767525168424333524549496235613445657443434645594C666250524A4342415159513449786867686A435547436949515237316F524A4666505277522F424264432B4B48684B34617271332F45495968524678776842416D4747414D49495A4951786C323349454951555177685268416A4443474543434D4D4D59595153774168694169384D686442644258787733415177762B50517867696A4C723443435063726142724A372F6E4C6B486469566569784A674944434742534F4959436777414667684442426C4343474743454D41594C73654D3849666A527768314D345141414B71714F6F346A68416A444545496F6F6F69484955464959557858565955786A484555525977786D544A4B4A454949414142444A41474549674543763731554934494C50325159714B704B466258657367566D455A5145783145494943415959706B716C464B4D6F55796C5A5869455A466B474146424B6C3650536456335474496D4A43636159372F73496F636A7A44634E775864633054646431486365686C46617256644D304B61585430394F47596469323754694F5A375A6973526A6E584167784F7A75627A575A397A3931353438654A6B656D45416B4A49514B52686B452F6C4F5139643135595643634151516B45564755446344517768464962684530383859566B57516F674141494967694D5669375861376978514577616C335476712B4C306D53626475753638374F7A6761324B387379353978313365726C537231657A365354776A4F584B706664774738326D3771757A3039645242536548447333622F4B7666754F766659396E456B592B6D374D5736314555324536724454676D5846616F4564636A69636D7954436C315854654B6F6A414D7530384D41527748516453796243617A304138554153616E7A6F64684F444F7A6D4D3455466970566E544A3773575746456247386A746C362F384C35754B48303950524D545A795078395471596D33733341544168464A3565505849334E523466332B2F455A72502F4F32332F2F36787836737A732B5A6C732B474C754B5A3347715A45674354446D474534485A2B4C534769526E474B55534654582F6443544D455549775777366879527963576F536363463962326C3230576F765872773037666E63744E7A7164435879484E2F74544338754A524B785671746C3650727073366341414C46343874396566736B4C6845546736564D586137563665576756513871424E31376676577648497A2F3472696244587A372F33434F5050426147724A67765745733133335545436A675778564B76704D69534A47554B50597168516F7A2B2B3850665A35684143416B695741676877716A6562494A41324C5937666D4561516C79647230494136725535456269755A78454D4636707A5446626650487A34794B6D546F5276366E4C64394D44646253796653505957424B4D5368467930734C4D5269785A646650666A63433638382B65516A4F322F5A3838797A7A2B37617548747870707050784A724E52697975757046587734744B5573336E3836357245346F526C55515549596B69684169456B45645236495775375446434B2F4F4C515167765430336154736578326F734C73776F6A3758617A326D354E546C796956486C3337494C56736F3464503737377874327A315A7056582B684C4A707432533865384D312B4A584B6551566A30622F396B58372B2F50447752635050535662357737636562797859744C3035646432787063325363416D4845374D5665504971385844776752616647456F656C434349515151515253716E67644A36576E357564723538636E48624E6A57316174576945673470357A63757969485556364C6E506830755577354B6256486C6B396375726B6D614D4844763779756165662F70382F47786B5A615457616E757643434E7268596952414A705676742F774E4136566B496D6645556E356B78314C362F6C2B2F74483739326F5861504B52493057522F735331454B4B445145366D5936366D7935766F4F516F68416A4B484150416A727A627272654652524B5A454F376E2F464E757432732B3447586D5675726E2F316D6E2F6639317045704368776F7969616E71396B644C32334A796454365934372F7242536D653759566A4B546A714A676668707347393059656C463549506E31723339355A586E566E6C74765435524B576B4B5A6D4C353471664C2B3374763241416D3656536554316E7A66783552426A414641504F444C4C386C454B6F6B452B734A6E37304F637A387A4D4A5850464934634F5A424C7971524F48472F58617262642B636D6A313269656666737142414746693170755A544737372B68474B306562524C5133664F5463396C52726F586231315932486C594C62634F37686D744E70794A2B626D34746C4578366E6E3872463976336E706A554F48392B7935325967706C646E4C5A3836646E462B63615A7431585655416849684948624D6A49467873744968454D4561346B4D31684C4833366A6F3854332B4B2B642B444947486343486C527A655533563439556D2F642F2F2F757A41794D70503358336E594B483433452B656676432B2B316173585233727A5A79382B4E3767396A56626274346570556B4C6D6A694758746E2F713535317658712F556C706455464A7133456A57466C76706548476F742F636E503370792F647131726D655A6474313157345A424C64734E50637835704D566C706A48486878414B68434153516B4149513939627246595735325A714335584636757A4D7A4777515163666E69567771516D44693876546F2B6F314167502F323362385A584456674132763170705533376231786462482F7163642F5244302B6D4F75566F6252373534316A37353648484E75324379483644376665736E727A4F704A6737312B6579425A79547A373150375A763334354372694257583168717439764E5A724E56623752625463647341383658503659397552344D344A3764312B48514E56754E6F366650616A4B5A6D726F5943445466736E3778386F74766A3431444146565878413331766A2B3535304A6C664D334F6B5259303230366E4D6C347039665578576130336D6F7970415166583762795253537244557131572B39584C4C2F61552B7A503978556172766D513274322B35397456662F337237356932316D546D644B5A62765330685756556F676C79534D69534A5243524E4D4141435951416B4B78327A4564616E5471414A50625A6A32597364373843742F63664C4D61543256786B4436307938386941462B2F63303374742B386E53626B38636E7056444B584C4D654C78654B32585476634D446A7A337275796F5A574C77785343466558537A68336279304F4476336A7868552F632F636E684461734551344F72563754716A544E6E78726A506137576D6E4461616A6157597967674F6B366C3455736B43684342435247464D2B5035536256614C3749356C6163516E737554346771724A524B4A34312B31372F2B56666E6B2B56312B58792B542F3637443072746730634F58764D7432524D6A5778706150654F33662F387A4D2F763668743048436564375930497468744E344676486A78363761646675622F335674774E4D6C737A572B544E486567614C382B5056762F7A72627A3377366339634E377046384743364D706C4E3646616E66646664747779557937566D32415A515945774141454949536E426C636A4949677637656E454E78504A30424A4B6D704D642B323737337A376B4B716248767A6D335A73454A636D6F5552506E5237376A352F2F59716C2F344B6D6E2F756C502F2B514C332F757633336E306B622B374F446E5A6B386A6A624370307248747675767476482F6D62356D4A7278343033313531324D6B6C614E625056332F7A53562F373858312F38315A667566324437746B32567555735151736835665846685957472B504C53525549566A6A50734B52537A436E65745742335A4C4346467232664F4E70564E6E4A78392F2F4B66315A7550745977642F2B67395068726148644C356F31704C6C62456A525066666570387278343064502F5045396E3234754E6B362B66584C4E716D73555251746366334770636E3773374F42772B5937623730676B736B654F6E7641432F38632F66664C7734534F7052505A546E3767485258442F622F5A763237706C5958595763554B516947436F475570506F642F48456B4159442F623371647A6675583745626C6D746C72327755482F33334C6A72686F6C4D4B706E4D66767175507A49626A526465664B62426137662F385A32344A3737336B352B773273375969544F725375572B664738716C377668443234574B72573442346A6F5564543976396E2F6E372F32746162726851424A434B744D766557574F7A5A7676693566365065443848657648586A344F3938396565776452592F626475684746714B69347764724E6D7A6E694343436B53524A49592F6137626171716F68675256465557564555356443426737376E596F784E713933756D506C5372326D61567174646D35326E45526A4D3934364F724E2F2F7969736149644433686550514D4749524A3451777869596D4A70724E5A6841454F376465507A6B3532617857657849704A74484B7A4E7A3944333478674F4463784153563161625A6C706B612B47455552554B4937673838436E6D6B716D6F51685A626A71495A752B39373035495368304F4742667176644F6E72735451476956447139373958587079767A4C7A7A2F776875762F4A2B4549762F38365A3964662B3232672F746671382F4E47555371585A706575446970412F54352B2B36372B654E374A46564F5A644B546C3662657533514F4931424D706A7A5431425332642B2F65695A6C70505A6439363852785052626664634E757073684F45484942676D683538304D496F384A7830396E4D5971555368554C544E4D473532577A6D63316E624D6C565678526A6E532F6D4837766F6D704D44697A73306632373169316644366A6573793666544B56617565654F4B4A366C4C743757504837762F63357A397A3132654241695247687761484B67734C4E2B32355A587071326A544E77506351464C4645676B666F705A64656470754F45553848667368446B532B57356D74546F51437171766F51516F51497768676778446B48474B6D4B50444E335371464D414467394F64472F517056564E6A352B626E683432424F7776332B673762526C52576C5A6E573033587238775739327A5A302B375937712B4E33626D336151525378574D6444477A652F75757438362B492B764736644F6E6E332F752B56747632744D796D792F74657A57654B39792B3977386E33703963315475637A2B615A496F637568354152516F6A45424D4959515941674868346555676A6F7A36556B684E6F6473394732706935633449444E4C7A5A36536E3142464749556C51594B2B77362B735762746D6B2F642B386B41686A577A5757307537666A59446331324D7744635343564B2F61566B4B766E464278344977754148662F39444E776F765835363262573930644F76737A4D796D7A57734756677958683165346C686559337567314734373837733159497136704769584137445145416C75762F526A6F377051343577684256566638304175436746494B6D537045564A3264575A7166636379573554722F3849382F32374C6A2B6D4D6E54312B596E414163796F4B654F6E686343316E6C2F4B574D6B6B4368384C30414B584B67796E642B396A4D585A365A506E446A525738787632546769754C33556D702B757A396D754252464E46764D62726833744C52576E78736542487834392F4959516E7170714D53504A675958773875634D63516742496F524B62617444434D6B584336324F6D636B6B4173634B5041744473587658445866397757336D556B4F5856646479445433322B632F642F2B6A66505A624B5A6E7A6674396F574A5178794F446333427941756C34654768316647395467506F3330762F58706B3754554359744D3063366C3047504B7457376357436A33662F4D593343424B64646D752B4D714D6F436D4D4D6F797337656F77786B5352464E7A43544E6331676A4F5A797558684363367732526D4555324A32326154566144332F374F772F652B7A6B464B652B666E366A576C67435448766A796C3377654B6F626D4F45376F2B34486A4A685174644C31476F3947547959364E6A645557466F61476869696D756836666E706F64663239635A396F766E6E752B302B6E59646B66544E4633585779327A302B6C4555615449326F636F41304B4A706F63436133704D59637A33335344775659322B64666851344E754F32557A704D65614C3939352B527A6A52632F2F7258354F4A395078433151324438596D4C683438635361625447475048737575314A6359555864462F38494E4868387244592B2B64662F766F3856517938384E4866376835342B624230754454502F6E48766266732B65337262307850583571364E4C466C64424F45554658315643704479504C4F46572F63734A357A7357313031484D39332F4E4634454F4A4C74587274745042465069656C30316E6A78342B7967435871567865755762546C6C47662B37463444414E2B7A5971566A4E497743457A545A4C4B635343616154624E52623237644E48726F774B473171306475335874624745596A367A62466163797574622F3139572F742B64684E646D4E706476715370697351524A35727062495A4935346F443635457545746445434C4C436D55714A504C673042434530506639564471683651794B494A314D76507A6969344D442F5738645039707574567A547163347372426759386B314C59395333585631574E55334C35484C502F7650506E3376683339342B66767A566C2F6531577531644F33635669373067457051796D656D61724A30374D7A5A322B75787658332F7472626665676842434B45797A58536755597246597A45674163495634324C422B4863526B7A3032334A493359557130715378424266486273585533584D4D62546C7976705A4E7033676D4A7645565035304E476A70303664797154546A74555A366974585A69714B716D58794F5968526558686F614869346C4D766663503275644371645343555048446977734C44516B793171657170634B475A6A7557662F365A6D46536B5742344E4162723563473870314F57395856644337666B792F30447051354242686A4648455568427779436C556C5779704A4D5532343375357431314569573035495A61585A72464D4A61504659454471793448474A46497A3032744C61623337317632543668744B6C67616E5A6559425250704E2B39736B66762F7A384C7948676C753830374D37576E54752F2F4F662F4B6642424B5A4F666E624F2F2F2B686A4B71565774576F744E54535A6463796C574D4A49396D546A32545452354C6256584C3648526B625745454C757550504F77484F67434232726A5156756455776E44415341416949496B6563365951526B52596B4556356879384F416845595A66652B69685938666636532F31527A78714E557864316C565A5033506D76577533373242556B5342316D75376A333373306F63596231665A7666374D766C7A44654F766836777442383331367A646D5862627658323957667A5066464555704B56516D385264636D71545673324D366273336274586C6D565A6C7350414A5578756457773948676349746C7074414469474D41723832767838544E554378347272366F57787364646532646562376830716C74382F663747514B545A7172554B32744758307567766E4A35754C35736A516D6F756E7A712F734866726864782F576766664577392B724C3077724649626347526A75727A55584337333973566938314665574E62322F584462695363454678686876324C685259764A74742B324E4F4D6353616A6271495263536B384D776B6D576C756A43587A5757623758626B2B34784A6C74554A50432B4B4969595245496E78735176486A787A4A462F4C5872466931636330364263757857484C316974584470584A6F32624F545538642B392B6234653266662F7433727A635A435479344C494A633175645A596C46557445552F32395A665450626D2B636C6D6973682B4542474F4545494545526F4C37454F7170314F4C63544B7051557549646A344D656947525A3372527077376E78383747304151506832513643556852464B73574152304B456A414F375076757A7837372F38782F2F534664303133626B54456149435068683644724A5A4E774C50535A5434446E72316C31546139527A78594A6D71427253436F5865766D49356E6333324476525456564D3076565A764969675167496751776A6B584844702B6F4D5869696D35344559386C6B6C526D45714F5A54435A58794B31594E527850786E4B39505A4A434234624C6C6D755A5A6B7557695351465044414A394B48664158346E70387243625273557154694B713053456C6D5951676278344A6B466A69703649637941776C677146336D4B78704F7136466A4D7331324E4D6B56585644344E6C4B68636846455952674E7932585A30787968524D4661594169536D4633704B6D4B55526D3563462B585645447A323831326B3748345745304F546E5A617256637A2B3559446954594E4530512B5977614D55494375363270386B4A3173545251616E5361795A34734A6D786D626A61565343645336554B6846492F485A61624655386C454D68314C4A7067737937494D42554149495969494C4D6B71517A674D64556C4B78524E4C556252327A645A61645A374A426B564151694C794864653165656A346E71664C696D733767575558556873464A4A3741555251356F5438784E546C312B584B74767152706A41464A4348484E78765763637A3252544B52546264636547436F726371797672367872436361556F6546683256416F70595A6841414334482B517A616464316C336C7141454155525971696D4231545552513363505634544E456F41634B7A7A634254776959494173493545514557424167465530786B796E774F624E66783275307457362F64734758307A4A6B7A746D64626C6755415949785253714D6F536D65794B597154696252684A4250785A4B485178366969615270545A555652776A446B6E47756156712F5844634E596471684C4350752B54796B31545A504B71753237717377596B7752425571527A4B7275754A376D65344E7931624D4146414142774556655945414A41614E7432504237764C362B676A4C6D42303271314B70574B726D714D4D6162496765444A5A466F69564E646A6955534B55535543776A434D494169694B464A5664585A324E70564B63633452517643725833766F4B68486570666A425666596641776E684B2B77345151684A2B414E7041554F494D53514959774A4A56336A41464244512F61583551454C41424F447546416C6A33483337495951672F71687730473254712F7A2B565359624959515275754969687667444D6141724D48545641344151774668674C4341537147736E41674F4549567857476A44434742494A4C6D736979386F4975684C382F79747064444E43507049684367424742434D73494D5249776B68434747494945454B59454C67634C685951416F6B4369424443585869414D4D5141454177786867677452344951776D785A57634467436A444156314B316E426843727567544548587263683968434248454742434D594E636D384A58304C6973794547474941494959434978414E316B51413441412F4542522B564342455559414934546773752F646648346B51387558714B764241414141414D74744241474356377458793464484141414977473739594158306579662F33706F664B682F70666D546B2F774A4A373144734E344A75626741414141424A52553545726B4A6767673D3D + + + 4 + 1 + android.png + image/png + 4295 + 89504E470D0A1A0A0000000D4948445200000080000000800806000000C33E61CB00000006624B474400FF00FF00FFA0BDA793000000097048597300000B1300000B1301009A9C180000000774494D4507DD011D0E180BE2306F78000010544944415478DAED5D6B745CD575FEBE7DEFC8961F3C0C01EC45480C2B8B0026A1D4206B2CB9C27181F208D074816D59069A16280B92A6246D42520A252D210FD2248426818418C9C63CD264C182BAE1154B1A4960CAB35E506A1E5D26501C9E768464CDDCF3F5C7BDA31796A59135F28CE66C2D594B9A19DF73F7FECEB71F67DF7388329096CCC293C1E997845174D1F2FACE374B7DBCCD1B17CF0F42DDDB1BED58F2E74B9E7DBB94C76AE5000069DA05A2CE8CA8EF94FA587FF6507D1503D71A018757D9EC334A7DBC650100B2E79F4C70B0E0336B338BFEA494C75A352DF70D1AE71AB8F9A5F51DCD1E001320AB163FB159C2CD12663A58D35D1DE9D9A538CE350F351C65C6931D1038B9CBAFBA11F200983016705F96DC9B3077CE4EC7926481B0BAF7F208760C22AD69AAEBEC2A07BD960D001AD39DBF27832F986C3A694DEBDA4F9A5352816A5BC332293CD790450AE115E5A2D7B201000050D10310FE57CC9DEAD47342A98CEBB6473E5585A0F72C3077805C78EDF2FAB6B7CA46A7283359DB9E5E2D6A0DA42E9B3E73C9CA850F6547FBCCBAB69A1991719E219C0146F38420A07400E40218009102BA01F70E2D34C1BD48177457F76CDFF6A7CB9ECE8D9AF6B5A76B403C4CEA8528179D76FE92C75E2F177D86E5060089F793DC08CBFD91EBED5905E0D6E1EFB9E7D7A7A5B6CFD85E47BAE3011C23E02002F300CD00381750086086C86133C0DE8364005E045C774FF5CCDFB574A4B7105107A2E0A5C6FA8EA7771D9FE07A11339C70533919BF2C1900009ADBEACE27A31F928E3DCF1FB5EF5F7CF6E7B907375F17BCF6EE7D75845B29E3498110413A5C4415101B5A1020825072E79404821093BF0CFC4100084A10F09E889728E668EE2E58EFFAC69A27B702C0DAAE450B11059B003D09F0338D8B332F7B004C46D09549B782564FD7773314DE01E3B7441C09A91A04094862FC1322C971F14DE21E10A3062024800ECEDD1B657139A6A183C0C141C4BF5B59DFF1BD72D3A3952B00E8EC3B0E511616FCA5026D70D47110A69348883DB139314EE327E44E80313DC43F6240848E38C7A6BB570D3CCCC4E742CDBCBB2CF5586E035ED75A77906374BA8C5F20B9801A740F1404F6D379516290D871C47048CA3CA2EBA37827841FCEDEE785473FFD8937E5015014DAAF3D9BB02F89AA0110304FC87BF12E84FC10040ADB40AC0F72D13F2F5FF2E81B1E0013286B3A177D3E10AF226C7FF4CF7A09E4DEBD07C59C80981048E07527BD2EBAAFAF4E77FDD203604F23FE478EFF10AAAAEE27834F00AAA228F183095C09E5A94E8441B683DCF9DDC6F4A67FF000182FE5B72F3A8EC0DD8E7604291156168C250146413038E46E545FF4E5D50D9BBA7D1650C8CC6FAF6D20C33B6176841162A2D2B2F0AB141C28C081B2CB2C0C7FBCB6ADE610CF00632EF4D42E03ED76331D085122588E050B498A07EE08173E9072D59F3D77C9035B3D03EC2ED8EB38611189663377A0627F3AC4F8FD2CA0815F94285B93481071553119811497103198A394142008C004BA3FDE99DA7E434BF3D98107C0483EBFB5EEE32985FF06E21080026803D9769EB20827C9D14114639A158C2439192088314711A2E8E020231C1947A7FDC3CDC3564412B352C1593AFCB59B3C007635F3DB3FB91F037C3F6270485C6461BE82C7FE843B9E66204593DD41B15E2E3C09D4CD4E8AE2A430FFAEE2794D4104B25BA19D17059C51A75C7635113DDBBFA4306400C99F62F0A608BB706D7BFA2B3E06F84091E7C46B81F06BCC2B99C290544F8098706EE4AE6BAA7FF4CA217143E6842B89F01A9261D18286643549E4EB51A4D3CEAFEF782AFFD2ADBF39E1A3A954F84B92C78DA45AE54B46D2FF98B4AAB1AEF331CF00009A338B9792C165C984573C69862A50042882C2CBA4EEFAC08D38B600F6BC8A896AC6CB4C14EEDA27D5F7CCE0972E6CD8F40AC9FB04E634E20808023D240E75C0579B5B97CCAE7800AC6B4FCF32E03A80FB4914A8DD509500E27D67DA39FCF569E1F6B71DD58D64E1B758819F20107CF59C458FBBE1AF3BB93700971DF1FA94245553ACA6F1D316642FA8780038D829803B7160E68E40DEFD457FCE35D841C35FEEC91E7244001DC4A252401E08EE9896F6F4B45D14001680563DD200E28549E66F0620AE696E3D69DF8A060019FD24B1B9304A7D3751DB1CCABED9D2567F707FFCB0B1617F0BB2D70236BFA8E19F986F275949E8ACC1AFDD96492F03B814D27BA351D0C00206F767D0FDAD8A0D029B330B2F37567D7FA0B83FDAF41506DE1BBDE5E0EE320494AC01D491717C56D4D5E0A4B813E7F764EE61297C4EEA3B9808FE0CB4FEE2C4686B15493E03D04541943A74457DEBFFED0D1B847B177DC15730A4238BA37E228EC1242A3C80D4250E02E3926BB15B0112C62263E34952B014744B8500A425FD64635B9E8C7B952081E6D8FB8F002EAA2817D0D256BB4AC6B990A9309B09042926052011A42545A1C921B498004832C69CD1125B16967C8A202588567767DBA70EACAC1820D05F518100C74279A33FA1E280CD277B7998838A3CFDDC349EFF8324611FC95ACFD9150380B5AD4B3F02D961B1439F84B0BD644549A518331CDD49150300A57A1B44EE17F75C56AAF1630E50E24688E0D0E6CE051FAA1017A005046654B2E9070702A000B92318EDBF60CA03E017FF716695938E066028970E8FE2C612F1CA91611E2D9AFA0CD03B63DB7E06CC2A853A44E96000824888C7ADED4807531A001686F3011E36100555BA07102832E92F98A149AECD4C7A2128723A90B039A050AEAD5E139E4E524999DB8E256C5F00DBA62C009227B7025478FC3FC2F430208B29CD0002B611F8B58499A477018366468A0A36050A764E6900107A42C205F404F0C1A9A1E939B959EF4FBA0B1AAF34676AE691566F48D508EE9DC8E9A954F7EC8D2B4ED9B0DD1BB438D29CA9F918192E31040B1DDC13514EAF9CBF24F3C0A402E0F68DB587E542DE48E014C6FE3CDFB02331474655B734D6B75DECCD3571B2AE75D127A330F839A5A3498679CE889BA4A26E44A9ABB163EBF71A4F7FC51515002D99DAD341DD06700E6183D6C7014870341111216D0E34FDBC1575BFD93CE4463A6A0E92C27B00D5F81CE003723380CF35A633BD43667DC7A28B41DE4467963C953E68E9537020880890D6079AF6D72BEA5AC7FC6472417580E6B69A1300FE2BC53954DC843F78F95B244C8E94810C8E7196BDBBA5BDF6C8A1AE4E7301DB4FCCB779FBAF415FBDC38BA32DED8B9AA8E0BB2658BE6A3878DD5B204C1211880C973B8BD6B4B4D7CD9A700034671A029A7D9BD487018BA7FDB0199C2C6FF6F7650AEEE3802E5DBB71516AD09B1C2097BC3F590EF25F498A3C24396E6E5F7C04C8AB49552BE993E72EEB08A424C6CF26B953A05CD3C43380BAEB9D6909644967EC983C8C447E2E0A73733DBB17E86A371E1FC8B26788383CAE9891BB2B9C924C1E5931C0ECEB130E005AEA6B26CB33FD989D374104ACBA6C70B6E3650CC158387D9621BC3451B546EF978C275CBCEF19E74C3C00C423FB2D3A16FB73A00D5AD2511393784EE92AC050C3C8428AF30BD43959605F9A1500D143C7B37C1B03D20EF3262E500C018854B197CC0B5B0D1C4FF52E0E08236FD1717242912BA6616103E29EDC8A977169ADB83ED30A9BCA1310DC78348C514FC464044C361938E69EE3A8E282C0C9D29379D5577AACE9C50360D2E9CD4BE500C00781A5AD27EF023C03F82CC067015E3C031417DDDEF157781AE879BF5453279F05946A16E083401F04FA20D08B07809729910578A95800F820B0B4F5E483401F047AF12EC08B07800F023D007C10E883402F9E017C16E0B3002F9E012618DDDEF157781AE879BF5453279F05946A16E083401F04961E00343E64FB495FBAAEA0803D82149F9B5CE8F8E39391426FC98215376E9D178901F842FE1C6C150A5FD9666FD142273E7300DFDFC571E4A3E75C2A0600A8479C84E470BEB182588C8F4369F74160614120C93E119D89CE59B0CE271A0074A95FC5C7DE8E313C91440674CAED10ED1E1F0416E8EAA3AA5E8A1B2C7FA450413AEFDB32E10050D0FD2085F6FCE9DEA3108DE2CD0B2384A8FA494AF686377161B2B2FEE11CADF75780B62001C16E483F09B748288714A65D3FE10068AC7D3C47049713B655D26E0F4A14C47833496D702E77FD7975AD7DDEA4E30041EDE35B8C760DA077F346DEB5778ECF1F4D7692BD75F9E2CC2D454903572E6E7B8AD0192032FD916A12AFF6EF6528C45182C32F9C729736D677FDCE9B72FCB2A236D302B87341BC0A80BBD0B980E4CC6C871B2297FB62510B412BD399670CC1994ED94B1CB955122947894E7410B545C0AA200A2F6CAADBF4F264E7B55325081CC2BEE9AE07082E72CA5EE5C8ED8374DE2B3A8AEC14706A900BBFBABA7ED3DB1375DDDDCA6DED7F405AB585C25CC7F0A326CD065C67CEB4A3A9B663C47D01D7654E3C56A8BA437447D14785C366067F00E06F876F17DFAFF3CC1F32642A05051F1683434DAA8E987B5030D794CEB8F15C75DC059AD5754F0A4004E0D5E47BEC90F32CB06BF38FA6F3C5FF29007D005E4CBE27B310E4652ACA5E0280A7FDCA05804830B2F8D21E0815070029F50E8077095750CD7AEAFA7E258513029069AA03C0FD7EF61B0ED816073D1E01C999C17454CEC936AE1A2103983200683AF5DFFB10F17E38F478F303B1FD01839E03DDD3151104EE089EFF1903BE3470D85C654241884F550201133734A53B5EA808005C9A7EABCF145C02302B89042B120194E448C0D96381E1DB159406022BD2ADED705806228B7C8D5B82244DCD4AD1209E4BFA3BE266293E196571DAB9B51DDBF60A08F7B65A9A1F699887AA9DFF02DA1924AAA87C7E38BC3696EF2E62D29352C0D0E3E316C7F639E52F81E458CC424E4AD1C0F8767529451028D144A72CA52F35D677FE60AFB250A9CC8FE6F68663C0F79752C1C930CC27866544F16F1F1335AD20FB4BC9D1C602C4A74104A3CC53519C25623E871DD23A46A70E88DB40BD81E14BE69203AA9E72DAB921E776DC77E192FFDAEB876C975525666D7BDDB330B7000503C000E4D098EE1AD3A7D6B52D5BE8C2DE4D540E5050200144809B76E5AABA8DD7F942D0441ABFAD9EC0EE67EF44615D8CF619FF550850D5E5A2D78A590CF235870A0780970A07805F76F20CE0C503C08B0780179F0578F141A017EF02BC780078F100F000F041A007800F023D00CA62066B4F66BFA780F20600A9713D56986F3F5701144044C975A67EE37A1901C040322C7432934CFA0C830240D3174285870E713323813D78E8D60360448920445D85FB732528C83D53006CBA18F7111674A97827172188824D1E00132C2B1767E4C88D4326DB581120C031BA77CC1F30ED10A2FFD69877C4CA030D800867D97B3C008A2081C3060AEF8820C4E489128D6475411044120E556EDF9BC67A9D55E92E19F023CA90B40703BB799251F90EE6785FC79F8239E701500479FDB73B5F8BA42B81C8C5BBE7891A21BACB3F73176F5785BF5F5EF7E06B05390EA5D608783ADE0E2BDE7D6FF71C0300DAE622BBA17171973C008A20579CF7B864582F879BD11FA727F6C2E07DB4D4FF9280DB65F6CD42AFB5AAAEED1D0997027815200752102529699E7F92A707A45E29FA22DC2BCFF92CA088727EBAF35DF5CCBA42C87E03021C92FD11E3CDD2E418EF4F2C3AC0E1A786E06F9A6A33E3DAA62E65DD5D70D17952EE29C9C131796A20F9D7E59F0171EE2D38AD9866B6AEA9E1B7659539966D816C4DE7B166D1CCA369EE6263D525CEB9300E0DF43E94BDC55C6AFD4EC3A3172EEED8637FBCA67D416A9AED7F7AD6B9CF9BB98678DE0812B790EE6A396E5855D7F15639EAF1FF015841FD48A44C570F0000000049454E44AE426082 + PNG + 6956424F5277304B47676F414141414E53556845556741414144414141414177434149414141445959473751414141414358424957584D41414137454141414F784147564B7734624141414470556C45515652596865315A585567555552512B5A39646358624E4E4C4C4D314E6247303341724B4A585533677167484B336F776968376336442B71682F372F33346F67736A434C364B45777A622B4B54497A6F77536853574E63734C4E61734B4372536367304E79705A437935335477395934732B73366439787252505539444C4E7A7633504F64382B636D5876504C494161584B7A4C557355767461766A44775737387449596D535A7A5645526B6946722F7167316D576730614C516F65387634634636654C546441626F6B4A36653451334C37353075586F453453647A7837475539664D623166704874515941554F6159302F72636E5A67614159546F36344149554F696A72546B504D75614E71616E7347485A424A66597372556244776953674C597675662F37557038712F566857377543354C47344C494E673045584A7762682B423539736A4E5835444A6243696F544E64714E597871524531545A6F354F6D54374B58745046614D4B55665031497A5948544A67414541674C68304B5A6D6A3063676F6B4238416A702F39486E624B7A635149654B30444D4D5357787850515158583072324A49595344713577766D7430376C6A554E6B7171614B7832314E7A3463574E6C4D6941434167446E72346E5868544C48594D685135776E7543524276324A515041366C334A6741457A744742704C4143597A416278536D696F39734B64544A5A59796756523270437049586D7045524743556A455267597844414A7358336E6433667838386E454B476F6D4E304B5068786B4F5642382B55676B4731376F704B566B71425665796571657177474256717A78797153464A614F71544E47457849765253416F65314951394C53704F7A534D7166425A6F4E47716E467030544768786257617033624A323979526549675A4551724B2B31473470735675796C78743968766F6C49304B5A33537065494242736C6F626A35624F4D53574644573450395155413269324F735558667961727033575361696F7279586436353369707A2B3237482F564A723831634B74636E773837733150452F6349694C686D3332517070372B4770706D6A354D623842586D6E61307A512B367355776131676565486646735253424C3956554D445657494C2F47564C43763133554C506866513072346B7A4D55754B3368425749493143386F622B657A51454E385558476D5661724939625A37344B6A4F786F3969373064417A676257586C4D74626C357142306D6750537461704B4F794C617A4E366B434547624F6A6E49306668304F4B57454D327179504771427366722F6350354C756E4A674935696565755348716E4F6C32396E613565663435436F587A392B6F33344E5230732F5975436F4D4F62483250676C6C6B56434F426D7854744647745073432B396D68656B3076397A4B7251676B66514835665650374F64776E55486E2B36317456372F6B496B714B3833696F3338755261376E6E506B6C496A6A78535A704E2B634C703974753148325670582F594638324A464558487548372B57734954576177677269334A73466E6944502B75677878423839626875496843415172714C71345454782F38764354764B536F7172423132415864726E5942454146356A35586E3271576A687A613267446474424C3039777642767351414159454A5365466D397862597477652B504467414138397A6F636F6631784A565A5133502B4138457749412B7133696A634141414141456C46546B5375516D4343 + + + + diff --git a/tests/res/datasets/syspass_accountSearch.xml b/tests/res/datasets/syspass_accountSearch.xml new file mode 100644 index 00000000..c2692e4b --- /dev/null +++ b/tests/res/datasets/syspass_accountSearch.xml @@ -0,0 +1,213 @@ + + + + + + 1 + 1 + 1 + 1 + 1 + Google + 1 + admin + http://google.com + a + a + aaaa + 341 + 35 + 2018-03-25 09:54:07 + 2018-04-02 21:38:25 + 0 + 0 + 0 + 0 + 1522341709 + 0 + 0 + + + 2 + 1 + 1 + 1 + 2 + Apple + 2 + admin + http://apple.com + a + a + bbbb + 341 + 35 + 2018-03-25 09:54:07 + 2018-04-02 21:38:25 + 0 + 0 + 0 + 0 + 1522341709 + 0 + 0 + + + 3 + 3 + 3 + 3 + 2 + Github + 2 + admin + http://github.com + a + a + bbbb + 341 + 35 + 2018-03-25 09:54:07 + 2018-04-02 21:38:25 + 0 + 0 + 1 + 0 + 1522341709 + 0 + 0 + + + 4 + 3 + 3 + 3 + 3 + Slack + 2 + admin + http://slack.com + a + a + bbbb + 341 + 35 + 2018-03-25 09:54:07 + 2018-04-02 21:38:25 + 0 + 0 + 0 + 1 + 1522341709 + 0 + 0 + + + + + 1 + 1 + sysPass.xml + text/xml + 1312 + a + XML + 6E6F5F7468756D62 + + + 3 + 2 + Clock 3.jpg + image/jpeg + 4273 + a + JPG + a + + + 4 + 1 + android.png + image/png + 4295 + a + PNG + a + + + + + 1 + 3 + + + 2 + 3 + + + 1 + 1 + + + 2 + 2 + + + + + 1 + 1 + + + 1 + 2 + + + 2 + 3 + + + 2 + 1 + + + + + 1 + 3 + 1 + + + 2 + 3 + 0 + + + + + 1 + 2 + 1 + + + 2 + 3 + 0 + + + + + 1 + 2 + + + 3 + 2 + + + 2 + 1 + + + + diff --git a/tests/res/imgs/add.png b/tests/res/imgs/add.png new file mode 100644 index 00000000..60a7a291 Binary files /dev/null and b/tests/res/imgs/add.png differ