diff --git a/behat.yml.dist b/behat.yml.dist index c07a0d1..bbe243e 100644 --- a/behat.yml.dist +++ b/behat.yml.dist @@ -10,31 +10,22 @@ default: snippets: false extensions: - DMore\ChromeExtension\Behat\ServiceContainer\ChromeExtension: ~ Robertfausk\Behat\PantherExtension: ~ FriendsOfBehat\MinkDebugExtension: directory: etc/build - clean_start: false + clean_start: true screenshot: true Behat\MinkExtension: files_path: "%paths.base%/vendor/sylius/sylius/src/Sylius/Behat/Resources/fixtures/" base_url: "https://127.0.0.1:8080/" default_session: symfony - javascript_session: panther + javascript_session: javascript_chrome sessions: symfony: symfony: ~ - chromedriver: - chrome: - api_url: http://127.0.0.1:9222 - validate_certificate: false - chrome_headless_second_session: - chrome: - api_url: http://127.0.0.1:9222 - validate_certificate: false - panther: + javascript_chrome: panther: options: webServerDir: "%paths.base%/tests/Application/public" @@ -49,6 +40,7 @@ default: acceptInsecureCerts: true unexpectedAlertBehaviour: accept show_auto: false + browser_name: 'behat_browser' FriendsOfBehat\SymfonyExtension: bootstrap: tests/Application/config/bootstrap.php diff --git a/composer.json b/composer.json index ca5ff17..9b98185 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,6 @@ "ext-json": "*", "behat/behat": "^3.7", "dbrekelmans/bdi": "^1.2", - "dmore/behat-chrome-extension": "^1.4", - "dmore/chrome-mink-driver": "^2.8", "friends-of-behat/mink": "^1.9", "friends-of-behat/mink-browserkit-driver": "^1.4", "friends-of-behat/mink-debug-extension": "^2.0", diff --git a/ecs.php b/ecs.php index 98fbfe6..aee42dc 100644 --- a/ecs.php +++ b/ecs.php @@ -5,19 +5,15 @@ use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; -return static function (ECSConfig $ecsConfig): void { - $ecsConfig->import(__DIR__ . '/vendor/sylius-labs/coding-standard/ecs.php'); +return static function (ECSConfig $config): void { + $config->import(__DIR__ . '/vendor/sylius-labs/coding-standard/ecs.php'); - $ecsConfig->paths([ + $config->paths([ 'src', 'tests/Behat', ]); - $services = $ecsConfig->services(); - // PHP 7 compatibility - $services - ->set(TrailingCommaInMultilineFixer::class) - ->call('configure', [['elements' => ['arrays']]]) - ; + $config->ruleWithConfiguration(TrailingCommaInMultilineFixer::class, ['elements' => ['arrays']]); + }; diff --git a/spec/Extension/UpdatePaymentStateExtensionSpec.php b/spec/Extension/UpdatePaymentStateExtensionSpec.php index bb38cf2..d82c281 100644 --- a/spec/Extension/UpdatePaymentStateExtensionSpec.php +++ b/spec/Extension/UpdatePaymentStateExtensionSpec.php @@ -5,6 +5,7 @@ namespace spec\FluxSE\SyliusPayumStripePlugin\Extension; use Exception; +use FluxSE\SyliusPayumStripePlugin\Abstraction\StateMachine\StateMachineInterface; use Payum\Core\Extension\Context; use Payum\Core\Extension\ExtensionInterface; use Payum\Core\GatewayInterface; @@ -15,20 +16,18 @@ use Payum\Core\Storage\IdentityInterface; use Payum\Core\Storage\StorageInterface; use PhpSpec\ObjectBehavior; -use SM\Factory\FactoryInterface; use Sylius\Bundle\PayumBundle\Factory\GetStatusFactoryInterface; use Sylius\Component\Core\Model\PaymentInterface; use Sylius\Component\Payment\PaymentTransitions; -use Sylius\Component\Resource\StateMachine\StateMachineInterface; final class UpdatePaymentStateExtensionSpec extends ObjectBehavior { public function let( - FactoryInterface $factory, + StateMachineInterface $stateMachine, StorageInterface $storage, GetStatusFactoryInterface $getStatusRequestFactory ): void { - $this->beConstructedWith($factory, $storage, $getStatusRequestFactory); + $this->beConstructedWith($stateMachine, $storage, $getStatusRequestFactory); } public function it_is_initializable(): void @@ -96,7 +95,6 @@ public function it_OnPostExecute_apply_a_transition( GetStatusInterface $status, GetStatusFactoryInterface $getStatusRequestFactory, GatewayInterface $gateway, - FactoryInterface $factory, StateMachineInterface $stateMachine ): void { $context->getException()->willReturn(null); @@ -114,9 +112,16 @@ public function it_OnPostExecute_apply_a_transition( $payment->getState()->willReturn(PaymentInterface::STATE_NEW); $status->getValue()->willReturn(PaymentInterface::STATE_COMPLETED); - $factory->get($payment, PaymentTransitions::GRAPH)->willReturn($stateMachine); - $stateMachine->getTransitionToState(PaymentInterface::STATE_COMPLETED)->willReturn('complete'); - $stateMachine->apply('complete')->shouldBeCalled(); + $stateMachine->getTransitionToState( + $payment, + PaymentTransitions::GRAPH, + PaymentInterface::STATE_COMPLETED + )->willReturn('complete'); + $stateMachine->apply( + $payment, + PaymentTransitions::GRAPH, + 'complete' + )->shouldBeCalled(); $this->onPostExecute($context); } @@ -131,7 +136,6 @@ public function it_OnPostExecute_apply_a_transition_without_a_Sylius_PaymentInte GetStatusInterface $status, GetStatusFactoryInterface $getStatusRequestFactory, GatewayInterface $gateway, - FactoryInterface $factory, StateMachineInterface $stateMachine ): void { $context->getException()->willReturn(null); @@ -152,9 +156,16 @@ public function it_OnPostExecute_apply_a_transition_without_a_Sylius_PaymentInte $previousPayment->getState()->willReturn(PaymentInterface::STATE_NEW); $status->getValue()->willReturn(PaymentInterface::STATE_COMPLETED); - $factory->get($previousPayment, PaymentTransitions::GRAPH)->willReturn($stateMachine); - $stateMachine->getTransitionToState(PaymentInterface::STATE_COMPLETED)->willReturn('complete'); - $stateMachine->apply('complete')->shouldBeCalled(); + $stateMachine->getTransitionToState( + $previousPayment, + PaymentTransitions::GRAPH, + PaymentInterface::STATE_COMPLETED + )->willReturn('complete'); + $stateMachine->apply( + $previousPayment, + PaymentTransitions::GRAPH, + 'complete' + )->shouldBeCalled(); $this->onPreExecute($previousContext); diff --git a/spec/StateMachine/CancelOrderProcessorSpec.php b/spec/StateMachine/CancelOrderProcessorSpec.php index bbc17d2..7f3eea3 100644 --- a/spec/StateMachine/CancelOrderProcessorSpec.php +++ b/spec/StateMachine/CancelOrderProcessorSpec.php @@ -19,50 +19,37 @@ public function let(MessageBusInterface $commandBus): void { public function it_is_invokable_when_it_is_new( PaymentInterface $payment, - TransitionEvent $event, MessageBusInterface $commandBus, ): void { - $event->getState()->willReturn(PaymentInterface::STATE_NEW); - $payment->getId()->willReturn(1); $command = new CancelPayment(1); $commandBus->dispatch($command)->willReturn(new Envelope($command)); - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_NEW); } public function it_is_invokable_when_is_authorized( PaymentInterface $payment, - TransitionEvent $event, MessageBusInterface $commandBus ): void { - - $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - $payment->getId()->willReturn(1); $command = new CancelPayment(1); $commandBus->dispatch($command)->willReturn(new Envelope($command)); - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_AUTHORIZED); } public function it_do_nothing_when_it_is_completed( - PaymentInterface $payment, - TransitionEvent $event + PaymentInterface $payment ): void { - $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); } public function it_do_nothing_when_it_is_refunded( PaymentInterface $payment, - TransitionEvent $event ): void { - $event->getState()->willReturn(PaymentInterface::STATE_REFUNDED); - - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_REFUNDED); } } diff --git a/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php b/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php index 530b4d2..81fa63c 100644 --- a/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php +++ b/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php @@ -19,34 +19,25 @@ public function let(MessageBusInterface $commandBus): void { public function it_is_invokable( PaymentInterface $payment, - TransitionEvent $event, MessageBusInterface $commandBus ): void { - $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - $payment->getId()->willReturn(1); $command = new CaptureAuthorizedPayment(1); $commandBus->dispatch($command)->willReturn(new Envelope($command)); - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_AUTHORIZED); } public function it_do_nothing_when_it_is_completed( - PaymentInterface $payment, - TransitionEvent $event + PaymentInterface $payment ): void { - $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); } public function it_do_nothing_when_it_is_refunded( - PaymentInterface $payment, - TransitionEvent $event + PaymentInterface $payment ): void { - $event->getState()->willReturn(PaymentInterface::STATE_REFUNDED); - - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_REFUNDED); } } diff --git a/spec/StateMachine/RefundOrderProcessorSpec.php b/spec/StateMachine/RefundOrderProcessorSpec.php index f376c74..8e8663a 100644 --- a/spec/StateMachine/RefundOrderProcessorSpec.php +++ b/spec/StateMachine/RefundOrderProcessorSpec.php @@ -14,30 +14,31 @@ final class RefundOrderProcessorSpec extends ObjectBehavior { public function let(MessageBusInterface $commandBus): void { - $this->beConstructedWith($commandBus); + $this->beConstructedWith($commandBus, false); } public function it_is_invokable( PaymentInterface $payment, - TransitionEvent $event, MessageBusInterface $commandBus ): void { - $event->getState()->willReturn(PaymentInterface::STATE_COMPLETED); - $payment->getId()->willReturn(1); $command = new RefundPayment(1); $commandBus->dispatch($command)->willReturn(new Envelope($command)); - $this->__invoke($payment, $event); + $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); } - public function it_do_nothing_when_it_is_authorized( + public function it_do_nothing_when_it_is_disabled( PaymentInterface $payment, - TransitionEvent $event + MessageBusInterface $commandBus ): void { - $event->getState()->willReturn(PaymentInterface::STATE_AUTHORIZED); - $this->__invoke($payment, $event); + $this->beConstructedWith($commandBus, true); + + $command = new RefundPayment(1); + $commandBus->dispatch($command)->shouldNotBeCalled(); + + $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); } } diff --git a/src/Abstraction/StateMachine/CompositeStateMachine.php b/src/Abstraction/StateMachine/CompositeStateMachine.php new file mode 100644 index 0000000..38adc44 --- /dev/null +++ b/src/Abstraction/StateMachine/CompositeStateMachine.php @@ -0,0 +1,27 @@ +stateMachine = $stateMachine; + } + + public function getTransitionToState(object $subject, string $graphName, string $toState): ?string + { + return $this->stateMachine->getTransitionToState($subject, $graphName, $toState); + } + + public function apply(object $subject, string $graphName, string $transition, array $context = []): void + { + $this->stateMachine->apply($subject, $graphName, $transition, $context); + } +} diff --git a/src/Abstraction/StateMachine/StateMachineInterface.php b/src/Abstraction/StateMachine/StateMachineInterface.php new file mode 100644 index 0000000..a8d27da --- /dev/null +++ b/src/Abstraction/StateMachine/StateMachineInterface.php @@ -0,0 +1,12 @@ +factory = $factory; + } + + public function getTransitionToState(object $subject, string $graphName, string $toState): ?string + { + $stateMachine = $this->factory->get($subject, $graphName); + Assert::isInstanceOf($stateMachine, SyliusStateMachineInterface::class); + + return $stateMachine->getTransitionToState($toState); + } + + public function apply(object $subject, string $graphName, string $transition, array $context = []): void + { + $stateMachine = $this->factory->get($subject, $graphName); + + $stateMachine->apply($transition); + } +} diff --git a/src/DependencyInjection/Compiler/WinzouStateMachineCallbacksModifier.php b/src/DependencyInjection/Compiler/WinzouStateMachineCallbacksModifier.php deleted file mode 100644 index e0fd4e4..0000000 --- a/src/DependencyInjection/Compiler/WinzouStateMachineCallbacksModifier.php +++ /dev/null @@ -1,28 +0,0 @@ -getParameter('flux_se.sylius_payum_stripe.refund.disabled'); - - $container->prependExtensionConfig('winzou_state_machine', [ - 'sylius_payment' => [ - 'callbacks' => [ - 'before' => [ - 'flux_se.sylius_payum_stripe_refund' => [ - 'disabled' => $refundDisabled, - ], - ], - ], - ], - ]); - } -} diff --git a/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php b/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php index 1f09038..9554d76 100644 --- a/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php +++ b/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php @@ -47,5 +47,10 @@ public function load(array $configs, ContainerBuilder $container): void new FileLocator(dirname(__DIR__) . '/Resources/config'), ); $loader->load('services.yaml'); + + if ($container->hasExtension('sylius_state_machine_abstraction')) { + $loader->load('services/abstraction/abstraction.yaml'); + $loader->load('services/listener/workflow/sylius_payment.yaml'); + } } } diff --git a/src/EventListener/Workflow/PaymentCompletedStateListener.php b/src/EventListener/Workflow/PaymentCompletedStateListener.php new file mode 100644 index 0000000..48e2b56 --- /dev/null +++ b/src/EventListener/Workflow/PaymentCompletedStateListener.php @@ -0,0 +1,35 @@ +paymentStateProcessor = $paymentStateProcessor; + } + + public function __invoke(CompletedEvent $event): void + { + /** @var PaymentInterface $payment */ + $payment = $event->getSubject(); + Assert::isInstanceOf($payment, PaymentInterface::class); + + $transition = $event->getTransition(); + Assert::notNull($transition); + // state machine transition from list always contains 1 element + $fromState = $transition->getFroms()[0]; + Assert::notNull($fromState); + + $this->paymentStateProcessor->__invoke($payment, $fromState); + } +} diff --git a/src/Extension/UpdatePaymentStateExtension.php b/src/Extension/UpdatePaymentStateExtension.php index f9c8e69..4f67dde 100644 --- a/src/Extension/UpdatePaymentStateExtension.php +++ b/src/Extension/UpdatePaymentStateExtension.php @@ -4,18 +4,15 @@ namespace FluxSE\SyliusPayumStripePlugin\Extension; +use FluxSE\SyliusPayumStripePlugin\Abstraction\StateMachine\StateMachineInterface; use Payum\Core\Extension\Context; use Payum\Core\Extension\ExtensionInterface; use Payum\Core\Model\ModelAggregateInterface; use Payum\Core\Storage\IdentityInterface; use Payum\Core\Storage\StorageInterface; -use SM\Factory\FactoryInterface; -use SM\SMException; use Sylius\Bundle\PayumBundle\Factory\GetStatusFactoryInterface; use Sylius\Component\Payment\Model\PaymentInterface; use Sylius\Component\Payment\PaymentTransitions; -use Sylius\Component\Resource\StateMachine\StateMachineInterface; -use Webmozart\Assert\Assert; /** * Reproduction of the Payum Core StorageExtension behaviour for Sylius payments @@ -24,26 +21,14 @@ */ final class UpdatePaymentStateExtension implements ExtensionInterface { - /** @var FactoryInterface */ - private $factory; - - /** @var StorageInterface */ - private $storage; - - /** @var GetStatusFactoryInterface */ - private $getStatusRequestFactory; - /** @var PaymentInterface[] */ - private $scheduledPaymentsToProcess = []; + private array $scheduledPaymentsToProcess = []; public function __construct( - FactoryInterface $factory, - StorageInterface $storage, - GetStatusFactoryInterface $getStatusRequestFactory + private StateMachineInterface $stateMachine, + private StorageInterface $storage, + private GetStatusFactoryInterface $getStatusRequestFactory ) { - $this->factory = $factory; - $this->storage = $storage; - $this->getStatusRequestFactory = $getStatusRequestFactory; } public function onPreExecute(Context $context): void @@ -73,9 +58,6 @@ public function onExecute(Context $context): void { } - /** - * @throws SMException - */ public function onPostExecute(Context $context): void { if (null !== $context->getException()) { @@ -105,9 +87,6 @@ public function onPostExecute(Context $context): void } } - /** - * @throws SMException - */ private function processPayment(Context $context, PaymentInterface $payment): void { $status = $this->getStatusRequestFactory->createNewWithModel($payment); @@ -125,21 +104,22 @@ private function processPayment(Context $context, PaymentInterface $payment): vo $this->updatePaymentState($payment, $value); } - /** - * @throws SMException - */ private function updatePaymentState(PaymentInterface $payment, string $nextState): void { - $stateMachine = $this->factory->get($payment, PaymentTransitions::GRAPH); - - Assert::isInstanceOf($stateMachine, StateMachineInterface::class); - - $transition = $stateMachine->getTransitionToState($nextState); + $transition = $this->stateMachine->getTransitionToState( + $payment, + PaymentTransitions::GRAPH, + $nextState + ); if (null === $transition) { return; } - $stateMachine->apply($transition); + $this->stateMachine->apply( + $payment, + PaymentTransitions::GRAPH, + $transition + ); } private function scheduleForProcessingIfSupported(PaymentInterface $payment): void diff --git a/src/FluxSESyliusPayumStripePlugin.php b/src/FluxSESyliusPayumStripePlugin.php index eea7f66..b28a4df 100644 --- a/src/FluxSESyliusPayumStripePlugin.php +++ b/src/FluxSESyliusPayumStripePlugin.php @@ -6,7 +6,6 @@ use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\PayumGatewayConfigOverride; use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\PayumStoragePaymentAliaser; -use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\WinzouStateMachineCallbacksModifier; use Sylius\Bundle\CoreBundle\Application\SyliusPluginTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -26,7 +25,6 @@ public function build(ContainerBuilder $container): void ], ])); - $container->addCompilerPass(new WinzouStateMachineCallbacksModifier()); $container->addCompilerPass(new PayumStoragePaymentAliaser()); parent::build($container); diff --git a/src/Resources/config/app/twig.yaml b/src/Resources/config/app/twig.yaml new file mode 100644 index 0000000..e10fdb2 --- /dev/null +++ b/src/Resources/config/app/twig.yaml @@ -0,0 +1,3 @@ +twig: + form_themes: + - '@FluxSESyliusPayumStripePlugin/Admin/PaymentMethod/Form/useAuthorize.html.twig' diff --git a/src/Resources/config/app/winzou_state_machine.yaml b/src/Resources/config/app/winzou_state_machine.yaml new file mode 100644 index 0000000..fe094ef --- /dev/null +++ b/src/Resources/config/app/winzou_state_machine.yaml @@ -0,0 +1,18 @@ +winzou_state_machine: + sylius_payment: + callbacks: + after: + flux_se.sylius_payum_stripe_refund: + # By default, this callback is disabled to avoid mistake + # you can enable it using this plugin config : `refund_disabled: false` + on: ["refund"] + do: ["@flux_se.sylius_payum_stripe.state_machine.refund", "__invoke"] + args: ["object", "event.getState()"] + flux_se.sylius_payum_stripe_cancel: + on: ["cancel"] + do: ["@flux_se.sylius_payum_stripe.state_machine.cancel", "__invoke"] + args: ["object", "event.getState()"] + flux_se.sylius_payum_stripe_complete_authorized: + on: ["complete"] + do: ["@flux_se.sylius_payum_stripe.state_machine.capture_authorized", "__invoke"] + args: ["object", "event.getState()"] diff --git a/src/Resources/config/config.yaml b/src/Resources/config/config.yaml index 3b0bef6..43a9fe8 100644 --- a/src/Resources/config/config.yaml +++ b/src/Resources/config/config.yaml @@ -1,22 +1,5 @@ -twig: - form_themes: - - '@FluxSESyliusPayumStripePlugin/Admin/PaymentMethod/Form/useAuthorize.html.twig' +imports: + - { resource: 'app/twig.yaml' } + - { resource: 'app/winzou_state_machine.yaml' } + -winzou_state_machine: - sylius_payment: - callbacks: - after: - flux_se.sylius_payum_stripe_refund: - # By default, this callback is disabled to avoid mistake - # you can enable it using this plugin config : `refund_disabled: false` - on: ["refund"] - do: ["@flux_se.sylius_payum_stripe.state_machine.refund", "__invoke"] - args: ["object", "event"] - flux_se.sylius_payum_stripe_cancel: - on: ["cancel"] - do: ["@flux_se.sylius_payum_stripe.state_machine.cancel", "__invoke"] - args: ["object", "event"] - flux_se.sylius_payum_stripe_complete_authorized: - on: ["complete"] - do: ["@flux_se.sylius_payum_stripe.state_machine.capture_authorized", "__invoke"] - args: ["object", "event"] diff --git a/src/Resources/config/services/abstraction/abstraction.yaml b/src/Resources/config/services/abstraction/abstraction.yaml new file mode 100644 index 0000000..e192a99 --- /dev/null +++ b/src/Resources/config/services/abstraction/abstraction.yaml @@ -0,0 +1,6 @@ +services: + + flux_se.sylius_payum_stripe.abstraction.state_machine.composite: + class: FluxSE\SyliusPayumStripePlugin\Abstraction\StateMachine\CompositeStateMachine + arguments: + $stateMachine: '@sylius_abstraction.state_machine.composite' diff --git a/src/Resources/config/services/listener/workflow/sylius_payment.yaml b/src/Resources/config/services/listener/workflow/sylius_payment.yaml new file mode 100644 index 0000000..92196c3 --- /dev/null +++ b/src/Resources/config/services/listener/workflow/sylius_payment.yaml @@ -0,0 +1,25 @@ +services: + + flux_se.sylius_payum_stripe_plugin.event_listener.workflow.payment_complete_state.cancel: + class: FluxSE\SyliusPayumStripePlugin\EventListener\Workflow\PaymentCompletedStateListener + arguments: + $paymentStateProcessor: '@flux_se.sylius_payum_stripe.state_machine.cancel' + tags: + - name: kernel.event_listener + event: workflow.sylius_payment.completed.cancel + + flux_se.sylius_payum_stripe_plugin.event_listener.workflow.payment_complete_state.refund: + class: FluxSE\SyliusPayumStripePlugin\EventListener\Workflow\PaymentCompletedStateListener + arguments: + $paymentStateProcessor: '@flux_se.sylius_payum_stripe.state_machine.refund' + tags: + - name: kernel.event_listener + event: workflow.sylius_payment.completed.refund + + flux_se.sylius_payum_stripe_plugin.event_listener.workflow.payment_complete_state.complete_authorized: + class: FluxSE\SyliusPayumStripePlugin\EventListener\Workflow\PaymentCompletedStateListener + arguments: + $paymentStateProcessor: '@flux_se.sylius_payum_stripe.state_machine.capture_authorized' + tags: + - name: kernel.event_listener + event: workflow.sylius_payment.completed.complete diff --git a/src/Resources/config/services/payum.yaml b/src/Resources/config/services/payum.yaml index d22547a..b553714 100644 --- a/src/Resources/config/services/payum.yaml +++ b/src/Resources/config/services/payum.yaml @@ -1,10 +1,18 @@ services: + flux_se.sylius_payum_stripe.abstraction.state_machine.winzou: + class: FluxSE\SyliusPayumStripePlugin\Abstraction\StateMachine\WinzouStateMachine + arguments: + $factory: '@sm.factory' + + flux_se.sylius_payum_stripe.abstraction.state_machine.composite: + alias: flux_se.sylius_payum_stripe.abstraction.state_machine.winzou + flux_se.sylius_payum_stripe.extension.update_payment_state: public: true class: FluxSE\SyliusPayumStripePlugin\Extension\UpdatePaymentStateExtension arguments: - $factory: '@sm.factory' + $stateMachine: '@flux_se.sylius_payum_stripe.abstraction.state_machine.composite' # Alias of "@payum.storage.sylius_component_core_model_payment" # or "@payum.storage.app_entity_payment_payment" or any other available # Payum storage handling Payment entity diff --git a/src/Resources/config/services/state_machine.yaml b/src/Resources/config/services/state_machine.yaml index 4676790..7dc87a7 100644 --- a/src/Resources/config/services/state_machine.yaml +++ b/src/Resources/config/services/state_machine.yaml @@ -5,6 +5,7 @@ services: class: FluxSE\SyliusPayumStripePlugin\StateMachine\RefundOrderProcessor arguments: $commandBus: '@sylius.command_bus' + $disabled: '%flux_se.sylius_payum_stripe.refund.disabled%' flux_se.sylius_payum_stripe.state_machine.cancel: public: true diff --git a/src/StateMachine/CancelOrderProcessor.php b/src/StateMachine/CancelOrderProcessor.php index 0ad3b18..faf1a55 100644 --- a/src/StateMachine/CancelOrderProcessor.php +++ b/src/StateMachine/CancelOrderProcessor.php @@ -5,15 +5,13 @@ namespace FluxSE\SyliusPayumStripePlugin\StateMachine; use FluxSE\SyliusPayumStripePlugin\Command\CancelPayment; -use SM\Event\TransitionEvent; use Sylius\Component\Core\Model\PaymentInterface; use Symfony\Component\Messenger\MessageBusInterface; use Webmozart\Assert\Assert; -final class CancelOrderProcessor +final class CancelOrderProcessor implements PaymentStateProcessorInterface { - /** @var MessageBusInterface */ - private $commandBus; + private MessageBusInterface $commandBus; public function __construct( MessageBusInterface $commandBus @@ -21,9 +19,9 @@ public function __construct( $this->commandBus = $commandBus; } - public function __invoke(PaymentInterface $payment, TransitionEvent $event): void + public function __invoke(PaymentInterface $payment, string $fromState): void { - if (false === in_array($event->getState(), [ + if (false === in_array($fromState, [ PaymentInterface::STATE_NEW, PaymentInterface::STATE_AUTHORIZED, ], true)) { @@ -32,7 +30,7 @@ public function __invoke(PaymentInterface $payment, TransitionEvent $event): voi /** @var int|null $paymentId */ $paymentId = $payment->getId(); - Assert::notNull($paymentId); + Assert::notNull($paymentId, 'A payment ID was not provided on the payment object.'); $this->commandBus->dispatch(new CancelPayment($paymentId)); } } diff --git a/src/StateMachine/CaptureAuthorizedOrderProcessor.php b/src/StateMachine/CaptureAuthorizedOrderProcessor.php index 228c108..33f2b63 100644 --- a/src/StateMachine/CaptureAuthorizedOrderProcessor.php +++ b/src/StateMachine/CaptureAuthorizedOrderProcessor.php @@ -5,30 +5,28 @@ namespace FluxSE\SyliusPayumStripePlugin\StateMachine; use FluxSE\SyliusPayumStripePlugin\Command\CaptureAuthorizedPayment; -use SM\Event\TransitionEvent; use Sylius\Component\Core\Model\PaymentInterface; use Symfony\Component\Messenger\MessageBusInterface; use Webmozart\Assert\Assert; -final class CaptureAuthorizedOrderProcessor +final class CaptureAuthorizedOrderProcessor implements PaymentStateProcessorInterface { - /** @var MessageBusInterface */ - private $commandBus; + private MessageBusInterface $commandBus; public function __construct(MessageBusInterface $commandBus) { $this->commandBus = $commandBus; } - public function __invoke(PaymentInterface $payment, TransitionEvent $event): void + public function __invoke(PaymentInterface $payment, string $fromState): void { - if (PaymentInterface::STATE_AUTHORIZED !== $event->getState()) { + if (PaymentInterface::STATE_AUTHORIZED !== $fromState) { return; } /** @var int|null $paymentId */ $paymentId = $payment->getId(); - Assert::notNull($paymentId); + Assert::notNull($paymentId, 'A payment ID was not provided on the payment object.'); $this->commandBus->dispatch(new CaptureAuthorizedPayment($paymentId)); } } diff --git a/src/StateMachine/PaymentStateProcessorInterface.php b/src/StateMachine/PaymentStateProcessorInterface.php new file mode 100644 index 0000000..97c04ea --- /dev/null +++ b/src/StateMachine/PaymentStateProcessorInterface.php @@ -0,0 +1,12 @@ +commandBus = $commandBus; + $this->disabled = $disabled; } - public function __invoke(PaymentInterface $payment, TransitionEvent $event): void + public function __invoke(PaymentInterface $payment, string $fromState): void { - if (PaymentInterface::STATE_COMPLETED !== $event->getState()) { + if ($this->disabled) { return; } /** @var int|null $paymentId */ $paymentId = $payment->getId(); - Assert::notNull($paymentId); + Assert::notNull($paymentId, 'A payment ID was not provided on the payment object.'); $this->commandBus->dispatch(new RefundPayment($paymentId)); } } diff --git a/tests/Application/config/sylius/1.13/packages/sylius_state_machine_abstraction.yaml b/tests/Application/config/sylius/1.13/packages/sylius_state_machine_abstraction.yaml new file mode 100644 index 0000000..ceee098 --- /dev/null +++ b/tests/Application/config/sylius/1.13/packages/sylius_state_machine_abstraction.yaml @@ -0,0 +1,2 @@ +sylius_state_machine_abstraction: + default_adapter: symfony_workflow diff --git a/tests/Behat/Bug/PantherCookieSetter.php b/tests/Behat/Bug/PantherCookieSetter.php new file mode 100644 index 0000000..0cf3c7f --- /dev/null +++ b/tests/Behat/Bug/PantherCookieSetter.php @@ -0,0 +1,31 @@ +minkSession->getDriver(); + + if ($driver instanceof PantherDriver) { + if (!$driver->isStarted()) { + $driver->start(); + } + } + + $this->decoratedCookieSetter->setCookie($name, $value); + } +} diff --git a/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php b/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php index 198fad3..86165e7 100644 --- a/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php +++ b/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php @@ -37,8 +37,8 @@ public function __construct( } /** - * @When I confirm my order with Stripe payment * @Given I have confirmed my order with Stripe payment + * @When I confirm my order with Stripe payment */ public function iConfirmMyOrderWithStripePayment(): void { diff --git a/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php b/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php index ad1ee7a..f452dd9 100644 --- a/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php +++ b/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php @@ -121,8 +121,8 @@ public function theStripeJsFormIsDisplayedAndICompleteThePaymentWithoutWebhookUs } /** - * @When I confirm my order with Stripe payment * @Given I have confirmed my order with Stripe payment + * @When I confirm my order with Stripe payment */ public function iConfirmMyOrderWithStripePayment(): void { diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml index 27485e3..1b2a5c7 100644 --- a/tests/Behat/Resources/services.xml +++ b/tests/Behat/Resources/services.xml @@ -2,6 +2,7 @@ + diff --git a/tests/Behat/Resources/services/bug.xml b/tests/Behat/Resources/services/bug.xml new file mode 100644 index 0000000..5539df3 --- /dev/null +++ b/tests/Behat/Resources/services/bug.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/tests/Behat/Resources/suites/stripe_checkout_session/shop.yaml b/tests/Behat/Resources/suites/stripe_checkout_session/shop.yaml index 0f4e9ea..f6bfa3c 100644 --- a/tests/Behat/Resources/suites/stripe_checkout_session/shop.yaml +++ b/tests/Behat/Resources/suites/stripe_checkout_session/shop.yaml @@ -47,6 +47,7 @@ default: contexts: - sylius.behat.context.hook.doctrine_orm - sylius.behat.context.transform.address + - sylius.behat.context.transform.cart - sylius.behat.context.transform.customer - sylius.behat.context.transform.lexical - sylius.behat.context.transform.locale diff --git a/tests/Behat/Resources/suites/stripe_js/shop.yaml b/tests/Behat/Resources/suites/stripe_js/shop.yaml index 9f530df..a84f855 100644 --- a/tests/Behat/Resources/suites/stripe_js/shop.yaml +++ b/tests/Behat/Resources/suites/stripe_js/shop.yaml @@ -47,6 +47,7 @@ default: contexts: - sylius.behat.context.hook.doctrine_orm - sylius.behat.context.transform.address + - sylius.behat.context.transform.cart - sylius.behat.context.transform.customer - sylius.behat.context.transform.lexical - sylius.behat.context.transform.locale