diff --git a/app/modules/web/Controllers/AccountFileController.php b/app/modules/web/Controllers/AccountFileController.php
index 6b561cbf..18a0ce6f 100644
--- a/app/modules/web/Controllers/AccountFileController.php
+++ b/app/modules/web/Controllers/AccountFileController.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.
@@ -38,6 +38,7 @@ use SP\Modules\Web\Controllers\Traits\ItemTrait;
use SP\Modules\Web\Controllers\Traits\JsonTrait;
use SP\Mvc\Controller\CrudControllerInterface;
use SP\Services\Account\AccountFileService;
+use SP\Services\Account\AccountService;
use SP\Util\ErrorUtil;
use SP\Util\FileUtil;
use SP\Util\Util;
@@ -195,11 +196,20 @@ class AccountFileController extends ControllerBase implements CrudControllerInte
$this->accountFileService->create($fileData);
+ $account = $this->dic->get(AccountService::class)
+ ->getById($accountId)
+ ->getAccountVData();
+
$this->eventDispatcher->notifyEvent('upload.accountFile',
new Event($this,
EventMessage::factory()
->addDescription(__u('Archivo guardado'))
- ->addDetail(__u('Archivo'), $fileData->getName()))
+ ->addDetail(__u('Archivo'), $fileData->getName())
+ ->addDetail(__u('Cuenta'), $account->getName())
+ ->addDetail(__u('Cliente'), $account->getClientName())
+ ->addDetail(__u('Tipo'), $fileData->getType())
+ ->addDetail(__u('Tamaño'), $fileData->getRoundSize() . 'KB')
+ )
);
$this->returnJsonResponse(0, __u('Archivo guardado'));
diff --git a/lib/SP/Account/AccountSearchFilter.php b/lib/SP/Account/AccountSearchFilter.php
index 8b91122c..9765426d 100644
--- a/lib/SP/Account/AccountSearchFilter.php
+++ b/lib/SP/Account/AccountSearchFilter.php
@@ -314,28 +314,28 @@ class AccountSearchFilter
{
switch ($this->sortKey) {
case self::SORT_NAME:
- $orderKey[] = 'A.name';
+ $orderKey[] = 'Account.name';
break;
case self::SORT_CATEGORY:
- $orderKey[] = 'A.categoryName';
+ $orderKey[] = 'Account.categoryName';
break;
case self::SORT_LOGIN:
- $orderKey[] = 'A.login';
+ $orderKey[] = 'Account.login';
break;
case self::SORT_URL:
- $orderKey[] = 'A.url';
+ $orderKey[] = 'Account.url';
break;
case self::SORT_CLIENT:
- $orderKey[] = 'A.clientName';
+ $orderKey[] = 'Account.clientName';
break;
case self::SORT_DEFAULT:
default:
- $orderKey[] = 'A.clientName, A.name';
+ $orderKey[] = 'Account.clientName, Account.name';
break;
}
if ($this->isSortViews() && !$this->getSortKey()) {
- array_unshift($orderKey, 'A.countView DESC');
+ array_unshift($orderKey, 'Account.countView DESC');
$this->setSortOrder(self::SORT_DIR_DESC);
}
diff --git a/lib/SP/Account/AccountUtil.php b/lib/SP/Account/AccountUtil.php
index 249886b5..19eb51cf 100644
--- a/lib/SP/Account/AccountUtil.php
+++ b/lib/SP/Account/AccountUtil.php
@@ -55,16 +55,16 @@ class AccountUtil
&& !($useGlobalSearch && $context->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
) {
// Filtro usuario y grupo
- $filter = '(AH.userId = ?
- OR AH.userGroupId = ?
- OR AH.accountId IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = AH.accountId AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = AH.accountId AND userGroupId = ?)
- OR AH.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = AH.userGroupId AND userId = ?))';
+ $filter = '(AccountHistory.userId = ?
+ OR AccountHistory.userGroupId = ?
+ OR AccountHistory.accountId IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = AccountHistory.accountId AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = AccountHistory.accountId AND userGroupId = ?)
+ OR AccountHistory.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = AccountHistory.userGroupId AND userId = ?))';
$params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
if ($configData->isAccountFullGroupAccess()) {
// Filtro de grupos secundarios en grupos que incluyen al usuario
- $filter .= PHP_EOL . 'OR AH.accountId = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = AH.accountId AND uug.userId = ? LIMIT 1)';
+ $filter .= PHP_EOL . 'OR AccountHistory.accountId = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = AccountHistory.accountId AND uug.userId = ? LIMIT 1)';
$params[] = $userData->getId();
}
@@ -72,7 +72,7 @@ class AccountUtil
}
$queryFilter->addFilter(
- '(AH.isPrivate IS NULL OR AH.isPrivate = 0 OR (AH.isPrivate = 1 AND AH.userId = ?)) AND (AH.isPrivateGroup IS NULL OR AH.isPrivateGroup = 0 OR (AH.isPrivateGroup = 1 AND AH.userGroupId = ?))',
+ '(AccountHistory.isPrivate IS NULL OR AccountHistory.isPrivate = 0 OR (AccountHistory.isPrivate = 1 AND AccountHistory.userId = ?)) AND (AccountHistory.isPrivateGroup IS NULL OR AccountHistory.isPrivateGroup = 0 OR (AccountHistory.isPrivateGroup = 1 AND AccountHistory.userGroupId = ?))',
[$userData->getId(), $userData->getUserGroupId()]
);
@@ -98,16 +98,16 @@ class AccountUtil
&& !($useGlobalSearch && $context->getUserProfile()->isAccGlobalSearch() && $configData->isGlobalSearch())
) {
// Filtro usuario y grupo
- $filter = '(A.userId = ?
- OR A.userGroupId = ?
- OR A.id IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = A.id AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = A.id AND userGroupId = ?)
- OR A.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = A.userGroupId AND userId = ?))';
+ $filter = '(Account.userId = ?
+ OR Account.userGroupId = ?
+ OR Account.id IN (SELECT accountId AS accountId FROM AccountToUser WHERE accountId = Account.id AND userId = ? UNION ALL SELECT accountId FROM AccountToUserGroup WHERE accountId = Account.id AND userGroupId = ?)
+ OR Account.userGroupId IN (SELECT userGroupId FROM UserToUserGroup WHERE userGroupId = Account.userGroupId AND userId = ?))';
$params = [$userData->getId(), $userData->getUserGroupId(), $userData->getId(), $userData->getUserGroupId(), $userData->getId()];
if ($configData->isAccountFullGroupAccess()) {
// Filtro de grupos secundarios en grupos que incluyen al usuario
- $filter .= PHP_EOL . 'OR A.id = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = A.id AND uug.userId = ? LIMIT 1)';
+ $filter .= PHP_EOL . 'OR Account.id = (SELECT accountId FROM AccountToUserGroup aug INNER JOIN UserToUserGroup uug ON uug.userGroupId = aug.userGroupId WHERE aug.accountId = Account.id AND uug.userId = ? LIMIT 1)';
$params[] = $userData->getId();
}
@@ -115,7 +115,7 @@ class AccountUtil
}
$queryFilter->addFilter(
- '(A.isPrivate IS NULL OR A.isPrivate = 0 OR (A.isPrivate = 1 AND A.userId = ?)) AND (A.isPrivateGroup IS NULL OR A.isPrivateGroup = 0 OR (A.isPrivateGroup = 1 AND A.userGroupId = ?))',
+ '(Account.isPrivate IS NULL OR Account.isPrivate = 0 OR (Account.isPrivate = 1 AND Account.userId = ?)) AND (Account.isPrivateGroup IS NULL OR Account.isPrivateGroup = 0 OR (Account.isPrivateGroup = 1 AND Account.userGroupId = ?))',
[$userData->getId(), $userData->getUserGroupId()]
);
diff --git a/lib/SP/Repositories/Account/AccountFileRepository.php b/lib/SP/Repositories/Account/AccountFileRepository.php
index 0b9cc651..78b74292 100644
--- a/lib/SP/Repositories/Account/AccountFileRepository.php
+++ b/lib/SP/Repositories/Account/AccountFileRepository.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.
@@ -56,7 +56,7 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac
$query = /** @lang SQL */
'INSERT INTO AccountFile
SET accountId = ?,
- name = ?,
+ `name` = ?,
type = ?,
size = ?,
content = ?,
@@ -76,21 +76,6 @@ class AccountFileRepository extends Repository implements RepositoryItemInterfac
]);
$Data->setOnErrorMessage(__u('No se pudo guardar el archivo'));
-// $Log = new Log();
-// $LogMessage = $Log->getLogMessage();
-// $LogMessage->setAction(__('Subir Archivo', false));
-// $LogMessage->addDetails(__('Cuenta', false), AccountUtil::getAccountNameById($this->itemData->getAccfileAccountId()));
-// $LogMessage->addDetails(__('Archivo', false), $this->itemData->getAccfileName());
-// $LogMessage->addDetails(__('Tipo', false), $this->itemData->getAccfileType());
-// $LogMessage->addDetails(__('Tamaño', false), $this->itemData->getRoundSize() . 'KB');
-//
-// DbWrapper::getQuery($Data);
-//
-// $LogMessage->addDescription(__('Archivo subido', false));
-// $Log->writeLog();
-//
-// Email::sendEmail($LogMessage);
-
DbWrapper::getQuery($Data, $this->db);
return $this->db->getLastId();
diff --git a/lib/SP/Repositories/Account/AccountRepository.php b/lib/SP/Repositories/Account/AccountRepository.php
index 80f4c3b6..967d461c 100644
--- a/lib/SP/Repositories/Account/AccountRepository.php
+++ b/lib/SP/Repositories/Account/AccountRepository.php
@@ -80,13 +80,13 @@ class AccountRepository extends Repository implements RepositoryItemInterface
public function getPasswordForId($id)
{
$queryFilter = AccountUtil::getAccountFilterUser($this->context)
- ->addFilter('A.id = ?', [$id]);
+ ->addFilter('Account.id = ?', [$id]);
$queryData = new QueryData();
$queryData->setMapClassName(AccountPassData::class);
$queryData->setLimit(1);
- $queryData->setSelect('A.id, A.name, A.login, A.pass, A.key, A.parentId');
- $queryData->setFrom('Account A');
+ $queryData->setSelect('Account.id, Account.name, Account.login, Account.pass, Account.key, Account.parentId');
+ $queryData->setFrom('Account');
$queryData->setWhere($queryFilter->getFilters());
$queryData->setParams($queryFilter->getParams());
@@ -411,7 +411,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
{
$queryData = new QueryData();
$queryData->setMapClassName(AccountData::class);
- $queryData->setQuery('SELECT * FROM Account A ORDER BY id');
+ $queryData->setQuery('SELECT * FROM Account ORDER BY id');
return DbWrapper::getResultsArray($queryData, $this->db);
}
@@ -486,14 +486,14 @@ class AccountRepository extends Repository implements RepositoryItemInterface
public function search(ItemSearchData $SearchData)
{
$queryData = new QueryData();
- $queryData->setSelect('A.id, A.name, C.name AS clientName, C2.name AS categoryName');
- $queryData->setFrom('Account A
- INNER JOIN Client C ON A.clientId = C.id
- INNER JOIN Category C2 ON A.categoryId = C2.id');
- $queryData->setOrder('A.name, C.name');
+ $queryData->setSelect('Account.id, Account.name, C.name AS clientName, C2.name AS categoryName');
+ $queryData->setFrom('Account
+ INNER JOIN Client C ON Account.clientId = C.id
+ INNER JOIN Category C2 ON Account.categoryId = C2.id');
+ $queryData->setOrder('Account.name, C.name');
if ($SearchData->getSeachString() !== '') {
- $queryData->setWhere('A.name LIKE ? OR C.name LIKE ?');
+ $queryData->setWhere('Account.name LIKE ? OR C.name LIKE ?');
$search = '%' . $SearchData->getSeachString() . '%';
$queryData->addParam($search);
@@ -540,18 +540,18 @@ class AccountRepository extends Repository implements RepositoryItemInterface
public function getDataForLink($id)
{
$query = /** @lang SQL */
- 'SELECT A.name,
- A.login,
- A.pass,
- A.key,
- A.url,
- A.notes,
+ 'SELECT Account.name,
+ Account.login,
+ Account.pass,
+ Account.key,
+ Account.url,
+ Account.notes,
C.name AS clientName,
C2.name AS categoryName
- FROM Account A
- INNER JOIN Client C ON A.clientId = C.id
- INNER JOIN Category C2 ON A.categoryId = C2.id
- WHERE A.id = ? LIMIT 1';
+ FROM Account
+ INNER JOIN Client C ON Account.clientId = C.id
+ INNER JOIN Category C2 ON Account.categoryId = C2.id
+ WHERE Account.id = ? LIMIT 1';
$queryData = new QueryData();
$queryData->setQuery($query);
@@ -586,7 +586,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
$searchText = $accountSearchFilter->getCleanTxtSearch();
if (!empty($searchText)) {
- $queryFilters->addFilter('A.name LIKE ? OR A.login LIKE ? OR A.url LIKE ? OR A.notes LIKE ?', array_fill(0, 4, '%' . $searchText . '%'));
+ $queryFilters->addFilter('Account.name LIKE ? OR Account.login LIKE ? OR Account.url LIKE ? OR Account.notes LIKE ?', array_fill(0, 4, '%' . $searchText . '%'));
}
// Gets special search filters
@@ -597,11 +597,11 @@ class AccountRepository extends Repository implements RepositoryItemInterface
}
if (!empty($accountSearchFilter->getCategoryId())) {
- $queryFilters->addFilter('A.categoryId = ?', [$accountSearchFilter->getCategoryId()]);
+ $queryFilters->addFilter('Account.categoryId = ?', [$accountSearchFilter->getCategoryId()]);
}
if (!empty($accountSearchFilter->getClientId())) {
- $queryFilters->addFilter('A.clientId = ?', [$accountSearchFilter->getClientId()]);
+ $queryFilters->addFilter('Account.clientId = ?', [$accountSearchFilter->getClientId()]);
}
$where = [];
@@ -615,11 +615,11 @@ class AccountRepository extends Repository implements RepositoryItemInterface
$queryJoins = new QueryJoin();
if ($accountSearchFilter->isSearchFavorites() === true) {
- $queryJoins->addJoin('INNER JOIN AccountToFavorite AF ON (AF.accountId = A.id AND AF.userId = ?)', [$this->context->getUserData()->getId()]);
+ $queryJoins->addJoin('INNER JOIN AccountToFavorite AF ON (AF.accountId = Account.id AND AF.userId = ?)', [$this->context->getUserData()->getId()]);
}
if ($accountSearchFilter->hasTags()) {
- $queryJoins->addJoin('INNER JOIN AccountToTag AT ON AT.accountId = A.id');
+ $queryJoins->addJoin('INNER JOIN AccountToTag AT ON AT.accountId = Account.id');
foreach ($accountSearchFilter->getTagsId() as $tag) {
$queryFilters->addFilter('AT.tagId = ?', [$tag]);
@@ -634,7 +634,7 @@ class AccountRepository extends Repository implements RepositoryItemInterface
$queryData->setWhere($where);
$queryData->setParams(array_merge($queryJoins->getParams(), $queryFilterUser->getParams(), $queryFilters->getParams()));
$queryData->setSelect('*');
- $queryData->setFrom('account_search_v A ' . $queryJoins->getJoins());
+ $queryData->setFrom('account_search_v Account ' . $queryJoins->getJoins());
$queryData->setOrder($accountSearchFilter->getOrderString());
if ($accountSearchFilter->getLimitCount() > 0) {
@@ -657,9 +657,9 @@ class AccountRepository extends Repository implements RepositoryItemInterface
public function getForUser(QueryCondition $queryFilter)
{
$query = /** @lang SQL */
- 'SELECT A.id, A.name, C.name AS clientName
- FROM Account A
- LEFT JOIN Client C ON A.clientId = C.id
+ 'SELECT Account.id, Account.name, C.name AS clientName
+ FROM Account
+ LEFT JOIN Client C ON Account.clientId = C.id
WHERE ' . $queryFilter->getFilters() . ' ORDER BY name';
$queryData = new QueryData();
@@ -677,9 +677,9 @@ class AccountRepository extends Repository implements RepositoryItemInterface
public function getLinked(QueryCondition $queryFilter)
{
$query = /** @lang SQL */
- 'SELECT A.id, A.name, C.name AS clientName
- FROM Account A
- INNER JOIN Client C ON A.clientId = C.id
+ 'SELECT Account.id, Account.name, C.name AS clientName
+ FROM Account
+ INNER JOIN Client C ON Account.clientId = C.id
WHERE ' . $queryFilter->getFilters() . ' ORDER BY name';
$queryData = new QueryData();
diff --git a/lib/SP/Repositories/Client/ClientRepository.php b/lib/SP/Repositories/Client/ClientRepository.php
index 036a46ce..4c245e90 100644
--- a/lib/SP/Repositories/Client/ClientRepository.php
+++ b/lib/SP/Repositories/Client/ClientRepository.php
@@ -24,6 +24,7 @@
namespace SP\Repositories\Client;
+use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\ClientData;
use SP\DataModel\ItemData;
@@ -146,8 +147,9 @@ class ClientRepository extends Repository implements RepositoryItemInterface
public function checkDuplicatedOnUpdate($itemData)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT id FROM Client WHERE `hash` = ? AND id <> ? LIMIT 1');
+ $queryData->setQuery('SELECT id FROM Client WHERE (`hash` = ? OR `name` = ?) AND id <> ?');
$queryData->addParam($this->makeItemHash($itemData->getName(), $this->db->getDbHandler()));
+ $queryData->addParam($itemData->getName());
$queryData->addParam($itemData->getId());
DbWrapper::getQuery($queryData, $this->db);
@@ -246,7 +248,8 @@ class ClientRepository extends Repository implements RepositoryItemInterface
*
* @param $id
* @return int
- * @throws SPException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
*/
public function delete($id)
{
@@ -311,18 +314,23 @@ class ClientRepository extends Repository implements RepositoryItemInterface
*
* @param QueryCondition $queryFilter
* @return ItemData[]
+ * @throws QueryException
*/
public function getAllForFilter(QueryCondition $queryFilter)
{
+ if (!$queryFilter->hasFilters()) {
+ throw new QueryException(__u('Filtro incorrecto'));
+ }
+
$query = /** @lang SQL */
- 'SELECT C.id, C.name
- FROM Account A
- RIGHT JOIN Client C ON A.clientId = C.id
- WHERE A.clientId IS NULL
- OR C.isGlobal = 1
- OR (' . $queryFilter->getFilters() . ')
+ 'SELECT Client.id, Client.name
+ FROM Account
+ RIGHT JOIN Client ON Account.clientId = Client.id
+ WHERE Account.clientId IS NULL
+ OR Client.isGlobal = 1
+ OR ' . $queryFilter->getFilters() . '
GROUP BY id
- ORDER BY C.name';
+ ORDER BY Client.name';
$queryData = new QueryData();
$queryData->setMapClassName(ItemData::class);
diff --git a/lib/SP/Repositories/EventLog/EventlogRepository.php b/lib/SP/Repositories/EventLog/EventlogRepository.php
index f7e0e125..f0b8de34 100644
--- a/lib/SP/Repositories/EventLog/EventlogRepository.php
+++ b/lib/SP/Repositories/EventLog/EventlogRepository.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.
@@ -43,7 +43,6 @@ class EventlogRepository extends Repository
* @return bool con el resultado
* @throws \SP\Core\Exceptions\QueryException
* @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\SPException
*/
public function clear()
{
@@ -108,12 +107,14 @@ class EventlogRepository extends Repository
$queryData = new QueryData();
$queryData->setQuery($sql);
- $queryData->addParam($eventlogData->getLogin());
- $queryData->addParam($eventlogData->getUserId());
- $queryData->addParam($eventlogData->getIpAddress());
- $queryData->addParam($eventlogData->getAction());
- $queryData->addParam($eventlogData->getDescription());
- $queryData->addParam($eventlogData->getLevel());
+ $queryData->setParams([
+ $eventlogData->getLogin(),
+ $eventlogData->getUserId(),
+ $eventlogData->getIpAddress(),
+ $eventlogData->getAction(),
+ $eventlogData->getDescription(),
+ $eventlogData->getLevel()]
+ );
DbWrapper::getQuery($queryData, $this->db);
diff --git a/lib/SP/Repositories/Tag/TagRepository.php b/lib/SP/Repositories/Tag/TagRepository.php
index 171f40b5..c646d004 100644
--- a/lib/SP/Repositories/Tag/TagRepository.php
+++ b/lib/SP/Repositories/Tag/TagRepository.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.
@@ -24,9 +24,9 @@
namespace SP\Repositories\Tag;
-use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemSearchData;
use SP\DataModel\TagData;
+use SP\Repositories\DuplicatedItemException;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
@@ -47,14 +47,14 @@ class TagRepository extends Repository implements RepositoryItemInterface
*
* @param TagData $itemData
* @return mixed
- * @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
+ * @throws DuplicatedItemException
*/
public function create($itemData)
{
if ($this->checkDuplicatedOnAdd($itemData)) {
- throw new SPException(__u('Etiqueta duplicada'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Etiqueta duplicada'));
}
$queryData = new QueryData();
@@ -79,7 +79,8 @@ class TagRepository extends Repository implements RepositoryItemInterface
public function checkDuplicatedOnAdd($itemData)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT id FROM Tag WHERE `hash` = ?');
+ $queryData->setQuery('SELECT id FROM Tag WHERE `name` = ? OR `hash` = ?');
+ $queryData->addParam($itemData->getName());
$queryData->addParam($this->makeItemHash($itemData->getName(), $this->db->getDbHandler()));
DbWrapper::getQuery($queryData, $this->db);
@@ -92,14 +93,14 @@ class TagRepository extends Repository implements RepositoryItemInterface
*
* @param TagData $itemData
* @return mixed
- * @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
+ * @throws DuplicatedItemException
*/
public function update($itemData)
{
if ($this->checkDuplicatedOnUpdate($itemData)) {
- throw new SPException(__u('Etiqueta duplicada'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Etiqueta duplicada'));
}
$queryData = new QueryData();
@@ -123,7 +124,8 @@ class TagRepository extends Repository implements RepositoryItemInterface
public function checkDuplicatedOnUpdate($itemData)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT hash FROM Tag WHERE `hash` = ? AND id <> ?');
+ $queryData->setQuery('SELECT hash FROM Tag WHERE (`name` = ? OR `hash` = ?) AND id <> ?');
+ $queryData->addParam($itemData->getName());
$queryData->addParam($this->makeItemHash($itemData->getName(), $this->db->getDbHandler()));
$queryData->addParam($itemData->getId());
@@ -141,7 +143,7 @@ class TagRepository extends Repository implements RepositoryItemInterface
public function getById($id)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT id, name FROM Tag WHERE id = ? LIMIT 1');
+ $queryData->setQuery('SELECT id, `name` FROM Tag WHERE id = ? ORDER BY `name` LIMIT 1');
$queryData->addParam($id);
$queryData->setMapClassName(TagData::class);
@@ -186,7 +188,8 @@ class TagRepository extends Repository implements RepositoryItemInterface
*
* @param array $ids
* @return int
- * @throws SPException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
*/
public function deleteByIdBatch(array $ids)
{
diff --git a/lib/SP/Repositories/User/UserRepository.php b/lib/SP/Repositories/User/UserRepository.php
index ca04a050..402bf2cb 100644
--- a/lib/SP/Repositories/User/UserRepository.php
+++ b/lib/SP/Repositories/User/UserRepository.php
@@ -28,6 +28,7 @@ use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemSearchData;
use SP\DataModel\UserData;
use SP\DataModel\UserPreferencesData;
+use SP\Repositories\DuplicatedItemException;
use SP\Repositories\NoSuchItemException;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
@@ -49,7 +50,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
* Updates an item
*
* @param UserData $itemData
- * @return mixed
+ * @return int
* @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
@@ -57,12 +58,12 @@ class UserRepository extends Repository implements RepositoryItemInterface
public function update($itemData)
{
if ($this->checkDuplicatedOnUpdate($itemData)) {
- throw new SPException(__u('Login/email de usuario duplicados'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Login/email de usuario duplicados'));
}
$query = /** @lang SQL */
'UPDATE User SET
- name = ?,
+ `name` = ?,
login = ?,
ssoLogin = ?,
email = ?,
@@ -96,11 +97,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
DbWrapper::getQuery($queryData, $this->db);
- if ($queryData->getQueryNumRows() > 0) {
- $itemData->setId(DbWrapper::getLastId());
- }
-
- return $this;
+ return $queryData->getQueryNumRows();
}
/**
@@ -188,7 +185,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
* Returns the item for given id
*
* @param int $id
- * @return mixed
+ * @return UserData
* @throws SPException
*/
public function getById($id)
@@ -231,7 +228,11 @@ class UserRepository extends Repository implements RepositoryItemInterface
$queryRes = DbWrapper::getResults($queryData, $this->db);
if ($queryRes === false) {
- throw new SPException(__u('Error al obtener los datos del usuario'), SPException::ERROR);
+ throw new SPException(__u('Error al obtener los datos del usuario'));
+ }
+
+ if (!($queryRes instanceof UserData)) {
+ throw new NoSuchItemException(__u('El usuario no existe'));
}
return $queryRes;
@@ -240,7 +241,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
/**
* Returns all the items
*
- * @return mixed
+ * @return UserData[]
*/
public function getAll()
{
@@ -282,7 +283,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
* Returns all the items for given ids
*
* @param array $ids
- * @return array
+ * @return UserData[]
*/
public function getByIdBatch(array $ids)
{
@@ -418,7 +419,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
public function create($itemData)
{
if ($this->checkDuplicatedOnAdd($itemData)) {
- throw new SPException(__u('Login/email de usuario duplicados'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Login/email de usuario duplicados'));
}
$query = /** @lang SQL */
@@ -540,7 +541,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
$queryRes = DbWrapper::getResults($queryData, $this->db);
if ($queryRes === false) {
- throw new SPException(__u('Error al obtener los datos del usuario'), SPException::ERROR);
+ throw new SPException(__u('Error al obtener los datos del usuario'));
}
if ($queryData->getQueryNumRows() === 0) {
@@ -553,7 +554,7 @@ class UserRepository extends Repository implements RepositoryItemInterface
/**
* Returns items' basic information
*
- * @return mixed
+ * @return UserData[]
*/
public function getBasicInfo()
{
diff --git a/lib/SP/Repositories/UserGroup/UserGroupRepository.php b/lib/SP/Repositories/UserGroup/UserGroupRepository.php
index 29f140a8..b565288d 100644
--- a/lib/SP/Repositories/UserGroup/UserGroupRepository.php
+++ b/lib/SP/Repositories/UserGroup/UserGroupRepository.php
@@ -24,9 +24,12 @@
namespace SP\Repositories\UserGroup;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
use SP\DataModel\ItemSearchData;
use SP\DataModel\UserGroupData;
+use SP\Repositories\DuplicatedItemException;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
@@ -51,10 +54,6 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
*/
public function delete($id)
{
- if ($this->checkInUse($id)) {
- throw new SPException(__u('Grupo en uso'), SPException::WARNING);
- }
-
$queryData = new QueryData();
$queryData->setQuery('DELETE FROM UserGroup WHERE id = ? LIMIT 1');
$queryData->addParam($id);
@@ -70,8 +69,8 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
*
* @param $id int
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkInUse($id)
{
@@ -186,7 +185,7 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
/**
* Returns all the items
*
- * @return mixed
+ * @return UserGroupData[]
*/
public function getAll()
{
@@ -201,7 +200,7 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
* Returns all the items for given ids
*
* @param array $ids
- * @return array
+ * @return UserGroupData[]
*/
public function getByIdBatch(array $ids)
{
@@ -225,8 +224,8 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
*
* @param array $ids
* @return int
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function deleteByIdBatch(array $ids)
{
@@ -280,13 +279,13 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
* @param UserGroupData $itemData
* @return int
* @throws SPException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function create($itemData)
{
if ($this->checkDuplicatedOnAdd($itemData)) {
- throw new SPException(__u('Nombre de grupo duplicado'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Nombre de grupo duplicado'));
}
$query = /** @lang SQL */
@@ -308,8 +307,8 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
*
* @param UserGroupData $itemData
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkDuplicatedOnAdd($itemData)
{
@@ -326,15 +325,15 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
* Updates an item
*
* @param UserGroupData $itemData
- * @return mixed
- * @throws SPException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @return int
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws DuplicatedItemException
*/
public function update($itemData)
{
if ($this->checkDuplicatedOnUpdate($itemData)) {
- throw new SPException(__u('Nombre de grupo duplicado'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Nombre de grupo duplicado'));
}
$queryData = new QueryData();
@@ -346,7 +345,7 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
DbWrapper::getQuery($queryData, $this->db);
- return $this;
+ return $this->db->getNumRows();
}
/**
@@ -354,8 +353,8 @@ class UserGroupRepository extends Repository implements RepositoryItemInterface
*
* @param UserGroupData $itemData
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkDuplicatedOnUpdate($itemData)
{
diff --git a/lib/SP/Repositories/UserProfile/UserProfileRepository.php b/lib/SP/Repositories/UserProfile/UserProfileRepository.php
index 9c8b926c..36f77681 100644
--- a/lib/SP/Repositories/UserProfile/UserProfileRepository.php
+++ b/lib/SP/Repositories/UserProfile/UserProfileRepository.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.
@@ -24,10 +24,11 @@
namespace SP\Repositories\UserProfile;
-use SP\Core\Exceptions\SPException;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
use SP\DataModel\ItemSearchData;
-use SP\DataModel\ProfileData;
use SP\DataModel\UserProfileData;
+use SP\Repositories\DuplicatedItemException;
use SP\Repositories\Repository;
use SP\Repositories\RepositoryItemInterface;
use SP\Repositories\RepositoryItemTrait;
@@ -63,16 +64,11 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param $id
* @return int
- * @throws SPException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function delete($id)
{
- if ($this->checkInUse($id)) {
- throw new SPException(__u('Perfil en uso'), SPException::INFO);
- }
-
$queryData = new QueryData();
$queryData->setQuery('DELETE FROM UserProfile WHERE id = ? LIMIT 1');
$queryData->addParam($id);
@@ -88,8 +84,8 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param $id int
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkInUse($id)
{
@@ -111,7 +107,7 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
public function getById($id)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT id, name, profile FROM UserProfile WHERE id = ? LIMIT 1');
+ $queryData->setQuery('SELECT id, `name`, `profile` FROM UserProfile WHERE id = ? LIMIT 1');
$queryData->addParam($id);
$queryData->setMapClassName(UserProfileData::class);
@@ -126,7 +122,7 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
public function getAll()
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT id, name FROM UserProfile ORDER BY name');
+ $queryData->setQuery('SELECT id, `name` FROM UserProfile ORDER BY `name`');
$queryData->setMapClassName(UserProfileData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
@@ -136,7 +132,7 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
* Returns all the items for given ids
*
* @param array $ids
- * @return array
+ * @return UserProfileData[]
*/
public function getByIdBatch(array $ids)
{
@@ -145,12 +141,12 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
}
$query = /** @lang SQL */
- 'SELECT id, name FROM UserProfile WHERE id IN (' . $this->getParamsFromArray($ids) . ')';
+ 'SELECT id, `name` FROM UserProfile WHERE id IN (' . $this->getParamsFromArray($ids) . ')';
$queryData = new QueryData();
$queryData->setQuery($query);
$queryData->setParams($ids);
- $queryData->setMapClassName(ProfileData::class);
+ $queryData->setMapClassName(UserProfileData::class);
return DbWrapper::getResultsArray($queryData, $this->db);
}
@@ -160,8 +156,8 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param array $ids
* @return int
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function deleteByIdBatch(array $ids)
{
@@ -213,18 +209,18 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param UserProfileData $itemData
* @return int
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
- * @throws SPException
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws DuplicatedItemException
*/
public function create($itemData)
{
if ($this->checkDuplicatedOnAdd($itemData)) {
- throw new SPException(__u('Nombre de perfil duplicado'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Nombre de perfil duplicado'));
}
$queryData = new QueryData();
- $queryData->setQuery('INSERT INTO UserProfile SET name = ?, profile = ?');
+ $queryData->setQuery('INSERT INTO UserProfile SET `name` = ?, `profile` = ?');
$queryData->addParam($itemData->getName());
$queryData->addParam(serialize($itemData->getProfile()));
$queryData->setOnErrorMessage(__u('Error al crear perfil'));
@@ -239,13 +235,13 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param UserProfileData $itemData
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkDuplicatedOnAdd($itemData)
{
$queryData = new QueryData();
- $queryData->setQuery('SELECT name FROM UserProfile WHERE UPPER(name) = ?');
+ $queryData->setQuery('SELECT `name` FROM UserProfile WHERE UPPER(`name`) = ?');
$queryData->addParam($itemData->getName());
DbWrapper::getQuery($queryData, $this->db);
@@ -258,18 +254,18 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param UserProfileData $itemData
* @return bool
- * @throws SPException
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws DuplicatedItemException
*/
public function update($itemData)
{
if ($this->checkDuplicatedOnUpdate($itemData)) {
- throw new SPException(__u('Nombre de perfil duplicado'), SPException::INFO);
+ throw new DuplicatedItemException(__u('Nombre de perfil duplicado'));
}
$query = /** @lang SQL */
- 'UPDATE UserProfile SET name = ?, profile = ? WHERE id = ? LIMIT 1';
+ 'UPDATE UserProfile SET `name` = ?, `profile` = ? WHERE id = ? LIMIT 1';
$queryData = new QueryData();
$queryData->setQuery($query);
@@ -288,15 +284,15 @@ class UserProfileRepository extends Repository implements RepositoryItemInterfac
*
* @param UserProfileData $itemData
* @return bool
- * @throws \SP\Core\Exceptions\ConstraintException
- * @throws \SP\Core\Exceptions\QueryException
+ * @throws ConstraintException
+ * @throws QueryException
*/
public function checkDuplicatedOnUpdate($itemData)
{
$query = /** @lang SQL */
- 'SELECT name
+ 'SELECT `name`
FROM UserProfile
- WHERE UPPER(name) = ?
+ WHERE UPPER(`name`) = ?
AND id <> ?';
$queryData = new QueryData();
diff --git a/lib/SP/Services/Client/ClientService.php b/lib/SP/Services/Client/ClientService.php
index 0933b8d2..12a78e67 100644
--- a/lib/SP/Services/Client/ClientService.php
+++ b/lib/SP/Services/Client/ClientService.php
@@ -145,6 +145,7 @@ class ClientService extends Service
* Returns all clients visible for a given user
*
* @return ItemData[]
+ * @throws \SP\Core\Exceptions\QueryException
*/
public function getAllForUser()
{
diff --git a/lib/SP/Services/User/UserService.php b/lib/SP/Services/User/UserService.php
index 249d8bc7..9e765454 100644
--- a/lib/SP/Services/User/UserService.php
+++ b/lib/SP/Services/User/UserService.php
@@ -260,14 +260,16 @@ class UserService extends Service
* Updates an item
*
* @param UserData $itemData
- * @return mixed
- * @throws SPException
* @throws \SP\Core\Exceptions\ConstraintException
* @throws \SP\Core\Exceptions\QueryException
+ * @throws ServiceException
+ * @throws SPException
*/
public function update($itemData)
{
- return $this->userRepository->update($itemData);
+ if ($this->userRepository->update($itemData) === 0) {
+ throw new ServiceException(__u('Error al actualizar el usuario'));
+ }
}
/**
diff --git a/lib/SP/Storage/Database.php b/lib/SP/Storage/Database.php
index 0470e5df..50da5bf4 100644
--- a/lib/SP/Storage/Database.php
+++ b/lib/SP/Storage/Database.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.
@@ -26,6 +26,7 @@ namespace SP\Storage;
use PDO;
use PDOStatement;
+use SP\Core\Exceptions\QueryException;
use SP\Core\Exceptions\SPException;
/**
@@ -140,7 +141,7 @@ class Database implements DatabaseInterface
* @param $queryData QueryData Los datos de la consulta
* @param $isCount bool Indica si es una consulta de contador de registros
* @return \PDOStatement|false
- * @throws SPException
+ * @throws QueryException
*/
private function prepareQueryData(QueryData $queryData, $isCount = false)
{
@@ -208,7 +209,7 @@ class Database implements DatabaseInterface
// debugLog('Exception: ' . $e->getMessage());
// debugLog(ob_get_clean());
- throw new SPException($e->getMessage(), SPException::CRITICAL, $e->getCode(), 0, $e);
+ throw new QueryException($e->getMessage(), SPException::CRITICAL, $e->getCode(), 0, $e);
}
}
diff --git a/lib/SP/Storage/DatabaseInterface.php b/lib/SP/Storage/DatabaseInterface.php
index 6851ad84..435144c1 100644
--- a/lib/SP/Storage/DatabaseInterface.php
+++ b/lib/SP/Storage/DatabaseInterface.php
@@ -25,7 +25,7 @@
namespace SP\Storage;
use PDOStatement;
-use SP\Core\Exceptions\SPException;
+use SP\Core\Exceptions\QueryException;
/**
* Interface DatabaseInterface
@@ -40,7 +40,7 @@ interface DatabaseInterface
* @param QueryData $queryData Query data
* @param bool $getRawData Don't fetch records and return prepared statement
* @return PDOStatement|array
- * @throws SPException
+ * @throws QueryException
*/
public function doQuery(QueryData $queryData, $getRawData = false);
diff --git a/lib/SP/Storage/DbWrapper.php b/lib/SP/Storage/DbWrapper.php
index 7181a031..7f9890ed 100644
--- a/lib/SP/Storage/DbWrapper.php
+++ b/lib/SP/Storage/DbWrapper.php
@@ -158,22 +158,29 @@ class DbWrapper
$db->doQuery($queryData);
return true;
- } catch (\Exception $e) {
+ } catch (QueryException $e) {
processException($e);
$queryData->setQueryStatus($e->getCode());
+ $previous = $e->getPrevious();
- switch ($e->getCode()) {
- case 23000:
- throw new ConstraintException(
- __u('Restricción de integridad'),
- SPException::ERROR,
- $e->getMessage(),
- $e->getCode(),
- $e
- );
+ if ($previous) {
+ switch ($previous->getCode()) {
+ case '23000':
+ throw new ConstraintException(
+ __u('Restricción de integridad'),
+ SPException::ERROR,
+ $e->getMessage(),
+ $e->getCode(),
+ $e
+ );
+ }
}
+ throw $e;
+ } catch (\Exception $e) {
+ processException($e);
+
throw new QueryException(
$errorMessage,
SPException::ERROR,
diff --git a/tests/AccountRepositoryTest.php b/tests/AccountRepositoryTest.php
index 7e1ced44..d4a697f3 100644
--- a/tests/AccountRepositoryTest.php
+++ b/tests/AccountRepositoryTest.php
@@ -25,11 +25,6 @@
namespace SP\Tests;
use DI\DependencyException;
-use PHPUnit\DbUnit\Database\Connection;
-use PHPUnit\DbUnit\Database\DefaultConnection;
-use PHPUnit\DbUnit\DataSet\IDataSet;
-use PHPUnit\DbUnit\TestCaseTrait;
-use PHPUnit\Framework\TestCase;
use SP\Account\AccountRequest;
use SP\Account\AccountSearchFilter;
use SP\Core\Crypt\Crypt;
@@ -41,7 +36,6 @@ use SP\Mvc\Model\QueryCondition;
use SP\Repositories\Account\AccountRepository;
use SP\Services\Account\AccountPasswordRequest;
use SP\Storage\DatabaseConnectionData;
-use SP\Storage\MySQLHandler;
/**
* Class AccountRepositoryTest
@@ -50,27 +44,13 @@ use SP\Storage\MySQLHandler;
*
* @package SP\Tests
*/
-class AccountRepositoryTest extends TestCase
+class AccountRepositoryTest extends DatabaseTestCase
{
- use TestCaseTrait;
-
const SECURE_KEY_PASSWORD = 'syspass123';
/**
* @var AccountRepository
*/
private static $accountRepository;
- /**
- * @var \PDO
- */
- private static $pdo;
- /**
- * @var DatabaseConnectionData
- */
- private static $databaseConnectionData;
- /**
- * @var DefaultConnection
- */
- private $conn;
/**
* @throws DependencyException
@@ -115,7 +95,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testEditRestore()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -153,7 +133,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testCheckInUse()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -219,7 +199,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testCheckDuplicatedOnAdd()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -246,7 +226,7 @@ class AccountRepositoryTest extends TestCase
{
// Comprobar búsqueda con el texto Google Inc
$itemSearchData = new ItemSearchData();
- $itemSearchData->setSeachString('Google Inc');
+ $itemSearchData->setSeachString('Google');
$itemSearchData->setLimitCount(10);
$search = self::$accountRepository->search($itemSearchData);
@@ -278,7 +258,7 @@ class AccountRepositoryTest extends TestCase
public function testGetLinked()
{
$filter = new QueryCondition();
- $filter->addFilter('A.parentId = 1');
+ $filter->addFilter('Account.parentId = 1');
$this->assertCount(0, self::$accountRepository->getLinked($filter));
}
@@ -362,7 +342,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testGetDataForLink()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -371,7 +351,7 @@ class AccountRepositoryTest extends TestCase
public function testGetForUser()
{
$queryCondition = new QueryCondition();
- $queryCondition->addFilter('A.isPrivate = 1');
+ $queryCondition->addFilter('Account.isPrivate = 1');
$this->assertCount(0, self::$accountRepository->getForUser($queryCondition));
}
@@ -425,7 +405,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testGetByIdBatch()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -433,7 +413,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testCheckDuplicatedOnUpdate()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -441,7 +421,7 @@ class AccountRepositoryTest extends TestCase
*/
public function testGetPasswordHistoryForId()
{
- $this->markTestSkipped();
+ $this->markTestSkipped('Not implemented');
}
/**
@@ -521,33 +501,4 @@ class AccountRepositoryTest extends TestCase
$this->assertCount(1, $response->getData());
$this->assertEquals(1, $response->getData()[0]->getId());
}
-
- /**
- * Returns the test database connection.
- *
- * @return Connection
- * @throws \SP\Core\Exceptions\SPException
- */
- protected function getConnection()
- {
- if ($this->conn === null) {
- if (self::$pdo === null) {
- self::$pdo = (new MySQLHandler(self::$databaseConnectionData))->getConnection();
- }
-
- $this->conn = $this->createDefaultDBConnection(self::$pdo, 'syspass');
- }
-
- return $this->conn;
- }
-
- /**
- * Returns the test dataset.
- *
- * @return IDataSet
- */
- protected function getDataSet()
- {
- return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass.xml');
- }
}
diff --git a/tests/CategoryRepositoryTest.php b/tests/CategoryRepositoryTest.php
new file mode 100644
index 00000000..57f09054
--- /dev/null
+++ b/tests/CategoryRepositoryTest.php
@@ -0,0 +1,279 @@
+.
+ */
+
+namespace SP\Tests;
+
+use SP\Core\Exceptions\ConstraintException;
+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
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a las categorías
+ *
+ * @package SP\Tests
+ */
+class CategoryRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @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()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('linux');
+
+ $search = self::$categoryRepository->search($itemSearchData);
+ $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);
+
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$categoryRepository->search($itemSearchData);
+ $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(ConstraintException::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(ConstraintException::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('Not implemented');
+ }
+}
diff --git a/tests/ClientRepositoryTest.php b/tests/ClientRepositoryTest.php
new file mode 100644
index 00000000..60f18276
--- /dev/null
+++ b/tests/ClientRepositoryTest.php
@@ -0,0 +1,293 @@
+.
+ */
+
+namespace SP\Tests;
+
+use SP\Core\Exceptions\ConstraintException;
+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
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a los clientes
+ *
+ * @package SP\Tests
+ */
+class ClientRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @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()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('google');
+
+ $search = self::$clientRepository->search($itemSearchData);
+ $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);
+
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$clientRepository->search($itemSearchData);
+ $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(ConstraintException::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(ConstraintException::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('Not implemented');
+ }
+
+ /**
+ * @throws QueryException
+ */
+ public function testGetAllForFilter()
+ {
+ $filter = new QueryCondition();
+ $filter->addFilter('Account.isPrivate = 0');
+
+ $this->assertCount(3, self::$clientRepository->getAllForFilter($filter));
+ }
+}
diff --git a/tests/ConfigTest.php b/tests/ConfigTest.php
index 44c073fa..3d16c415 100644
--- a/tests/ConfigTest.php
+++ b/tests/ConfigTest.php
@@ -25,10 +25,8 @@
namespace SP\Tests;
use DI\Container;
-use DI\ContainerBuilder;
use DI\DependencyException;
use DI\NotFoundException;
-use Doctrine\Common\Cache\ArrayCache;
use PHPUnit\Framework\TestCase;
use SP\Config\Config;
use SP\Config\ConfigData;
@@ -47,10 +45,6 @@ class ConfigTest extends TestCase
* @var Container
*/
protected static $dic;
- /**
- * @var Config
- */
- protected $config;
/**
* @throws DependencyException
@@ -59,17 +53,7 @@ class ConfigTest extends TestCase
*/
public static function setUpBeforeClass()
{
- // Instancia del contenedor de dependencias con las definiciones de los objetos necesarios
- // para la aplicación
- $builder = new ContainerBuilder();
- $builder->setDefinitionCache(new ArrayCache());
- $builder->addDefinitions(APP_ROOT . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR . 'Definitions.php');
-
- self::$dic = $builder->build();
-
- // Inicializar el contexto
- $context = self::$dic->get(ContextInterface::class);
- $context->initialize();
+ self::$dic = setupContext();
}
/**
diff --git a/tests/DatabaseTestCase.php b/tests/DatabaseTestCase.php
new file mode 100644
index 00000000..de8f4166
--- /dev/null
+++ b/tests/DatabaseTestCase.php
@@ -0,0 +1,86 @@
+.
+ */
+
+namespace SP\Tests;
+
+use PHPUnit\DbUnit\Database\DefaultConnection;
+use PHPUnit\DbUnit\DataSet\IDataSet;
+use PHPUnit\DbUnit\TestCaseTrait;
+use PHPUnit\Framework\TestCase;
+use SP\Storage\DatabaseConnectionData;
+use SP\Storage\MySQLHandler;
+
+/**
+ * Class DatabaseBaseTest
+ *
+ * Caso de test para tests que requieran consultas a la BBDD
+ *
+ * @package SP\Tests
+ */
+abstract class DatabaseTestCase extends TestCase
+{
+ use TestCaseTrait;
+
+ /**
+ * @var DatabaseConnectionData
+ */
+ protected static $databaseConnectionData;
+ /**
+ * @var \PDO
+ */
+ private static $pdo;
+ /**
+ * @var DefaultConnection
+ */
+ protected $conn;
+
+ /**
+ * Returns the test database connection.
+ *
+ * @return DefaultConnection
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ final public function getConnection()
+ {
+ if ($this->conn === null) {
+ if (self::$pdo === null) {
+ self::$pdo = (new MySQLHandler(self::$databaseConnectionData))->getConnection();
+ }
+
+ $this->conn = $this->createDefaultDBConnection(self::$pdo, 'syspass');
+ }
+
+ return $this->conn;
+ }
+
+ /**
+ * Returns the test dataset.
+ *
+ * @return IDataSet
+ */
+ protected function getDataSet()
+ {
+ return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass.xml');
+ }
+}
\ No newline at end of file
diff --git a/tests/EventlogRepositoryTest.php b/tests/EventlogRepositoryTest.php
new file mode 100644
index 00000000..5d46e555
--- /dev/null
+++ b/tests/EventlogRepositoryTest.php
@@ -0,0 +1,150 @@
+.
+ */
+
+namespace SP\Tests;
+
+use PHPUnit\DbUnit\DataSet\IDataSet;
+use SP\Core\Exceptions\ConstraintException;
+use SP\DataModel\EventlogData;
+use SP\DataModel\ItemSearchData;
+use SP\Repositories\EventLog\EventlogRepository;
+use SP\Storage\DatabaseConnectionData;
+
+/**
+ * Class EventlogRepositoryTest
+ *
+ * @package SP\Tests
+ */
+class EventlogRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @var EventlogRepository
+ */
+ private static $eventlogRepository;
+
+ /**
+ * @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::$eventlogRepository = $dic->get(EventlogRepository::class);
+ }
+
+ /**
+ * Comprobar la búsqueda de eventos por texto
+ */
+ public function testSearch()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('login.auth.database');
+
+ $search = self::$eventlogRepository->search($itemSearchData);
+ $this->assertCount(5, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(4, $search['count']);
+ $this->assertEquals('login.auth.database', $search[0]->action);
+
+ $itemSearchData->setSeachString('login.auth.');
+
+ $search = self::$eventlogRepository->search($itemSearchData);
+ $this->assertCount(5, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(4, $search['count']);
+
+ $itemSearchData->setSeachString('Tiempo inactivo : 0 min.');
+
+ $search = self::$eventlogRepository->search($itemSearchData);
+ $this->assertCount(2, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(1, $search['count']);
+
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$eventlogRepository->search($itemSearchData);
+ $this->assertCount(1, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(0, $search['count']);
+ }
+
+ /**
+ * Comprobar la limpieza el registro de eventos
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testClear()
+ {
+ self::$eventlogRepository->clear();
+
+ $this->assertEquals(0, $this->conn->getRowCount('EventLog'));
+ }
+
+ /**
+ * Comprobar la creación de eventos
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws \SP\Core\Exceptions\QueryException
+ */
+ public function testCreate()
+ {
+ $eventlogData = new EventlogData();
+ $eventlogData->setAction('test');
+ $eventlogData->setLevel('INFO');
+ $eventlogData->setUserId(1);
+ $eventlogData->setLogin('Admin');
+ $eventlogData->setIpAddress('127.0.0.1');
+ $eventlogData->setDescription('Prueba');
+
+ $countBefore = $this->conn->getRowCount('EventLog');
+
+ self::$eventlogRepository->create($eventlogData);
+
+ $countAfter = $this->conn->getRowCount('EventLog');
+
+ $this->assertEquals($countBefore + 1, $countAfter);
+
+ $this->expectException(ConstraintException::class);
+
+ self::$eventlogRepository->create(new EventlogData());
+ }
+
+ /**
+ * Returns the test dataset.
+ *
+ * @return IDataSet
+ */
+ protected function getDataSet()
+ {
+ return $this->createMySQLXMLDataSet(RESOURCE_DIR . DIRECTORY_SEPARATOR . 'datasets' . DIRECTORY_SEPARATOR . 'syspass_eventlog.xml');
+ }
+}
diff --git a/tests/TagRepositoryTest.php b/tests/TagRepositoryTest.php
new file mode 100644
index 00000000..b359aefa
--- /dev/null
+++ b/tests/TagRepositoryTest.php
@@ -0,0 +1,235 @@
+.
+ */
+
+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
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a las etiquetas
+ *
+ * @package SP\Tests
+ */
+class TagRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @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()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('www');
+
+ $search = self::$tagRepository->search($itemSearchData);
+ $this->assertCount(2, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(1, $search['count']);
+ $this->assertEquals(1, $search[0]->id);
+
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$tagRepository->search($itemSearchData);
+ $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/UserGroupRepositoryTest.php b/tests/UserGroupRepositoryTest.php
new file mode 100644
index 00000000..70f5f7bd
--- /dev/null
+++ b/tests/UserGroupRepositoryTest.php
@@ -0,0 +1,263 @@
+.
+ */
+
+namespace SP\Tests;
+
+use DI\DependencyException;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
+use SP\DataModel\ItemSearchData;
+use SP\DataModel\UserGroupData;
+use SP\Repositories\DuplicatedItemException;
+use SP\Repositories\UserGroup\UserGroupRepository;
+use SP\Storage\DatabaseConnectionData;
+
+/**
+ * Class UserGroupRepositoryTest
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a los grupos de usuarios
+ *
+ * @package SP\Tests
+ */
+class UserGroupRepositoryTestCase extends DatabaseTestCase
+{
+ /**
+ * @var UserGroupRepository
+ */
+ private static $userGroupRepository;
+
+ /**
+ * @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::$userGroupRepository = $dic->get(UserGroupRepository::class);
+ }
+
+ /**
+ * Comprobar la obtención de uso del grupo por usuarios
+ */
+ public function testGetUsageByUsers()
+ {
+ $this->assertCount(2, self::$userGroupRepository->getUsageByUsers(1));
+ $this->assertCount(5, self::$userGroupRepository->getUsageByUsers(2));
+ $this->assertCount(0, self::$userGroupRepository->getUsageByUsers(3));
+ }
+
+ /**
+ * Comprobar si el grupo está en uso
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws QueryException
+ */
+ public function testCheckInUse()
+ {
+ $this->assertTrue(self::$userGroupRepository->checkInUse(1));
+ $this->assertTrue(self::$userGroupRepository->checkInUse(2));
+ $this->assertFalse(self::$userGroupRepository->checkInUse(5));
+ }
+
+ /**
+ * Comprobar la obtención de grupos por nombre
+ */
+ public function testGetByName()
+ {
+ $group = self::$userGroupRepository->getByName('Demo');
+
+ $this->assertInstanceOf(UserGroupData::class, $group);
+ $this->assertEquals('Demo', $group->getName());
+ $this->assertEmpty($group->getDescription());
+
+ $group = self::$userGroupRepository->getByName('Prueba');
+ $this->assertCount(0, $group);
+ }
+
+ /**
+ * Comprobar la eliminación de grupos en lote
+ *
+ * @throws \SP\Core\Exceptions\ConstraintException
+ * @throws QueryException
+ */
+ public function testDeleteByIdBatch()
+ {
+ // Se lanza excepción en caso de restricción relacional
+ $this->expectException(ConstraintException::class);
+
+ $result = self::$userGroupRepository->deleteByIdBatch([1, 2, 3]);
+
+ $this->assertEquals(1, $result);
+ }
+
+ /**
+ * Comprobar la actualización de grupos
+ *
+ * @covers \SP\Repositories\UserGroup\UserGroupRepository::checkDuplicatedOnUpdate()
+ * @throws ConstraintException
+ * @throws DuplicatedItemException
+ * @throws QueryException
+ */
+ public function testUpdate()
+ {
+ $userGroupData = new UserGroupData();
+ $userGroupData->setId(2);
+ $userGroupData->setName('Grupo demo');
+ $userGroupData->setDescription('Grupo para usuarios demo');
+
+ $this->assertEquals(1, self::$userGroupRepository->update($userGroupData));
+
+ $this->expectException(DuplicatedItemException::class);
+
+ $userGroupData->setName('Admins');
+
+ self::$userGroupRepository->update($userGroupData);
+
+ }
+
+ /**
+ * Comprobar la obtención de grupos por Id
+ */
+ public function testGetById()
+ {
+ $group = self::$userGroupRepository->getById(2);
+
+ $this->assertInstanceOf(UserGroupData::class, $group);
+ $this->assertEquals('Demo', $group->getName());
+ $this->assertEmpty($group->getDescription());
+
+ $group = self::$userGroupRepository->getById(4);
+ $this->assertCount(0, $group);
+ }
+
+ /**
+ * Comprobar la creación de grupos
+ *
+ * @covers \SP\Repositories\UserGroup\UserGroupRepository::checkDuplicatedOnAdd()
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testCreate()
+ {
+ $userGroupData = new UserGroupData();
+ $userGroupData->setName('Grupo Prueba');
+ $userGroupData->setDescription('Grupo de prueba para usuarios');
+
+ $this->assertEquals(4, self::$userGroupRepository->create($userGroupData));
+
+ $this->expectException(DuplicatedItemException::class);
+
+ $userGroupData->setName('Admins');
+
+ self::$userGroupRepository->create($userGroupData);
+ }
+
+ /**
+ * Comprobar la obtención de grupos
+ */
+ public function testGetAll()
+ {
+ $groups = self::$userGroupRepository->getAll();
+
+ $this->assertCount(3, $groups);
+ $this->assertInstanceOf(UserGroupData::class, $groups[0]);
+ $this->assertEquals('Admins', $groups[0]->getName());
+ $this->assertInstanceOf(UserGroupData::class, $groups[1]);
+ $this->assertEquals('Demo', $groups[1]->getName());
+ }
+
+ /**
+ * Comprobar la eliminación de grupos
+ *
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testDelete()
+ {
+ $result = self::$userGroupRepository->delete(3);
+
+ $this->assertEquals(1, $result);
+ $this->assertEquals(2, $this->conn->getRowCount('UserGroup'));
+
+ $this->expectException(ConstraintException::class);
+
+ self::$userGroupRepository->delete(1);
+ self::$userGroupRepository->delete(2);
+ }
+
+ /**
+ * Comprobar la obtención de uso de grupos
+ */
+ public function testGetUsage()
+ {
+ $this->assertCount(5, self::$userGroupRepository->getUsage(2));
+ $this->assertCount(0, self::$userGroupRepository->getUsage(3));
+ }
+
+ /**
+ * Comprobar la obtención de grupos en lote
+ */
+ public function testGetByIdBatch()
+ {
+ $groups = self::$userGroupRepository->getByIdBatch([1, 2, 5]);
+
+ $this->assertCount(2, $groups);
+ $this->assertInstanceOf(UserGroupData::class, $groups[0]);
+ $this->assertEquals(1, $groups[0]->getId());
+ $this->assertEquals('Admins', $groups[0]->getName());
+ $this->assertInstanceOf(UserGroupData::class, $groups[1]);
+ }
+
+ /**
+ * Comprobar la búsqueda de grupos
+ */
+ public function testSearch()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('Demo');
+
+ $search = self::$userGroupRepository->search($itemSearchData);
+ $this->assertCount(2, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(1, $search['count']);
+ $this->assertEquals(2, $search[0]->id);
+ $this->assertEquals('Demo', $search[0]->name);
+
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$userGroupRepository->search($itemSearchData);
+ $this->assertCount(1, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(0, $search['count']);
+ }
+}
diff --git a/tests/UserProfileRepositoryTest.php b/tests/UserProfileRepositoryTest.php
new file mode 100644
index 00000000..4fa7fc3e
--- /dev/null
+++ b/tests/UserProfileRepositoryTest.php
@@ -0,0 +1,244 @@
+.
+ */
+
+namespace SP\Tests;
+
+use DI\DependencyException;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
+use SP\DataModel\ItemSearchData;
+use SP\DataModel\ProfileData;
+use SP\DataModel\UserProfileData;
+use SP\Repositories\DuplicatedItemException;
+use SP\Repositories\UserProfile\UserProfileRepository;
+use SP\Storage\DatabaseConnectionData;
+
+/**
+ * Class UserProfileRepositoryTest
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a los perfiles de usuarios
+ *
+ * @package SP\Tests
+ */
+class UserProfileRepositoryTest extends DatabaseTestCase
+{
+ /**
+ * @var UserProfileRepository
+ */
+ private static $userProfileRepository;
+
+ /**
+ * @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::$userProfileRepository = $dic->get(UserProfileRepository::class);
+ }
+
+ /**
+ * Comprobar la obtención de perfiles
+ */
+ public function testGetAll()
+ {
+ $profiles = self::$userProfileRepository->getAll();
+
+ $this->assertCount(3, $profiles);
+ $this->assertInstanceOf(UserProfileData::class, $profiles[0]);
+ $this->assertEquals('Admin', $profiles[0]->getName());
+ $this->assertInstanceOf(UserProfileData::class, $profiles[1]);
+ $this->assertEquals('Demo', $profiles[1]->getName());
+ }
+
+ /**
+ * Comprobar la búsqueda de perfiles
+ */
+ public function testSearch()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('Demo');
+
+ $search = self::$userProfileRepository->search($itemSearchData);
+ $this->assertCount(2, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(1, $search['count']);
+ $this->assertEquals(2, $search[0]->id);
+ $this->assertEquals('Demo', $search[0]->name);
+
+ // Nueva búsqueda de perfil no existente
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$userProfileRepository->search($itemSearchData);
+ $this->assertCount(1, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(0, $search['count']);
+ }
+
+ /**
+ * Comprobar la actualización de perfiles
+ *
+ * @covers \SP\Repositories\UserGroup\UserGroupRepository::checkDuplicatedOnUpdate()
+ * @throws ConstraintException
+ * @throws DuplicatedItemException
+ * @throws QueryException
+ */
+ public function testUpdate()
+ {
+ $userProfileData = new UserProfileData();
+ $userProfileData->setId(2);
+ $userProfileData->setName('Perfil Demo');
+
+ $this->assertEquals(1, self::$userProfileRepository->update($userProfileData));
+
+ $this->expectException(DuplicatedItemException::class);
+
+ $userProfileData->setName('Admin');
+
+ self::$userProfileRepository->update($userProfileData);
+ }
+
+ /**
+ * Comprobar la eliminación de perfiles
+ *
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function testDelete()
+ {
+ $result = self::$userProfileRepository->delete(3);
+
+ $this->assertEquals(1, $result);
+ $this->assertEquals(2, $this->conn->getRowCount('UserProfile'));
+
+ $this->expectException(ConstraintException::class);
+
+ self::$userProfileRepository->delete(1);
+ self::$userProfileRepository->delete(2);
+ }
+
+ /**
+ * Comprobar si el perfil está en uso
+ *
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function testCheckInUse()
+ {
+ $this->assertTrue(self::$userProfileRepository->checkInUse(1));
+ $this->assertTrue(self::$userProfileRepository->checkInUse(2));
+ $this->assertFalse(self::$userProfileRepository->checkInUse(3));
+ }
+
+ /**
+ * Comprobar la creación de perfiles
+ *
+ * @throws ConstraintException
+ * @throws DuplicatedItemException
+ * @throws QueryException
+ */
+ public function testCreate()
+ {
+ $profileData = new ProfileData();
+ $profileData->setAccAdd(true);
+ $profileData->setAccDelete(true);
+ $profileData->setConfigBackup(true);
+
+ $userProfileData = new UserProfileData();
+ $userProfileData->setName('Prueba');
+ $userProfileData->setProfile($profileData);
+
+ $result = self::$userProfileRepository->create($userProfileData);
+
+ $this->assertEquals(4, $result);
+ $this->assertEquals(4, $this->conn->getRowCount('UserProfile'));
+
+ $this->expectException(DuplicatedItemException::class);
+
+ $userProfileData->setName('Demo');
+
+ self::$userProfileRepository->create($userProfileData);
+ }
+
+ /**
+ * Comprobar la obtención de perfiles por Id
+ */
+ public function testGetById()
+ {
+ $profile = self::$userProfileRepository->getById(2);
+
+ $this->assertInstanceOf(UserProfileData::class, $profile);
+ $this->assertEquals('Demo', $profile->getName());
+ $this->assertNotEmpty($profile->getProfile());
+
+ $profile = self::$userProfileRepository->getById(4);
+ $this->assertCount(0, $profile);
+ }
+
+ /**
+ * Comprobar la obtención de los usuarios asociados a un perfil
+ */
+ public function testGetUsersForProfile()
+ {
+ $this->assertCount(1, self::$userProfileRepository->getUsersForProfile(2));
+ $this->assertCount(0, self::$userProfileRepository->getUsersForProfile(3));
+ }
+
+ /**
+ * Comprobar la obtención de perfiles en lote
+ */
+ public function testGetByIdBatch()
+ {
+ $profiles = self::$userProfileRepository->getByIdBatch([1, 2, 5]);
+
+ $this->assertCount(2, $profiles);
+ $this->assertInstanceOf(UserProfileData::class, $profiles[0]);
+ $this->assertEquals(1, $profiles[0]->getId());
+ $this->assertEquals('Admin', $profiles[0]->getName());
+ $this->assertInstanceOf(UserProfileData::class, $profiles[1]);
+ }
+
+ /**
+ * Comprobar la eliminación de perfiles en lote
+ *
+ * @throws ConstraintException
+ * @throws QueryException
+ */
+ public function testDeleteByIdBatch()
+ {
+ // Se lanza excepción en caso de restricción relacional
+ $this->expectException(ConstraintException::class);
+
+ $result = self::$userProfileRepository->deleteByIdBatch([1, 2, 3, 4]);
+
+ $this->assertEquals(1, $result);
+ }
+}
diff --git a/tests/UserRepositoryTest.php b/tests/UserRepositoryTest.php
new file mode 100644
index 00000000..4aeaf5d9
--- /dev/null
+++ b/tests/UserRepositoryTest.php
@@ -0,0 +1,388 @@
+.
+ */
+
+namespace SP\Tests;
+
+use DI\DependencyException;
+use SP\Core\Crypt\Crypt;
+use SP\Core\Crypt\Hash;
+use SP\Core\Exceptions\ConstraintException;
+use SP\Core\Exceptions\QueryException;
+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\User\UpdatePassRequest;
+use SP\Storage\DatabaseConnectionData;
+
+/**
+ * Class UserRepositoryTest
+ *
+ * Tests unitarios para comprobar las consultas a la BBDD relativas a los usuarios
+ *
+ * @package SP\Tests
+ */
+class UserRepositoryTest extends DatabaseTestCase
+{
+
+ /**
+ * @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
+ *
+ * @covers \SP\Repositories\User\UserRepository::checkDuplicatedOnUpdate()
+ * @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->setId(3);
+
+ $this->expectException(DuplicatedItemException::class);
+
+ self::$userRepository->update($userData);
+
+ $userData->setId(10);
+
+ $this->assertEquals(0, 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(5);
+ }
+
+ /**
+ * 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]->getLogin());
+ $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]->getLogin());
+ }
+
+ /**
+ * 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()
+ {
+ $this->expectException(ConstraintException::class);
+
+ $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 usuarios
+ *
+ * @throws QueryException
+ * @throws \SP\Core\Exceptions\ConstraintException
+ */
+ public function testDelete()
+ {
+ $result = self::$userRepository->delete(3);
+
+ $this->assertEquals(1, $result);
+ $this->assertEquals(3, $this->conn->getRowCount('User'));
+
+ $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);
+ }
+
+ /**
+ * Comprobar la búsqueda de usuarios mediante texto
+ */
+ public function testSearch()
+ {
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('User A');
+
+ $search = self::$userRepository->search($itemSearchData);
+ $this->assertCount(2, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(1, $search['count']);
+ $this->assertEquals(3, $search[0]->id);
+ $this->assertEquals('User A', $search[0]->name);
+
+ $itemSearchData = new ItemSearchData();
+ $itemSearchData->setLimitCount(10);
+ $itemSearchData->setSeachString('prueba');
+
+ $search = self::$userRepository->search($itemSearchData);
+ $this->assertCount(1, $search);
+ $this->assertArrayHasKey('count', $search);
+ $this->assertEquals(0, $search['count']);
+ }
+
+ /**
+ * @throws ConstraintException
+ * @throws QueryException
+ * @throws \Defuse\Crypto\Exception\CryptoException
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testUpdateMasterPassById()
+ {
+ $key = Crypt::makeSecuredKey('prueba123');
+ $pass = Crypt::encrypt('prueba_key', $key, 'prueba123');
+
+ $this->assertTrue(self::$userRepository->updateMasterPassById(3, $pass, $key));
+
+ $user = self::$userRepository->getById(3);
+
+ $this->assertEquals($pass, $user->getMPass());
+ $this->assertEquals($key, $user->getMKey());
+ }
+
+ /**
+ * Comprobar la creación de usuarios
+ *
+ * @covers \SP\Repositories\User\UserRepository::checkDuplicatedOnAdd()
+ * @throws \SP\Core\Exceptions\SPException
+ */
+ public function testCreate()
+ {
+ $userData = new UserData();
+ $userData->setName('Usuario Prueba');
+ $userData->setLogin('prueba');
+ $userData->setEmail('prueba@syspass.org');
+ $userData->setNotes('Usuario Prueba');
+ $userData->setUserGroupId(1);
+ $userData->setUserProfileId(1);
+ $userData->setIsAdminApp(1);
+ $userData->setIsAdminAcc(1);
+ $userData->setIsDisabled(1);
+ $userData->setIsChangePass(1);
+ $userData->setIsLdap(0);
+ $userData->setPass(Hash::hashKey('prueba123'));
+
+ $this->assertEquals(5, self::$userRepository->create($userData));
+
+ $userData->setLogin('demo');
+ $userData->setEmail('prueba@syspass.org');
+
+ $this->expectException(DuplicatedItemException::class);
+
+ self::$userRepository->create($userData);
+
+ $userData->setLogin('prueba');
+ $userData->setEmail('demo@syspass.org');
+
+ self::$userRepository->create($userData);
+ }
+
+ /**
+ * Comprobar la obtención de email de usuario por Id de grupo
+ */
+ public function testGetUserEmailForGroup()
+ {
+ $this->assertCount(4, self::$userRepository->getUserEmailForGroup(2));
+ }
+}
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index bb3e44a8..315c43bb 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -88,8 +88,9 @@ function setupContext()
$context->setUserData($userData);
+ // Establecer configuración de conexión con la BBDD
$databaseConnectionData = (new DatabaseConnectionData())
- ->setDbHost('172.17.0.2')
+ ->setDbHost('172.17.0.3')
->setDbName('syspass')
->setDbUser('root')
->setDbPass('syspass');
diff --git a/tests/res/datasets/syspass.xml b/tests/res/datasets/syspass.xml
new file mode 100644
index 00000000..ebc4a1e6
--- /dev/null
+++ b/tests/res/datasets/syspass.xml
@@ -0,0 +1,366 @@
+
+
+
+
+
+ 1
+ Admin
+ 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A303B733A31343A22002A006163635669657750617373223B623A303B733A31373A22002A0061636356696577486973746F7279223B623A303B733A31303A22002A0061636345646974223B623A303B733A31343A22002A006163634564697450617373223B623A303B733A393A22002A00616363416464223B623A303B733A31323A22002A0061636344656C657465223B623A303B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A313B733A31383A22002A006163635072697661746547726F7570223B623A313B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D
+
+
+ 2
+ Demo
+ 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A313B733A31343A22002A006163635669657750617373223B623A313B733A31373A22002A0061636356696577486973746F7279223B623A313B733A31303A22002A0061636345646974223B623A313B733A31343A22002A006163634564697450617373223B623A313B733A393A22002A00616363416464223B623A313B733A31323A22002A0061636344656C657465223B623A313B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A303B733A31383A22002A006163635072697661746547726F7570223B623A303B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D
+
+
+ 3
+ Usuarios
+ 4F3A32343A2253505C446174614D6F64656C5C50726F66696C6544617461223A32393A7B733A31303A22002A0061636356696577223B623A313B733A31343A22002A006163635669657750617373223B623A313B733A31373A22002A0061636356696577486973746F7279223B623A313B733A31303A22002A0061636345646974223B623A313B733A31343A22002A006163634564697450617373223B623A313B733A393A22002A00616363416464223B623A313B733A31323A22002A0061636344656C657465223B623A313B733A31313A22002A0061636346696C6573223B623A303B733A31333A22002A0061636350726976617465223B623A303B733A31383A22002A006163635072697661746547726F7570223B623A303B733A31363A22002A006163635065726D697373696F6E223B623A303B733A31373A22002A006163635075626C69634C696E6B73223B623A303B733A31383A22002A00616363476C6F62616C536561726368223B623A303B733A31363A22002A00636F6E66696747656E6572616C223B623A303B733A31393A22002A00636F6E666967456E6372797074696F6E223B623A303B733A31353A22002A00636F6E6669674261636B7570223B623A303B733A31353A22002A00636F6E666967496D706F7274223B623A303B733A31313A22002A006D676D5573657273223B623A303B733A31323A22002A006D676D47726F757073223B623A303B733A31343A22002A006D676D50726F66696C6573223B623A303B733A31363A22002A006D676D43617465676F72696573223B623A303B733A31353A22002A006D676D437573746F6D657273223B623A303B733A31353A22002A006D676D417069546F6B656E73223B623A303B733A31373A22002A006D676D5075626C69634C696E6B73223B623A303B733A31343A22002A006D676D4163636F756E7473223B623A303B733A31303A22002A006D676D54616773223B623A303B733A31313A22002A006D676D46696C6573223B623A303B733A363A22002A0065766C223B623A303B733A31383A22002A006D676D437573746F6D4669656C6473223B623A303B7D
+
+
+
+
+ 1
+ Web
+ Web sites
+ 3235363761356563393730356562376163326339383430333365303631383964
+
+
+ 2
+ Linux
+ Linux server
+ 6532303661353465393736393063636535306363383732646437306565383936
+
+
+ 3
+ SSH
+ SSH access
+ 3137383764373634363330346335643938376366346536346133393733646337
+
+
+
+
+ 1
+ Google
+ 6338323263316236333835336564323733623839363837616335303566396661
+ Google Inc.
+ 0
+
+
+ 2
+ Apple
+ 3166333837306265323734663663343962336533316130633637323839353766
+ Apple Inc.
+ 0
+
+
+ 3
+ Microsoft
+ 3566353332613366633466316561343033663337303730663539613761353361
+ Microsoft Inc.
+ 1
+
+
+
+
+ 1
+ www
+ 3465616533356631623335393737613030656264383038366332353964346339
+
+
+ 2
+ windows
+ 3066343133376564313530326235303435643630383361613235386235633432
+
+
+ 3
+ Linux
+ 6532303661353465393736393063636535306363383732646437306565383936
+
+
+
+
+ 1
+ Admins
+ sysPass Admins
+
+
+ 2
+ Demo
+
+
+
+ 3
+ Usuarios
+ Grupo Usuarios
+
+
+
+
+ 1
+ sysPass Admin
+ 1
+ admin
+
+ 243279243130247635695230547A4933744E3036416A304C4A656B39755371496834356C70575539366E644A71444A704E6969713139306A444A486D
+ 64656635303230306330383635633335373637316233366261353266333137346134356466333633626135656431613962323261356461353965376134373930356664656239373436356462373934613831373635316133316432626363636266663836626233353235643930333932393734323535663937316261616239656436346637383266363066646465386539336637363164356663633436393031356433363164333234643436633533633138313335613334663739633039
+ 6465663130303030646566353032303062316163626161346361643036643237386562323533616462643433613966376463636439343063656265313962343061383436643464633035303636306466653630613561653139363433643636353936643733333764646236386536363930336562383031373764356463386430663963623661643361663565643766303936376262393964663530373936316330656132373462663830346333663966373563336538643539396336326231623738333730303963616263373836383637366433636337376162383365386338323335336335626164396534656535333532656132346632653434653663316336656131643162313264393332386335303539623437656235343534666138356435626437343637353333383132636662313230316634633635383733316465323934613664643035396332613362373333613765343462633539306338363337393032306662303263363262303565613030623234646235323566653863303263323138666561356661353139306563396266333461316637613937633733396637343534323333316466323932343965323138656338343233306161623038373336346463353236363935383630656638623232313439626262656636656266373030366638376434343661333535353863323062353462376336623330
+
+
+ 81
+ 1
+ 2018-04-19 23:46:48
+
+ 1521887152
+ 1
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+ 4F3A33323A2253505C446174614D6F64656C5C55736572507265666572656E63657344617461223A31303A7B733A373A22757365725F6964223B693A313B733A363A22757365324661223B623A303B733A343A226C616E67223B733A353A22656E5F5553223B733A353A227468656D65223B733A31333A226D6174657269616C2D626C7565223B733A31343A22726573756C747350657250616765223B693A34383B733A31313A226163636F756E744C696E6B223B623A313B733A393A22736F72745669657773223B623A303B733A393A22746F704E6176626172223B623A303B733A31353A226F7074696F6E616C416374696F6E73223B623A303B733A31343A22726573756C747341734361726473223B623A303B7D
+
+
+ 2
+ sysPass demo
+ 2
+ demo
+ demo
+ 2432792431302454726E69756C5763754361433635346F76566F35392E766B4C5433414E31624A6D726A79553462696335325069436A6B5572396669
+ 64656635303230303231616533353730373263373165626239393534353966366236636164373235336534316336633534353036336339326136653730616366333930393165373934613865376662386662326664333931383932363562396466303133333631623063323732323339653465373165343839313030646534326265633737623966343238396635633936613837646531343864313963653663643338613131343932623163313765653630326430623532343564346566
+ 6465663130303030646566353032303035643534316262633462653032333563313338626561366561333536626436663037353365313035653030333563653166316235336534663364343565366262353335626163396639646538653131316262356334383865336535633637323333666632626365313837626335386135353839373535373034386564353634366361646638623736396132323164363032353435653034306264613135663138323638383665373536313236353361313037306530333261323365636364336339616438323162306363383962643130333035303931653965626332653935313465656631373462663339343664656132393661346262366264343463646333363361643335623032373561356633323430313936346531633131663937313764313139633130633561373161666332356365346534366661623234646663626362326237303964336335316532623834326464303933653230353965373265356638376363366236626239306231346265376264373637663163303937366231313362393630613265636565336633313131663538656131346139353736623332653163303962636435313366383733656664653062373333366238643464646637616237323333373038613264393965633738356139393036306135643262316366306262663739346262663765
+ demo@syspass.org
+ aaaa
+ 12
+ 2
+ 2018-04-01 21:29:47
+ 2018-04-14 08:47:43
+ 1522582852
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+ 3
+ User A
+ 2
+ user_a
+ user_a
+ 2432792431302469444B442E2F4F624D79742E6F43594F5249514D5065624454783966744D636A703034365A435976662E765479597A594F6A4C472E
+
+
+ user_a@syspass.org
+
+ 0
+ 1
+
+ 2018-04-14 08:48:08
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+ 4
+ User B
+ 2
+ user_b
+
+ 243279243130244C37643658736A663955794F6E583662472E6F384E4F713961674B6F64536B4B5674485350462F6861414E657971517065372E6532
+
+
+ user_b@syspass.org
+
+ 0
+ 1
+
+ 2018-03-30 18:38:32
+ 0
+ 0
+ 0
+ 0
+ 0
+
+ 0
+ 0
+ 0
+
+
+
+
+
+ 1
+ 1
+ 1
+ 1
+ 1
+ Google
+ 1
+ admin
+ http://google.com
+ 6465663530323030656135663361636362366237656462653536343938666234313231616635323237363539663162346532383963386361346565323732656530636238333632316436393736353665373631393435623033353236616164333730336662306531333535626437333638653033666137623565633364306365323634663863643436393436633365353234316534373338376130393133663935303736396364613365313234643432306636393834386434613262316231306138
+ 6465663130303030646566353032303065646434636466636231333437613739616166313734343462343839626362643364353664376664356562373233363235653130316261666432323539343633336664626639326630613135373461653562613562323535353230393236353237623863633534313862653363376361376536366139356366353366356162663031623064343236613234336162643533643837643239636633643165326532663732626664396433366133653061343534656664373134633661366237616338363966636263366435303166613964316338386365623264303861333438626633656638653135356538633865353838623938636465653061306463313835646636366535393138393831653366303464323139386236383738333539616563653034376434643637663835313235636661313237633138373865643530616630393434613934616363356265316130323566623065633362663831613933626365366365343734336164363562656638353131343466343332323837356438323339303236656363613866643862376330396563356465373233666466313636656166386336356539666537353436333535333664393766383366316366663931396530386339373730636166633136376661656364306366656262323931666334343831333238333662366432
+ 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
+ 6465663530323030656135663361636362366237656462653536343938666234313231616635323237363539663162346532383963386361346565323732656530636238333632316436393736353665373631393435623033353236616164333730336662306531333535626437333638653033666137623565633364306365323634663863643436393436633365353234316534373338376130393133663935303736396364613365313234643432306636393834386434613262316231306138
+ 6465663130303030646566353032303065646434636466636231333437613739616166313734343462343839626362643364353664376664356562373233363235653130316261666432323539343633336664626639326630613135373461653562613562323535353230393236353237623863633534313862653363376361376536366139356366353366356162663031623064343236613234336162643533643837643239636633643165326532663732626664396433366133653061343534656664373134633661366237616338363966636263366435303166613964316338386365623264303861333438626633656638653135356538633865353838623938636465653061306463313835646636366535393138393831653366303464323139386236383738333539616563653034376434643637663835313235636661313237633138373865643530616630393434613934616363356265316130323566623065633362663831613933626365366365343734336164363562656638353131343466343332323837356438323339303236656363613866643862376330396563356465373233666466313636656166386336356539666537353436333535333664393766383366316366663931396530386339373730636166633136376661656364306366656262323931666334343831333238333662366432
+ bbbb
+ 341
+ 35
+ 2018-03-25 09:54:07
+ 2018-04-02 21:38:25
+ 0
+ 0
+ 0
+ 0
+ 1522341709
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+
+
+
+
+ 1
+ 3
+ 1
+
+
+
+
+
+
+ config_backup
+ 789ca5586d6fdb3610ee6f31b67d59ab897a978b024deda46f69e3c569d00dc30a8aa26dc2b2a48a5413b7e87fdf919454c7092515fb628bd23d47f25e9e3bf262ead8d3c972f1cfacc8576cddfccdb1c09369144fbff1a9eb4c278f1e12785497eb0aa7f42ddd4f9ef229a8917f6e68124f8b6d7dc3b6ec34c74946d3c95336b525c01d027ca8b29f9a00e45f604e0f31de2086d3eaa7000bccf921201e02bcc73bca4b4ceeac2b32a1b2149773bac275265e56455d4a6b214078f608c4a22a562ca32dc6bc99b22a6ef7a3fda1a497b4fa72d754a8577e515442aa8eecc81e963e76c380ee231f18ad59d649c6f22d7f876faf19bde172416e6f2c1d20aed84e9932b0ed5190037bf65b1f1352d4b998c91f29ed45bde66fc4cf618e61dd6443c9f64399624179e7d97ee9bc108c1c481bf39ea8c757986f264d4486514a504a91ef077865e3d4a324214e6ca72840b6e77a2875e255ec1029ef18bd9426af0a2ea40c029d7c0fd9c2f9933451be35c67d9a2c0bb2a5e22010faa690692865c26e8621441b6528984efe9efe5b64b35f67fb3f9ecf6f3fc76c08dbc6b3c4f2f2938f93c009f18ab8c9b031dacc715d3b90a266dea349bd1e41a774571ce7ba717ac91ffc24cb8a1b9a9ede0a30009ea270faadc14d278bf9591785d3c99bc54b3972f4e8e5ebb32ec340f2bdfae6e9d1c5fc4a8efc76b454a9a547f38b991c8532aad4e8a3620efdf1e3b9128d9bd1f25c4ddface67a3957c36639571fd524a859cf6c79ad86cd825e9cbc55c3664597f3851a364b7a7bfa971a366b9a5d82aaef634db5645f35edda8ed79b710a349a29d65991e06c497145369def8cdcc8722e7076a8b8b768b4b5d281184dc9331926e8313cac2a4a5989e56351adfbaba2d2c3f2b48d771f82b566e9339cee58fe98e4cf6af8c0e543c362fcf1ff9daa4d4b28bc4b4a2a2a90e32aa4df875c3c54658c2923114729e3180bbd143e49f9b07fa46053d47facc1c8b652fa47d175402b58ca52a6b31abb59a38c26778d85a8c6cd5aac8fa3d3bc1f90fd42734d12b0c086242004c02d5080ac5605bc4969469b373239c1573465c26ae9028c4b6f092d052bf296344086e32f1a23731449eade143756134a962671cd22f73e664db90c9b8fa428f7f790926210188f64906216959b814db57403790123965b1de3e837452d3ad28137a2c2646b75bc037c8149068ecaf71df938720e596b2d4177e53bcc05ad641cdf1455da5192238d725bb28a9aa4a4151c705d452100f8c6dadd1709b4b96bd501e845290b008aed4aa82c960c09fd21d27c5bd5cd0e63ed084ef31454b34c39cb6e4ca48d5b8bcd55b1a5b9a646636592e81390a5635b4c0938ae5146f292c26755b16b0b2cb43ae27953d4bb94e84577a51dccf2db9b5f6eb6e277f4e7865e8c4036c5d991bef08ca921452fe9e71a56c68ff7654c5609024aab2b26f6a39255035a8a90a6906fac9f32c561a7f2a02183fe3d1256b296033a0a7858d9f7a1bdb46c3282a1413c17105e39a1c3862d9b0c59e24cb58b01a88fa807fd95ed9198ac2859a1d023768cbd88068484b117267e902684da61e078714830c5e1ca0f50e2c3c77ebb406ac2598c9ff019ae0eca82519e53ce81f6e471a36516c7eecf00ce043dc7b972105854e6631f514bf1ab0dd50d30726598006f309c3d49b29af6174fddf45f431557d4ac73c6b56d0b45b6ebb8b6337036879f041a8d210546473f7473600c22297cc63231b2ccebf3fc9ad6772f1a8cb690f2ba193b420c1c99e0517787bee3a108a150d604cf086a0f94af77b0b6e36a6cdc4c0255a82e3f6d0e8e6724469e13475112a731c26ee8131cb96e14ae6c3f7649889143f1cac7031e809a04a47757b117a31586a39e43ed3884a4481c9424d875c220c0aee7db382469e024fdcdc94688f21e3b1a8d0f5472b739b17b19588b5f42bb24e86806d6a0fb571d465769405b147c55c7cd57354dfb21abcf55a1bc3b5c1975042d71b322308feaadfb2988e6a4da9762a999a533d6d08dc4599d65aa413d2184ea0e49c59cf10824fb013846307214a59e910f3a04b407c5b9ecae8e037c183a2f24fb8fba1ae4bc78e836cd7c6bf703707499664ed7c678a7aa753bde8d71a23ba8f6aa09d96e10d940fedfff039026f3d1
+
+
+ config_backup_date
+ 1524181202
+
+
+ lastupdatempass
+ 1521887151
+
+
+ masterPwd
+ $2y$10$p/x8ECCP1Lz/SjbGQy.6/OJ/.OLICBLGkXPiVkaA5Kf1.1HvRQOWG
+
+
+ version
+ 300.18032302
+
+
+
+
+ 1
+ text
+ Texto
+
+
+ 2
+ password
+ Clave
+
+
+ 3
+ date
+ Fecha
+
+
+ 4
+ number
+ Número
+
+
+ 5
+ email
+ Email
+
+
+ 6
+ telephone
+ Teléfono
+
+
+ 7
+ url
+ URL
+
+
+ 8
+ color
+ Color
+
+
+ 9
+ wiki
+ Wiki
+
+
+ 10
+ textarea
+ Área de Texto
+
+
+
+
+ 1
+ 2
+
+
+ 3
+ 2
+
+
+ 2
+ 1
+
+
+
+
diff --git a/tests/res/datasets/syspass_eventlog.xml b/tests/res/datasets/syspass_eventlog.xml
new file mode 100644
index 00000000..252e2228
--- /dev/null
+++ b/tests/res/datasets/syspass_eventlog.xml
@@ -0,0 +1,165 @@
+
+
+
+
+
+ 1
+ 1527720052
+ -
+
+ 172.19.0.1
+ login.auth.database
+
+Tipo : authDatabase
+Usuario : admin
+ INFO
+
+
+ 2
+ 1527720053
+ admin
+ 1
+ 172.19.0.1
+ login.session.load
+
+Usuario : admin
+ INFO
+
+
+ 3
+ 1527720053
+ admin
+ 1
+ 172.19.0.1
+ login.preferences.load
+
+ INFO
+
+
+ 4
+ 1527723866
+ admin
+ 1
+ 172.19.0.1
+ logout
+ Finalizar sesión
+Usuario : admin
+Tiempo inactivo : 0.02 min.
+Tiempo total : 63.72 min.
+ INFO
+
+
+ 5
+ 1527796875
+ -
+
+ 172.19.0.1
+ login.auth.database
+
+Tipo : authDatabase
+Usuario : admin
+ INFO
+
+
+ 6
+ 1527796876
+ admin
+ 1
+ 172.19.0.1
+ login.session.load
+
+Usuario : admin
+ INFO
+
+
+ 7
+ 1527796876
+ admin
+ 1
+ 172.19.0.1
+ login.preferences.load
+
+ INFO
+
+
+ 8
+ 1527800242
+ -
+
+ 172.19.0.1
+ login.auth.database
+
+Tipo : authDatabase
+Usuario : admin
+ INFO
+
+
+ 9
+ 1527800243
+ admin
+ 1
+ 172.19.0.1
+ login.session.load
+
+Usuario : admin
+ INFO
+
+
+ 10
+ 1527800243
+ admin
+ 1
+ 172.19.0.1
+ login.preferences.load
+
+ INFO
+
+
+ 11
+ 1527807482
+ -
+
+ 172.19.0.1
+ login.auth.database
+
+Tipo : authDatabase
+Usuario : admin
+ INFO
+
+
+ 12
+ 1527807483
+ admin
+ 1
+ 172.19.0.1
+ login.session.load
+
+Usuario : admin
+ INFO
+
+
+ 13
+ 1527807483
+ admin
+ 1
+ 172.19.0.1
+ login.preferences.load
+
+ INFO
+
+
+ 14
+ 1527807531
+ admin
+ 1
+ 172.19.0.1
+ logout
+ Finalizar sesión
+Usuario : admin
+Tiempo inactivo : 0 min.
+Tiempo total : 0.92 min.
+ INFO
+
+
+
+