chore(tests): UT for PluginBase service

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2024-04-19 20:58:50 +02:00
parent 21f392bb17
commit 03e4a57562
32 changed files with 360 additions and 320 deletions

View File

@@ -27,7 +27,7 @@ namespace SP\Modules\Api\Controllers\Account;
use Klein\Klein;
use SP\Core\Application;
use SP\Domain\Account\Adapters\AccountAdapterInterface;
use SP\Domain\Account\Ports\AccountAdapter;
use SP\Domain\Account\Ports\AccountPresetService;
use SP\Domain\Account\Ports\AccountService;
use SP\Domain\Api\Ports\ApiService;
@@ -45,7 +45,7 @@ abstract class AccountBase extends ControllerBase
protected AccountPresetService $accountPresetService;
protected AccountService $accountService;
protected CustomFieldDataService $customFieldService;
protected AccountAdapterInterface $accountAdapter;
protected AccountAdapter $accountAdapter;
/**
* @throws InvalidClassException
@@ -58,7 +58,7 @@ abstract class AccountBase extends ControllerBase
AccountPresetService $accountPresetService,
AccountService $accountService,
CustomFieldDataService $customFieldService,
AccountAdapterInterface $accountAdapter
AccountAdapter $accountAdapter
) {
parent::__construct($application, $router, $apiService, $acl);

View File

@@ -28,7 +28,7 @@ namespace SP\Modules\Api\Controllers\Client;
use Klein\Klein;
use SP\Core\Application;
use SP\Domain\Api\Ports\ApiService;
use SP\Domain\Client\Ports\ClientAdapterInterface;
use SP\Domain\Client\Ports\ClientAdapter;
use SP\Domain\Client\Ports\ClientService;
use SP\Domain\Core\Acl\AclInterface;
use SP\Domain\Core\Exceptions\InvalidClassException;
@@ -41,7 +41,7 @@ use SP\Modules\Api\Controllers\Help\ClientHelp;
abstract class ClientBase extends ControllerBase
{
protected ClientService $clientService;
protected ClientAdapterInterface $clientAdapter;
protected ClientAdapter $clientAdapter;
/**
* @throws InvalidClassException
@@ -52,7 +52,7 @@ abstract class ClientBase extends ControllerBase
ApiService $apiService,
AclInterface $acl,
ClientService $clientService,
ClientAdapterInterface $clientAdapter
ClientAdapter $clientAdapter
) {
parent::__construct($application, $router, $apiService, $acl);

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -37,7 +37,7 @@
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Core\UI\ThemeIconsInterface;
use SP\Domain\Install\Services\InstallerService;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Mvc\View\TemplateInterface;
use SP\Util\VersionUtil;
@@ -246,7 +246,7 @@
<ul class="mdl-list">
<?php
/** @var PluginInterface $plugin */
/** @var Plugin $plugin */
foreach ($_getvar('plugins') as $name => $plugin): ?>
<li class="mdl-list__item">
<span class="mdl-list__item-primary-content">

View File

@@ -24,7 +24,7 @@
/**
* @var Plugin $plugin
* @var PluginInterface $pluginInfo
* @var Plugin $pluginInfo
* @var ThemeIconsInterface $icons
* @var ConfigDataInterface $configData
* @var callable $_getvar
@@ -34,7 +34,7 @@
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Core\UI\ThemeIconsInterface;
use SP\Domain\Plugin\Models\Plugin;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Mvc\View\TemplateInterface;
$plugin = $_getvar('plugin');

View File

@@ -26,7 +26,9 @@ namespace SP\Domain\Account\Adapters;
use League\Fractal\Resource\Collection;
use SP\Domain\Account\Dtos\AccountEnrichedDto;
use SP\Domain\Account\Ports\AccountAdapter;
use SP\Domain\Common\Adapters\Adapter;
use SP\Domain\Common\Dtos\Dto;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Core\Acl\AclActionsInterface;
@@ -35,25 +37,25 @@ use SP\Domain\Core\Acl\ActionsInterface;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\CustomField\Adapters\CustomFieldAdapter;
use SP\Domain\CustomField\Adapters\CustomField;
use SP\Domain\CustomField\Ports\CustomFieldDataService;
use SP\Mvc\Controller\ItemTrait;
use SP\Mvc\View\Components\SelectItemAdapter;
use SP\Util\Link;
/**
* Class AccountAdapter
* Class Account
*/
final class AccountAdapter extends Adapter implements AccountAdapterInterface
final class Account extends Adapter implements AccountAdapter
{
use ItemTrait;
protected array $availableIncludes = ['customFields'];
public function __construct(
ConfigDataInterface $configData,
ConfigDataInterface $configData,
private readonly CustomFieldDataService $customFieldService,
private readonly ActionsInterface $actions
private readonly ActionsInterface $actions
) {
parent::__construct($configData);
}
@@ -64,18 +66,22 @@ final class AccountAdapter extends Adapter implements AccountAdapterInterface
* @throws SPException
* @throws ServiceException
*/
public function includeCustomFields(AccountEnrichedDto $data,): Collection
public function includeCustomFields(AccountEnrichedDto $accountEnrichedDto): Collection
{
return $this->collection(
$this->getCustomFieldsForItem(AclActionsInterface::ACCOUNT, $data->getId(), $this->customFieldService),
new CustomFieldAdapter($this->configData)
$this->getCustomFieldsForItem(
AclActionsInterface::ACCOUNT,
$accountEnrichedDto->getId(),
$this->customFieldService
),
new CustomField($this->configData)
);
}
/**
* @throws ActionNotFoundException
*/
public function transform(AccountEnrichedDto $data): array
public function transform(Dto|AccountEnrichedDto $data): array
{
$account = $data->getAccountDataView();
$actionRoute = $this->actions->getActionById(AclActionsInterface::ACCOUNT_VIEW)->getRoute();

View File

@@ -26,12 +26,13 @@ namespace SP\Domain\Account\Dtos;
use SP\DataModel\Item;
use SP\Domain\Account\Models\AccountView;
use SP\Domain\Common\Dtos\Dto;
use SP\Domain\Common\Dtos\ItemDataTrait;
/**
* Class AccountEnrichedDto
*/
class AccountEnrichedDto
class AccountEnrichedDto extends Dto
{
use ItemDataTrait;

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -22,7 +22,7 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Account\Adapters;
namespace SP\Domain\Account\Ports;
use League\Fractal\Resource\Collection;
use SP\Domain\Account\Dtos\AccountEnrichedDto;
@@ -32,9 +32,9 @@ use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Core\Exceptions\SPException;
/**
* Class AccountAdapterInterface
* Interface AccountAdapter
*/
interface AccountAdapterInterface
interface AccountAdapter
{
/**
* @throws ConstraintException
@@ -42,7 +42,7 @@ interface AccountAdapterInterface
* @throws SPException
* @throws ServiceException
*/
public function includeCustomFields(AccountEnrichedDto $data,): Collection;
public function includeCustomFields(AccountEnrichedDto $accountEnrichedDto): Collection;
public function transform(AccountEnrichedDto $data): array;
}

View File

@@ -1,141 +0,0 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Domain\Auth\Services;
use Exception;
use SP\Core\Application;
use SP\Core\Events\Event;
use SP\Core\Events\EventMessage;
use SP\Domain\Auth\Ports\AuthTokenService;
use SP\Domain\Auth\Ports\UpgradeAuthTokenService;
use SP\Domain\Common\Services\Service;
use SP\Domain\Core\Acl\AclActionsInterface;
use SP\Infrastructure\Database\DatabaseInterface;
use function SP\__u;
use function SP\processException;
/**
* Class UpgradeAuthToken
*/
final class UpgradeAuthToken extends Service implements UpgradeAuthTokenService
{
public function __construct(
Application $application,
protected readonly AuthTokenService $authTokenService,
private readonly DatabaseInterface $database
) {
parent::__construct($application);
}
/**
* upgrade_300_18072901
*
* @throws Exception
*/
public function upgradeV300B18072901(): void
{
$this->eventDispatcher->notify(
'upgrade.authToken.start',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('API authorizations update'))
->addDescription(__FUNCTION__)
)
);
try {
$this->transactionAware(
function () {
foreach ($this->authTokenService->getAll() as $item) {
$itemData = clone $item;
$itemData->setActionId($this->actionMapper($item->getActionId()));
$this->authTokenService->updateRaw($itemData);
$this->eventDispatcher->notify(
'upgrade.authToken.process',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('Authorization updated'))
->addDetail(__u('Authorization'), $item->getId())
)
);
}
},
$this->database
);
} catch (Exception $e) {
processException($e);
$this->eventDispatcher->notify('exception', new Event($e));
throw $e;
}
$this->eventDispatcher->notify(
'upgrade.authToken.end',
new Event(
$this,
EventMessage::factory()
->addDescription(__u('API authorizations update'))
->addDescription(__FUNCTION__)
)
);
}
private function actionMapper(int $moduleId): int
{
return match ($moduleId) {
1 => AclActionsInterface::ACCOUNT_SEARCH,
100 => AclActionsInterface::ACCOUNT_VIEW,
104 => AclActionsInterface::ACCOUNT_VIEW_PASS,
103 => AclActionsInterface::ACCOUNT_DELETE,
101 => AclActionsInterface::ACCOUNT_CREATE,
615 => AclActionsInterface::CATEGORY_SEARCH,
610 => AclActionsInterface::CATEGORY_VIEW,
611 => AclActionsInterface::CATEGORY_CREATE,
612 => AclActionsInterface::CATEGORY_EDIT,
613 => AclActionsInterface::CATEGORY_DELETE,
625 => AclActionsInterface::CLIENT_SEARCH,
620 => AclActionsInterface::CLIENT_VIEW,
621 => AclActionsInterface::CLIENT_CREATE,
622 => AclActionsInterface::CLIENT_EDIT,
623 => AclActionsInterface::CLIENT_DELETE,
685 => AclActionsInterface::TAG_SEARCH,
681 => AclActionsInterface::TAG_VIEW,
680 => AclActionsInterface::TAG_CREATE,
682 => AclActionsInterface::TAG_EDIT,
683 => AclActionsInterface::TAG_DELETE,
1041 => AclActionsInterface::CONFIG_BACKUP_RUN,
1061 => AclActionsInterface::CONFIG_EXPORT_RUN,
default => $moduleId,
};
}
}

View File

@@ -28,6 +28,7 @@ use League\Fractal\Resource\Collection;
use SP\Domain\Category\Models\Category as CategoryModel;
use SP\Domain\Category\Ports\CategoryAdapter;
use SP\Domain\Common\Adapters\Adapter;
use SP\Domain\Common\Models\Model;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Config\Ports\ConfigDataInterface;
use SP\Domain\Core\Acl\AclActionsInterface;
@@ -36,15 +37,13 @@ use SP\Domain\Core\Acl\ActionsInterface;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\CustomField\Adapters\CustomFieldAdapter;
use SP\Domain\CustomField\Adapters\CustomField;
use SP\Domain\CustomField\Ports\CustomFieldDataService;
use SP\Mvc\Controller\ItemTrait;
use SP\Util\Link;
/**
* Class CategoryAdapter
*
* @package SP\Adapters
* Class Category
*/
final class Category extends Adapter implements CategoryAdapter
{
@@ -70,14 +69,14 @@ final class Category extends Adapter implements CategoryAdapter
{
return $this->collection(
$this->getCustomFieldsForItem(AclActionsInterface::CATEGORY, $data->id, $this->customFieldService),
new CustomFieldAdapter($this->configData)
new CustomField($this->configData)
);
}
/**
* @throws ActionNotFoundException
*/
public function transform(CategoryModel $data): array
public function transform(Model|CategoryModel $data): array
{
$actionRoute = $this->actions->getActionById(AclActionsInterface::CATEGORY_VIEW)->getRoute();

View File

@@ -25,25 +25,24 @@
namespace SP\Domain\Client\Adapters;
use League\Fractal\Resource\Collection;
use SP\Domain\Client\Models\Client;
use SP\Domain\Client\Ports\ClientAdapterInterface;
use SP\Domain\Client\Models\Client as ClientModel;
use SP\Domain\Client\Ports\ClientAdapter;
use SP\Domain\Common\Adapters\Adapter;
use SP\Domain\Common\Models\Model;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Core\Acl\AclActionsInterface;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Core\Exceptions\SPException;
use SP\Domain\CustomField\Adapters\CustomFieldAdapter;
use SP\Domain\CustomField\Adapters\CustomField;
use SP\Domain\CustomField\Ports\CustomFieldDataService;
use SP\Mvc\Controller\ItemTrait;
use SP\Util\Link;
/**
* Class ClientAdapter
*
* @package SP\Adapters
* Class Client
*/
final class ClientAdapter extends Adapter implements ClientAdapterInterface
final class Client extends Adapter implements ClientAdapter
{
use ItemTrait;
@@ -55,15 +54,15 @@ final class ClientAdapter extends Adapter implements ClientAdapterInterface
* @throws SPException
* @throws ServiceException
*/
public function includeCustomFields(Client $data, CustomFieldDataService $customFieldService): Collection
public function includeCustomFields(ClientModel $client, CustomFieldDataService $customFieldService): Collection
{
return $this->collection(
$this->getCustomFieldsForItem(AclActionsInterface::CLIENT, $data->id, $customFieldService),
new CustomFieldAdapter($this->configData)
$this->getCustomFieldsForItem(AclActionsInterface::CLIENT, $client->getId(), $customFieldService),
new CustomField($this->configData)
);
}
public function transform(Client $data): array
public function transform(Model|ClientModel $data): array
{
return [
'id' => $data->getId(),

View File

@@ -37,7 +37,7 @@ use SP\Domain\CustomField\Ports\CustomFieldDataService;
*
* @package SP\Adapters
*/
interface ClientAdapterInterface
interface ClientAdapter
{
/**
* @throws ConstraintException
@@ -45,7 +45,7 @@ interface ClientAdapterInterface
* @throws SPException
* @throws ServiceException
*/
public function includeCustomFields(Client $data, CustomFieldDataService $customFieldService): Collection;
public function includeCustomFields(Client $client, CustomFieldDataService $customFieldService): Collection;
public function transform(Client $data): array;
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -25,24 +25,18 @@
namespace SP\Domain\Common\Adapters;
use League\Fractal\TransformerAbstract;
use RuntimeException;
use SP\Domain\Common\Dtos\Dto;
use SP\Domain\Common\Models\Model;
use SP\Domain\Config\Ports\ConfigDataInterface;
/**
* Class AdapterBase
*
* @package SP\Adapters
* Class Adapter
*/
abstract class Adapter extends TransformerAbstract
{
protected ConfigDataInterface $configData;
public function __construct(ConfigDataInterface $configData)
public function __construct(protected readonly ConfigDataInterface $configData)
{
$this->configData = $configData;
if (!method_exists(static::class, 'transform')) {
throw new RuntimeException('\'transform\' method must be implemented');
}
}
abstract public function transform(Model&Dto $data);
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,15 +24,26 @@
namespace SP\Domain\CustomField\Adapters;
use SP\Domain\Common\Adapters\Adapter;
use SP\Domain\Common\Dtos\Dto;
use SP\Domain\CustomField\Services\CustomFieldItem;
/**
* Class CustomFieldAdapter
*
* @package SP\Adapters
*/
interface CustomFieldAdapterInterface
final class CustomField extends Adapter implements CustomFieldAdapter
{
public function transform(CustomFieldItem $data): array;
public function transform(Dto|CustomFieldItem $data): array
{
return [
'type' => $data->typeName,
'typeText' => $data->typeText,
'definitionId' => $data->definitionId,
'definitionName' => $data->definitionName,
'help' => $data->help,
'value' => $data->value,
'encrypted' => $data->isEncrypted,
'required' => $data->required,
];
}
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -24,27 +24,12 @@
namespace SP\Domain\CustomField\Adapters;
use SP\Domain\Common\Adapters\Adapter;
use SP\Domain\CustomField\Services\CustomFieldItem;
/**
* Class CustomFieldAdapter
*
* @package SP\Adapters
*/
final class CustomFieldAdapter extends Adapter implements CustomFieldAdapterInterface
interface CustomFieldAdapter
{
public function transform(CustomFieldItem $data): array
{
return [
'type' => $data->typeName,
'typeText' => $data->typeText,
'definitionId' => $data->definitionId,
'definitionName' => $data->definitionName,
'help' => $data->help,
'value' => $data->value,
'encrypted' => $data->isEncrypted,
'required' => $data->required,
];
}
public function transform(CustomFieldItem $data): array;
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2022, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -25,27 +25,30 @@
namespace SP\Domain\CustomField\Services;
use JsonSerializable;
use SP\Domain\Common\Dtos\Dto;
/**
* Class CustomFieldItem
*
* @package SP\Domain\CustomField\Services
*/
final class CustomFieldItem implements JsonSerializable
final class CustomFieldItem extends Dto implements JsonSerializable
{
public $required = false;
public $showInList = false;
public $help;
public $definitionId = 0;
public $definitionName;
public $typeId = 0;
public $typeName;
public $typeText;
public $moduleId = 0;
public $formId;
public $value;
public $isEncrypted;
public $isValueEncrypted;
public function __construct(
public readonly bool $required,
public readonly bool $showInList,
public readonly string $help,
public readonly int $definitionId,
public readonly string $definitionName,
public readonly int $typeId,
public readonly string $typeName,
public readonly string $typeText,
public readonly int $moduleId,
public readonly string $formId,
public readonly mixed $value,
public readonly bool $isEncrypted,
public readonly bool $isValueEncrypted
) {
}
/**
* @inheritDoc
@@ -53,15 +56,15 @@ final class CustomFieldItem implements JsonSerializable
public function jsonSerialize(): array
{
return [
'required' => $this->required,
'showInList' => $this->showInList,
'help' => $this->help,
'typeId' => $this->typeId,
'typeName' => $this->typeName,
'typeText' => $this->typeText,
'moduleId' => $this->moduleId,
'value' => $this->value,
'isEncrypted' => $this->isEncrypted,
'required' => $this->required,
'showInList' => $this->showInList,
'help' => $this->help,
'typeId' => $this->typeId,
'typeName' => $this->typeName,
'typeText' => $this->typeText,
'moduleId' => $this->moduleId,
'value' => $this->value,
'isEncrypted' => $this->isEncrypted,
'isValueEncrypted' => $this->isValueEncrypted,
];
}

View File

@@ -29,7 +29,7 @@ use SP\Domain\Core\Events\EventReceiver;
/**
* Interface PluginInterface
*/
interface PluginInterface extends EventReceiver
interface Plugin extends EventReceiver
{
/**
* Devuelve el directorio base del plugin

View File

@@ -34,12 +34,12 @@ use SP\Infrastructure\Common\Repositories\NoSuchItemException;
interface PluginCompatilityService
{
/**
* @param PluginInterface $plugin
* @param Plugin $plugin
*
* @return bool
* @throws ConstraintException
* @throws NoSuchItemException
* @throws QueryException
*/
public function checkFor(PluginInterface $plugin): bool;
public function checkFor(Plugin $plugin): bool;
}

View File

@@ -29,5 +29,5 @@ namespace SP\Domain\Plugin\Ports;
*/
interface PluginLoaderService
{
public function loadFor(PluginInterface $plugin): void;
public function loadFor(Plugin $plugin): void;
}

View File

@@ -29,5 +29,5 @@ namespace SP\Domain\Plugin\Ports;
*/
interface PluginRegisterService
{
public function registerFor(PluginInterface $plugin): void;
public function registerFor(Plugin $plugin): void;
}

View File

@@ -4,7 +4,7 @@
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2023, Rubén Domínguez nuxsmin@$syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
@@ -29,5 +29,5 @@ namespace SP\Domain\Plugin\Ports;
*/
interface PluginUpgraderInterface
{
public function upgradeFor(PluginInterface $plugin, string $version): void;
public function upgradeFor(Plugin $plugin, string $version): void;
}

View File

@@ -22,15 +22,15 @@
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SP\Plugin;
namespace SP\Domain\Plugin\Services;
use Defuse\Crypto\Exception\CryptoException;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\NoSuchPropertyException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginCompatilityService;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\PluginLoaderService;
use SP\Domain\Plugin\Ports\PluginOperationInterface;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -38,11 +38,11 @@ use SP\Infrastructure\Common\Repositories\NoSuchItemException;
/**
* Class PluginBase
*/
abstract class PluginBase implements PluginInterface
abstract class PluginBase implements Plugin
{
protected ?string $base = null;
protected ?string $themeDir = null;
protected mixed $data;
protected mixed $data = null;
/**
* @throws ConstraintException
@@ -52,7 +52,7 @@ abstract class PluginBase implements PluginInterface
public function __construct(
protected readonly PluginOperationInterface $pluginOperation,
private readonly PluginCompatilityService $pluginCompatilityService,
private readonly PluginLoaderService $pluginLoadService
private readonly PluginLoaderService $pluginLoaderService
) {
$this->load();
}
@@ -65,7 +65,7 @@ abstract class PluginBase implements PluginInterface
private function load(): void
{
if ($this->pluginCompatilityService->checkFor($this)) {
$this->pluginLoadService->loadFor($this);
$this->pluginLoaderService->loadFor($this);
}
}

View File

@@ -31,8 +31,8 @@ use SP\Domain\Common\Services\Service;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Install\Services\InstallerService;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginCompatilityService;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -52,14 +52,14 @@ final class PluginCompatility extends Service implements PluginCompatilityServic
}
/**
* @param PluginInterface $plugin
* @param Plugin $plugin
*
* @return bool
* @throws ConstraintException
* @throws NoSuchItemException
* @throws QueryException
*/
public function checkFor(PluginInterface $plugin): bool
public function checkFor(Plugin $plugin): bool
{
$pluginVersion = implode('.', $plugin->getCompatibleVersion());
$appVersion = implode('.', array_slice(InstallerService::VERSION, 0, 2));

View File

@@ -30,7 +30,7 @@ use SP\Core\Events\EventMessage;
use SP\Domain\Common\Services\Service;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginLoaderService;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -51,7 +51,7 @@ final class PluginLoader extends Service implements PluginLoaderService
* @throws ConstraintException
* @throws QueryException
*/
public function loadFor(PluginInterface $plugin): void
public function loadFor(Plugin $plugin): void
{
try {
$model = $this->pluginManagerService->getByName($plugin->getName());

View File

@@ -31,7 +31,7 @@ use SP\Domain\Common\Services\Service;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Models\Plugin as PluginModel;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Ports\PluginRegisterService;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -52,7 +52,7 @@ final class PluginRegister extends Service implements PluginRegisterService
* @throws ConstraintException
* @throws QueryException
*/
public function registerFor(PluginInterface $plugin): void
public function registerFor(Plugin $plugin): void
{
try {
$this->pluginManagerService->getByName($plugin->getName());
@@ -85,7 +85,7 @@ final class PluginRegister extends Service implements PluginRegisterService
* @throws ConstraintException
* @throws QueryException
*/
private function register(PluginInterface $plugin): void
private function register(Plugin $plugin): void
{
$this->pluginManagerService->create(new PluginModel(['name' => $plugin->getName(), 'enabled' => false]));

View File

@@ -30,7 +30,7 @@ use SP\Core\Events\EventMessage;
use SP\Domain\Common\Services\Service;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Ports\PluginUpgraderInterface;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -52,12 +52,12 @@ final class PluginUpgrader extends Service implements PluginUpgraderInterface
}
/**
* @param PluginInterface $plugin
* @param Plugin $plugin
* @param string $version
* @throws ConstraintException
* @throws QueryException
*/
public function upgradeFor(PluginInterface $plugin, string $version): void
public function upgradeFor(Plugin $plugin, string $version): void
{
try {
$pluginModel = $this->pluginManagerService->getByName($plugin->getName());

View File

@@ -52,28 +52,26 @@ trait ItemTrait
$customFields = [];
foreach ($customFieldDataService->getBy($moduleId, $itemId) as $item) {
$customField = new CustomFieldItem();
$customField->required = (bool)$item['required'];
$customField->showInList = (bool)$item['showInList'];
$customField->help = $item['help'];
$customField->definitionId = (int)$item['definitionId'];
$customField->definitionName = $item['definitionName'];
$customField->typeId = (int)$item['typeId'];
$customField->typeName = $item['typeName'];
$customField->typeText = $item['typeText'];
$customField->moduleId = (int)$item['moduleId'];
$customField->formId = self::getFormIdForName($item['definitionName']);
$customField->isEncrypted = (int)$item['isEncrypted'];
$valueEncrypted = !empty($item['data']) && !empty($item['key']);
$value = $valueEncrypted
? self::formatValue($customFieldDataService->decrypt($item['data'], $item['key']) ?? '')
: $item['data'];
if (!empty($item['data']) && !empty($item['key'])) {
$customField->isValueEncrypted = true;
$customField->value = self::formatValue(
$customFieldDataService->decrypt($item['data'], $item['key']) ?? ''
);
} else {
$customField->isValueEncrypted = false;
$customField->value = $item['data'];
}
$customField = new CustomFieldItem(
required: (bool)$item['required'],
showInList: (bool)$item['showInList'],
help: $item['help'],
definitionId: (int)$item['definitionId'],
definitionName: $item['definitionName'],
typeId: (int)$item['typeId'],
typeName: $item['typeName'],
typeText: $item['typeText'],
moduleId: (int)$item['moduleId'],
formId: self::getFormIdForName($item['definitionName']),
value: $value,
isEncrypted: (int)$item['isEncrypted'],
isValueEncrypted: $valueEncrypted
);
$customFields[] = $customField;
}
@@ -81,14 +79,6 @@ trait ItemTrait
return $customFields;
}
/**
* Returns the form Id for a given name
*/
private static function getFormIdForName(string $name): string
{
return sprintf('cf_%s', strtolower(preg_replace('/\W*/', '', $name)));
}
/**
* Formatear el valor del campo
*
@@ -105,6 +95,14 @@ trait ItemTrait
return $value;
}
/**
* Returns the form Id for a given name
*/
private static function getFormIdForName(string $name): string
{
return sprintf('cf_%s', strtolower(preg_replace('/\W*/', '', $name)));
}
/**
* Añadir los campos personalizados del elemento
*

View File

@@ -29,7 +29,7 @@ use League\Fractal\Resource\Item;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\Exception;
use SP\DataModel\Action;
use SP\Domain\Account\Adapters\AccountAdapter;
use SP\Domain\Account\Adapters\Account;
use SP\Domain\Core\Acl\AclActionsInterface;
use SP\Domain\Core\Acl\ActionNotFoundException;
use SP\Domain\Core\Acl\ActionsInterface;
@@ -66,7 +66,7 @@ class AccountAdapterTest extends UnitaryTestCase
)
);
$adapter = new AccountAdapter(
$adapter = new Account(
$this->config->getConfigData(),
$this->createStub(CustomFieldDataService::class),
$actions
@@ -150,7 +150,7 @@ class AccountAdapterTest extends UnitaryTestCase
);
$adapter = new AccountAdapter($this->config->getConfigData(), $customFieldsService, $actions);
$adapter = new Account($this->config->getConfigData(), $customFieldsService, $actions);
$fractal = new Manager();
$fractal->parseIncludes('customFields');

View File

@@ -0,0 +1,185 @@
<?php
/*
* sysPass
*
* @author nuxsmin
* @link https://syspass.org
* @copyright 2012-2024, Rubén Domínguez nuxsmin@$syspass.org
*
* This file is part of sysPass.
*
* sysPass is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* sysPass is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with sysPass. If not, see <http://www.gnu.org/licenses/>.
*/
namespace SPT\Domain\Plugin\Services;
use Defuse\Crypto\Exception\CryptoException;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Core\Events\Event;
use SP\Domain\Common\Services\ServiceException;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\NoSuchPropertyException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\PluginCompatilityService;
use SP\Domain\Plugin\Ports\PluginLoaderService;
use SP\Domain\Plugin\Ports\PluginOperationInterface;
use SP\Domain\Plugin\Services\PluginBase;
use SPT\UnitaryTestCase;
/**
* Class PluginBaseTest
*/
#[Group('unitary')]
class PluginBaseTest extends UnitaryTestCase
{
private PluginBase $pluginBase;
private PluginOperationInterface|MockObject $pluginOperation;
private PluginCompatilityService|MockObject $pluginCompatilityService;
private PluginLoaderService|MockObject $pluginLoaderService;
public function testGetThemeDir()
{
$this->assertNull($this->pluginBase->getThemeDir());
}
public function testGetBase()
{
$this->assertNull($this->pluginBase->getBase());
}
public function testGetData()
{
$this->assertNull($this->pluginBase->getData());
}
/**
* @throws ServiceException
* @throws ConstraintException
* @throws NoSuchPropertyException
* @throws CryptoException
* @throws QueryException
*/
public function testSaveData()
{
$data = (object)['a' => 'test', 'b' => ['test']];
$this->pluginOperation
->expects($this->once())
->method('create')
->with(100, $data);
$this->pluginBase->saveData(100, $data);
$this->assertEquals($data, $this->pluginBase->getData());
}
/**
* @throws ServiceException
* @throws ConstraintException
* @throws NoSuchPropertyException
* @throws CryptoException
* @throws QueryException
*/
public function testSaveDataWithUpdate()
{
$dataCreate = (object)['a' => 'test', 'b' => ['test']];
$this->pluginOperation
->expects($this->once())
->method('create')
->with(100, $dataCreate);
$this->pluginBase->saveData(100, $dataCreate);
$dataUpdate = (object)['c' => 'test', 'd' => ['test']];
$this->pluginOperation
->expects($this->once())
->method('update')
->with(100, $dataUpdate);
$this->pluginBase->saveData(100, $dataUpdate);
$this->assertEquals($dataUpdate, $this->pluginBase->getData());
}
protected function setUp(): void
{
parent::setUp();
$this->pluginOperation = $this->createMock(PluginOperationInterface::class);
$this->pluginCompatilityService = $this->createMock(PluginCompatilityService::class);
$this->pluginLoaderService = $this->createMock(PluginLoaderService::class);
$this->pluginCompatilityService
->expects($this->once())
->method('checkFor')
->with(self::isInstanceOf(PluginBase::class))
->willReturn(true);
$this->pluginLoaderService
->expects($this->once())
->method('loadFor')
->with(self::isInstanceOf(PluginBase::class));
$this->pluginBase = new class(
$this->pluginOperation,
$this->pluginCompatilityService,
$this->pluginLoaderService
) extends PluginBase {
public function update(string $eventType, Event $event): void
{
// TODO: Implement update() method.
}
public function getEventsString(): ?string
{
// TODO: Implement getEventsString() method.
}
public function getAuthor(): ?string
{
// TODO: Implement getAuthor() method.
}
public function getVersion(): ?array
{
// TODO: Implement getVersion() method.
}
public function getCompatibleVersion(): ?array
{
// TODO: Implement getCompatibleVersion() method.
}
public function getName(): ?string
{
// TODO: Implement getName() method.
}
public function onLoad()
{
// TODO: Implement onLoad() method.
}
public function onUpgrade(string $version)
{
// TODO: Implement onUpgrade() method.
}
};
}
}

View File

@@ -29,7 +29,7 @@ use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Services\PluginCompatility;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -53,7 +53,7 @@ class PluginCompatilityTest extends UnitaryTestCase
*/
public function testCheckForWithCompatible()
{
$plugin = $this->createMock(PluginInterface::class);
$plugin = $this->createMock(Plugin::class);
$plugin->expects($this->once())
->method('getCompatibleVersion')
@@ -76,7 +76,7 @@ class PluginCompatilityTest extends UnitaryTestCase
*/
public function testCheckForWithNoCompatible()
{
$plugin = $this->createMock(PluginInterface::class);
$plugin = $this->createMock(Plugin::class);
$plugin->expects($this->once())
->method('getCompatibleVersion')

View File

@@ -29,7 +29,7 @@ use PHPUnit\Framework\MockObject\Exception;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Models\Plugin;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Services\PluginLoader;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -49,7 +49,7 @@ class PluginLoaderTest extends UnitaryTestCase
public function testLoadForWithEnabled()
{
$pluginManagerService = $this->createMock(PluginManagerService::class);
$plugin = $this->createStub(PluginInterface::class);
$plugin = $this->createStub(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginModel = new Plugin(['enabled' => true]);
@@ -72,7 +72,7 @@ class PluginLoaderTest extends UnitaryTestCase
public function testLoadForWithDisabled()
{
$pluginManagerService = $this->createMock(PluginManagerService::class);
$plugin = $this->createStub(PluginInterface::class);
$plugin = $this->createStub(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginModel = new Plugin(['enabled' => false]);
@@ -95,7 +95,7 @@ class PluginLoaderTest extends UnitaryTestCase
public function testLoadForWithException()
{
$pluginManagerService = $this->createMock(PluginManagerService::class);
$plugin = $this->createStub(PluginInterface::class);
$plugin = $this->createStub(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService

View File

@@ -29,7 +29,7 @@ use PHPUnit\Framework\MockObject\Exception;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Models\Plugin;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Services\PluginRegister;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -49,7 +49,7 @@ class PluginRegisterTest extends UnitaryTestCase
*/
public function testRegisterForWithUnregisteredPlugin()
{
$plugin = $this->createStub(PluginInterface::class);
$plugin = $this->createStub(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService = $this->createMock(PluginManagerService::class);
@@ -74,7 +74,7 @@ class PluginRegisterTest extends UnitaryTestCase
*/
public function testRegisterForWithRegisteredPlugin()
{
$plugin = $this->createStub(PluginInterface::class);
$plugin = $this->createStub(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService = $this->createMock(PluginManagerService::class);

View File

@@ -28,7 +28,7 @@ use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\Exception;
use SP\Domain\Core\Exceptions\ConstraintException;
use SP\Domain\Core\Exceptions\QueryException;
use SP\Domain\Plugin\Ports\PluginInterface;
use SP\Domain\Plugin\Ports\Plugin;
use SP\Domain\Plugin\Ports\PluginManagerService;
use SP\Domain\Plugin\Services\PluginUpgrader;
use SP\Infrastructure\Common\Repositories\NoSuchItemException;
@@ -55,7 +55,7 @@ class PluginUpgraderTest extends UnitaryTestCase
$pluginUpgrader = new PluginUpgrader($this->application, $pluginManagerService);
$plugin = self::createMock(PluginInterface::class);
$plugin = self::createMock(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService->expects($this->once())
@@ -90,7 +90,7 @@ class PluginUpgraderTest extends UnitaryTestCase
$pluginUpgrader = new PluginUpgrader($this->application, $pluginManagerService);
$plugin = self::createMock(PluginInterface::class);
$plugin = self::createMock(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService->expects($this->once())
@@ -123,7 +123,7 @@ class PluginUpgraderTest extends UnitaryTestCase
$pluginUpgrader = new PluginUpgrader($this->application, $pluginManagerService);
$plugin = self::createMock(PluginInterface::class);
$plugin = self::createMock(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService->expects($this->once())
@@ -152,7 +152,7 @@ class PluginUpgraderTest extends UnitaryTestCase
$pluginUpgrader = new PluginUpgrader($this->application, $pluginManagerService);
$plugin = self::createMock(PluginInterface::class);
$plugin = self::createMock(Plugin::class);
$plugin->method('getName')->willReturn('test_plugin');
$pluginManagerService->expects($this->once())