Compare commits
9 commits
Author | SHA1 | Date | |
---|---|---|---|
|
a06ec22341 | ||
|
f15d9a2a86 | ||
|
a104eebf2a | ||
|
3f87618424 | ||
|
5520c4ca68 | ||
|
ac0a1ae95d | ||
|
d9dca7b78b | ||
|
1e99455b65 | ||
|
7516ec60cb |
39 changed files with 1441 additions and 178 deletions
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace RetailCrm\ServiceBundle\ArgumentResolver;
|
namespace RetailCrm\ServiceBundle\ArgumentResolver;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\Adapter;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
|
||||||
use Generator;
|
use Generator;
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ class CallbackValueResolver extends AbstractValueResolver implements ArgumentVal
|
||||||
/**
|
/**
|
||||||
* CallbackValueResolver constructor.
|
* CallbackValueResolver constructor.
|
||||||
*
|
*
|
||||||
* @param SerializerInterface $serializer
|
* @param Adapter $serializer
|
||||||
* @param ValidatorInterface $validator
|
* @param ValidatorInterface $validator
|
||||||
* @param array $requestSchema
|
* @param array $requestSchema
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
SerializerInterface $serializer,
|
Adapter $serializer,
|
||||||
ValidatorInterface $validator,
|
ValidatorInterface $validator,
|
||||||
array $requestSchema
|
array $requestSchema
|
||||||
) {
|
) {
|
||||||
|
@ -55,7 +55,7 @@ class CallbackValueResolver extends AbstractValueResolver implements ArgumentVal
|
||||||
public function resolve(Request $request, ArgumentMetadata $argument): Generator
|
public function resolve(Request $request, ArgumentMetadata $argument): Generator
|
||||||
{
|
{
|
||||||
$parameter = $this->search($request, $argument);
|
$parameter = $this->search($request, $argument);
|
||||||
$data = $this->serializer->deserialize($request->request->get($parameter), $argument->getType(), 'json');
|
$data = $this->serializer->deserialize($request->request->get($parameter), $argument->getType());
|
||||||
$this->validate($data);
|
$this->validate($data);
|
||||||
|
|
||||||
yield $data;
|
yield $data;
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
|
|
||||||
namespace RetailCrm\ServiceBundle\ArgumentResolver;
|
namespace RetailCrm\ServiceBundle\ArgumentResolver;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\Adapter;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||||
use Symfony\Component\Serializer\Exception\ExceptionInterface;
|
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
|
||||||
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
use Symfony\Component\Validator\Validator\ValidatorInterface;
|
||||||
use Generator;
|
use Generator;
|
||||||
|
|
||||||
|
@ -19,27 +17,24 @@ use Generator;
|
||||||
class ClientValueResolver extends AbstractValueResolver implements ArgumentValueResolverInterface
|
class ClientValueResolver extends AbstractValueResolver implements ArgumentValueResolverInterface
|
||||||
{
|
{
|
||||||
private $serializer;
|
private $serializer;
|
||||||
private $denormalizer;
|
|
||||||
private $requestSchema;
|
private $requestSchema;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ClientValueResolver constructor.
|
* ClientValueResolver constructor.
|
||||||
*
|
*
|
||||||
|
*
|
||||||
|
* @param Adapter $serializer
|
||||||
* @param ValidatorInterface $validator
|
* @param ValidatorInterface $validator
|
||||||
* @param SerializerInterface $serializer
|
|
||||||
* @param DenormalizerInterface $denormalizer
|
|
||||||
* @param array $requestSchema
|
* @param array $requestSchema
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
Adapter $serializer,
|
||||||
ValidatorInterface $validator,
|
ValidatorInterface $validator,
|
||||||
SerializerInterface $serializer,
|
|
||||||
DenormalizerInterface $denormalizer,
|
|
||||||
array $requestSchema
|
array $requestSchema
|
||||||
) {
|
) {
|
||||||
parent::__construct($validator);
|
parent::__construct($validator);
|
||||||
|
|
||||||
$this->serializer = $serializer;
|
$this->serializer = $serializer;
|
||||||
$this->denormalizer = $denormalizer;
|
|
||||||
$this->requestSchema = $requestSchema;
|
$this->requestSchema = $requestSchema;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,12 +67,10 @@ class ClientValueResolver extends AbstractValueResolver implements ArgumentValue
|
||||||
* @param string $type
|
* @param string $type
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*
|
|
||||||
* @throws ExceptionInterface
|
|
||||||
*/
|
*/
|
||||||
private function handleGetData(array $data, string $type): object
|
private function handleGetData(array $data, string $type): object
|
||||||
{
|
{
|
||||||
return $this->denormalizer->denormalize($data, $type);
|
return $this->serializer->arrayToObject($data, $type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,6 +81,6 @@ class ClientValueResolver extends AbstractValueResolver implements ArgumentValue
|
||||||
*/
|
*/
|
||||||
private function handlePostData(string $data, string $type): object
|
private function handlePostData(string $data, string $type): object
|
||||||
{
|
{
|
||||||
return $this->serializer->deserialize($data, $type, 'json');
|
return $this->serializer->deserialize($data, $type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Configuration implements ConfigurationInterface
|
||||||
->arrayNode('request_schema')
|
->arrayNode('request_schema')
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('callback')
|
->arrayNode('callback')
|
||||||
|
->children()
|
||||||
|
->arrayNode('supports')
|
||||||
->arrayPrototype()
|
->arrayPrototype()
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('type')->isRequired()->end()
|
->scalarNode('type')->isRequired()->end()
|
||||||
|
@ -34,9 +36,27 @@ class Configuration implements ConfigurationInterface
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
|
->scalarNode('serializer')
|
||||||
|
->defaultValue('retail_crm_service.symfony_serializer.adapter')
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
->arrayNode('client')
|
->arrayNode('client')
|
||||||
|
->children()
|
||||||
|
->arrayNode('supports')
|
||||||
->scalarPrototype()->end()
|
->scalarPrototype()->end()
|
||||||
->end()
|
->end()
|
||||||
|
->scalarNode('serializer')
|
||||||
|
->defaultValue('retail_crm_service.symfony_serializer.adapter')
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->end()
|
||||||
|
->arrayNode('messenger')
|
||||||
|
->children()
|
||||||
|
->scalarNode('message_handler')->isRequired()->defaultValue('simple_console_runner')->end()
|
||||||
|
->scalarNode('process_timeout')->end()
|
||||||
->end()
|
->end()
|
||||||
->end()
|
->end()
|
||||||
->end();
|
->end();
|
||||||
|
|
|
@ -4,11 +4,15 @@ namespace RetailCrm\ServiceBundle\DependencyInjection;
|
||||||
|
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\JMSSerializerAdapter;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\SymfonySerializerAdapter;
|
||||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||||
|
use Symfony\Component\DependencyInjection\Reference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RetailCrmServiceExtension
|
* Class RetailCrmServiceExtension
|
||||||
|
@ -27,24 +31,64 @@ class RetailCrmServiceExtension extends Extension
|
||||||
$config = $this->processConfiguration($configuration, $configs);
|
$config = $this->processConfiguration($configuration, $configs);
|
||||||
|
|
||||||
$container->setParameter(
|
$container->setParameter(
|
||||||
'retail_crm_service.request_schema.callback',
|
'retail_crm_service.request_schema.callback.supports',
|
||||||
$config['request_schema']['callback']
|
$config['request_schema']['callback']['supports']
|
||||||
);
|
);
|
||||||
|
|
||||||
$container->setParameter(
|
$container->setParameter(
|
||||||
'retail_crm_service.request_schema.client',
|
'retail_crm_service.request_schema.client.supports',
|
||||||
$config['request_schema']['client']
|
$config['request_schema']['client']['supports']
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.request_schema.callback.serializer',
|
||||||
|
$config['request_schema']['callback']['serializer']
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.request_schema.client.serializer',
|
||||||
|
$config['request_schema']['client']['serializer']
|
||||||
|
);
|
||||||
|
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.messenger.message_handler',
|
||||||
|
$config['messenger']['message_handler']
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($config['messenger']['process_timeout'])) {
|
||||||
|
$container->setParameter(
|
||||||
|
'retail_crm_service.messenger.process_timeout',
|
||||||
|
$config['messenger']['process_timeout']
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(SymfonySerializerAdapter::class)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('retail_crm_service.symfony_serializer.adapter', SymfonySerializerAdapter::class);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(JMSSerializerAdapter::class)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('retail_crm_service.jms_serializer.adapter', JMSSerializerAdapter::class);
|
||||||
|
|
||||||
$container
|
$container
|
||||||
->register(CallbackValueResolver::class)
|
->register(CallbackValueResolver::class)
|
||||||
->setArgument('$requestSchema', '%retail_crm_service.request_schema.callback%')
|
->setArguments([
|
||||||
|
new Reference($container->getParameter('retail_crm_service.request_schema.callback.serializer')),
|
||||||
|
new Reference('validator'),
|
||||||
|
$container->getParameter('retail_crm_service.request_schema.callback.supports')
|
||||||
|
])
|
||||||
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
||||||
->setAutowired(true);
|
->setAutowired(true);
|
||||||
|
|
||||||
$container
|
$container
|
||||||
->register(ClientValueResolver::class)
|
->register(ClientValueResolver::class)
|
||||||
->setArgument('$requestSchema', '%retail_crm_service.request_schema.client%')
|
->setArguments([
|
||||||
|
new Reference($container->getParameter('retail_crm_service.request_schema.client.serializer')),
|
||||||
|
new Reference('validator'),
|
||||||
|
$container->getParameter('retail_crm_service.request_schema.client.supports')
|
||||||
|
])
|
||||||
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
->addTag('controller.argument_value_resolver', ['priority' => 50])
|
||||||
->setAutowired(true);
|
->setAutowired(true);
|
||||||
|
|
||||||
|
@ -59,5 +103,28 @@ class RetailCrmServiceExtension extends Extension
|
||||||
$container
|
$container
|
||||||
->register(FrontApiClientAuthenticator::class)
|
->register(FrontApiClientAuthenticator::class)
|
||||||
->setAutowired(true);
|
->setAutowired(true);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler\SimpleConsoleRunner::class)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('simple_console_runner', MessageHandler\SimpleConsoleRunner::class);
|
||||||
|
|
||||||
|
$timeout = $container->hasParameter('retail_crm_service.messenger.process_timeout')
|
||||||
|
? $container->getParameter('retail_crm_service.messenger.process_timeout')
|
||||||
|
: null;
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler\InNewProcessRunner::class)
|
||||||
|
->setArgument('$timeout', $timeout)
|
||||||
|
->setAutowired(true);
|
||||||
|
$container->setAlias('in_new_process_runner', MessageHandler\InNewProcessRunner::class);
|
||||||
|
|
||||||
|
$container
|
||||||
|
->register(MessageHandler::class)
|
||||||
|
->addTag('messenger.message_handler')
|
||||||
|
->setArguments([
|
||||||
|
new Reference($container->getParameter('retail_crm_service.messenger.message_handler'))
|
||||||
|
])
|
||||||
|
->setAutowired(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
113
Messenger/CommandMessage.php
Normal file
113
Messenger/CommandMessage.php
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Message
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger
|
||||||
|
*/
|
||||||
|
abstract class CommandMessage
|
||||||
|
{
|
||||||
|
/** @var string */
|
||||||
|
protected $commandName;
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $options = [];
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
protected $arguments = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getCommandName(): string
|
||||||
|
{
|
||||||
|
return $this->commandName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $commandName
|
||||||
|
*/
|
||||||
|
public function setCommandName(string $commandName): void
|
||||||
|
{
|
||||||
|
$this->commandName = $commandName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getOptions(): array
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $options
|
||||||
|
*/
|
||||||
|
public function setOptions(array $options): void
|
||||||
|
{
|
||||||
|
$this->options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getArguments(): array
|
||||||
|
{
|
||||||
|
return $this->arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $arguments
|
||||||
|
*/
|
||||||
|
public function setArguments(array $arguments): void
|
||||||
|
{
|
||||||
|
$this->arguments = $arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function addOption(string $key, string $value): void
|
||||||
|
{
|
||||||
|
$this->options[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function addArgument(string $key, string $value): void
|
||||||
|
{
|
||||||
|
$this->arguments[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getFormattedOptions(): array
|
||||||
|
{
|
||||||
|
$options = [];
|
||||||
|
foreach ($this->options as $option => $value) {
|
||||||
|
$options['--' . $option] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For lockable message
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function __serialize(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'commandName' => $this->getCommandName(),
|
||||||
|
'arguments' => $this->getArguments(),
|
||||||
|
'options' => $this->getOptions()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
40
Messenger/MessageHandler.php
Normal file
40
Messenger/MessageHandler.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\JobRunner;
|
||||||
|
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MessageHandler
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger
|
||||||
|
*/
|
||||||
|
class MessageHandler implements MessageHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var JobRunner
|
||||||
|
*/
|
||||||
|
private $runner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param JobRunner $runner
|
||||||
|
*/
|
||||||
|
public function __construct(JobRunner $runner)
|
||||||
|
{
|
||||||
|
$this->runner = $runner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function __invoke(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$this->runner->run($message);
|
||||||
|
}
|
||||||
|
}
|
109
Messenger/MessageHandler/InNewProcessRunner.php
Normal file
109
Messenger/MessageHandler/InNewProcessRunner.php
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
use Symfony\Component\Process\Exception\ProcessTimedOutException;
|
||||||
|
use Symfony\Component\Process\PhpExecutableFinder;
|
||||||
|
use Symfony\Component\Process\Process;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InNewProcessRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class InNewProcessRunner implements JobRunner
|
||||||
|
{
|
||||||
|
/** @var int Default timeout for process */
|
||||||
|
public const DEFAULT_TIMEOUT = 3600;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var KernelInterface
|
||||||
|
*/
|
||||||
|
private $kernel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $timeout = self::DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @param KernelInterface $kernel
|
||||||
|
* @param int|null $timeout
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
LoggerInterface $logger,
|
||||||
|
KernelInterface $kernel,
|
||||||
|
?int $timeout = null
|
||||||
|
) {
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->kernel = $kernel;
|
||||||
|
|
||||||
|
if (null !== $timeout) {
|
||||||
|
$this->timeout = $timeout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$phpBinaryPath = (new PhpExecutableFinder)->find();
|
||||||
|
$consoleCommand = [
|
||||||
|
'php' => $phpBinaryPath ?: 'php',
|
||||||
|
'console' => sprintf('%s/bin/console', $this->kernel->getContainer()->getParameter('kernel.project_dir')),
|
||||||
|
'command' => $message->getCommandName()
|
||||||
|
];
|
||||||
|
|
||||||
|
$process = new Process(
|
||||||
|
array_merge(
|
||||||
|
array_values($consoleCommand),
|
||||||
|
array_values($message->getArguments()),
|
||||||
|
array_values($this->getOptions($message)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$process
|
||||||
|
->setTimeout($this->timeout)
|
||||||
|
->run(static function(string $type, string $buffer) {
|
||||||
|
echo $buffer;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
} catch (ProcessTimedOutException $processTimedOutException) {
|
||||||
|
$this->logger->error(
|
||||||
|
sprintf(
|
||||||
|
'Process "%s" killed after %d seconds of execution',
|
||||||
|
$processTimedOutException->getProcess()->getCommandLine(),
|
||||||
|
$processTimedOutException->getProcess()->getTimeout()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getOptions(CommandMessage $message): array
|
||||||
|
{
|
||||||
|
$options = [];
|
||||||
|
foreach ($message->getFormattedOptions() as $option => $value) {
|
||||||
|
$options[] = $option . '=' . $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
}
|
18
Messenger/MessageHandler/JobRunner.php
Normal file
18
Messenger/MessageHandler/JobRunner.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface JobRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
interface JobRunner
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param CommandMessage $message
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void;
|
||||||
|
}
|
66
Messenger/MessageHandler/SimpleConsoleRunner.php
Normal file
66
Messenger/MessageHandler/SimpleConsoleRunner.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||||
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
|
use Symfony\Component\Console\Output\BufferedOutput;
|
||||||
|
use Symfony\Component\HttpKernel\KernelInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SimpleConsoleRunner
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class SimpleConsoleRunner implements JobRunner
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var KernelInterface
|
||||||
|
*/
|
||||||
|
private $kernel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CommandQueueHandler constructor.
|
||||||
|
*
|
||||||
|
* @param LoggerInterface $logger
|
||||||
|
* @param KernelInterface $kernel
|
||||||
|
*/
|
||||||
|
public function __construct(LoggerInterface $logger, KernelInterface $kernel)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->kernel = $kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function run(CommandMessage $message): void
|
||||||
|
{
|
||||||
|
$application = new Application($this->kernel);
|
||||||
|
$application->setAutoExit(false);
|
||||||
|
|
||||||
|
$input = new ArrayInput(
|
||||||
|
array_merge(
|
||||||
|
['command' => $message->getCommandName()],
|
||||||
|
$message->getFormattedOptions(),
|
||||||
|
$message->getArguments()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$output = new BufferedOutput();
|
||||||
|
if ($application->run($input, $output) > 0) {
|
||||||
|
$this->logger->error($output->fetch());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $output->fetch();
|
||||||
|
}
|
||||||
|
}
|
13
Messenger/Middleware/LockableMessage.php
Normal file
13
Messenger/Middleware/LockableMessage.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\Middleware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface LockableMessage
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\Middleware
|
||||||
|
*/
|
||||||
|
interface LockableMessage
|
||||||
|
{
|
||||||
|
public function __serialize(): array;
|
||||||
|
}
|
74
Messenger/Middleware/LockableMessageMiddleware.php
Normal file
74
Messenger/Middleware/LockableMessageMiddleware.php
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Messenger\Middleware;
|
||||||
|
|
||||||
|
use Symfony\Component\Lock\LockFactory;
|
||||||
|
use Symfony\Component\Messenger\Envelope;
|
||||||
|
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
|
||||||
|
use Symfony\Component\Messenger\Middleware\StackInterface;
|
||||||
|
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LockableMessageMiddleware
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Messenger\Middleware
|
||||||
|
*/
|
||||||
|
class LockableMessageMiddleware implements MiddlewareInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LockFactory
|
||||||
|
*/
|
||||||
|
private $lockFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int|null
|
||||||
|
*/
|
||||||
|
private $ttl;
|
||||||
|
|
||||||
|
public function __construct(LockFactory $lockFactory, int $ttl = null)
|
||||||
|
{
|
||||||
|
$this->lockFactory = $lockFactory;
|
||||||
|
$this->ttl = $ttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Envelope $envelope
|
||||||
|
* @param StackInterface $stack
|
||||||
|
*
|
||||||
|
* @return Envelope
|
||||||
|
*
|
||||||
|
* @throws Throwable
|
||||||
|
*/
|
||||||
|
public function handle(Envelope $envelope, StackInterface $stack): Envelope
|
||||||
|
{
|
||||||
|
$message = $envelope->getMessage();
|
||||||
|
|
||||||
|
if ($envelope->all(ReceivedStamp::class) && $message instanceof LockableMessage) {
|
||||||
|
$lock = $this->lockFactory->createLock($this->objectHash($message), $this->ttl);
|
||||||
|
if (!$lock->acquire()) {
|
||||||
|
return $envelope;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $stack->next()->handle($envelope, $stack);
|
||||||
|
} catch (Throwable $exception) {
|
||||||
|
throw $exception;
|
||||||
|
} finally {
|
||||||
|
$lock->release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $stack->next()->handle($envelope, $stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param LockableMessage $message
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function objectHash(LockableMessage $message): string
|
||||||
|
{
|
||||||
|
return hash('crc32', serialize($message));
|
||||||
|
}
|
||||||
|
}
|
60
Resources/doc/Messenger.md
Normal file
60
Resources/doc/Messenger.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
### Messenger
|
||||||
|
|
||||||
|
#### Messages
|
||||||
|
|
||||||
|
The library provides a basic message for executing console commands as message handlers - `RetailCrm\ServiceBundle\Messenger\CommandMessage`.
|
||||||
|
This makes it easier to create new message types. For example:
|
||||||
|
|
||||||
|
* Create your message
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
namespace App\Message;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
class MyMessage extends CommandMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = \App\Command\MyCommand::getDefaultName();
|
||||||
|
$this->options = ['optionName' => 'optionValue'];
|
||||||
|
$this->arguments = ['argumentName' => 'argumentValue'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
* Add a message to a routing
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# config/packages/messenger.yaml
|
||||||
|
framework:
|
||||||
|
messenger:
|
||||||
|
transports:
|
||||||
|
async: "%env(MESSENGER_TRANSPORT_DSN)%"
|
||||||
|
|
||||||
|
routing:
|
||||||
|
'App\Message\MyMessage': async
|
||||||
|
```
|
||||||
|
|
||||||
|
Now when sending this message through messenger (```$messageBus->dispatch(new MyMessage())```) the message handler will run the associated command
|
||||||
|
|
||||||
|
#### Message handlers
|
||||||
|
|
||||||
|
Two messages handlers are is supported:
|
||||||
|
|
||||||
|
* all messages handling in one worker process
|
||||||
|
* each message is a processed in a separate process
|
||||||
|
|
||||||
|
By default, messages will be processed in one process. To set up a handler to run in a separate process, add to the bundle config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
messenger:
|
||||||
|
message_handler: in_new_process_runner
|
||||||
|
process_timeout: 60
|
||||||
|
```
|
||||||
|
|
||||||
|
`process_timeout` - an optional parameter that only makes sense when `message_handler` is equal `in_new_process_runner` and determines the lifetime of the process.
|
||||||
|
By default, process timeout - 3600 (in seconds).
|
71
Resources/doc/Requests.md
Normal file
71
Resources/doc/Requests.md
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
### Deserialize incoming requests
|
||||||
|
|
||||||
|
#### Callbacks (form data)
|
||||||
|
|
||||||
|
To automatically get the callback request parameter
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function activityAction(\App\Dto\Callback\Activity $activity): Response
|
||||||
|
{
|
||||||
|
// handle activity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
add to the config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
callback:
|
||||||
|
supports:
|
||||||
|
- { type: App\Dto\Callback\Activity, params: ["activity"] }
|
||||||
|
```
|
||||||
|
|
||||||
|
request automatically will be deserialization to $activity.
|
||||||
|
|
||||||
|
#### Body json content
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function someAction(\App\Dto\Body $activity): Response
|
||||||
|
{
|
||||||
|
// handle activity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
add to the config:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
client:
|
||||||
|
supports:
|
||||||
|
- App\Dto\Body
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Serializers
|
||||||
|
At this time supported [Symfony serializer](https://symfony.com/doc/current/components/serializer.html) and [JMS serializer](https://jmsyst.com/libs/serializer).
|
||||||
|
By default, the library using a Symfony serializer. For use JMS install JMS serializer bundle - `composer require jms/serializer-bundle`
|
||||||
|
You can explicitly specify the type of serializer used for request schema:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
retail_crm_service:
|
||||||
|
request_schema:
|
||||||
|
client:
|
||||||
|
supports:
|
||||||
|
# types
|
||||||
|
serializer: retail_crm_service.symfony_serializer.adapter # or retail_crm_service.jms_serializer.adapter
|
||||||
|
callback:
|
||||||
|
supports:
|
||||||
|
# types
|
||||||
|
serializer: retail_crm_service.jms_serializer.adapter # or retail_crm_service.symfony_serializer.adapter
|
||||||
|
```
|
70
Resources/doc/Security.md
Normal file
70
Resources/doc/Security.md
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
### Authentication
|
||||||
|
|
||||||
|
Example security configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
security:
|
||||||
|
providers:
|
||||||
|
client:
|
||||||
|
entity:
|
||||||
|
class: 'App\Entity\Connection' # must implements UserInterface
|
||||||
|
property: 'clientId'
|
||||||
|
firewalls:
|
||||||
|
api:
|
||||||
|
pattern: ^/api
|
||||||
|
provider: client
|
||||||
|
anonymous: ~
|
||||||
|
lazy: true
|
||||||
|
stateless: false
|
||||||
|
guard:
|
||||||
|
authenticators:
|
||||||
|
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
||||||
|
callback:
|
||||||
|
pattern: ^/callback
|
||||||
|
provider: client
|
||||||
|
anonymous: ~
|
||||||
|
lazy: true
|
||||||
|
stateless: true
|
||||||
|
guard:
|
||||||
|
authenticators:
|
||||||
|
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
||||||
|
main:
|
||||||
|
anonymous: true
|
||||||
|
lazy: true
|
||||||
|
|
||||||
|
access_control:
|
||||||
|
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # login for programmatically authentication user
|
||||||
|
- { path: ^/api, roles: ROLE_USER }
|
||||||
|
- { path: ^/callback, roles: ROLE_USER }
|
||||||
|
```
|
||||||
|
|
||||||
|
To authenticate the user after creating it, you can use the following code
|
||||||
|
|
||||||
|
```php
|
||||||
|
|
||||||
|
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
||||||
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class AppController extends AbstractController
|
||||||
|
{
|
||||||
|
public function someAction(
|
||||||
|
Request $request,
|
||||||
|
GuardAuthenticatorHandler $guardAuthenticatorHandler,
|
||||||
|
FrontApiClientAuthenticator $frontApiClientAuthenticator,
|
||||||
|
ConnectionManager $manager
|
||||||
|
): Response {
|
||||||
|
$user = $manager->getUser(); // getting user
|
||||||
|
|
||||||
|
$guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
|
||||||
|
$user,
|
||||||
|
$request,
|
||||||
|
$frontApiClientAuthenticator,
|
||||||
|
'api'
|
||||||
|
);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
`composer require retailcrm/service-bundle`
|
`composer require retailcrm/service-bundle`
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Enable bundle in `config/bundles.php`:
|
Enable bundle in `config/bundles.php`:
|
||||||
|
|
||||||
```php
|
```php
|
||||||
|
@ -18,131 +16,15 @@ return [
|
||||||
|
|
||||||
Create bundle config file in `config/packages/retail_crm_service.yaml`:
|
Create bundle config file in `config/packages/retail_crm_service.yaml`:
|
||||||
|
|
||||||
```yaml
|
|
||||||
retail_crm_service:
|
|
||||||
request_schema: ~
|
|
||||||
```
|
|
||||||
|
|
||||||
### Deserializing incoming requests
|
|
||||||
|
|
||||||
#### Callbacks (form data)
|
|
||||||
|
|
||||||
To automatically get the callback request parameter
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function activityAction(\App\Dto\Callback\Activity $activity): Response
|
|
||||||
{
|
|
||||||
// handle activity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
add to the config:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
retail_crm_service:
|
retail_crm_service:
|
||||||
request_schema:
|
request_schema:
|
||||||
callback:
|
callback: ~
|
||||||
- type: App\Dto\Callback\Activity
|
client: ~
|
||||||
params: ["activity"]
|
messenger: ~
|
||||||
```
|
```
|
||||||
|
|
||||||
request automatically will be deserialization to $activity.
|
## Usage
|
||||||
|
* [Handling incoming requests data](./Requests.md)
|
||||||
#### Body json content
|
* [Security](./Security.md)
|
||||||
|
* [Messenger](./Messenger.md)
|
||||||
```php
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function someAction(\App\Dto\Body $activity): Response
|
|
||||||
{
|
|
||||||
// handle activity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
add to the config:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
retail_crm_service:
|
|
||||||
request_schema:
|
|
||||||
client:
|
|
||||||
- App\Dto\Body
|
|
||||||
```
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
|
|
||||||
Example security configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
security:
|
|
||||||
providers:
|
|
||||||
client:
|
|
||||||
entity:
|
|
||||||
class: 'App\Entity\Connection' # must implements UserInterface
|
|
||||||
property: 'clientId'
|
|
||||||
firewalls:
|
|
||||||
api:
|
|
||||||
pattern: ^/api
|
|
||||||
provider: client
|
|
||||||
anonymous: ~
|
|
||||||
lazy: true
|
|
||||||
stateless: false
|
|
||||||
guard:
|
|
||||||
authenticators:
|
|
||||||
- RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator
|
|
||||||
callback:
|
|
||||||
pattern: ^/callback
|
|
||||||
provider: client
|
|
||||||
anonymous: ~
|
|
||||||
lazy: true
|
|
||||||
stateless: true
|
|
||||||
guard:
|
|
||||||
authenticators:
|
|
||||||
- RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator
|
|
||||||
main:
|
|
||||||
anonymous: true
|
|
||||||
lazy: true
|
|
||||||
|
|
||||||
access_control:
|
|
||||||
- { path: ^/api/login, roles: IS_AUTHENTICATED_ANONYMOUSLY } # login for programmatically authentication user
|
|
||||||
- { path: ^/api, roles: ROLE_USER }
|
|
||||||
- { path: ^/callback, roles: ROLE_USER }
|
|
||||||
```
|
|
||||||
|
|
||||||
To authenticate the user after creating it, you can use the following code
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
|
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
|
||||||
|
|
||||||
class AppController extends AbstractController
|
|
||||||
{
|
|
||||||
public function someAction(
|
|
||||||
Request $request,
|
|
||||||
GuardAuthenticatorHandler $guardAuthenticatorHandler,
|
|
||||||
FrontApiClientAuthenticator $frontApiClientAuthenticator,
|
|
||||||
ConnectionManager $manager
|
|
||||||
): Response {
|
|
||||||
$user = $manager->getUser(); // getting user
|
|
||||||
|
|
||||||
$guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
|
|
||||||
$user,
|
|
||||||
$request,
|
|
||||||
$frontApiClientAuthenticator,
|
|
||||||
'api'
|
|
||||||
);
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
29
Serializer/Adapter.php
Normal file
29
Serializer/Adapter.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Serializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface Adapter
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Serializer
|
||||||
|
*/
|
||||||
|
interface Adapter
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $data
|
||||||
|
* @param string $type
|
||||||
|
* @param string $format
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function deserialize(string $data, string $type, string $format = 'json'): object;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param string $type
|
||||||
|
* @param string|null $format
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public function arrayToObject(array $data, string $type, ?string $format = null): object;
|
||||||
|
}
|
57
Serializer/JMSSerializerAdapter.php
Normal file
57
Serializer/JMSSerializerAdapter.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Serializer;
|
||||||
|
|
||||||
|
use JMS\Serializer\ArrayTransformerInterface;
|
||||||
|
use JMS\Serializer\Context;
|
||||||
|
use JMS\Serializer\SerializerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JMSSerializerAdapter
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Serializer
|
||||||
|
*/
|
||||||
|
class JMSSerializerAdapter implements Adapter
|
||||||
|
{
|
||||||
|
private $serializer;
|
||||||
|
private $transformer;
|
||||||
|
private $context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JMSSerializerAdapter constructor.
|
||||||
|
*
|
||||||
|
* @param SerializerInterface $serializer
|
||||||
|
* @param ArrayTransformerInterface $transformer
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
SerializerInterface $serializer,
|
||||||
|
ArrayTransformerInterface $transformer
|
||||||
|
) {
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
$this->transformer = $transformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function deserialize(string $data, string $type, string $format = 'json'): object
|
||||||
|
{
|
||||||
|
return $this->serializer->deserialize($data, $type, $format, $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function arrayToObject(array $data, string $type, ?string $format = null): object
|
||||||
|
{
|
||||||
|
return $this->transformer->fromArray($data, $type, $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Context $context
|
||||||
|
*/
|
||||||
|
public function setContext(Context $context): void
|
||||||
|
{
|
||||||
|
$this->context = $context;
|
||||||
|
}
|
||||||
|
}
|
54
Serializer/SymfonySerializerAdapter.php
Normal file
54
Serializer/SymfonySerializerAdapter.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Serializer;
|
||||||
|
|
||||||
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\SerializerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SymfonySerializerAdapter
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Serializer
|
||||||
|
*/
|
||||||
|
class SymfonySerializerAdapter implements Adapter
|
||||||
|
{
|
||||||
|
private $serializer;
|
||||||
|
private $denormalizer;
|
||||||
|
private $context = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SymfonySerializerAdapter constructor.
|
||||||
|
*
|
||||||
|
* @param SerializerInterface $serializer
|
||||||
|
* @param DenormalizerInterface $denormalizer
|
||||||
|
*/
|
||||||
|
public function __construct(SerializerInterface $serializer, DenormalizerInterface $denormalizer)
|
||||||
|
{
|
||||||
|
$this->serializer = $serializer;
|
||||||
|
$this->denormalizer = $denormalizer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function deserialize(string $data, string $type,string $format = 'json'): object
|
||||||
|
{
|
||||||
|
return $this->serializer->deserialize($data, $type, $format, $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc }
|
||||||
|
*/
|
||||||
|
public function arrayToObject(array $data, string $type, string $format = null): object
|
||||||
|
{
|
||||||
|
return $this->denormalizer->denormalize($data, $type, $format, $this->context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $context
|
||||||
|
*/
|
||||||
|
public function setContext(array $context): void
|
||||||
|
{
|
||||||
|
$this->context = $context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ namespace RetailCrm\ServiceBundle\Tests\ArgumentResolver;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\CallbackValueResolver;
|
||||||
use RetailCrm\ServiceBundle\Exceptions\InvalidRequestArgumentException;
|
use RetailCrm\ServiceBundle\Exceptions\InvalidRequestArgumentException;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\SymfonySerializerAdapter;
|
||||||
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||||
|
@ -27,7 +28,7 @@ class CallbackValueResolverTest extends TestCase
|
||||||
{
|
{
|
||||||
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
||||||
$this->resolver = new CallbackValueResolver(
|
$this->resolver = new CallbackValueResolver(
|
||||||
$serializer,
|
new SymfonySerializerAdapter($serializer, $serializer),
|
||||||
Validation::createValidatorBuilder()
|
Validation::createValidatorBuilder()
|
||||||
->enableAnnotationMapping()
|
->enableAnnotationMapping()
|
||||||
->getValidator(),
|
->getValidator(),
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace RetailCrm\ServiceBundle\Tests\ArgumentResolver;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
use RetailCrm\ServiceBundle\ArgumentResolver\ClientValueResolver;
|
||||||
use RetailCrm\ServiceBundle\Exceptions\InvalidRequestArgumentException;
|
use RetailCrm\ServiceBundle\Exceptions\InvalidRequestArgumentException;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\SymfonySerializerAdapter;
|
||||||
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||||
|
@ -27,11 +28,10 @@ class ClientValueResolverTest extends TestCase
|
||||||
{
|
{
|
||||||
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
||||||
$this->resolver = new ClientValueResolver(
|
$this->resolver = new ClientValueResolver(
|
||||||
|
new SymfonySerializerAdapter($serializer, $serializer),
|
||||||
Validation::createValidatorBuilder()
|
Validation::createValidatorBuilder()
|
||||||
->enableAnnotationMapping()
|
->enableAnnotationMapping()
|
||||||
->getValidator(),
|
->getValidator(),
|
||||||
$serializer,
|
|
||||||
$serializer,
|
|
||||||
[
|
[
|
||||||
RequestDto::class
|
RequestDto::class
|
||||||
]
|
]
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace RetailCrm\ServiceBundle\Tests\DataFixtures;
|
namespace RetailCrm\ServiceBundle\Tests\DataFixtures;
|
||||||
|
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use JMS\Serializer\Annotation as JMS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class RequestDto
|
* Class RequestDto
|
||||||
|
@ -14,6 +15,7 @@ class RequestDto
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
* @Assert\NotNull()
|
* @Assert\NotNull()
|
||||||
|
* @JMS\Type("string")
|
||||||
*/
|
*/
|
||||||
public $param;
|
public $param;
|
||||||
}
|
}
|
||||||
|
|
16
Tests/DataFixtures/TestMessage.php
Normal file
16
Tests/DataFixtures/TestMessage.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\DataFixtures;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\Middleware\LockableMessage;
|
||||||
|
|
||||||
|
class TestMessage extends CommandMessage implements LockableMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = 'test';
|
||||||
|
$this->arguments = ['argument' => 'argument'];
|
||||||
|
$this->options = ['option' => 'option'];
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,16 +21,24 @@ class ConfigurationTest extends TestCase
|
||||||
[
|
[
|
||||||
'request_schema' => [
|
'request_schema' => [
|
||||||
'callback' => [
|
'callback' => [
|
||||||
|
'supports' => [
|
||||||
[
|
[
|
||||||
'type' => 'type',
|
'type' => 'type',
|
||||||
'params' => ['param']
|
'params' => ['param']
|
||||||
]
|
]
|
||||||
|
]
|
||||||
],
|
],
|
||||||
'client' => [
|
'client' => [
|
||||||
|
'supports' => [
|
||||||
'type1',
|
'type1',
|
||||||
'type2'
|
'type2'
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner',
|
||||||
|
'process_timeout' => 60
|
||||||
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -44,14 +52,14 @@ class ConfigurationTest extends TestCase
|
||||||
'type' => 'type',
|
'type' => 'type',
|
||||||
'params' => ['param']
|
'params' => ['param']
|
||||||
],
|
],
|
||||||
$config['request_schema']['callback'][0]
|
$config['request_schema']['callback']['supports'][0]
|
||||||
);
|
);
|
||||||
static::assertEquals(
|
static::assertEquals(
|
||||||
[
|
[
|
||||||
'type1',
|
'type1',
|
||||||
'type2'
|
'type2'
|
||||||
],
|
],
|
||||||
$config['request_schema']['client']
|
$config['request_schema']['client']['supports']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,15 +71,20 @@ class ConfigurationTest extends TestCase
|
||||||
[
|
[
|
||||||
'request_schema' => [
|
'request_schema' => [
|
||||||
'client' => [
|
'client' => [
|
||||||
|
'supports' => [
|
||||||
'type',
|
'type',
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
$config = $processor->processConfiguration(new Configuration(), $configs);
|
$config = $processor->processConfiguration(new Configuration(), $configs);
|
||||||
|
|
||||||
static::assertArrayHasKey('client', $config['request_schema']);
|
static::assertArrayHasKey('client', $config['request_schema']);
|
||||||
static::assertEquals(['type'], $config['request_schema']['client']);
|
static::assertEquals(['type'], $config['request_schema']['client']['supports']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,13 @@ class RetailCrmServiceExtensionTest extends TestCase
|
||||||
$extension->load(
|
$extension->load(
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
'request_schema' => []
|
'request_schema' => [
|
||||||
|
'callback' => [],
|
||||||
|
'client' => []
|
||||||
|
],
|
||||||
|
'messenger' => [
|
||||||
|
'message_handler' => 'simple_console_runner'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
$container
|
$container
|
||||||
|
@ -44,8 +50,10 @@ class RetailCrmServiceExtensionTest extends TestCase
|
||||||
|
|
||||||
public function testLoad(): void
|
public function testLoad(): void
|
||||||
{
|
{
|
||||||
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.callback'));
|
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.callback.supports'));
|
||||||
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.client'));
|
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.callback.serializer'));
|
||||||
|
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.client.supports'));
|
||||||
|
static::assertTrue($this->container->hasParameter('retail_crm_service.request_schema.client.serializer'));
|
||||||
static::assertTrue($this->container->hasDefinition(CallbackValueResolver::class));
|
static::assertTrue($this->container->hasDefinition(CallbackValueResolver::class));
|
||||||
static::assertTrue($this->container->hasDefinition(ClientValueResolver::class));
|
static::assertTrue($this->container->hasDefinition(ClientValueResolver::class));
|
||||||
static::assertTrue($this->container->hasDefinition(ErrorJsonResponseFactory::class));
|
static::assertTrue($this->container->hasDefinition(ErrorJsonResponseFactory::class));
|
||||||
|
|
33
Tests/Fixtures/App/Kernel.php
Normal file
33
Tests/Fixtures/App/Kernel.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||||
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
class Kernel extends \Symfony\Component\HttpKernel\Kernel
|
||||||
|
{
|
||||||
|
use MicroKernelTrait;
|
||||||
|
|
||||||
|
public function registerBundles()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configureContainer(ContainerBuilder $container/*, LoaderInterface $loader*/): void
|
||||||
|
{
|
||||||
|
$container
|
||||||
|
->register(TestCommand::class, TestCommand::class)
|
||||||
|
->addTag('console.command', ['command' => TestCommand::getDefaultName()])
|
||||||
|
;
|
||||||
|
|
||||||
|
$container->setParameter('kernel.project_dir', __DIR__ . '/..');
|
||||||
|
}
|
||||||
|
|
||||||
|
// public function registerContainerConfiguration(LoaderInterface $loader)
|
||||||
|
// {
|
||||||
|
// }
|
||||||
|
}
|
36
Tests/Fixtures/App/TestCommand.php
Normal file
36
Tests/Fixtures/App/TestCommand.php
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class TestCommand extends Command
|
||||||
|
{
|
||||||
|
protected static $defaultName = 'test';
|
||||||
|
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this
|
||||||
|
->addArgument(
|
||||||
|
'argument',
|
||||||
|
InputArgument::REQUIRED
|
||||||
|
)
|
||||||
|
->addOption(
|
||||||
|
'option',
|
||||||
|
null,
|
||||||
|
InputOption::VALUE_REQUIRED
|
||||||
|
)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
echo self::$defaultName . ' ' . $input->getArgument('argument') . ' ' . $input->getOption('option');
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
15
Tests/Fixtures/App/TestCommandMessage.php
Normal file
15
Tests/Fixtures/App/TestCommandMessage.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Fixtures\App;
|
||||||
|
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
|
||||||
|
class TestCommandMessage extends CommandMessage
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->commandName = 'test';
|
||||||
|
$this->arguments = ['argument' => 'test'];
|
||||||
|
$this->options = ['option' => 'test'];
|
||||||
|
}
|
||||||
|
}
|
9
Tests/Fixtures/bin/console
Normal file
9
Tests/Fixtures/bin/console
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../../vendor/autoload.php';
|
||||||
|
|
||||||
|
$input = new Symfony\Component\Console\Input\ArgvInput();
|
||||||
|
$kernel = new RetailCrm\ServiceBundle\Tests\Fixtures\App\Kernel('test', true);
|
||||||
|
$application = new Symfony\Bundle\FrameworkBundle\Console\Application($kernel);
|
||||||
|
$application->run($input);
|
38
Tests/Messenger/CommandMessageTest.php
Normal file
38
Tests/Messenger/CommandMessageTest.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\TestMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CommandMessageTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger
|
||||||
|
*/
|
||||||
|
class CommandMessageTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testMessage(): void
|
||||||
|
{
|
||||||
|
$message = new TestMessage();
|
||||||
|
|
||||||
|
static::assertEquals('test', $message->getCommandName());
|
||||||
|
static::assertEquals(['argument' => 'argument'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option'], $message->getFormattedOptions());
|
||||||
|
|
||||||
|
$message->addOption('option2', 'option2');
|
||||||
|
$message->addArgument('argument2', 'argument2');
|
||||||
|
|
||||||
|
static::assertEquals(['argument' => 'argument', 'argument2' => 'argument2'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option', 'option2' => 'option2'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option', '--option2' => 'option2'], $message->getFormattedOptions());
|
||||||
|
|
||||||
|
$message->setOptions(['option' => 'option']);
|
||||||
|
$message->setArguments(['argument' => 'argument']);
|
||||||
|
|
||||||
|
static::assertEquals(['argument' => 'argument'], $message->getArguments());
|
||||||
|
static::assertEquals(['option' => 'option'], $message->getOptions());
|
||||||
|
static::assertEquals(['--option' => 'option'], $message->getFormattedOptions());
|
||||||
|
}
|
||||||
|
}
|
32
Tests/Messenger/MessageHandler/InNewProcessRunnerTest.php
Normal file
32
Tests/Messenger/MessageHandler/InNewProcessRunnerTest.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\InNewProcessRunner;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\Fixtures\App\TestCommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class InNewProcessRunnerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class InNewProcessRunnerTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel(['environment' => 'test']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = new InNewProcessRunner(new NullLogger, self::$kernel);
|
||||||
|
|
||||||
|
ob_clean();
|
||||||
|
ob_start();
|
||||||
|
$runner->run(new TestCommandMessage());
|
||||||
|
|
||||||
|
static::assertEquals('test test test', ob_get_clean());
|
||||||
|
}
|
||||||
|
}
|
32
Tests/Messenger/MessageHandler/SimpleConsoleRunnerTest.php
Normal file
32
Tests/Messenger/MessageHandler/SimpleConsoleRunnerTest.php
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler;
|
||||||
|
|
||||||
|
use Psr\Log\NullLogger;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\SimpleConsoleRunner;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\Fixtures\App\TestCommandMessage;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SimpleConsoleRunnerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger\MessageHandler
|
||||||
|
*/
|
||||||
|
class SimpleConsoleRunnerTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
self::bootKernel(['environment' => 'test']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = new SimpleConsoleRunner(new NullLogger, self::$kernel);
|
||||||
|
|
||||||
|
ob_clean();
|
||||||
|
ob_start();
|
||||||
|
$runner->run(new TestCommandMessage());
|
||||||
|
|
||||||
|
static::assertEquals('test test test', ob_get_clean());
|
||||||
|
}
|
||||||
|
}
|
26
Tests/Messenger/MessageHandlerTest.php
Normal file
26
Tests/Messenger/MessageHandlerTest.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\CommandMessage;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\MessageHandler\JobRunner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MessageHandlerTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger
|
||||||
|
*/
|
||||||
|
class MessageHandlerTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testRun(): void
|
||||||
|
{
|
||||||
|
$runner = $this->createMock(JobRunner::class);
|
||||||
|
$runner->expects(static::once())->method('run');
|
||||||
|
$message = $this->createMock(CommandMessage::class);
|
||||||
|
|
||||||
|
$handler = new MessageHandler($runner);
|
||||||
|
$handler->__invoke($message);
|
||||||
|
}
|
||||||
|
}
|
113
Tests/Messenger/Middleware/LockableMessageMiddlewareTest.php
Normal file
113
Tests/Messenger/Middleware/LockableMessageMiddlewareTest.php
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Messenger\Middleware;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Messenger\Middleware\LockableMessageMiddleware;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\TestMessage;
|
||||||
|
use Symfony\Component\Lock\Exception\LockConflictedException;
|
||||||
|
use Symfony\Component\Lock\Key;
|
||||||
|
use Symfony\Component\Lock\Lock;
|
||||||
|
use Symfony\Component\Lock\LockFactory;
|
||||||
|
use Symfony\Component\Lock\PersistingStoreInterface;
|
||||||
|
use Symfony\Component\Messenger\Envelope;
|
||||||
|
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
|
||||||
|
use Symfony\Component\Messenger\Middleware\StackInterface;
|
||||||
|
use Symfony\Component\Messenger\Stamp\ReceivedStamp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class LockableMessageMiddlewareTest
|
||||||
|
*
|
||||||
|
* @package RetailCrm\ServiceBundle\Tests\Messenger\Middleware
|
||||||
|
*/
|
||||||
|
class LockableMessageMiddlewareTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var LockFactory
|
||||||
|
*/
|
||||||
|
private $lockFactory;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->lockFactory = $this->createMock(LockFactory::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testHandle(): void
|
||||||
|
{
|
||||||
|
$store = $this->createMock(PersistingStoreInterface::class);
|
||||||
|
$key = new Key(uniqid());
|
||||||
|
$lock = new Lock($key, $store);
|
||||||
|
$this->lockFactory->expects(static::once())->method('createLock')->willReturn($lock);
|
||||||
|
$envelope = new Envelope(new TestMessage(), [new ReceivedStamp('test')]);
|
||||||
|
|
||||||
|
$next = $this->createMock(MiddlewareInterface::class);
|
||||||
|
$next->method('handle')->willReturn($envelope);
|
||||||
|
$stack = $this->createMock(StackInterface::class);
|
||||||
|
$stack->method('next')->willReturn($next);
|
||||||
|
|
||||||
|
$middleware = new LockableMessageMiddleware($this->lockFactory);
|
||||||
|
$result = $middleware->handle($envelope, $stack);
|
||||||
|
|
||||||
|
static::assertInstanceOf(Envelope::class, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLockHandle(): void
|
||||||
|
{
|
||||||
|
$store = $this->createMock(PersistingStoreInterface::class);
|
||||||
|
$store->method('save')->willThrowException(new LockConflictedException);
|
||||||
|
$key = new Key(uniqid());
|
||||||
|
$lock = new Lock($key, $store);
|
||||||
|
$this->lockFactory->expects(static::once())->method('createLock')->willReturn($lock);
|
||||||
|
$envelope = new Envelope(new TestMessage(), [new ReceivedStamp('test')]);
|
||||||
|
|
||||||
|
$next = $this->createMock(MiddlewareInterface::class);
|
||||||
|
$next->method('handle')->willReturn($envelope);
|
||||||
|
$stack = $this->createMock(StackInterface::class);
|
||||||
|
$stack->method('next')->willReturn($next);
|
||||||
|
|
||||||
|
$middleware = new LockableMessageMiddleware($this->lockFactory);
|
||||||
|
$result = $middleware->handle($envelope, $stack);
|
||||||
|
|
||||||
|
static::assertInstanceOf(Envelope::class, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNonLockableHandle(): void
|
||||||
|
{
|
||||||
|
$store = $this->createMock(PersistingStoreInterface::class);
|
||||||
|
$store->method('save')->willThrowException(new LockConflictedException);
|
||||||
|
$key = new Key(uniqid());
|
||||||
|
$lock = new Lock($key, $store);
|
||||||
|
$this->lockFactory->expects(static::never())->method('createLock')->willReturn($lock);
|
||||||
|
$envelope = new Envelope(new \stdClass(), [new ReceivedStamp('test')]);
|
||||||
|
|
||||||
|
$next = $this->createMock(MiddlewareInterface::class);
|
||||||
|
$next->method('handle')->willReturn($envelope);
|
||||||
|
$stack = $this->createMock(StackInterface::class);
|
||||||
|
$stack->method('next')->willReturn($next);
|
||||||
|
|
||||||
|
$middleware = new LockableMessageMiddleware($this->lockFactory);
|
||||||
|
$result = $middleware->handle($envelope, $stack);
|
||||||
|
|
||||||
|
static::assertInstanceOf(Envelope::class, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNonReceivedHandle(): void
|
||||||
|
{
|
||||||
|
$store = $this->createMock(PersistingStoreInterface::class);
|
||||||
|
$store->method('save')->willThrowException(new LockConflictedException);
|
||||||
|
$key = new Key(uniqid());
|
||||||
|
$lock = new Lock($key, $store);
|
||||||
|
$this->lockFactory->expects(static::never())->method('createLock')->willReturn($lock);
|
||||||
|
$envelope = new Envelope(new TestMessage());
|
||||||
|
|
||||||
|
$next = $this->createMock(MiddlewareInterface::class);
|
||||||
|
$next->method('handle')->willReturn($envelope);
|
||||||
|
$stack = $this->createMock(StackInterface::class);
|
||||||
|
$stack->method('next')->willReturn($next);
|
||||||
|
|
||||||
|
$middleware = new LockableMessageMiddleware($this->lockFactory);
|
||||||
|
$result = $middleware->handle($envelope, $stack);
|
||||||
|
|
||||||
|
static::assertInstanceOf(Envelope::class, $result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,11 +5,14 @@ namespace RetailCrm\ServiceBundle\Tests\Security;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class CallbackClientAuthenticatorTest
|
* Class CallbackClientAuthenticatorTest
|
||||||
|
@ -99,7 +102,7 @@ class CallbackClientAuthenticatorTest extends TestCase
|
||||||
);
|
);
|
||||||
|
|
||||||
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
$result = $auth->start(new Request(), new AuthenticationException());
|
$result = $auth->onAuthenticationFailure(new Request(), new AuthenticationException());
|
||||||
|
|
||||||
static::assertInstanceOf(JsonResponse::class, $result);
|
static::assertInstanceOf(JsonResponse::class, $result);
|
||||||
static::assertEquals(Response::HTTP_FORBIDDEN, $result->getStatusCode());
|
static::assertEquals(Response::HTTP_FORBIDDEN, $result->getStatusCode());
|
||||||
|
@ -132,4 +135,34 @@ class CallbackClientAuthenticatorTest extends TestCase
|
||||||
|
|
||||||
static::assertFalse($result);
|
static::assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUser(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$user = new User();
|
||||||
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
|
|
||||||
|
$userProvider = $this->createMock(UserProviderInterface::class);
|
||||||
|
$userProvider
|
||||||
|
->expects(static::once())
|
||||||
|
->method('loadUserByUsername')
|
||||||
|
->with('clientId')
|
||||||
|
->willReturn($user)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $auth->getUser('clientId', $userProvider);
|
||||||
|
static::assertEquals($user, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnAuthenticationSuccess(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$token = $this->createMock(TokenInterface::class);
|
||||||
|
$auth = new CallbackClientAuthenticator($errorResponseFactory);
|
||||||
|
|
||||||
|
$result = $auth->onAuthenticationSuccess($request, $token, 'key');
|
||||||
|
|
||||||
|
static::assertNull($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,15 @@ namespace RetailCrm\ServiceBundle\Tests\Security;
|
||||||
|
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
use RetailCrm\ServiceBundle\Response\ErrorJsonResponseFactory;
|
||||||
use RetailCrm\ServiceBundle\Security\CallbackClientAuthenticator;
|
|
||||||
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
use RetailCrm\ServiceBundle\Security\FrontApiClientAuthenticator;
|
||||||
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\User;
|
||||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\Security;
|
use Symfony\Component\Security\Core\Security;
|
||||||
use Symfony\Component\Security\Core\User\UserInterface;
|
use Symfony\Component\Security\Core\User\UserProviderInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FrontApiClientAuthenticatorTest
|
* Class FrontApiClientAuthenticatorTest
|
||||||
|
@ -45,11 +45,11 @@ class FrontApiClientAuthenticatorTest extends TestCase
|
||||||
$security = $this->createMock(Security::class);
|
$security = $this->createMock(Security::class);
|
||||||
|
|
||||||
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
$result = $auth->getCredentials(new Request([], [CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
$result = $auth->getCredentials(new Request([], [FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
|
|
||||||
static::assertEquals('123', $result);
|
static::assertEquals('123', $result);
|
||||||
|
|
||||||
$result = $auth->getCredentials(new Request([CallbackClientAuthenticator::AUTH_FIELD => '123']));
|
$result = $auth->getCredentials(new Request([FrontApiClientAuthenticator::AUTH_FIELD => '123']));
|
||||||
|
|
||||||
static::assertEquals('123', $result);
|
static::assertEquals('123', $result);
|
||||||
}
|
}
|
||||||
|
@ -120,4 +120,37 @@ class FrontApiClientAuthenticatorTest extends TestCase
|
||||||
|
|
||||||
static::assertTrue($result);
|
static::assertTrue($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetUser(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$security = $this->createMock(Security::class);
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
|
|
||||||
|
$userProvider = $this->createMock(UserProviderInterface::class);
|
||||||
|
$userProvider
|
||||||
|
->expects(static::once())
|
||||||
|
->method('loadUserByUsername')
|
||||||
|
->with('clientId')
|
||||||
|
->willReturn($user)
|
||||||
|
;
|
||||||
|
|
||||||
|
$result = $auth->getUser('clientId', $userProvider);
|
||||||
|
static::assertEquals($user, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testOnAuthenticationSuccess(): void
|
||||||
|
{
|
||||||
|
$errorResponseFactory = $this->createMock(ErrorJsonResponseFactory::class);
|
||||||
|
$security = $this->createMock(Security::class);
|
||||||
|
$request = $this->createMock(Request::class);
|
||||||
|
$token = $this->createMock(TokenInterface::class);
|
||||||
|
$auth = new FrontApiClientAuthenticator($errorResponseFactory, $security);
|
||||||
|
|
||||||
|
$result = $auth->onAuthenticationSuccess($request, $token, 'key');
|
||||||
|
|
||||||
|
static::assertNull($result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
38
Tests/Serializer/JSMSerializerAdapterTest.php
Normal file
38
Tests/Serializer/JSMSerializerAdapterTest.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Serializer;
|
||||||
|
|
||||||
|
use JMS\Serializer\SerializerBuilder;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\JMSSerializerAdapter;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
||||||
|
|
||||||
|
class JSMSerializerAdapterTest extends TestCase
|
||||||
|
{
|
||||||
|
private $serializer;
|
||||||
|
private $transformer;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->serializer = SerializerBuilder::create()->build();
|
||||||
|
$this->transformer = SerializerBuilder::create()->build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDeserialize(): void
|
||||||
|
{
|
||||||
|
$adapter = new JMSSerializerAdapter($this->serializer, $this->transformer);
|
||||||
|
$object = $adapter->deserialize('{"param": "string"}', RequestDto::class,'json');
|
||||||
|
|
||||||
|
static::assertInstanceOf(RequestDto::class, $object);
|
||||||
|
static::assertEquals('string', $object->param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArrayToObject(): void
|
||||||
|
{
|
||||||
|
$adapter = new JMSSerializerAdapter($this->serializer, $this->transformer);
|
||||||
|
$object = $adapter->arrayToObject(['param' => 'string'], RequestDto::class);
|
||||||
|
|
||||||
|
static::assertInstanceOf(RequestDto::class, $object);
|
||||||
|
static::assertEquals('string', $object->param);
|
||||||
|
}
|
||||||
|
}
|
40
Tests/Serializer/SymfonySerializerAdapterTest.php
Normal file
40
Tests/Serializer/SymfonySerializerAdapterTest.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace RetailCrm\ServiceBundle\Tests\Serializer;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use RetailCrm\ServiceBundle\Serializer\SymfonySerializerAdapter;
|
||||||
|
use RetailCrm\ServiceBundle\Tests\DataFixtures\RequestDto;
|
||||||
|
use Symfony\Component\Serializer\Encoder\JsonEncoder;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
||||||
|
use Symfony\Component\Serializer\Serializer;
|
||||||
|
|
||||||
|
class SymfonySerializerAdapterTest extends TestCase
|
||||||
|
{
|
||||||
|
private $serializer;
|
||||||
|
private $denormalizer;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
||||||
|
$this->denormalizer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDeserialize(): void
|
||||||
|
{
|
||||||
|
$adapter = new SymfonySerializerAdapter($this->serializer, $this->denormalizer);
|
||||||
|
$object = $adapter->deserialize('{"param": "string"}', RequestDto::class,'json');
|
||||||
|
|
||||||
|
static::assertInstanceOf(RequestDto::class, $object);
|
||||||
|
static::assertEquals('string', $object->param);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testArrayToObject(): void
|
||||||
|
{
|
||||||
|
$adapter = new SymfonySerializerAdapter($this->serializer, $this->denormalizer);
|
||||||
|
$object = $adapter->arrayToObject(['param' => 'string'], RequestDto::class);
|
||||||
|
|
||||||
|
static::assertInstanceOf(RequestDto::class, $object);
|
||||||
|
static::assertEquals('string', $object->param);
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,8 +15,13 @@
|
||||||
"symfony/framework-bundle": "^4.0|^5.0",
|
"symfony/framework-bundle": "^4.0|^5.0",
|
||||||
"symfony/serializer": "^5.2",
|
"symfony/serializer": "^5.2",
|
||||||
"symfony/http-kernel": "^4.0|^5.0",
|
"symfony/http-kernel": "^4.0|^5.0",
|
||||||
"symfony/validator": "^4.0|^5.0",
|
"symfony/validator": "^4.0|^5.3",
|
||||||
"symfony/security-guard": "^4.0|^5.0"
|
"symfony/security-guard": "^4.0|^5.0",
|
||||||
|
"symfony/console": "^5.2",
|
||||||
|
"symfony/messenger": "^5.2",
|
||||||
|
"symfony/process": "^5.2",
|
||||||
|
"symfony/event-dispatcher": "^5.2",
|
||||||
|
"symfony/lock": "^5.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
@ -35,7 +40,8 @@
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"phpunit/phpunit": "^8.0 || ^9.0",
|
"phpunit/phpunit": "^8.0 || ^9.0",
|
||||||
"doctrine/annotations": "^1.11",
|
"doctrine/annotations": "^1.11",
|
||||||
"doctrine/cache": "^1.10"
|
"doctrine/cache": "^1.10",
|
||||||
|
"jms/serializer-bundle": "^3.8"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tests": "./vendor/bin/phpunit -c phpunit.xml.dist"
|
"tests": "./vendor/bin/phpunit -c phpunit.xml.dist"
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
stopOnFailure="false"
|
stopOnFailure="false"
|
||||||
bootstrap="vendor/autoload.php"
|
bootstrap="vendor/autoload.php"
|
||||||
>
|
>
|
||||||
|
<php>
|
||||||
|
<server name="KERNEL_CLASS" value="RetailCrm\ServiceBundle\Tests\Fixtures\App\Kernel" />
|
||||||
|
</php>
|
||||||
<coverage>
|
<coverage>
|
||||||
<include>
|
<include>
|
||||||
<directory>./</directory>
|
<directory>./</directory>
|
||||||
|
|
Loading…
Add table
Reference in a new issue