diff --git a/.gitattibutes b/.gitattibutes index a37293b..166211e 100644 --- a/.gitattibutes +++ b/.gitattibutes @@ -1,5 +1,4 @@ /features export-ignore -/spec export-ignore /ecs.php export-ignore /behat.yml.dist export-ignore /phpspec.yml.dist export-ignore @@ -8,4 +7,4 @@ /psalm.xml export-ignore /tests export-ignore /.gitattributes export-ignore -/.gitignore export-ignore \ No newline at end of file +/.gitignore export-ignore diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b4dec3..014d131 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,12 +28,8 @@ jobs: strategy: fail-fast: false matrix: - php: [ "7.4", "8.1" ] - symfony: [ "^5.4", "^6.4" ] - exclude: - - - php: "7.4" - symfony: "^6.4" + php: [ "8.2" ] + symfony: [ "^6.4", "^7.2" ] steps: - @@ -99,11 +95,6 @@ jobs: name: Run PHPStan run: vendor/bin/phpstan analyse if: always() && steps.end-of-setup.outcome == 'success' - - - - name: Run PHPSpec - run: vendor/bin/phpspec run --ansi -f progress --no-interaction - if: always() && steps.end-of-setup.outcome == 'success' tests: runs-on: ubuntu-latest @@ -112,26 +103,12 @@ jobs: strategy: fail-fast: false matrix: - php: ["8.0", "8.1", "8.2", "8.3"] - symfony: ["^5.4", "^6.4"] - sylius: ["~1.12.0", "~1.13.0"] + php: ["8.2", "8.3", "8.4"] + symfony: ["^6.4", "7.2"] + sylius: ["~2.0.0"] node: ["20.x"] mysql: ["8.0"] - exclude: - - - sylius: "~1.12.0" - php: "7.4" - - - sylius: "~1.13.0" - php: "7.4" - - - sylius: "~1.13.0" - php: "8.0" - - - php: "8.0" - symfony: "^6.4" - env: APP_ENV: test DATABASE_URL: "mysql://root:root@127.0.0.1/sylius?serverVersion=${{ matrix.mysql }}" @@ -197,12 +174,6 @@ jobs: if: matrix.sylius != '' run: composer require "sylius/sylius:${{ matrix.sylius }}" --no-update --no-scripts --no-interaction - - - name: Fix build with PHP 8.3 - if: matrix.php == '8.3' - run: | - composer remove --dev "phpspec/phpspec" --no-update --no-scripts --no-interaction - - name: Fix build with Symfony ^5.4 if: matrix.symfony == '^5.4' diff --git a/.gitignore b/.gitignore index edd50c5..7ec1623 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ drivers /.phpunit.result.cache /phpunit.xml /phpstan.neon -/phpspec.yml /behat.yml # Symfony CLI https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project diff --git a/composer.json b/composer.json index 9b98185..571ee29 100644 --- a/composer.json +++ b/composer.json @@ -11,46 +11,49 @@ } ], "require": { - "flux-se/payum-stripe-bundle": "^2.0", - "sylius/sylius": "^1.9" + "flux-se/payum-stripe-bundle": "^3.0", + "sylius/sylius": "^2.0" }, "require-dev": { "ext-json": "*", "behat/behat": "^3.7", - "dbrekelmans/bdi": "^1.2", + "dbrekelmans/bdi": "^1.4", "friends-of-behat/mink": "^1.9", "friends-of-behat/mink-browserkit-driver": "^1.4", "friends-of-behat/mink-debug-extension": "^2.0", "friends-of-behat/mink-extension": "^2.5", "friends-of-behat/page-object-extension": "^0.3", "friends-of-behat/suite-settings-extension": "^1.1", - "friends-of-behat/symfony-extension": "^2.1", + "friends-of-behat/symfony-extension": "^2.0", "friends-of-behat/variadic-extension": "^1.3", - "phpspec/phpspec": "^7.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan-doctrine": "^1.0", - "phpstan/phpstan-strict-rules": "^1.0", - "phpstan/phpstan-webmozart-assert": "^1.0", - "phpunit/phpunit": "^9.5", - "polishsymfonycommunity/symfony-mocker-container": "^1.0", + "nyholm/psr7": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-doctrine": "^2.0", + "phpstan/phpstan-symfony": "^2.0", + "phpstan/phpstan-webmozart-assert": "^2.0", + "spaze/phpstan-stripe": "^3.2", + "phpunit/phpunit": "^10", "robertfausk/behat-panther-extension": "^1.1", "sylius-labs/coding-standard": "^4.1", "sylius-labs/suite-tags-extension": "^0.2.0", - "symfony/browser-kit": "^5.4|^6.4", - "symfony/debug-bundle": "^5.4|^6.4", - "symfony/dotenv": "^5.4|^6.4", - "symfony/http-client": "^5.4|^6.4", - "symfony/intl": "^5.4|^6.4", - "symfony/runtime": "^5.4|^6.4", - "symfony/web-profiler-bundle": "^5.4|^6.4", - "symfony/webpack-encore-bundle": "^1|^2" + "symfony/browser-kit": "^6.4|^7.2", + "symfony/debug-bundle": "^6.4|^7.2", + "symfony/dotenv": "^6.4|^7.2", + "symfony/http-client": "^6.4|^7.2", + "symfony/intl": "^6.4|^7.2", + "symfony/runtime": "^6.4|^7.2", + "symfony/web-profiler-bundle": "^6.4|^7.2", + "symfony/webpack-encore-bundle": "^2", + "rector/rector": "^2.0", + "mockery/mockery": "^1.6", + "phpstan/phpstan-mockery": "^2.0" }, "autoload": { "psr-4": { "FluxSE\\SyliusPayumStripePlugin\\": "src/" } }, "autoload-dev": { "psr-4": { - "spec\\FluxSE\\SyliusPayumStripePlugin\\": "spec/", "Tests\\FluxSE\\SyliusPayumStripePlugin\\": "tests/", "Tests\\FluxSE\\SyliusPayumStripePlugin\\App\\": "tests/Application/src/" } @@ -68,16 +71,15 @@ }, "config": { "allow-plugins": { - "dealerdirect/phpcodesniffer-composer-installer": false, - "phpstan/extension-installer": false, - "symfony/flex": false, + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true, "symfony/thanks": true, "symfony/runtime": true } }, "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" }, "runtime": { "project_dir": "tests/Application", diff --git a/config/app/twig_hooks.yaml b/config/app/twig_hooks.yaml new file mode 100644 index 0000000..239a74a --- /dev/null +++ b/config/app/twig_hooks.yaml @@ -0,0 +1,2 @@ +imports: + - { resource: 'twig_hooks/**/*.yaml' } diff --git a/config/app/twig_hooks/admin/payment_method/admin.yaml b/config/app/twig_hooks/admin/payment_method/admin.yaml new file mode 100644 index 0000000..1914bdc --- /dev/null +++ b/config/app/twig_hooks/admin/payment_method/admin.yaml @@ -0,0 +1,40 @@ +sylius_twig_hooks: + hooks: + 'sylius_admin.payment_method.create.content': &component + form: + props: + factoryName: '@=_context.resource.getGatewayConfig().getFactoryName()' + 'sylius_admin.payment_method.update.content': *component + + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_checkout_session': &form + form: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form.html.twig' + priority: 0 + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_js': *form + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_checkout_session': *form + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_js': *form + + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_checkout_session.form': &form_inner + publishable_key: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form/publishable_key.html.twig' + priority: 400 + secret_key: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form/secret_key.html.twig' + priority: 300 + use_authorize: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form/use_authorize.html.twig' + priority: 200 + webhook_secret_keys: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form/webhook_secret_keys.html.twig' + priority: 100 + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_js.form': *form_inner + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_checkout_session.form': *form_inner + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_js.form': *form_inner + + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_checkout_session.form.webhook_secret_keys': &webhook_secret_keys + webhook_secret_key: + template: '@FluxSESyliusPayumStripePlugin/admin/payment_method/form/webhook_secret_keys/webhook_secret_key.html.twig' + priority: 0 + 'sylius_admin.payment_method.create.content.form.sections.gateway_configuration.stripe_js.form.webhook_secret_keys': *webhook_secret_keys + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_checkout_session.form.webhook_secret_keys': *webhook_secret_keys + 'sylius_admin.payment_method.update.content.form.sections.gateway_configuration.stripe_js.form.webhook_secret_keys': *webhook_secret_keys diff --git a/config/config.yaml b/config/config.yaml new file mode 100644 index 0000000..4333553 --- /dev/null +++ b/config/config.yaml @@ -0,0 +1,4 @@ +imports: + - { resource: 'app/twig_hooks.yaml' } + + diff --git a/src/Resources/config/services.yaml b/config/services.yaml similarity index 100% rename from src/Resources/config/services.yaml rename to config/services.yaml diff --git a/src/Resources/config/services/command_handlers.yaml b/config/services/command_handlers.yaml similarity index 100% rename from src/Resources/config/services/command_handlers.yaml rename to config/services/command_handlers.yaml diff --git a/src/Resources/config/services/factory.yaml b/config/services/factory.yaml similarity index 100% rename from src/Resources/config/services/factory.yaml rename to config/services/factory.yaml diff --git a/src/Resources/config/services/listener/workflow/sylius_payment.yaml b/config/services/listener/workflow/sylius_payment.yaml similarity index 100% rename from src/Resources/config/services/listener/workflow/sylius_payment.yaml rename to config/services/listener/workflow/sylius_payment.yaml diff --git a/src/Resources/config/services/payum.yaml b/config/services/payum.yaml similarity index 59% rename from src/Resources/config/services/payum.yaml rename to config/services/payum.yaml index b553714..7cc3f42 100644 --- a/src/Resources/config/services/payum.yaml +++ b/config/services/payum.yaml @@ -1,23 +1,15 @@ 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: - $stateMachine: '@flux_se.sylius_payum_stripe.abstraction.state_machine.composite' + $stateMachine: '@sylius_abstraction.state_machine' # 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 $storage: '@payum.storage.flux_se_sylius_payment' - $getStatusRequestFactory: '@sylius.factory.payum_get_status_action' + $getStatusRequestFactory: '@sylius_payum.factory.get_status' tags: - name: payum.extension factory: stripe_checkout_session diff --git a/src/Resources/config/services/state_machine.yaml b/config/services/state_machine.yaml similarity index 100% rename from src/Resources/config/services/state_machine.yaml rename to config/services/state_machine.yaml diff --git a/src/Resources/config/services/stripe_checkout_session/api_platform.yaml b/config/services/stripe_checkout_session/api_platform.yaml similarity index 100% rename from src/Resources/config/services/stripe_checkout_session/api_platform.yaml rename to config/services/stripe_checkout_session/api_platform.yaml diff --git a/src/Resources/config/services/stripe_checkout_session/gateway_configuration_types.yaml b/config/services/stripe_checkout_session/gateway_configuration_types.yaml similarity index 100% rename from src/Resources/config/services/stripe_checkout_session/gateway_configuration_types.yaml rename to config/services/stripe_checkout_session/gateway_configuration_types.yaml diff --git a/src/Resources/config/services/stripe_checkout_session/payum.yaml b/config/services/stripe_checkout_session/payum.yaml similarity index 100% rename from src/Resources/config/services/stripe_checkout_session/payum.yaml rename to config/services/stripe_checkout_session/payum.yaml diff --git a/src/Resources/config/services/stripe_checkout_session/providers.yaml b/config/services/stripe_checkout_session/providers.yaml similarity index 100% rename from src/Resources/config/services/stripe_checkout_session/providers.yaml rename to config/services/stripe_checkout_session/providers.yaml diff --git a/src/Resources/config/services/stripe_js/api_platform.yaml b/config/services/stripe_js/api_platform.yaml similarity index 100% rename from src/Resources/config/services/stripe_js/api_platform.yaml rename to config/services/stripe_js/api_platform.yaml diff --git a/src/Resources/config/services/stripe_js/gateway_configuration_types.yaml b/config/services/stripe_js/gateway_configuration_types.yaml similarity index 100% rename from src/Resources/config/services/stripe_js/gateway_configuration_types.yaml rename to config/services/stripe_js/gateway_configuration_types.yaml diff --git a/src/Resources/config/services/stripe_js/payum.yaml b/config/services/stripe_js/payum.yaml similarity index 100% rename from src/Resources/config/services/stripe_js/payum.yaml rename to config/services/stripe_js/payum.yaml diff --git a/src/Resources/config/services/stripe_js/providers.yaml b/config/services/stripe_js/providers.yaml similarity index 100% rename from src/Resources/config/services/stripe_js/providers.yaml rename to config/services/stripe_js/providers.yaml diff --git a/ecs.php b/ecs.php index a20090f..2908459 100644 --- a/ecs.php +++ b/ecs.php @@ -2,19 +2,14 @@ declare(strict_types=1); -use PhpCsFixer\Fixer\ControlStructure\TrailingCommaInMultilineFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; -return static function (ECSConfig $config): void { - $config->import(__DIR__ . '/vendor/sylius-labs/coding-standard/ecs.php'); - - $config->paths([ +return ECSConfig::configure() + ->withSets([ + 'vendor/sylius-labs/coding-standard/ecs.php', + ]) + ->withPaths([ 'src', 'tests/Behat', - 'spec', - 'ecs.php', - ]); - - // PHP 7 compatibility - $config->ruleWithConfiguration(TrailingCommaInMultilineFixer::class, ['elements' => ['arrays']]); -}; + ]) +; diff --git a/features/admin/stripe_checkout_session/managing_payment_method.feature b/features/admin/stripe_checkout_session/managing_payment_method.feature index d1552b8..b3aa247 100644 --- a/features/admin/stripe_checkout_session/managing_payment_method.feature +++ b/features/admin/stripe_checkout_session/managing_payment_method.feature @@ -10,10 +10,10 @@ Feature: Adding a new Stripe Checkout Session payment method @ui @javascript Scenario: Adding a new stripe payment method using authorize - Given I want to create a new Stripe Checkout Session payment method + Given I want to create a new payment method with "Stripe Checkout Session" gateway factory When I name it "Stripe Checkout Session" in "English (United States)" And I specify its code as "stripe_sca_test" - And I configure it with test stripe gateway data "TEST", "TEST" + And I configure it with test stripe gateway data "TEST" and "TEST" And I add a webhook secret key "TEST" And I use authorize And I add it @@ -23,13 +23,13 @@ Feature: Adding a new Stripe Checkout Session payment method @ui @javascript Scenario: Adding a new stripe payment method not using authorize - Given I want to create a new Stripe Checkout Session payment method + Given I want to create a new payment method with "Stripe Checkout Session" gateway factory When I name it "Stripe Checkout Session" in "English (United States)" And I specify its code as "stripe_sca_test" - And I configure it with test stripe gateway data "TEST", "TEST" + And I configure it with test stripe gateway data "TEST" and "TEST" And I add a webhook secret key "TEST" And I don't use authorize And I add it Then I should be notified that it has been successfully created - And I shouldn't see a warning message under the use authorize field + And I should not see a warning message under the use authorize field And the payment method "Stripe Checkout Session" should appear in the registry diff --git a/features/admin/stripe_checkout_session/refunding_order.feature b/features/admin/stripe_checkout_session/refunding_order.feature index 0513286..53743b0 100644 --- a/features/admin/stripe_checkout_session/refunding_order.feature +++ b/features/admin/stripe_checkout_session/refunding_order.feature @@ -22,4 +22,4 @@ Feature: Refunding an order with Stripe Checkout Session When I mark this order's payment as refunded Then I should be notified that the order's payment has been successfully refunded And it should have payment with state refunded - And it's payment state should be refunded + And it should have payment state "Refunded" diff --git a/features/admin/stripe_js/managing_payment_method.feature b/features/admin/stripe_js/managing_payment_method.feature index 7ae29d8..e72307d 100644 --- a/features/admin/stripe_js/managing_payment_method.feature +++ b/features/admin/stripe_js/managing_payment_method.feature @@ -10,10 +10,10 @@ Feature: Adding a new Stripe JS payment method @ui @javascript Scenario: Adding a new stripe payment method using authorize - Given I want to create a new Stripe JS payment method + Given I want to create a new payment method with "Stripe JS" gateway factory When I name it "Stripe JS" in "English (United States)" And I specify its code as "stripe_sca_test" - And I configure it with test stripe gateway data "TEST", "TEST" + And I configure it with test stripe gateway data "TEST" and "TEST" And I add a webhook secret key "TEST" And I use authorize And I add it @@ -23,13 +23,13 @@ Feature: Adding a new Stripe JS payment method @ui @javascript Scenario: Adding a new stripe payment method not using authorize - Given I want to create a new Stripe JS payment method + Given I want to create a new payment method with "Stripe JS" gateway factory When I name it "Stripe JS" in "English (United States)" And I specify its code as "stripe_sca_test" - And I configure it with test stripe gateway data "TEST", "TEST" + And I configure it with test stripe gateway data "TEST" and "TEST" And I add a webhook secret key "TEST" And I don't use authorize And I add it Then I should be notified that it has been successfully created - And I shouldn't see a warning message under the use authorize field + And I should not see a warning message under the use authorize field And the payment method "Stripe JS" should appear in the registry diff --git a/features/admin/stripe_js/refunding_order.feature b/features/admin/stripe_js/refunding_order.feature index 494d263..f36b10f 100644 --- a/features/admin/stripe_js/refunding_order.feature +++ b/features/admin/stripe_js/refunding_order.feature @@ -22,4 +22,4 @@ Feature: Refunding an order with Stripe JS When I mark this order's payment as refunded Then I should be notified that the order's payment has been successfully refunded And it should have payment with state refunded - And it's payment state should be refunded + And it should have payment state "Refunded" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index be3601f..3aa3c48 100755 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,27 +5,14 @@ parameters: paths: - src - - tests - - excludePaths: - # Makes PHPStan crash - - 'src/DependencyInjection/Configuration.php' - - - tests/Application/Kernel.php - - tests/Application/public/index.php - - tests/Application/config/**.php - - tests/Application/var/**.php - - tests/Application/node_modules/**.php + - tests/Behat + - tests/Unit ignoreErrors: - - identifier: missingType.iterableValue + - identifier: return.unusedType - identifier: missingType.generics - - '/Parameter #1 \$configuration of method Symfony\\Component\\DependencyInjection\\Extension\\Extension::processConfiguration\(\) expects Symfony\\Component\\Config\\Definition\\ConfigurationInterface, Symfony\\Component\\Config\\Definition\\ConfigurationInterface\|null given\./' - - '/Parameter #1 \$request \(Payum\\Core\\Request\\Convert\) of method FluxSE\\SyliusPayumStripePlugin\\Action\\ConvertPaymentAction::execute\(\) should be contravariant with parameter \$request \(mixed\) of method Payum\\Core\\Action\\ActionInterface::execute\(\)/' - - '/Parameter #1 \$request \(Payum\\Core\\Request\\Convert\) of method FluxSE\\SyliusPayumStripePlugin\\Action\\StripeJs\\ConvertPaymentAction::execute\(\) should be contravariant with parameter \$request \(mixed\) of method Payum\\Core\\Action\\ActionInterface::execute\(\)/' - - - message: '/Call to an undefined method Mockery\\ExpectationInterface\|Mockery\\HigherOrderMessage::(once|andReturnUsing)\(\)\./' - paths: - - tests/Behat/Mocker/Api/CheckoutSessionMocker.php - - tests/Behat/Mocker/Api/PaymentIntentMocker.php - - tests/Behat/Mocker/Api/RefundMocker.php + path: src/Form/Type/StripeGatewayConfigurationType.php + - identifier: argument.type + path: tests/Behat/Mocker/PayumActionMocker.php + - identifier: staticMethod.unresolvableReturnType + path: tests/Behat/Mocker/PayumActionMocker.php diff --git a/phpunit.xml.dist b/phpunit.xml.dist index af808d4..d00ec7a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,10 +1,11 @@ + displayDetailsOnTestsThatTriggerDeprecations="true" + bootstrap="vendor/autoload.php" +> tests @@ -12,7 +13,16 @@ + + + + + + + + + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..4d32a12 --- /dev/null +++ b/rector.php @@ -0,0 +1,17 @@ +withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests/Behat', + __DIR__ . '/tests/Unit', + ]) + ->withSets([ + LevelSetList::UP_TO_PHP_82, + ]) +; diff --git a/spec/Action/ConvertPaymentActionSpec.php b/spec/Action/ConvertPaymentActionSpec.php deleted file mode 100644 index 389bcd9..0000000 --- a/spec/Action/ConvertPaymentActionSpec.php +++ /dev/null @@ -1,74 +0,0 @@ -beConstructedWith($detailsProvider); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(ConvertPaymentAction::class); - } - - public function it_implements_action_interface(): void - { - $this->shouldHaveType(ActionInterface::class); - $this->shouldHaveType(ConvertPaymentActionInterface::class); - } - - /** - * @param Convert|Collaborator $request - * @param Collaborator|PaymentInterface $payment - * @param Collaborator|OrderInterface $order - * @param Collaborator|DetailsProviderInterface $detailsProvider - */ - public function it_executes( - Convert $request, - PaymentInterface $payment, - OrderInterface $order, - DetailsProviderInterface $detailsProvider - ): void { - $details = []; - $payment->getOrder()->willReturn($order); - $request->getSource()->willReturn($payment); - $request->getTo()->willReturn('array'); - $detailsProvider->getDetails($order)->willReturn($details); - - $request->setResult($details)->shouldBeCalled(); - - $this->execute($request); - } - - /** - * @param Convert|Collaborator $request - * @param Collaborator|PaymentInterface $payment - */ - public function it_supports_only_convert_request_payment_source_and_array_to( - Convert $request, - PaymentInterface $payment - ): void { - $request->getSource()->willReturn($payment); - $request->getTo()->willReturn('array'); - - $this->supports($request)->shouldReturn(true); - } -} diff --git a/spec/Extension/CancelExistingPaymentIntentExtensionSpec.php b/spec/Extension/CancelExistingPaymentIntentExtensionSpec.php deleted file mode 100644 index 49a8b1d..0000000 --- a/spec/Extension/CancelExistingPaymentIntentExtensionSpec.php +++ /dev/null @@ -1,219 +0,0 @@ -beConstructedWith( - $expireSessionRequestFactory, - $allSessionRequestFactory - ); - } - - public function it_is_initializable(): void - { - $this->shouldBeAnInstanceOf(ExtensionInterface::class); - } - - public function it_does_nothing_when_action_is_not_the_convert_payment_action_targeted( - Context $context, - ActionInterface $action - ): void { - $context->getAction()->willReturn($action); - - $this->onExecute($context); - } - - public function it_does_nothing_when_payment_details_are_empty( - Context $context, - ConvertPaymentActionInterface $action, - Convert $request, - PaymentInterface $payment - ): void { - $context->getAction()->willReturn($action); - $context->getRequest()->willReturn($request); - $request->getSource()->willReturn($payment); - - $payment->getDetails()->willReturn([]); - - $this->onExecute($context); - } - - public function it_does_nothing_when_payment_details_are_something_else_than_a_payment_intent( - Context $context, - ConvertPaymentActionInterface $action, - Convert $request, - PaymentInterface $payment - ): void { - $context->getAction()->willReturn($action); - $context->getRequest()->willReturn($request); - $request->getSource()->willReturn($payment); - - $payment->getDetails()->willReturn([ - 'object' => SetupIntent::OBJECT_NAME, - ]); - - $this->onExecute($context); - } - - public function it_doesnt_found_the_related_session_and_do_nothing( - Context $context, - ConvertPaymentActionInterface $action, - Convert $request, - PaymentInterface $payment, - GatewayInterface $gateway, - AllSessionRequestFactoryInterface $allSessionRequestFactory, - AllInterface $allSessionRequest - ): void { - $context->getAction()->willReturn($action); - $context->getRequest()->willReturn($request); - $request->getSource()->willReturn($payment); - $context->getGateway()->willReturn($gateway); - - $piId = 'pi_test_0000000000000000000'; - $payment->getDetails()->willReturn([ - 'id' => $piId, - 'object' => PaymentIntent::OBJECT_NAME, - ]); - - $allSessionRequestFactory - ->createNew() - ->willReturn($allSessionRequest); - - $allSessionRequest->setParameters([ - 'payment_intent' => $piId, - ])->shouldBeCalled(); - $allSessionRequest->getApiResources()->willReturn(Collection::constructFrom(['data' => []])); - - $gateway->execute($allSessionRequest)->shouldBeCalled(); - - $this->onExecute($context); - } - - public function it_founds_a_related_expired_session_and_does_nothing( - Context $context, - ConvertPaymentActionInterface $action, - Convert $request, - PaymentInterface $payment, - GatewayInterface $gateway, - AllSessionRequestFactoryInterface $allSessionRequestFactory, - AllInterface $allSessionRequest - ): void { - $context->getAction()->willReturn($action); - $context->getRequest()->willReturn($request); - $request->getSource()->willReturn($payment); - $context->getGateway()->willReturn($gateway); - - $piId = 'pi_test_0000000000000000000'; - $csId = 'cs_test_0000000000000000000'; - $payment->getDetails()->willReturn([ - 'id' => $piId, - 'object' => PaymentIntent::OBJECT_NAME, - ]); - - $allSessionRequestFactory - ->createNew() - ->willReturn($allSessionRequest); - - $allSessionRequest->setParameters([ - 'payment_intent' => $piId, - ])->shouldBeCalled(); - $allSessionRequest->getApiResources()->willReturn(Collection::constructFrom([ - 'data' => [ - [ - 'id' => $csId, - 'status' => Session::STATUS_EXPIRED, - ], - ], - ])); - - $gateway->execute($allSessionRequest)->shouldBeCalled(); - - $this->onExecute($context); - } - - public function it_founds_a_related_session_and_expires_it( - Context $context, - ConvertPaymentActionInterface $action, - Convert $request, - PaymentInterface $payment, - GatewayInterface $gateway, - AllSessionRequestFactoryInterface $allSessionRequestFactory, - AllInterface $allSessionRequest, - ExpireSessionRequestFactoryInterface $expireSessionRequestFactory, - CustomCallInterface $expireSessionRequest - ): void { - $context->getAction()->willReturn($action); - $context->getRequest()->willReturn($request); - $request->getSource()->willReturn($payment); - $context->getGateway()->willReturn($gateway); - - $piId = 'pi_test_0000000000000000000'; - $csId = 'cs_test_0000000000000000000'; - $payment->getDetails()->willReturn([ - 'id' => $piId, - 'object' => PaymentIntent::OBJECT_NAME, - ]); - - $allSessionRequestFactory - ->createNew() - ->willReturn($allSessionRequest); - - $allSessionRequest->setParameters([ - 'payment_intent' => $piId, - ])->shouldBeCalled(); - $allSessionRequest->getApiResources()->willReturn(Collection::constructFrom([ - 'data' => [ - [ - 'id' => $csId, - 'status' => Session::STATUS_OPEN, - ], - ], - ])); - - $gateway->execute($allSessionRequest)->shouldBeCalled(); - - $expireSessionRequest->beConstructedWith([$csId]); - - $expireSessionRequestFactory - ->createNew($csId) - ->willReturn($expireSessionRequest); - - $gateway->execute($expireSessionRequest)->shouldBeCalled(); - - $this->onExecute($context); - } - - public function it_onPreExecute_does_nothing(Context $context): void - { - $this->onPreExecute($context); - } - - public function it_onPostExecute_does_nothing(Context $context): void - { - $this->onPostExecute($context); - } -} diff --git a/spec/Extension/UpdatePaymentStateExtensionSpec.php b/spec/Extension/UpdatePaymentStateExtensionSpec.php deleted file mode 100644 index d82c281..0000000 --- a/spec/Extension/UpdatePaymentStateExtensionSpec.php +++ /dev/null @@ -1,222 +0,0 @@ -beConstructedWith($stateMachine, $storage, $getStatusRequestFactory); - } - - public function it_is_initializable(): void - { - $this->shouldBeAnInstanceOf(ExtensionInterface::class); - } - - public function it_onPreExecute_with_Identity_finds_the_related_payment_and_stores_it( - Context $context, - ModelAggregateInterface $request, - IdentityInterface $model, - StorageInterface $storage, - PaymentInterface $payment - ): void { - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($model); - - $storage->find($model)->willReturn($payment); - $model->getId()->willReturn(1); - - $this->onPreExecute($context); - } - - public function it_onPreExecute_with_Payment_stores_it( - Context $context, - ModelAggregateInterface $request, - PaymentInterface $model - ): void { - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($model); - $model->getId()->willReturn(1); - - $this->onPreExecute($context); - } - - public function it_onPreExecute_without_Payment_or_Identify_does_nothing( - Context $context, - ModelAggregateInterface $request, - PayumPaymentInterface $model - ): void { - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($model); - - $this->onPreExecute($context); - } - - public function it_onPreExecute_without_ModelAggregateInterface_does_nothing( - Context $context, - TokenAggregateInterface $request - ): void { - $context->getRequest()->willReturn($request); - - $this->onPreExecute($context); - } - - public function it_onExecute_does_nothing(Context $context): void - { - $this->onExecute($context); - } - - public function it_OnPostExecute_apply_a_transition( - Context $context, - ModelAggregateInterface $request, - PaymentInterface $payment, - GetStatusInterface $status, - GetStatusFactoryInterface $getStatusRequestFactory, - GatewayInterface $gateway, - StateMachineInterface $stateMachine - ): void { - $context->getException()->willReturn(null); - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($payment); - $payment->getId()->willReturn(1); - - $context->getPrevious()->willReturn([]); - - $context->getGateway()->willReturn($gateway); - $status->beConstructedWith([$payment]); - $getStatusRequestFactory->createNewWithModel($payment)->willReturn($status); - - $gateway->execute($status)->shouldBeCalled(); - $payment->getState()->willReturn(PaymentInterface::STATE_NEW); - $status->getValue()->willReturn(PaymentInterface::STATE_COMPLETED); - - $stateMachine->getTransitionToState( - $payment, - PaymentTransitions::GRAPH, - PaymentInterface::STATE_COMPLETED - )->willReturn('complete'); - $stateMachine->apply( - $payment, - PaymentTransitions::GRAPH, - 'complete' - )->shouldBeCalled(); - - $this->onPostExecute($context); - } - - public function it_OnPostExecute_apply_a_transition_without_a_Sylius_PaymentInterface_when_there_was_previously_stored_payment( - Context $previousContext, - ModelAggregateInterface $previousRequest, - PaymentInterface $previousPayment, - Context $context, - ModelAggregateInterface $request, - PayumPaymentInterface $payment, - GetStatusInterface $status, - GetStatusFactoryInterface $getStatusRequestFactory, - GatewayInterface $gateway, - StateMachineInterface $stateMachine - ): void { - $context->getException()->willReturn(null); - $previousContext->getRequest()->willReturn($previousRequest); - $previousRequest->getModel()->willReturn($previousPayment); - $previousPayment->getId()->willReturn(1); - - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($payment); - - $context->getPrevious()->willReturn([]); - - $context->getGateway()->willReturn($gateway); - $status->beConstructedWith([$previousPayment]); - $getStatusRequestFactory->createNewWithModel($previousPayment)->willReturn($status); - - $gateway->execute($status)->shouldBeCalled(); - $previousPayment->getState()->willReturn(PaymentInterface::STATE_NEW); - $status->getValue()->willReturn(PaymentInterface::STATE_COMPLETED); - - $stateMachine->getTransitionToState( - $previousPayment, - PaymentTransitions::GRAPH, - PaymentInterface::STATE_COMPLETED - )->willReturn('complete'); - $stateMachine->apply( - $previousPayment, - PaymentTransitions::GRAPH, - 'complete' - )->shouldBeCalled(); - - $this->onPreExecute($previousContext); - - $this->onPostExecute($context); - } - - public function it_OnPostExecute_without_ModelAggregateInterface_does_nothing_if_there_is_previous_context( - Context $context, - TokenAggregateInterface $request - ): void { - $context->getException()->willReturn(null); - $context->getRequest()->willReturn($request); - - $context->getPrevious()->willReturn([1]); - - $this->onPostExecute($context); - } - - public function it_OnPostExecute_without_ModelAggregateInterface_does_nothing_if_there_is_no_previous_context( - Context $context, - TokenAggregateInterface $request - ): void { - $context->getException()->willReturn(null); - $context->getRequest()->willReturn($request); - - $context->getPrevious()->willReturn([]); - - $this->onPostExecute($context); - } - - public function it_OnPostExecute_with_ModelAggregateInterface_does_nothing_if_it_is_not_a_sylius_PaymentInterface( - Context $context, - ModelAggregateInterface $request, - PayumPaymentInterface $model - ): void { - $context->getException()->willReturn(null); - $context->getRequest()->willReturn($request); - $request->getModel()->willReturn($model); - - $context->getPrevious()->willReturn([]); - - $this->onPostExecute($context); - } - - public function it_onPostExecute_with_exception_does_nothing( - Context $context, - TokenAggregateInterface $request - ): void { - $exception = new Exception(); - $context->getException()->willReturn($exception); - - $this->onPostExecute($context); - } -} diff --git a/spec/Provider/CustomerEmailProviderSpec.php b/spec/Provider/CustomerEmailProviderSpec.php deleted file mode 100644 index db66905..0000000 --- a/spec/Provider/CustomerEmailProviderSpec.php +++ /dev/null @@ -1,38 +0,0 @@ -shouldHaveType(CustomerEmailProvider::class); - $this->shouldHaveType(CustomerEmailProviderInterface::class); - } - - public function it_get_customer_email_from_a_customer( - OrderInterface $order, - CustomerInterface $customer - ): void { - $order->getCustomer()->willReturn($customer); - $customer->getEmail()->willReturn('customer@domain.tld'); - - $this->getCustomerEmail($order)->shouldReturn('customer@domain.tld'); - } - - public function it_could_return_null( - OrderInterface $order - ): void { - $order->getCustomer()->willReturn(null); - - $this->getCustomerEmail($order)->shouldReturn(null); - } -} diff --git a/spec/Provider/DetailsProviderSpec.php b/spec/Provider/DetailsProviderSpec.php deleted file mode 100644 index 903e763..0000000 --- a/spec/Provider/DetailsProviderSpec.php +++ /dev/null @@ -1,75 +0,0 @@ -beConstructedWith( - $customerEmailProvider, - $lineItemsProvider, - $paymentMethodTypesProvider, - $modeProvider - ); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(DetailsProvider::class); - $this->shouldHaveType(DetailsProviderInterface::class); - } - - public function it_get_full_details( - OrderInterface $order, - CustomerEmailProviderInterface $customerEmailProvider, - LineItemsProviderInterface $lineItemsProvider, - PaymentMethodTypesProviderInterface $paymentMethodTypesProvider, - ModeProviderInterface $modeProvider - ): void { - $customerEmailProvider->getCustomerEmail($order)->willReturn('customer@domain.tld'); - $lineItemsProvider->getLineItems($order)->willReturn([]); - $paymentMethodTypesProvider->getPaymentMethodTypes($order)->willReturn(['card']); - $modeProvider->getMode($order)->willReturn(Session::MODE_PAYMENT); - - $this->getDetails($order)->shouldReturn([ - 'customer_email' => 'customer@domain.tld', - 'mode' => Session::MODE_PAYMENT, - 'line_items' => [], - 'payment_method_types' => ['card'], - ]); - } - - public function it_get_minimum_details( - OrderInterface $order, - CustomerEmailProviderInterface $customerEmailProvider, - LineItemsProviderInterface $lineItemsProvider, - PaymentMethodTypesProviderInterface $paymentMethodTypesProvider, - ModeProviderInterface $modeProvider - ): void { - $customerEmailProvider->getCustomerEmail($order)->willReturn(null); - $lineItemsProvider->getLineItems($order)->willReturn(null); - $paymentMethodTypesProvider->getPaymentMethodTypes($order)->willReturn([]); - $modeProvider->getMode($order)->willReturn(Session::MODE_PAYMENT); - - $this->getDetails($order)->shouldReturn([ - 'mode' => Session::MODE_PAYMENT, - ]); - } -} diff --git a/spec/Provider/LineItemImagesProviderSpec.php b/spec/Provider/LineItemImagesProviderSpec.php deleted file mode 100644 index 882d1ee..0000000 --- a/spec/Provider/LineItemImagesProviderSpec.php +++ /dev/null @@ -1,94 +0,0 @@ -beConstructedWith( - $imagineCacheManager, - 'my_filter', - 'https://somewhere-online.tld/fallbak.jpg' - ); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(LineItemImagesProvider::class); - $this->shouldHaveType(LineItemImagesProviderInterface::class); - } - - public function it_get_image_urls( - OrderItemInterface $orderItem, - ProductInterface $product, - ProductImageInterface $productImage, - CacheManager $imagineCacheManager - ): void { - $productImage->getPath()->willReturn('/path/image.jpg'); - $orderItem->getProduct()->willReturn($product); - $product->getImages()->willReturn(new ArrayCollection([ - $productImage->getWrappedObject(), - ])); - $imagineCacheManager - ->getBrowserPath('/path/image.jpg', 'my_filter') - ->willReturn('https://somewhere-online.tld/path/image.jpg'); - - $this->getImageUrlFromProduct($product)->shouldReturn('https://somewhere-online.tld/path/image.jpg'); - - $this->getImageUrls($orderItem)->shouldReturn([ - 'https://somewhere-online.tld/path/image.jpg', - ]); - } - - public function it_get_fallback_image_urls_on_localhost( - OrderItemInterface $orderItem, - ProductInterface $product, - ProductImageInterface $productImage, - CacheManager $imagineCacheManager - ): void { - $productImage->getPath()->willReturn('/path/image.jpg'); - $orderItem->getProduct()->willReturn($product); - $product->getImages()->willReturn(new ArrayCollection([ - $productImage->getWrappedObject(), - ])); - $imagineCacheManager - ->getBrowserPath('/path/image.jpg', 'my_filter') - ->willReturn('https://localhost/path/image.jpg'); - - $this->getImageUrlFromProduct($product)->shouldReturn('https://somewhere-online.tld/fallbak.jpg'); - - $this->getImageUrls($orderItem)->shouldReturn([ - 'https://somewhere-online.tld/fallbak.jpg', - ]); - } - - public function it_get_fallback_image_urls__when_there_is_no_image( - OrderItemInterface $orderItem, - ProductInterface $product, - CacheManager $imagineCacheManager - ): void { - $orderItem->getProduct()->willReturn($product); - $product->getImages()->willReturn(new ArrayCollection()); - $imagineCacheManager - ->getBrowserPath('https://somewhere-online.tld/fallbak.jpg', 'my_filter') - ->willReturn('https://somewhere-online.tld/fallbak.jpg'); - - $this->getImageUrlFromProduct($product)->shouldReturn('https://somewhere-online.tld/fallbak.jpg'); - - $this->getImageUrls($orderItem)->shouldReturn([ - 'https://somewhere-online.tld/fallbak.jpg', - ]); - } -} diff --git a/spec/Provider/LineItemProviderSpec.php b/spec/Provider/LineItemProviderSpec.php deleted file mode 100644 index 1918c5e..0000000 --- a/spec/Provider/LineItemProviderSpec.php +++ /dev/null @@ -1,117 +0,0 @@ -beConstructedWith( - $lineItemImagesProvider, - $lineItemNameProvider - ); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(LineItemProvider::class); - $this->shouldHaveType(LineItemProviderInterface::class); - } - - public function it_get_line_item( - OrderItemInterface $orderItem, - OrderInterface $order, - LineItemImagesProviderInterface $lineItemImagesProvider, - LinetItemNameProviderInterface $lineItemNameProvider - ): void { - $orderItem->getOrder()->willReturn($order); - $orderItem->getTotal()->willReturn(1000); - $order->getCurrencyCode()->willReturn('USD'); - $lineItemImagesProvider->getImageUrls($orderItem)->willReturn(['/path/image.jpg']); - $lineItemNameProvider->getItemName($orderItem)->willReturn('1x - My item name'); - - $this->getLineItem($orderItem)->shouldReturn([ - 'price_data' => [ - 'unit_amount' => 1000, - 'currency' => 'USD', - 'product_data' => [ - 'name' => '1x - My item name', - 'images' => [ - '/path/image.jpg', - ], - ], - ], - 'quantity' => 1, - ]); - } - - public function it_get_line_item_with_no_images( - OrderItemInterface $orderItem, - OrderInterface $order, - LineItemImagesProviderInterface $lineItemImagesProvider, - LinetItemNameProviderInterface $lineItemNameProvider - ): void { - $orderItem->getOrder()->willReturn($order); - $orderItem->getTotal()->willReturn(1000); - $order->getCurrencyCode()->willReturn('USD'); - $lineItemImagesProvider->getImageUrls($orderItem)->willReturn([]); - $lineItemNameProvider->getItemName($orderItem)->willReturn('1x - My item name'); - - $this->getLineItem($orderItem)->shouldReturn([ - 'price_data' => [ - 'unit_amount' => 1000, - 'currency' => 'USD', - 'product_data' => [ - 'name' => '1x - My item name', - 'images' => [], - ], - ], - 'quantity' => 1, - ]); - } - - public function it_get_line_item_when_quantity_is_greater_than_1( - OrderItemInterface $orderItem, - OrderInterface $order, - LineItemImagesProviderInterface $lineItemImagesProvider, - LinetItemNameProviderInterface $lineItemNameProvider - ): void { - $orderItem->getOrder()->willReturn($order); - $orderItem->getTotal()->willReturn(1000); - $order->getCurrencyCode()->willReturn('USD'); - $lineItemImagesProvider->getImageUrls($orderItem)->willReturn([]); - $lineItemNameProvider->getItemName($orderItem)->willReturn('2x - My item name'); - - $this->getLineItem($orderItem)->shouldReturn([ - 'price_data' => [ - 'unit_amount' => 1000, - 'currency' => 'USD', - 'product_data' => [ - 'name' => '2x - My item name', - 'images' => [], - ], - ], - 'quantity' => 1, - ]); - } - - public function it_get_line_item_with_null_order( - OrderItemInterface $orderItem - ): void { - $orderItem->getOrder()->willReturn(null); - - $this->getLineItem($orderItem)->shouldReturn(null); - } -} diff --git a/spec/Provider/LineItemsProviderSpec.php b/spec/Provider/LineItemsProviderSpec.php deleted file mode 100644 index f073b59..0000000 --- a/spec/Provider/LineItemsProviderSpec.php +++ /dev/null @@ -1,63 +0,0 @@ -beConstructedWith( - $lineItemProvider, - $shippingLineItemProvider - ); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(LineItemsProvider::class); - $this->shouldHaveType(LineItemsProviderInterface::class); - } - - public function it_get_line_items( - OrderInterface $order, - OrderItemInterface $orderItem, - LineItemProviderInterface $lineItemProvider, - ShippingLineItemProviderInterface $shippingLineItemProvider - ): void { - $lineItem = []; - $orderItems = new ArrayCollection([ - $orderItem->getWrappedObject(), - ]); - $order->getItems()->willReturn($orderItems); - $lineItemProvider->getLineItem($orderItem)->willReturn($lineItem); - $shippingLineItemProvider->getLineItem($order)->willReturn(null); - - $this->getLineItems($order)->shouldReturn([ - $lineItem, - ]); - } - - public function it_get_empty_line_items( - OrderInterface $order, - ShippingLineItemProviderInterface $shippingLineItemProvider - ): void { - $orderItems = new ArrayCollection([]); - $order->getItems()->willReturn($orderItems); - $shippingLineItemProvider->getLineItem($order)->willReturn(null); - - $this->getLineItems($order)->shouldReturn([]); - } -} diff --git a/spec/Provider/LinetItemNameProviderSpec.php b/spec/Provider/LinetItemNameProviderSpec.php deleted file mode 100644 index aebd850..0000000 --- a/spec/Provider/LinetItemNameProviderSpec.php +++ /dev/null @@ -1,82 +0,0 @@ -shouldHaveType(LinetItemNameProvider::class); - $this->shouldHaveType(LinetItemNameProviderInterface::class); - } - - public function it_get_product_and_variant_name_when_product_has_options( - OrderItemInterface $orderItem, - ProductInterface $product - ): void { - $orderItem->getQuantity()->willReturn(1); - $orderItem->getProduct()->willReturn($product); - $orderItem->getProductName()->willReturn('My Product'); - $orderItem->getVariantName()->willReturn('variant'); - - $product->hasOptions()->willReturn(true); - - $this->getItemName($orderItem)->shouldReturn('1x - My Product variant'); - } - - public function it_get_product_and_variant_name_when_product_has_no_options( - OrderItemInterface $orderItem, - ProductInterface $product - ): void { - $orderItem->getQuantity()->willReturn(1); - $orderItem->getProduct()->willReturn($product); - $orderItem->getProductName()->willReturn('My Product'); - $orderItem->getVariantName()->willReturn('variant'); - - $product->hasOptions()->willReturn(false); - - $this->getItemName($orderItem)->shouldReturn('1x - variant'); - } - - public function it_get_item_name_with_variant_name( - OrderItemInterface $orderItem, - ProductInterface $product - ): void { - $orderItem->getQuantity()->willReturn(1); - $orderItem->getProduct()->willReturn($product); - $orderItem->getProductName()->willReturn(null); - $orderItem->getVariantName()->willReturn('My variant name'); - - $product->hasOptions()->willReturn(false); - - $this->getItemName($orderItem)->shouldReturn('1x - My variant name'); - } - - public function it_get_item_name_with_product_name( - OrderItemInterface $orderItem - ): void { - $orderItem->getQuantity()->willReturn(1); - $orderItem->getProductName()->willReturn('My variant name'); - $orderItem->getVariantName()->willReturn(null); - - $this->getItemName($orderItem)->shouldReturn('1x - My variant name'); - } - - public function it_get_item_name_without_variant_name_or_product_name( - OrderItemInterface $orderItem - ): void { - $orderItem->getQuantity()->willReturn(1); - $orderItem->getProductName()->willReturn(null); - $orderItem->getVariantName()->willReturn(null); - - $this->getItemName($orderItem)->shouldReturn('1x - '); - } -} diff --git a/spec/Provider/ModeProviderSpec.php b/spec/Provider/ModeProviderSpec.php deleted file mode 100644 index 1adf619..0000000 --- a/spec/Provider/ModeProviderSpec.php +++ /dev/null @@ -1,26 +0,0 @@ -shouldHaveType(ModeProvider::class); - $this->shouldHaveType(ModeProviderInterface::class); - } - - public function it_get_payment_method_types( - OrderInterface $order - ): void { - $this->getMode($order)->shouldReturn(Session::MODE_PAYMENT); - } -} diff --git a/spec/Provider/PaymentMethodTypesProviderSpec.php b/spec/Provider/PaymentMethodTypesProviderSpec.php deleted file mode 100644 index 724435a..0000000 --- a/spec/Provider/PaymentMethodTypesProviderSpec.php +++ /dev/null @@ -1,34 +0,0 @@ -beConstructedWith([ - 'card', - ]); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(PaymentMethodTypesProvider::class); - $this->shouldHaveType(PaymentMethodTypesProviderInterface::class); - } - - public function it_get_payment_method_types( - OrderInterface $order - ): void { - $this->getPaymentMethodTypes($order)->shouldReturn([ - 'card', - ]); - } -} diff --git a/spec/Provider/ShippingLineItemNameProviderSpec.php b/spec/Provider/ShippingLineItemNameProviderSpec.php deleted file mode 100644 index 7012236..0000000 --- a/spec/Provider/ShippingLineItemNameProviderSpec.php +++ /dev/null @@ -1,66 +0,0 @@ -shouldHaveType(ShippingLineItemNameProvider::class); - $this->shouldHaveType(ShippingLineItemNameProviderInterface::class); - } - - public function it_get_item_name( - OrderInterface $order, - ShipmentInterface $shipment, - ShippingMethodInterface $shippingMethod - ): void { - $shippingMethod->getName()->willReturn('My shipping method'); - $shipment->getMethod()->willReturn($shippingMethod); - $shipments = new ArrayCollection([ - $shipment->getWrappedObject(), - ]); - $order->getShipments()->willReturn($shipments); - - $this->getItemName($order)->shouldReturn('My shipping method'); - } - - public function it_get_item_name_when_there_is_multiple_shipments( - OrderInterface $order, - ShipmentInterface $shipment, - ShippingMethodInterface $shippingMethod, - ShipmentInterface $shipment2, - ShippingMethodInterface $shippingMethod2 - ): void { - $shippingMethod->getName()->willReturn('My shipping method #1'); - $shipment->getMethod()->willReturn($shippingMethod); - $shippingMethod2->getName()->willReturn('My shipping method #2'); - $shipment2->getMethod()->willReturn($shippingMethod2); - $shipments = new ArrayCollection([ - $shipment->getWrappedObject(), - $shipment2->getWrappedObject(), - ]); - $order->getShipments()->willReturn($shipments); - - $this->getItemName($order)->shouldReturn('My shipping method #1, My shipping method #2'); - } - - public function it_get_item_name_when_there_is_no_shipments( - OrderInterface $order - ): void { - $shipments = new ArrayCollection(); - $order->getShipments()->willReturn($shipments); - - $this->getItemName($order)->shouldReturn(''); - } -} diff --git a/spec/Provider/ShippingLineItemProviderSpec.php b/spec/Provider/ShippingLineItemProviderSpec.php deleted file mode 100644 index fa0c213..0000000 --- a/spec/Provider/ShippingLineItemProviderSpec.php +++ /dev/null @@ -1,55 +0,0 @@ -beConstructedWith( - $shippingLineItemNameProvider - ); - } - - public function it_is_initializable(): void - { - $this->shouldHaveType(ShippingLineItemProvider::class); - $this->shouldHaveType(ShippingLineItemProviderInterface::class); - } - - public function it_get_line_item( - OrderInterface $order, - ShippingLineItemNameProviderInterface $shippingLineItemNameProvider - ): void { - $shippingLineItemNameProvider->getItemName($order)->willReturn('My shipping method'); - $order->getShippingTotal()->willReturn(1000); - $order->getCurrencyCode()->willReturn('USD'); - - $this->getLineItem($order)->shouldReturn([ - 'price_data' => [ - 'unit_amount' => 1000, - 'currency' => 'USD', - 'product_data' => [ - 'name' => 'My shipping method', - ], - ], - 'quantity' => 1, - ]); - } - - public function it_get_line_item_when_there_is_no_shipping( - OrderInterface $order - ): void { - $order->getShippingTotal()->willReturn(0); - $this->getLineItem($order)->shouldReturn(null); - } -} diff --git a/spec/StateMachine/CancelOrderProcessorSpec.php b/spec/StateMachine/CancelOrderProcessorSpec.php deleted file mode 100644 index bbc9e9f..0000000 --- a/spec/StateMachine/CancelOrderProcessorSpec.php +++ /dev/null @@ -1,55 +0,0 @@ -beConstructedWith($commandBus); - } - - public function it_is_invokable_when_it_is_new( - PaymentInterface $payment, - MessageBusInterface $commandBus - ): void { - $payment->getId()->willReturn(1); - - $command = new CancelPayment(1); - $commandBus->dispatch($command)->willReturn(new Envelope($command)); - - $this->__invoke($payment, PaymentInterface::STATE_NEW); - } - - public function it_is_invokable_when_is_authorized( - PaymentInterface $payment, - MessageBusInterface $commandBus - ): void { - $payment->getId()->willReturn(1); - - $command = new CancelPayment(1); - $commandBus->dispatch($command)->willReturn(new Envelope($command)); - - $this->__invoke($payment, PaymentInterface::STATE_AUTHORIZED); - } - - public function it_do_nothing_when_it_is_completed( - PaymentInterface $payment - ): void { - $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); - } - - public function it_do_nothing_when_it_is_refunded( - PaymentInterface $payment - ): void { - $this->__invoke($payment, PaymentInterface::STATE_REFUNDED); - } -} diff --git a/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php b/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php deleted file mode 100644 index 2b454da..0000000 --- a/spec/StateMachine/CaptureAuthorizedOrderProcessorSpec.php +++ /dev/null @@ -1,43 +0,0 @@ -beConstructedWith($commandBus); - } - - public function it_is_invokable( - PaymentInterface $payment, - MessageBusInterface $commandBus - ): void { - $payment->getId()->willReturn(1); - - $command = new CaptureAuthorizedPayment(1); - $commandBus->dispatch($command)->willReturn(new Envelope($command)); - - $this->__invoke($payment, PaymentInterface::STATE_AUTHORIZED); - } - - public function it_do_nothing_when_it_is_completed( - PaymentInterface $payment - ): void { - $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); - } - - public function it_do_nothing_when_it_is_refunded( - PaymentInterface $payment - ): void { - $this->__invoke($payment, PaymentInterface::STATE_REFUNDED); - } -} diff --git a/spec/StateMachine/RefundOrderProcessorSpec.php b/spec/StateMachine/RefundOrderProcessorSpec.php deleted file mode 100644 index 3c9e700..0000000 --- a/spec/StateMachine/RefundOrderProcessorSpec.php +++ /dev/null @@ -1,43 +0,0 @@ -beConstructedWith($commandBus, false); - } - - public function it_is_invokable( - PaymentInterface $payment, - MessageBusInterface $commandBus - ): void { - $payment->getId()->willReturn(1); - - $command = new RefundPayment(1); - $commandBus->dispatch($command)->willReturn(new Envelope($command)); - - $this->__invoke($payment, PaymentInterface::STATE_COMPLETED); - } - - public function it_do_nothing_when_it_is_disabled( - PaymentInterface $payment, - MessageBusInterface $commandBus - ): void { - $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 deleted file mode 100644 index 38adc44..0000000 --- a/src/Abstraction/StateMachine/CompositeStateMachine.php +++ /dev/null @@ -1,27 +0,0 @@ -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 deleted file mode 100644 index a8d27da..0000000 --- a/src/Abstraction/StateMachine/StateMachineInterface.php +++ /dev/null @@ -1,12 +0,0 @@ -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/Action/ConvertPaymentAction.php b/src/Action/ConvertPaymentAction.php index 452a1f4..1166f7b 100644 --- a/src/Action/ConvertPaymentAction.php +++ b/src/Action/ConvertPaymentAction.php @@ -10,14 +10,10 @@ use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\PaymentInterface; -final class ConvertPaymentAction implements ConvertPaymentActionInterface +final readonly class ConvertPaymentAction implements ConvertPaymentActionInterface { - /** @var DetailsProviderInterface */ - private $detailsProvider; - - public function __construct(DetailsProviderInterface $detailsProvider) + public function __construct(private DetailsProviderInterface $detailsProvider) { - $this->detailsProvider = $detailsProvider; } /** @param Convert $request */ diff --git a/src/Action/StripeJs/ConvertPaymentAction.php b/src/Action/StripeJs/ConvertPaymentAction.php index 2110d6b..c75b4c1 100644 --- a/src/Action/StripeJs/ConvertPaymentAction.php +++ b/src/Action/StripeJs/ConvertPaymentAction.php @@ -9,14 +9,10 @@ use Payum\Core\Request\Convert; use Sylius\Component\Core\Model\PaymentInterface; -final class ConvertPaymentAction implements ConvertPaymentActionInterface +final readonly class ConvertPaymentAction implements ConvertPaymentActionInterface { - /** @var DetailsProviderInterface */ - private $detailsProvider; - - public function __construct(DetailsProviderInterface $detailsProvider) + public function __construct(private DetailsProviderInterface $detailsProvider) { - $this->detailsProvider = $detailsProvider; } /** @param Convert $request */ diff --git a/src/Api/PaymentConfiguration/StripeCheckoutSessionPaymentConfigProvider.php b/src/Api/PaymentConfiguration/StripeCheckoutSessionPaymentConfigProvider.php index b9a33d0..ecec328 100644 --- a/src/Api/PaymentConfiguration/StripeCheckoutSessionPaymentConfigProvider.php +++ b/src/Api/PaymentConfiguration/StripeCheckoutSessionPaymentConfigProvider.php @@ -15,16 +15,16 @@ final class StripeCheckoutSessionPaymentConfigProvider implements PaymentConfigu StripePaymentConfigProviderTrait::__construct as private __stripePaymentConfigProviderConstruct; } - private ProcessorInterface $captureProcessor; - public function __construct( - ProcessorInterface $captureProcessor, - string $factoryName + private ProcessorInterface $captureProcessor, + string $factoryName, ) { - $this->captureProcessor = $captureProcessor; $this->__stripePaymentConfigProviderConstruct($factoryName); } + /** + * @return array + */ public function provideConfiguration(PaymentInterface $payment): array { $config = $this->provideDefaultConfiguration($payment); diff --git a/src/Api/PaymentConfiguration/StripeJsPaymentConfigProvider.php b/src/Api/PaymentConfiguration/StripeJsPaymentConfigProvider.php index c1220e8..fe87923 100644 --- a/src/Api/PaymentConfiguration/StripeJsPaymentConfigProvider.php +++ b/src/Api/PaymentConfiguration/StripeJsPaymentConfigProvider.php @@ -15,16 +15,20 @@ final class StripeJsPaymentConfigProvider implements PaymentConfigurationProvide StripePaymentConfigProviderTrait::__construct as private __stripePaymentConfigProviderConstruct; } - private ProcessorInterface $captureProcessor; - public function __construct( - ProcessorInterface $captureProcessor, - string $factoryName + private ProcessorInterface $captureProcessor, + string $factoryName, ) { - $this->captureProcessor = $captureProcessor; $this->__stripePaymentConfigProviderConstruct($factoryName); } + /** + * @return array{ + * 'publishable_key': string, + * 'use_authorize': bool, + * 'stripe_payment_intent_client_secret': string|null, + * } + */ public function provideConfiguration(PaymentInterface $payment): array { $config = $this->provideDefaultConfiguration($payment); diff --git a/src/Api/PaymentConfiguration/StripePaymentConfigProviderTrait.php b/src/Api/PaymentConfiguration/StripePaymentConfigProviderTrait.php index 01b176b..d2fb23f 100644 --- a/src/Api/PaymentConfiguration/StripePaymentConfigProviderTrait.php +++ b/src/Api/PaymentConfiguration/StripePaymentConfigProviderTrait.php @@ -31,10 +31,17 @@ public function supports(PaymentMethodInterface $paymentMethod): bool return $factory === $this->factoryName; } + /** + * @return array{ + * 'publishable_key': string, + * 'use_authorize': bool, + * } + */ public function provideDefaultConfiguration(PaymentInterface $payment): array { $gatewayConfig = $this->getGatewayConfig($payment); + /** @var array{'publishable_key': string, 'use_authorize'?: bool} $config */ $config = $gatewayConfig->getConfig(); return [ @@ -47,11 +54,11 @@ private function getGatewayConfig(PaymentInterface $payment): GatewayConfigInter { /** @var PaymentMethodInterface|null $paymentMethod */ $paymentMethod = $payment->getMethod(); - Assert::notNull($paymentMethod, 'Unable to found a PaymentMethod on this Payment.'); + Assert::notNull($paymentMethod, 'Unable to find a PaymentMethod on this Payment.'); /** @var GatewayConfigInterface|null $gatewayConfig */ $gatewayConfig = $paymentMethod->getGatewayConfig(); - Assert::notNull($gatewayConfig, 'Unable to found a GatewayConfig on this PaymentMethod.'); + Assert::notNull($gatewayConfig, 'Unable to find a GatewayConfig on this PaymentMethod.'); return $gatewayConfig; } diff --git a/src/Api/Payum/AfterUrlProvider.php b/src/Api/Payum/AfterUrlProvider.php index 7e20925..ad3aab3 100644 --- a/src/Api/Payum/AfterUrlProvider.php +++ b/src/Api/Payum/AfterUrlProvider.php @@ -6,18 +6,13 @@ use Sylius\Component\Core\Model\PaymentInterface; -final class AfterUrlProvider implements AfterUrlProviderInterface +final readonly class AfterUrlProvider implements AfterUrlProviderInterface { - private string $afterPath; - - private array $afterParameters; - - public function __construct( - string $afterPath, - array $afterParameters = [] - ) { - $this->afterPath = $afterPath; - $this->afterParameters = $afterParameters; + /** + * @param array $afterParameters + */ + public function __construct(private string $afterPath, private array $afterParameters = []) + { } public function getAfterPath(PaymentInterface $payment): string diff --git a/src/Api/Payum/AfterUrlProviderInterface.php b/src/Api/Payum/AfterUrlProviderInterface.php index 65f468b..fa7215e 100644 --- a/src/Api/Payum/AfterUrlProviderInterface.php +++ b/src/Api/Payum/AfterUrlProviderInterface.php @@ -10,5 +10,8 @@ interface AfterUrlProviderInterface { public function getAfterPath(PaymentInterface $payment): string; + /** + * @return array + */ public function getAfterParameters(PaymentInterface $payment): array; } diff --git a/src/Api/Payum/Processor.php b/src/Api/Payum/Processor.php index c8ed8cc..69c58d5 100644 --- a/src/Api/Payum/Processor.php +++ b/src/Api/Payum/Processor.php @@ -12,32 +12,17 @@ use Sylius\Component\Core\Model\PaymentMethodInterface; use Webmozart\Assert\Assert; -final class Processor implements ProcessorInterface +final readonly class Processor implements ProcessorInterface { - private Payum $payum; - - private ModelAggregateFactoryInterface $captureRequestFactory; - - private ModelAggregateFactoryInterface $authorizeRequestFactory; - - private AfterUrlProviderInterface $afterUrlProvider; - - public function __construct( - Payum $payum, - ModelAggregateFactoryInterface $captureRequestFactory, - ModelAggregateFactoryInterface $authorizeRequestFactory, - AfterUrlProviderInterface $afterUrlProvider - ) { - $this->payum = $payum; - $this->captureRequestFactory = $captureRequestFactory; - $this->authorizeRequestFactory = $authorizeRequestFactory; - $this->afterUrlProvider = $afterUrlProvider; + public function __construct(private Payum $payum, private ModelAggregateFactoryInterface $captureRequestFactory, private ModelAggregateFactoryInterface $authorizeRequestFactory, private AfterUrlProviderInterface $afterUrlProvider) + { } public function __invoke(PaymentInterface $payment, bool $useAuthorize): array { $tokenFactory = $this->payum->getTokenFactory(); $gatewayName = $this->getGatewayConfig($payment)->getGatewayName(); + Assert::notNull($gatewayName, 'Unable to find a GatewayName on this GatewayConfig.'); $gateway = $this->payum->getGateway($gatewayName); @@ -46,7 +31,7 @@ public function __invoke(PaymentInterface $payment, bool $useAuthorize): array $gatewayName, $payment, $this->afterUrlProvider->getAfterPath($payment), - $this->afterUrlProvider->getAfterParameters($payment) + $this->afterUrlProvider->getAfterParameters($payment), ); $request = $this->authorizeRequestFactory->createNewWithToken($token); } else { @@ -54,7 +39,7 @@ public function __invoke(PaymentInterface $payment, bool $useAuthorize): array $gatewayName, $payment, $this->afterUrlProvider->getAfterPath($payment), - $this->afterUrlProvider->getAfterParameters($payment) + $this->afterUrlProvider->getAfterParameters($payment), ); $request = $this->captureRequestFactory->createNewWithToken($token); } diff --git a/src/Api/Payum/ProcessorInterface.php b/src/Api/Payum/ProcessorInterface.php index 8a473b3..82763ec 100644 --- a/src/Api/Payum/ProcessorInterface.php +++ b/src/Api/Payum/ProcessorInterface.php @@ -10,7 +10,10 @@ interface ProcessorInterface { /** - * @return array{'reply': ReplyInterface|null, "details": array} + * @return array{ + * 'reply': ReplyInterface|null, + * 'details': array, + * } */ public function __invoke(PaymentInterface $payment, bool $useAuthorize): array; } diff --git a/src/Command/CancelPayment.php b/src/Command/CancelPayment.php index 4192d7d..1a787b7 100644 --- a/src/Command/CancelPayment.php +++ b/src/Command/CancelPayment.php @@ -6,11 +6,8 @@ class CancelPayment implements PaymentIdAwareCommandInterface { - protected int $paymentId; - - public function __construct(int $paymentId) + public function __construct(protected int $paymentId) { - $this->paymentId = $paymentId; } public function getPaymentId(): int diff --git a/src/Command/CaptureAuthorizedPayment.php b/src/Command/CaptureAuthorizedPayment.php index 46ae9cd..4695cdf 100644 --- a/src/Command/CaptureAuthorizedPayment.php +++ b/src/Command/CaptureAuthorizedPayment.php @@ -6,11 +6,8 @@ class CaptureAuthorizedPayment implements PaymentIdAwareCommandInterface { - protected int $paymentId; - - public function __construct(int $paymentId) + public function __construct(protected int $paymentId) { - $this->paymentId = $paymentId; } public function getPaymentId(): int diff --git a/src/Command/RefundPayment.php b/src/Command/RefundPayment.php index f1ed2db..1f4ec17 100644 --- a/src/Command/RefundPayment.php +++ b/src/Command/RefundPayment.php @@ -6,11 +6,8 @@ class RefundPayment implements PaymentIdAwareCommandInterface { - protected int $paymentId; - - public function __construct(int $paymentId) + public function __construct(protected int $paymentId) { - $this->paymentId = $paymentId; } public function getPaymentId(): int diff --git a/src/CommandHandler/AbstractPayumPaymentHandler.php b/src/CommandHandler/AbstractPayumPaymentHandler.php index 5b93d4f..711e41e 100644 --- a/src/CommandHandler/AbstractPayumPaymentHandler.php +++ b/src/CommandHandler/AbstractPayumPaymentHandler.php @@ -15,34 +15,20 @@ abstract class AbstractPayumPaymentHandler { - /** @var PaymentRepositoryInterface */ - private $paymentRepository; - - /** @var Payum */ - protected $payum; - - /** @var string[] */ - protected array $supportedGateways; - /** + * @param PaymentRepositoryInterface $paymentRepository * @param string[] $supportedGateways */ public function __construct( - PaymentRepositoryInterface $paymentRepository, - Payum $payum, - array $supportedGateways + private readonly PaymentRepositoryInterface $paymentRepository, + protected Payum $payum, + protected array $supportedGateways, ) { - $this->paymentRepository = $paymentRepository; - $this->payum = $payum; - $this->supportedGateways = $supportedGateways; } protected function retrievePayment(PaymentIdAwareCommandInterface $command): ?PaymentInterface { - /** @var PaymentInterface|null $payment */ - $payment = $this->paymentRepository->find($command->getPaymentId()); - - return $payment; + return $this->paymentRepository->find($command->getPaymentId()); } protected function getGatewayNameFromPayment(PaymentInterface $payment): ?string diff --git a/src/CommandHandler/CancelPaymentHandler.php b/src/CommandHandler/CancelPaymentHandler.php index e46fbe6..9212f0d 100644 --- a/src/CommandHandler/CancelPaymentHandler.php +++ b/src/CommandHandler/CancelPaymentHandler.php @@ -11,20 +11,15 @@ final class CancelPaymentHandler extends AbstractPayumPaymentHandler { - /** @var CancelRequestFactoryInterface */ - private $cancelRequestFactory; - /** * @param string[] $supportedGateways */ public function __construct( - CancelRequestFactoryInterface $cancelRequestFactory, + private readonly CancelRequestFactoryInterface $cancelRequestFactory, PaymentRepositoryInterface $paymentRepository, Payum $payum, - array $supportedGateways + array $supportedGateways, ) { - $this->cancelRequestFactory = $cancelRequestFactory; - parent::__construct($paymentRepository, $payum, $supportedGateways); } diff --git a/src/CommandHandler/CaptureAuthorizedPaymentHandler.php b/src/CommandHandler/CaptureAuthorizedPaymentHandler.php index c0f3295..96fae7b 100644 --- a/src/CommandHandler/CaptureAuthorizedPaymentHandler.php +++ b/src/CommandHandler/CaptureAuthorizedPaymentHandler.php @@ -13,20 +13,15 @@ final class CaptureAuthorizedPaymentHandler extends AbstractPayumPaymentHandler { - /** @var ModelAggregateFactoryInterface */ - private $captureRequestFactory; - /** * @param string[] $supportedGateways */ public function __construct( - ModelAggregateFactoryInterface $captureRequestFactory, + private readonly ModelAggregateFactoryInterface $captureRequestFactory, PaymentRepositoryInterface $paymentRepository, Payum $payum, - array $supportedGateways + array $supportedGateways, ) { - $this->captureRequestFactory = $captureRequestFactory; - parent::__construct($paymentRepository, $payum, $supportedGateways); } diff --git a/src/CommandHandler/RefundPaymentHandler.php b/src/CommandHandler/RefundPaymentHandler.php index 1e6777e..c909189 100644 --- a/src/CommandHandler/RefundPaymentHandler.php +++ b/src/CommandHandler/RefundPaymentHandler.php @@ -11,20 +11,15 @@ final class RefundPaymentHandler extends AbstractPayumPaymentHandler { - /** @var RefundRequestFactoryInterface */ - private $refundRequestFactory; - /** * @param string[] $supportedGateways */ public function __construct( - RefundRequestFactoryInterface $refundRequestFactory, + private readonly RefundRequestFactoryInterface $refundRequestFactory, PaymentRepositoryInterface $paymentRepository, Payum $payum, - array $supportedGateways + array $supportedGateways, ) { - $this->refundRequestFactory = $refundRequestFactory; - parent::__construct($paymentRepository, $payum, $supportedGateways); } diff --git a/src/DependencyInjection/Compiler/LiveTwigComponentCompilerPass.php b/src/DependencyInjection/Compiler/LiveTwigComponentCompilerPass.php new file mode 100644 index 0000000..625d9d5 --- /dev/null +++ b/src/DependencyInjection/Compiler/LiveTwigComponentCompilerPass.php @@ -0,0 +1,31 @@ +getDefinition('sylius_admin.twig.component.payment_method.form'); + if (!$definition->hasTag('sylius.twig_component')) { + return; + } + + /** @var array> $tagConfig */ + $tagConfig = $definition->getTag('sylius.twig_component'); + + $definition + ->setClass(FormComponent::class) + ->addArgument(new Reference('sylius.custom_factory.payment_method')) + ->addTag('sylius.live_component.admin', $tagConfig[0]) + ->clearTag('sylius.twig_component') + ; + } +} diff --git a/src/DependencyInjection/Compiler/PayumGatewayConfigOverride.php b/src/DependencyInjection/Compiler/PayumGatewayConfigOverride.php index 848e967..272fd3c 100644 --- a/src/DependencyInjection/Compiler/PayumGatewayConfigOverride.php +++ b/src/DependencyInjection/Compiler/PayumGatewayConfigOverride.php @@ -7,15 +7,11 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; -final class PayumGatewayConfigOverride implements CompilerPassInterface +final readonly class PayumGatewayConfigOverride implements CompilerPassInterface { - /** @var array */ - private $gatewayConfigs; - - /** @param array $gatewayConfigs */ - public function __construct(array $gatewayConfigs) + /** @param array> $gatewayConfigs */ + public function __construct(private array $gatewayConfigs) { - $this->gatewayConfigs = $gatewayConfigs; } public function process(ContainerBuilder $container): void diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 7699691..dca1eb9 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -12,7 +12,7 @@ class Configuration implements ConfigurationInterface { public const CONFIG_ROOT_NAME = 'flux_se_sylius_payum_stripe'; - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder(self::CONFIG_ROOT_NAME); $rootNode = $treeBuilder->getRootNode(); @@ -21,7 +21,7 @@ public function getConfigTreeBuilder() return $treeBuilder; } - protected function addGlobalSection(ArrayNodeDefinition $node) + protected function addGlobalSection(ArrayNodeDefinition $node): void { $node ->addDefaultsIfNotSet() @@ -39,15 +39,15 @@ protected function addGlobalSection(ArrayNodeDefinition $node) ->children() ->scalarNode('imagine_filter') ->defaultValue('sylius_shop_product_original') - ->info('This is the imagine filter use to get the image displayed on Stripe Checkout Session (default: the filter uses into `@ShopBundle/Product/Show/_images.html.twig`)') + ->info('This is the Imagine filter used to get the image displayed on Stripe Checkout Session (default: the filter uses into `@ShopBundle/templates/product/show/page/info/overview/images.html.twig`)') ->end() ->scalarNode('fallback_image') - ->defaultValue('https://via.placeholder.com/300') + ->defaultValue('https://placehold.co/300') ->info('Fallback image used when no image is set on a product and also when you test this plugin from a private web server (ex: from localhost)') ->end() ->scalarNode('localhost_pattern') - ->defaultValue('#//localhost#') - ->info('Localhost images are not displayed by Stripe because it cache them on a CDN, this preg_match() pattern will allow the line item image provider to test if the image is from a localhost network or not.') + ->defaultValue('#://(localhost|127.0.0.1|[^:/]+\.wip|[^:/]+\.local)[:/]#') + ->info('Stripe does not display localhost images because it caches them on a CDN, this preg_match() pattern will allow the line item image provider to test it if the image is from a localhost network or not.') ->end() ->end() ->end() diff --git a/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php b/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php index 4e2eb27..572e29a 100644 --- a/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php +++ b/src/DependencyInjection/FluxSESyliusPayumStripeExtension.php @@ -4,22 +4,27 @@ namespace FluxSE\SyliusPayumStripePlugin\DependencyInjection; -use Exception; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\Extension; -use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; -class FluxSESyliusPayumStripeExtension extends Extension implements PrependExtensionInterface +class FluxSESyliusPayumStripeExtension extends Extension { - /** - * @throws Exception - */ public function load(array $configs, ContainerBuilder $container): void { $configuration = $this->getConfiguration([], $container); - assert(null !== $configuration); + + /** @var array{ + * refund_disabled: bool, + * payment_method_types: array, + * line_item_image: array{ + * imagine_filter: string, + * fallback_image: string, + * localhost_pattern: string, + * }, + * } $configs + */ $configs = $this->processConfiguration($configuration, $configs); $container->setParameter( @@ -45,21 +50,8 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new YamlFileLoader( $container, - new FileLocator(dirname(__DIR__) . '/Resources/config'), + new FileLocator(dirname(__DIR__) . '/../config'), ); $loader->load('services.yaml'); } - - public function prepend(ContainerBuilder $container): void - { - $loader = new YamlFileLoader( - $container, - new FileLocator(dirname(__DIR__) . '/Resources/config'), - ); - - 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 index 48e2b56..3436471 100644 --- a/src/EventListener/Workflow/PaymentCompletedStateListener.php +++ b/src/EventListener/Workflow/PaymentCompletedStateListener.php @@ -9,26 +9,21 @@ use Symfony\Component\Workflow\Event\CompletedEvent; use Webmozart\Assert\Assert; -final class PaymentCompletedStateListener +final readonly class PaymentCompletedStateListener { - private PaymentStateProcessorInterface $paymentStateProcessor; - - public function __construct(PaymentStateProcessorInterface $paymentStateProcessor) + public function __construct(private PaymentStateProcessorInterface $paymentStateProcessor) { - $this->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 + // state machine transition froms will always contain 1 element $fromState = $transition->getFroms()[0]; - Assert::notNull($fromState); $this->paymentStateProcessor->__invoke($payment, $fromState); } diff --git a/src/Extension/CancelExistingPaymentIntentExtension.php b/src/Extension/CancelExistingPaymentIntentExtension.php index 972512b..f074992 100644 --- a/src/Extension/CancelExistingPaymentIntentExtension.php +++ b/src/Extension/CancelExistingPaymentIntentExtension.php @@ -25,20 +25,10 @@ * You cannot cancel the PaymentIntent for a Checkout Session. Expire the Checkout Session instead * @see https://github.com/FLUX-SE/SyliusPayumStripePlugin/issues/32 */ -final class CancelExistingPaymentIntentExtension implements ExtensionInterface +final readonly class CancelExistingPaymentIntentExtension implements ExtensionInterface { - /** @var ExpireSessionRequestFactoryInterface */ - private $expireSessionRequestFactory; - - /** @var AllSessionRequestFactoryInterface */ - private $allSessionRequestFactory; - - public function __construct( - ExpireSessionRequestFactoryInterface $expireSessionRequestFactory, - AllSessionRequestFactoryInterface $allSessionRequestFactory - ) { - $this->expireSessionRequestFactory = $expireSessionRequestFactory; - $this->allSessionRequestFactory = $allSessionRequestFactory; + public function __construct(private ExpireSessionRequestFactoryInterface $expireSessionRequestFactory, private AllSessionRequestFactoryInterface $allSessionRequestFactory) + { } public function onPreExecute(Context $context): void @@ -86,9 +76,8 @@ public function onExecute(Context $context): void $gateway->execute($allSessionRequest); - /** @var Collection $sessions */ + /** @var Collection $sessions */ $sessions = $allSessionRequest->getApiResources(); - /** @var Session|null $session */ $session = $sessions->first(); if (null === $session) { return; diff --git a/src/Extension/UpdatePaymentStateExtension.php b/src/Extension/UpdatePaymentStateExtension.php index f0a6752..227a564 100644 --- a/src/Extension/UpdatePaymentStateExtension.php +++ b/src/Extension/UpdatePaymentStateExtension.php @@ -4,18 +4,18 @@ 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 Sylius\Abstraction\StateMachine\StateMachineInterface; use Sylius\Bundle\PayumBundle\Factory\GetStatusFactoryInterface; use Sylius\Component\Payment\Model\PaymentInterface; use Sylius\Component\Payment\PaymentTransitions; /** - * Reproduction of the Payum Core StorageExtension behaviour for Sylius payments + * Reproduction of the Payum Core StorageExtension behavior for Sylius payments * * @see \Payum\Core\Extension\StorageExtension */ @@ -24,20 +24,11 @@ final class UpdatePaymentStateExtension implements ExtensionInterface /** @var PaymentInterface[] */ private array $scheduledPaymentsToProcess = []; - private StateMachineInterface $stateMachine; - - private StorageInterface $storage; - - private GetStatusFactoryInterface $getStatusRequestFactory; - public function __construct( - StateMachineInterface $stateMachine, - StorageInterface $storage, - GetStatusFactoryInterface $getStatusRequestFactory + private readonly StateMachineInterface $stateMachine, + private readonly StorageInterface $storage, + private readonly GetStatusFactoryInterface $getStatusRequestFactory, ) { - $this->getStatusRequestFactory = $getStatusRequestFactory; - $this->storage = $storage; - $this->stateMachine = $stateMachine; } public function onPreExecute(Context $context): void @@ -52,7 +43,6 @@ public function onPreExecute(Context $context): void if ($request->getModel() instanceof IdentityInterface) { $payment = $this->storage->find($request->getModel()); } else { - /** @var PaymentInterface|mixed $payment */ $payment = $request->getModel(); } @@ -118,7 +108,7 @@ private function updatePaymentState(PaymentInterface $payment, string $nextState $transition = $this->stateMachine->getTransitionToState( $payment, PaymentTransitions::GRAPH, - $nextState + $nextState, ); if (null === $transition) { return; @@ -127,7 +117,7 @@ private function updatePaymentState(PaymentInterface $payment, string $nextState $this->stateMachine->apply( $payment, PaymentTransitions::GRAPH, - $transition + $transition, ); } diff --git a/src/FluxSESyliusPayumStripePlugin.php b/src/FluxSESyliusPayumStripePlugin.php index b28a4df..105acb5 100644 --- a/src/FluxSESyliusPayumStripePlugin.php +++ b/src/FluxSESyliusPayumStripePlugin.php @@ -4,6 +4,7 @@ namespace FluxSE\SyliusPayumStripePlugin; +use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\LiveTwigComponentCompilerPass; use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\PayumGatewayConfigOverride; use FluxSE\SyliusPayumStripePlugin\DependencyInjection\Compiler\PayumStoragePaymentAliaser; use Sylius\Bundle\CoreBundle\Application\SyliusPluginTrait; @@ -26,7 +27,14 @@ public function build(ContainerBuilder $container): void ])); $container->addCompilerPass(new PayumStoragePaymentAliaser()); + // Before SyliusUiBundle compiler pass + $container->addCompilerPass(new LiveTwigComponentCompilerPass(), priority: 501); parent::build($container); } + + public function getPath(): string + { + return dirname(__DIR__); + } } diff --git a/src/Form/Type/StripeCheckoutSessionGatewayConfigurationType.php b/src/Form/Type/StripeCheckoutSessionGatewayConfigurationType.php deleted file mode 100644 index e9b0437..0000000 --- a/src/Form/Type/StripeCheckoutSessionGatewayConfigurationType.php +++ /dev/null @@ -1,30 +0,0 @@ - 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.publishable_key', 'constraints' => [ new NotBlank([ - 'message' => 'flux_se_sylius_payum_stripe_plugin.stripe.publishable_key', - 'groups' => 'sylius', + 'message' => 'flux_se_sylius_payum_stripe_plugin.stripe.publishable_key.not_blank', + 'groups' => [ + 'sylius', + 'stripe_checkout_session', + 'stripe_js', + ], ]), ], ]) @@ -29,25 +33,52 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'label' => 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.secret_key', 'constraints' => [ new NotBlank([ - 'message' => 'flux_se_sylius_payum_stripe_plugin.stripe.secret_key', - 'groups' => 'sylius', + 'message' => 'flux_se_sylius_payum_stripe_plugin.stripe.secret_key.not_blank', + 'groups' => [ + 'sylius', + 'stripe_checkout_session', + 'stripe_js', + ], ]), ], ]) ->add('use_authorize', CheckboxType::class, [ + 'required' => false, 'label' => 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.use_authorize', ]) - ->add('webhook_secret_keys', CollectionType::class, [ + ->add('webhook_secret_keys', LiveCollectionType::class, [ + 'label' => 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.webhook_secret_keys', 'allow_add' => true, 'allow_delete' => true, 'delete_empty' => true, - 'label' => 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.webhook_secret_keys', + 'button_delete_options' => [ + 'label' => 'sylius.ui.delete', + 'translation_domain' => 'messages', + 'attr' => [ + 'class' => 'btn btn-danger', + ], + ], + 'button_add_options' => [ + 'label' => 'sylius.ui.add', + ], + 'error_bubbling' => false, 'constraints' => [ new NotBlank([ 'message' => 'flux_se_sylius_payum_stripe_plugin.stripe.webhook_secret_keys.not_blank', - 'groups' => 'sylius', + 'groups' => [ + 'sylius', + 'stripe_checkout_session', + 'stripe_js', + ], ]), ], + 'entry_options' => [ + 'label' => false, + 'translation_domain' => false, + 'attr' => [ + 'placeholder' => 'whsec_', + ], + ], ]) ; } diff --git a/src/Provider/DetailsProvider.php b/src/Provider/DetailsProvider.php index 1472299..408e1af 100644 --- a/src/Provider/DetailsProvider.php +++ b/src/Provider/DetailsProvider.php @@ -6,30 +6,10 @@ use Sylius\Component\Core\Model\OrderInterface; -final class DetailsProvider implements DetailsProviderInterface +final readonly class DetailsProvider implements DetailsProviderInterface { - /** @var CustomerEmailProviderInterface */ - private $customerEmailProvider; - - /** @var LineItemsProviderInterface */ - private $lineItemsProvider; - - /** @var PaymentMethodTypesProviderInterface */ - private $paymentMethodTypesProvider; - - /** @var ModeProviderInterface */ - private $modeProvider; - - public function __construct( - CustomerEmailProviderInterface $customerEmailProvider, - LineItemsProviderInterface $lineItemsProvider, - PaymentMethodTypesProviderInterface $paymentMethodTypesProvider, - ModeProviderInterface $modeProvider - ) { - $this->customerEmailProvider = $customerEmailProvider; - $this->lineItemsProvider = $lineItemsProvider; - $this->paymentMethodTypesProvider = $paymentMethodTypesProvider; - $this->modeProvider = $modeProvider; + public function __construct(private CustomerEmailProviderInterface $customerEmailProvider, private LineItemsProviderInterface $lineItemsProvider, private PaymentMethodTypesProviderInterface $paymentMethodTypesProvider, private ModeProviderInterface $modeProvider) + { } public function getDetails(OrderInterface $order): array diff --git a/src/Provider/DetailsProviderInterface.php b/src/Provider/DetailsProviderInterface.php index 2a63178..447a00e 100644 --- a/src/Provider/DetailsProviderInterface.php +++ b/src/Provider/DetailsProviderInterface.php @@ -8,5 +8,8 @@ interface DetailsProviderInterface { + /** + * @return array + */ public function getDetails(OrderInterface $order): array; } diff --git a/src/Provider/LineItemImagesProvider.php b/src/Provider/LineItemImagesProvider.php index 111fc02..38a7d04 100644 --- a/src/Provider/LineItemImagesProvider.php +++ b/src/Provider/LineItemImagesProvider.php @@ -10,30 +10,10 @@ use Sylius\Component\Core\Model\ProductImageInterface; use Sylius\Component\Core\Model\ProductInterface; -final class LineItemImagesProvider implements LineItemImagesProviderInterface +final readonly class LineItemImagesProvider implements LineItemImagesProviderInterface { - /** @var CacheManager */ - private $imagineCacheManager; - - /** @var string */ - private $filterName; - - /** @var string */ - private $fallbackImage; - - /** @var string */ - private $localhostPattern; - - public function __construct( - CacheManager $imagineCacheManager, - string $filterName, - string $fallbackImage, - string $localhostPattern = '#//localhost#' - ) { - $this->imagineCacheManager = $imagineCacheManager; - $this->filterName = $filterName; - $this->fallbackImage = $fallbackImage; - $this->localhostPattern = $localhostPattern; + public function __construct(private CacheManager $imagineCacheManager, private string $filterName, private string $fallbackImage, private string $localhostPattern = '#//localhost#') + { } public function getImageUrls(OrderItemInterface $orderItem): array @@ -85,7 +65,7 @@ private function getUrlFromPath(string $path): string try { $url = $this->imagineCacheManager->getBrowserPath($path, $this->filterName); - } catch (Exception $e) { + } catch (Exception) { return $this->fallbackImage; } diff --git a/src/Provider/LineItemProvider.php b/src/Provider/LineItemProvider.php index 23ed59d..3eb2717 100644 --- a/src/Provider/LineItemProvider.php +++ b/src/Provider/LineItemProvider.php @@ -7,20 +7,10 @@ use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderItemInterface; -final class LineItemProvider implements LineItemProviderInterface +final readonly class LineItemProvider implements LineItemProviderInterface { - /** @var LineItemImagesProviderInterface */ - private $lineItemImagesProvider; - - /** @var LinetItemNameProviderInterface */ - private $lineItemNameProvider; - - public function __construct( - LineItemImagesProviderInterface $lineItemImagesProvider, - LinetItemNameProviderInterface $lineItemNameProvider - ) { - $this->lineItemImagesProvider = $lineItemImagesProvider; - $this->lineItemNameProvider = $lineItemNameProvider; + public function __construct(private LineItemImagesProviderInterface $lineItemImagesProvider, private LinetItemNameProviderInterface $lineItemNameProvider) + { } public function getLineItem(OrderItemInterface $orderItem): ?array diff --git a/src/Provider/LineItemProviderInterface.php b/src/Provider/LineItemProviderInterface.php index 10e744d..37bdf02 100644 --- a/src/Provider/LineItemProviderInterface.php +++ b/src/Provider/LineItemProviderInterface.php @@ -8,5 +8,8 @@ interface LineItemProviderInterface { + /** + * @return array|null + */ public function getLineItem(OrderItemInterface $orderItem): ?array; } diff --git a/src/Provider/LineItemsProvider.php b/src/Provider/LineItemsProvider.php index a980e0d..2197fdf 100644 --- a/src/Provider/LineItemsProvider.php +++ b/src/Provider/LineItemsProvider.php @@ -6,20 +6,10 @@ use Sylius\Component\Core\Model\OrderInterface; -final class LineItemsProvider implements LineItemsProviderInterface +final readonly class LineItemsProvider implements LineItemsProviderInterface { - /** @var LineItemProviderInterface */ - private $lineItemProvider; - - /** @var ShippingLineItemProviderInterface */ - private $shippingLineItemProvider; - - public function __construct( - LineItemProviderInterface $lineItemProvider, - ShippingLineItemProviderInterface $shippingLineItemProvider - ) { - $this->lineItemProvider = $lineItemProvider; - $this->shippingLineItemProvider = $shippingLineItemProvider; + public function __construct(private LineItemProviderInterface $lineItemProvider, private ShippingLineItemProviderInterface $shippingLineItemProvider) + { } public function getLineItems(OrderInterface $order): ?array diff --git a/src/Provider/LineItemsProviderInterface.php b/src/Provider/LineItemsProviderInterface.php index f87d608..d2f1cdb 100644 --- a/src/Provider/LineItemsProviderInterface.php +++ b/src/Provider/LineItemsProviderInterface.php @@ -8,5 +8,8 @@ interface LineItemsProviderInterface { + /** + * @return array|null + */ public function getLineItems(OrderInterface $order): ?array; } diff --git a/src/Provider/PaymentMethodTypesProvider.php b/src/Provider/PaymentMethodTypesProvider.php index 6893ced..997fea5 100644 --- a/src/Provider/PaymentMethodTypesProvider.php +++ b/src/Provider/PaymentMethodTypesProvider.php @@ -6,17 +6,13 @@ use Sylius\Component\Core\Model\OrderInterface; -final class PaymentMethodTypesProvider implements PaymentMethodTypesProviderInterface +final readonly class PaymentMethodTypesProvider implements PaymentMethodTypesProviderInterface { - /** @var string[] */ - private $paymentMethodTypes; - /** * @param string[] $paymentMethodTypes */ - public function __construct(array $paymentMethodTypes) + public function __construct(private array $paymentMethodTypes) { - $this->paymentMethodTypes = $paymentMethodTypes; } public function getPaymentMethodTypes(OrderInterface $order): array diff --git a/src/Provider/ShippingLineItemProvider.php b/src/Provider/ShippingLineItemProvider.php index d28693b..04f136f 100644 --- a/src/Provider/ShippingLineItemProvider.php +++ b/src/Provider/ShippingLineItemProvider.php @@ -6,14 +6,10 @@ use Sylius\Component\Core\Model\OrderInterface; -final class ShippingLineItemProvider implements ShippingLineItemProviderInterface +final readonly class ShippingLineItemProvider implements ShippingLineItemProviderInterface { - /** @var ShippingLineItemNameProviderInterface */ - private $shippingLineItemProvider; - - public function __construct(ShippingLineItemNameProviderInterface $shippingLineItemProvider) + public function __construct(private ShippingLineItemNameProviderInterface $shippingLineItemProvider) { - $this->shippingLineItemProvider = $shippingLineItemProvider; } public function getLineItem(OrderInterface $order): ?array diff --git a/src/Provider/ShippingLineItemProviderInterface.php b/src/Provider/ShippingLineItemProviderInterface.php index 3ef8794..f75797f 100644 --- a/src/Provider/ShippingLineItemProviderInterface.php +++ b/src/Provider/ShippingLineItemProviderInterface.php @@ -8,5 +8,8 @@ interface ShippingLineItemProviderInterface { + /** + * @return array|null + */ public function getLineItem(OrderInterface $order): ?array; } diff --git a/src/Provider/StripeJs/DetailsProvider.php b/src/Provider/StripeJs/DetailsProvider.php index d337246..575d69f 100644 --- a/src/Provider/StripeJs/DetailsProvider.php +++ b/src/Provider/StripeJs/DetailsProvider.php @@ -6,22 +6,10 @@ use Sylius\Component\Core\Model\PaymentInterface; -final class DetailsProvider implements DetailsProviderInterface +final readonly class DetailsProvider implements DetailsProviderInterface { - private AmountProviderInterface $amountProvider; - - private CurrencyProviderInterface $currencyProvider; - - private PaymentMethodTypesProviderInterface $paymentMethodTypesProvider; - - public function __construct( - AmountProviderInterface $amountProvider, - CurrencyProviderInterface $currencyProvider, - PaymentMethodTypesProviderInterface $paymentMethodTypesProvider - ) { - $this->amountProvider = $amountProvider; - $this->currencyProvider = $currencyProvider; - $this->paymentMethodTypesProvider = $paymentMethodTypesProvider; + public function __construct(private AmountProviderInterface $amountProvider, private CurrencyProviderInterface $currencyProvider, private PaymentMethodTypesProviderInterface $paymentMethodTypesProvider) + { } public function getDetails(PaymentInterface $payment): array diff --git a/src/Provider/StripeJs/DetailsProviderInterface.php b/src/Provider/StripeJs/DetailsProviderInterface.php index fb9a5b0..c8dc078 100644 --- a/src/Provider/StripeJs/DetailsProviderInterface.php +++ b/src/Provider/StripeJs/DetailsProviderInterface.php @@ -8,5 +8,8 @@ interface DetailsProviderInterface { + /** + * @return array + */ public function getDetails(PaymentInterface $payment): array; } diff --git a/src/Provider/StripeJs/PaymentMethodTypesProvider.php b/src/Provider/StripeJs/PaymentMethodTypesProvider.php index dacca33..003c08c 100644 --- a/src/Provider/StripeJs/PaymentMethodTypesProvider.php +++ b/src/Provider/StripeJs/PaymentMethodTypesProvider.php @@ -6,17 +6,13 @@ use Sylius\Component\Core\Model\PaymentInterface; -final class PaymentMethodTypesProvider implements PaymentMethodTypesProviderInterface +final readonly class PaymentMethodTypesProvider implements PaymentMethodTypesProviderInterface { - /** @var string[] */ - private $paymentMethodTypes; - /** * @param string[] $paymentMethodTypes */ - public function __construct(array $paymentMethodTypes) + public function __construct(private array $paymentMethodTypes) { - $this->paymentMethodTypes = $paymentMethodTypes; } public function getPaymentMethodTypes(PaymentInterface $payment): array diff --git a/src/Resources/config/app/twig.yaml b/src/Resources/config/app/twig.yaml deleted file mode 100644 index e10fdb2..0000000 --- a/src/Resources/config/app/twig.yaml +++ /dev/null @@ -1,3 +0,0 @@ -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 deleted file mode 100644 index fe094ef..0000000 --- a/src/Resources/config/app/winzou_state_machine.yaml +++ /dev/null @@ -1,18 +0,0 @@ -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 deleted file mode 100644 index 43a9fe8..0000000 --- a/src/Resources/config/config.yaml +++ /dev/null @@ -1,5 +0,0 @@ -imports: - - { resource: 'app/twig.yaml' } - - { resource: 'app/winzou_state_machine.yaml' } - - diff --git a/src/Resources/config/services/abstraction/abstraction.yaml b/src/Resources/config/services/abstraction/abstraction.yaml deleted file mode 100644 index e192a99..0000000 --- a/src/Resources/config/services/abstraction/abstraction.yaml +++ /dev/null @@ -1,6 +0,0 @@ -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/translations/messages.de.yaml b/src/Resources/translations/messages.de.yaml deleted file mode 100644 index 4b4f38f..0000000 --- a/src/Resources/translations/messages.de.yaml +++ /dev/null @@ -1,17 +0,0 @@ -flux_se_sylius_payum_stripe_plugin: - payum_gateway_factory: - stripe_checkout_session: Stripe Checkout-Session (mit SCA-Unterstützung) - stripe_js: Stripe JS (mit SCA-Unterstützung) - form: - gateway_configuration: - stripe: - publishable_key: Öffentlicher Schlüssel - secret_key: Geheimschlüssel - use_authorize: Autorisierung verwenden - webhook_secret_keys: Geheimschlüssel für Webhooks - help: - use_authorize: > - Wenn eine Zahlung autorisiert wird, garantiert die Bank den Betrag und reserviert ihn bis zu sieben Tage auf der Karte des Kunden. - - Weiterlesen - diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml deleted file mode 100644 index 4c50f28..0000000 --- a/src/Resources/translations/messages.en.yaml +++ /dev/null @@ -1,17 +0,0 @@ -flux_se_sylius_payum_stripe_plugin: - payum_gateway_factory: - stripe_checkout_session: Stripe Checkout Session (with SCA support) - stripe_js: Stripe JS (with SCA support) - form: - gateway_configuration: - stripe: - publishable_key: Publishable key - secret_key: Secret key - use_authorize: Use authorize - webhook_secret_keys: Webhook secret keys - help: - use_authorize: > - When a payment is authorized, the bank guarantees the amount and holds it on the customer’s card for up to seven days. - - Read more - diff --git a/src/Resources/translations/messages.fr.yaml b/src/Resources/translations/messages.fr.yaml deleted file mode 100644 index 806508f..0000000 --- a/src/Resources/translations/messages.fr.yaml +++ /dev/null @@ -1,17 +0,0 @@ -flux_se_sylius_payum_stripe_plugin: - payum_gateway_factory: - stripe_checkout_session: Stripe Checkout Session (avec support SCA) - stripe_js: Stripe JS (avec support SCA) - form: - gateway_configuration: - stripe: - publishable_key: Clé publique - secret_key: Clé secrète - use_authorize: Utiliser "authorize" - webhook_secret_keys: Clés secrètes du webhook - help: - use_authorize: > - Lorsqu'un paiement est autorisé, la banque garantit le montant et le conserve sur la carte du client jusqu'à sept jours. - - En savoir plus - diff --git a/src/Resources/translations/validators.en.yaml b/src/Resources/translations/validators.en.yaml deleted file mode 100644 index 90a765e..0000000 --- a/src/Resources/translations/validators.en.yaml +++ /dev/null @@ -1,8 +0,0 @@ -flux_se_sylius_payum_stripe_plugin: - stripe: - webhook_secret_keys: - not_blank: Please enter stripe webhook secret key. - secret_key: - not_blank: Please enter stripe secret key. - publishable_key: - not_blank: Please enter stripe publishable key. diff --git a/src/Resources/views/Admin/PaymentMethod/Form/useAuthorize.html.twig b/src/Resources/views/Admin/PaymentMethod/Form/useAuthorize.html.twig deleted file mode 100644 index 4dfb7f7..0000000 --- a/src/Resources/views/Admin/PaymentMethod/Form/useAuthorize.html.twig +++ /dev/null @@ -1,22 +0,0 @@ -{% block _sylius_payment_method_gatewayConfig_config_use_authorize_label %} - {{ form_label(form) }} -
- -
- {% autoescape false %}{{ 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.help.use_authorize'|trans }}{% endautoescape %} -
-
- -{% endblock %} \ No newline at end of file diff --git a/src/StateMachine/CancelOrderProcessor.php b/src/StateMachine/CancelOrderProcessor.php index faf1a55..e0c5537 100644 --- a/src/StateMachine/CancelOrderProcessor.php +++ b/src/StateMachine/CancelOrderProcessor.php @@ -9,14 +9,10 @@ use Symfony\Component\Messenger\MessageBusInterface; use Webmozart\Assert\Assert; -final class CancelOrderProcessor implements PaymentStateProcessorInterface +final readonly class CancelOrderProcessor implements PaymentStateProcessorInterface { - private MessageBusInterface $commandBus; - - public function __construct( - MessageBusInterface $commandBus - ) { - $this->commandBus = $commandBus; + public function __construct(private MessageBusInterface $commandBus) + { } public function __invoke(PaymentInterface $payment, string $fromState): void diff --git a/src/StateMachine/CaptureAuthorizedOrderProcessor.php b/src/StateMachine/CaptureAuthorizedOrderProcessor.php index 33f2b63..259f905 100644 --- a/src/StateMachine/CaptureAuthorizedOrderProcessor.php +++ b/src/StateMachine/CaptureAuthorizedOrderProcessor.php @@ -9,13 +9,10 @@ use Symfony\Component\Messenger\MessageBusInterface; use Webmozart\Assert\Assert; -final class CaptureAuthorizedOrderProcessor implements PaymentStateProcessorInterface +final readonly class CaptureAuthorizedOrderProcessor implements PaymentStateProcessorInterface { - private MessageBusInterface $commandBus; - - public function __construct(MessageBusInterface $commandBus) + public function __construct(private MessageBusInterface $commandBus) { - $this->commandBus = $commandBus; } public function __invoke(PaymentInterface $payment, string $fromState): void diff --git a/src/StateMachine/RefundOrderProcessor.php b/src/StateMachine/RefundOrderProcessor.php index aeac65b..af0b9a8 100644 --- a/src/StateMachine/RefundOrderProcessor.php +++ b/src/StateMachine/RefundOrderProcessor.php @@ -9,18 +9,10 @@ use Symfony\Component\Messenger\MessageBusInterface; use Webmozart\Assert\Assert; -final class RefundOrderProcessor implements PaymentStateProcessorInterface +final readonly class RefundOrderProcessor implements PaymentStateProcessorInterface { - private MessageBusInterface $commandBus; - - private bool $disabled; - - public function __construct( - MessageBusInterface $commandBus, - bool $disabled - ) { - $this->commandBus = $commandBus; - $this->disabled = $disabled; + public function __construct(private MessageBusInterface $commandBus, private bool $disabled) + { } public function __invoke(PaymentInterface $payment, string $fromState): void diff --git a/src/Twig/Component/AdminPaymentMethod/FormComponent.php b/src/Twig/Component/AdminPaymentMethod/FormComponent.php new file mode 100644 index 0000000..2e292bc --- /dev/null +++ b/src/Twig/Component/AdminPaymentMethod/FormComponent.php @@ -0,0 +1,53 @@ + */ + use ResourceFormComponentTrait { + initialize as public __construct; + } + + /** + * @param RepositoryInterface $paymentMethodRepository + * @param PaymentMethodFactoryInterface $paymentMethodFactory + */ + public function __construct( + RepositoryInterface $paymentMethodRepository, + FormFactoryInterface $formFactory, + string $resourceClass, + string $formClass, + private readonly PaymentMethodFactoryInterface $paymentMethodFactory, + ) { + $this->initialize($paymentMethodRepository, $formFactory, $resourceClass, $formClass); + } + + #[LiveProp(fieldName: 'factoryName')] + public ?string $factoryName = null; + + protected function createResource(): ResourceInterface + { + Assert::notNull($this->factoryName, 'A factory name is required to create a new payment method.'); + + return $this->paymentMethodFactory->createWithGateway($this->factoryName); + } +} diff --git a/templates/admin/payment_method/form.html.twig b/templates/admin/payment_method/form.html.twig new file mode 100644 index 0000000..976f1ce --- /dev/null +++ b/templates/admin/payment_method/form.html.twig @@ -0,0 +1,14 @@ +{% set form = hookable_metadata.context.form %} + +
+
+
+ {{ ('flux_se_sylius_payum_stripe_plugin.gateway_factory.'~form.gatewayConfig.vars.data.factoryName)|trans }} +
+
+
+
+ {% hook 'form' with { form } %} +
+
+
diff --git a/templates/admin/payment_method/form/publishable_key.html.twig b/templates/admin/payment_method/form/publishable_key.html.twig new file mode 100644 index 0000000..14ccbc0 --- /dev/null +++ b/templates/admin/payment_method/form/publishable_key.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form.gatewayConfig.config.publishable_key %} + +
+ {{ form_row(form, sylius_test_form_attribute('config-publishable-key')) }} +
diff --git a/templates/admin/payment_method/form/secret_key.html.twig b/templates/admin/payment_method/form/secret_key.html.twig new file mode 100644 index 0000000..93f5326 --- /dev/null +++ b/templates/admin/payment_method/form/secret_key.html.twig @@ -0,0 +1,5 @@ +{% set form = hookable_metadata.context.form.gatewayConfig.config.secret_key %} + +
+ {{ form_row(form, sylius_test_form_attribute('config-secret-key')) }} +
diff --git a/templates/admin/payment_method/form/use_authorize.html.twig b/templates/admin/payment_method/form/use_authorize.html.twig new file mode 100644 index 0000000..e62a206 --- /dev/null +++ b/templates/admin/payment_method/form/use_authorize.html.twig @@ -0,0 +1,21 @@ +{% set form = hookable_metadata.context.form.gatewayConfig.config.use_authorize %} + +
+ {{ form_row(form, sylius_test_form_attribute('use-authorize')) }} +
+
+
+
{{ ux_icon('tabler:info-circle', {'class': 'icon alert-icon'}) }}
+
+

+ {{ 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.info.use_authorize'|trans }} +

+

+ + {{ 'sylius.ui.view_more'|trans }} + +

+
+
+
+ diff --git a/templates/admin/payment_method/form/webhook_secret_keys.html.twig b/templates/admin/payment_method/form/webhook_secret_keys.html.twig new file mode 100644 index 0000000..6e7e7ac --- /dev/null +++ b/templates/admin/payment_method/form/webhook_secret_keys.html.twig @@ -0,0 +1,34 @@ +{% set form = hookable_metadata.context.form.gatewayConfig.config.webhook_secret_keys %} + +
+ {{ form_label(form) }} +
+
+
{{ ux_icon('tabler:info-circle', {'class': 'icon alert-icon'}) }}
+
+

+ {{ 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.info.webhook_secret_key'|trans }} + + {{ 'sylius.ui.view_more'|trans }} + +

+

+ + {{ 'flux_se_sylius_payum_stripe_plugin.form.gateway_configuration.stripe.action.webhook_secret_key'|trans }} + +

+
+
+
+ + {{ form_errors(form) }} + +
+ {% for child_form in form %} + {% hook 'webhook_secret_keys' with { form: child_form } %} + {% endfor %} + + {{ form_row(form.vars.button_add, sylius_test_form_attribute('add-webhook-secret-key')) }} +
+ +
diff --git a/templates/admin/payment_method/form/webhook_secret_keys/webhook_secret_key.html.twig b/templates/admin/payment_method/form/webhook_secret_keys/webhook_secret_key.html.twig new file mode 100644 index 0000000..be2267f --- /dev/null +++ b/templates/admin/payment_method/form/webhook_secret_keys/webhook_secret_key.html.twig @@ -0,0 +1,13 @@ +{% set form = hookable_metadata.context.form %} + +
+
+ {{ form_label(form) }} + {{ form_widget(form, sylius_test_form_attribute('webhook-secret-key')) }} + {{ form_help(form) }} +
+
+ {{ form_row(form.vars.button_delete, sylius_test_form_attribute('delete-webhook-secret-key')) }} +
+ {{ form_errors(form) }} +
diff --git a/tests/Application/.env b/tests/Application/.env index 91c2dda..e536f00 100644 --- a/tests/Application/.env +++ b/tests/Application/.env @@ -9,37 +9,32 @@ APP_SECRET=EDITME ###< symfony/framework-bundle ### ###> doctrine/doctrine-bundle ### -# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url -# For a sqlite database, use: "sqlite:///%kernel.project_dir%/var/data.db" -# Set "serverVersion" to your server version to avoid edge-case exceptions and extra database calls -DATABASE_URL=mysql://root@127.0.0.1/sylius_%kernel.environment%?serverVersion=5.7 +# Choose one of the following DBMS, adjust the server version and charset if needed +DATABASE_URL=mysql://root@127.0.0.1/sylius_%kernel.environment%?serverVersion=8&charset=utf8mb4 +#DATABASE_URL=pgsql://postgres:postgres@127.0.0.1/sylius_%kernel.environment%?serverVersion=15&charset=utf8 ###< doctrine/doctrine-bundle ### +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +MESSENGER_TRANSPORT_DSN=doctrine://default +SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=doctrine://default +SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=doctrine://default?queue_name=main_failed +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=doctrine://default?queue_name=catalog_promotion_removal +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=doctrine://default?queue_name=catalog_promotion_removal_failed +SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_FAILED_DSN=sync:// +###< symfony/messenger ### + ###> lexik/jwt-authentication-bundle ### -JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem -JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem -JWT_PASSPHRASE=ALL_THAT_IS_GOLD_DOES_NOT_GLITTER_NOT_ALL_THOSE_WHO_WANDER_ARE_LOST +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem +JWT_PASSPHRASE=e7c5fca1060bdf6ad23c33e4c236081f ###< lexik/jwt-authentication-bundle ### -###> symfony/swiftmailer-bundle ### -# For Gmail as a transport, use: "gmail://username:password@localhost" -# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" -# Delivery is disabled by default via "null://localhost" -MAILER_URL=null://localhost -###< symfony/swiftmailer-bundle ### - ###> symfony/mailer ### MAILER_DSN=null://null ###< symfony/mailer ### -###> symfony/messenger ### -# Choose one of the transports below -# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages -MESSENGER_TRANSPORT_DSN=sync:// -# Sylius > 1.12.4 -SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=sync:// -SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=sync:// -SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=sync:// -SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=sync:// -# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages -###< symfony/messenger ### +SYLIUS_PAYMENT_ENCRYPTION_KEY_PATH=%kernel.project_dir%/config/encryption/dev.key diff --git a/tests/Application/.env.test b/tests/Application/.env.test index 6d7d2c8..0993b3b 100644 --- a/tests/Application/.env.test +++ b/tests/Application/.env.test @@ -1,22 +1,22 @@ -###> symfony/framework-bundle ### -APP_ENV=test -APP_DEBUG=1 -APP_SECRET=ch4mb3r0f5ecr3ts -###< symfony/framework-bundle ### +APP_SECRET='s$cretf0rt3st' KERNEL_CLASS='Tests\FluxSE\SyliusPayumStripePlugin\Application\Kernel' -###> symfony/swiftmailer-bundle ### -# For Gmail as a transport, use: "gmail://username:password@localhost" -# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode=" -# Delivery is disabled by default via "null://localhost" -MAILER_URL=null://localhost -###< symfony/swiftmailer-bundle ### +###> lexik/jwt-authentication-bundle ### +JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private-test.pem +JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public-test.pem +JWT_PASSPHRASE=ALL_THAT_IS_GOLD_DOES_NOT_GLITTER_NOT_ALL_THOSE_WHO_WANDER_ARE_LOST +###< lexik/jwt-authentication-bundle ### ###> symfony/messenger ### +# Sync transport turned for testing env for the ease of testing MESSENGER_TRANSPORT_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_MAIN_FAILED_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_CATALOG_PROMOTION_REMOVAL_FAILED_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_DSN=sync:// +SYLIUS_MESSENGER_TRANSPORT_PAYMENT_REQUEST_FAILED_DSN=sync:// ###< symfony/messenger ### -###> symfony/mailer ### -MAILER_DSN=null://null -###< symfony/mailer ### +SYLIUS_PAYMENT_ENCRYPTION_KEY_PATH=%kernel.project_dir%/config/encryption/test.key diff --git a/tests/Application/.gitignore b/tests/Application/.gitignore index bc600a8..a6c0fa5 100644 --- a/tests/Application/.gitignore +++ b/tests/Application/.gitignore @@ -2,12 +2,12 @@ /public/build /public/css /public/js -/public/media/* -!/public/media/image/ -/public/media/image/* -!/public/media/image/.gitignore +/public/media +!/public/media/image/.gitkeep + +/etc/build/* +!/etc/build/.gitignore -/node_modules ###> symfony/framework-bundle ### /.env.*.local @@ -18,6 +18,24 @@ /vendor/ ###< symfony/framework-bundle ### +###> lexik/jwt-authentication-bundle ### +/config/jwt/*.pem +!/config/jwt/*-test.pem +###< lexik/jwt-authentication-bundle ### + +###> symfony/webpack-encore-bundle ### +/node_modules/ +/public/build/ +/npm-debug.log +/yarn-error.log +/yarn.lock +/package-lock.json +###< symfony/webpack-encore-bundle ### + +###> liip/imagine-bundle ### +/public/media/cache/ +###< liip/imagine-bundle ### + ###> symfony/web-server-bundle ### /.web-server-pid ###< symfony/web-server-bundle ### diff --git a/tests/Application/Kernel.php b/tests/Application/Kernel.php index fb6df96..234db5e 100644 --- a/tests/Application/Kernel.php +++ b/tests/Application/Kernel.php @@ -4,123 +4,10 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Application; -use PSS\SymfonyMockerContainer\DependencyInjection\MockerContainer; -use Sylius\Bundle\CoreBundle\SyliusCoreBundle; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\Config\Resource\FileResource; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\HttpKernel\Bundle\BundleInterface; use Symfony\Component\HttpKernel\Kernel as BaseKernel; -use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; final class Kernel extends BaseKernel { use MicroKernelTrait; - - private const CONFIG_EXTS = '.{php,xml,yaml,yml}'; - - public function getCacheDir(): string - { - return $this->getProjectDir() . '/var/cache/' . $this->environment; - } - - public function getLogDir(): string - { - return $this->getProjectDir() . '/var/log'; - } - - public function registerBundles(): iterable - { - foreach ($this->getConfigurationDirectories() as $confDir) { - $bundlesFile = $confDir . '/bundles.php'; - if (false === is_file($bundlesFile)) { - continue; - } - yield from $this->registerBundlesFromFile($bundlesFile); - } - } - - private function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void - { - foreach ($this->getConfigurationDirectories() as $confDir) { - $bundlesFile = $confDir . '/bundles.php'; - if (false === is_file($bundlesFile)) { - continue; - } - $container->addResource(new FileResource($bundlesFile)); - } - - $container->setParameter('container.dumper.inline_class_loader', true); - - foreach ($this->getConfigurationDirectories() as $confDir) { - $this->loadContainerConfiguration($loader, $confDir); - } - } - - private function configureRoutes(RoutingConfigurator $routes): void - { - foreach ($this->getConfigurationDirectories() as $confDir) { - $this->loadRoutesConfiguration($routes, $confDir); - } - } - - protected function getContainerBaseClass(): string - { - if ($this->isTestEnvironment()) { - return MockerContainer::class; - } - - return parent::getContainerBaseClass(); - } - - private function isTestEnvironment(): bool - { - return 0 === strpos($this->getEnvironment(), 'test'); - } - - private function loadContainerConfiguration(LoaderInterface $loader, string $confDir): void - { - $loader->load($confDir . '/{packages}/*' . self::CONFIG_EXTS, 'glob'); - $loader->load($confDir . '/{packages}/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob'); - $loader->load($confDir . '/{services}' . self::CONFIG_EXTS, 'glob'); - $loader->load($confDir . '/{services}_' . $this->environment . self::CONFIG_EXTS, 'glob'); - } - - private function loadRoutesConfiguration(RoutingConfigurator $routes, string $confDir): void - { - $routes->import($confDir . '/{routes}/*' . self::CONFIG_EXTS); - $routes->import($confDir . '/{routes}/' . $this->environment . '/**/*' . self::CONFIG_EXTS); - $routes->import($confDir . '/{routes}' . self::CONFIG_EXTS); - } - - /** - * @return BundleInterface[] - */ - private function registerBundlesFromFile(string $bundlesFile): iterable - { - /** @var array $contents */ - $contents = require $bundlesFile; - foreach ($contents as $class => $envs) { - if (isset($envs['all']) || isset($envs[$this->environment])) { - yield new $class(); - } - } - } - - /** - * @return string[] - */ - private function getConfigurationDirectories(): iterable - { - yield $this->getProjectDir() . '/config'; - $syliusConfigDir = $this->getProjectDir() . '/config/sylius/' . SyliusCoreBundle::MAJOR_VERSION . '.' . SyliusCoreBundle::MINOR_VERSION; - if (is_dir($syliusConfigDir)) { - yield $syliusConfigDir; - } - $symfonyConfigDir = $this->getProjectDir() . '/config/symfony/' . BaseKernel::MAJOR_VERSION . '.' . BaseKernel::MINOR_VERSION; - if (is_dir($symfonyConfigDir)) { - yield $symfonyConfigDir; - } - } } diff --git a/tests/Application/assets/admin/entry.js b/tests/Application/assets/admin/entry.js deleted file mode 100644 index 635f5ac..0000000 --- a/tests/Application/assets/admin/entry.js +++ /dev/null @@ -1 +0,0 @@ -import 'sylius/bundle/AdminBundle/Resources/private/entry'; diff --git a/tests/Application/assets/shop/entry.js b/tests/Application/assets/shop/entry.js deleted file mode 100644 index aadc317..0000000 --- a/tests/Application/assets/shop/entry.js +++ /dev/null @@ -1 +0,0 @@ -import 'sylius/bundle/ShopBundle/Resources/private/entry'; diff --git a/tests/Application/config/bootstrap.php b/tests/Application/config/bootstrap.php index d219924..2291ab4 100644 --- a/tests/Application/config/bootstrap.php +++ b/tests/Application/config/bootstrap.php @@ -13,15 +13,11 @@ $_ENV += $env; } elseif (!class_exists(Dotenv::class)) { throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); -} elseif (method_exists(Dotenv::class, 'bootEnv')) { - (new Dotenv())->bootEnv(dirname(__DIR__) . '/.env'); - - return; } else { // load all the .env files (new Dotenv())->loadEnv(dirname(__DIR__) . '/.env'); } $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; -$_SERVER['APP_DEBUG'] ??= $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; +$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; diff --git a/tests/Application/config/bundles.php b/tests/Application/config/bundles.php index 095a28e..4a49ca7 100644 --- a/tests/Application/config/bundles.php +++ b/tests/Application/config/bundles.php @@ -1,13 +1,12 @@ ['all' => true], Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true], Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true], Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true], + Sylius\Abstraction\StateMachine\SyliusStateMachineAbstractionBundle::class => ['all' => true], Sylius\Bundle\OrderBundle\SyliusOrderBundle::class => ['all' => true], Sylius\Bundle\MoneyBundle\SyliusMoneyBundle::class => ['all' => true], Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle::class => ['all' => true], @@ -30,16 +29,12 @@ Sylius\Bundle\CoreBundle\SyliusCoreBundle::class => ['all' => true], Sylius\Bundle\ResourceBundle\SyliusResourceBundle::class => ['all' => true], Sylius\Bundle\GridBundle\SyliusGridBundle::class => ['all' => true], - winzou\Bundle\StateMachineBundle\winzouStateMachineBundle::class => ['all' => true], - Sonata\BlockBundle\SonataBlockBundle::class => ['all' => true], - Bazinga\Bundle\HateoasBundle\BazingaHateoasBundle::class => ['all' => true], - JMS\SerializerBundle\JMSSerializerBundle::class => ['all' => true], - FOS\RestBundle\FOSRestBundle::class => ['all' => true], Knp\Bundle\GaufretteBundle\KnpGaufretteBundle::class => ['all' => true], Knp\Bundle\MenuBundle\KnpMenuBundle::class => ['all' => true], Liip\ImagineBundle\LiipImagineBundle::class => ['all' => true], Payum\Bundle\PayumBundle\PayumBundle::class => ['all' => true], Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle::class => ['all' => true], + BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true], Sylius\Bundle\FixturesBundle\SyliusFixturesBundle::class => ['all' => true], Sylius\Bundle\PayumBundle\SyliusPayumBundle::class => ['all' => true], @@ -50,11 +45,19 @@ Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'test_cached' => true], FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true, 'test_cached' => true], Sylius\Behat\Application\SyliusTestPlugin\SyliusTestPlugin::class => ['test' => true, 'test_cached' => true], - ApiPlatform\Core\Bridge\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], + ApiPlatform\Symfony\Bundle\ApiPlatformBundle::class => ['all' => true], Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true], Sylius\Bundle\ApiBundle\SyliusApiBundle::class => ['all' => true], SyliusLabs\DoctrineMigrationsExtraBundle\SyliusLabsDoctrineMigrationsExtraBundle::class => ['all' => true], + League\FlysystemBundle\FlysystemBundle::class => ['all' => true], Symfony\WebpackEncoreBundle\WebpackEncoreBundle::class => ['all' => true], + Sylius\TwigHooks\SyliusTwigHooksBundle::class => ['all' => true], + Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true], + Symfony\UX\LiveComponent\LiveComponentBundle::class => ['all' => true], + Symfony\UX\Autocomplete\AutocompleteBundle::class => ['all' => true], + Symfony\UX\StimulusBundle\StimulusBundle::class => ['all' => true], + Sylius\TwigExtra\Symfony\SyliusTwigExtraBundle::class => ['all' => true], + Symfony\UX\Icons\UXIconsBundle::class => ['all' => true], FluxSE\PayumStripeBundle\FluxSEPayumStripeBundle::class => ['all' => true], FluxSE\SyliusPayumStripePlugin\FluxSESyliusPayumStripePlugin::class => ['all' => true], ]; diff --git a/tests/Application/config/symfony/.gitkeep b/tests/Application/config/encryption/.gitkeep similarity index 100% rename from tests/Application/config/symfony/.gitkeep rename to tests/Application/config/encryption/.gitkeep diff --git a/tests/Application/config/encryption/test.key b/tests/Application/config/encryption/test.key new file mode 100644 index 0000000..0059874 --- /dev/null +++ b/tests/Application/config/encryption/test.key @@ -0,0 +1 @@ +31400500d6649581d6ac178bc41c92acc686dd869e6aa8665b4dad27f8921075e8cbf34059793bf9a0c603cd870f0433fb817afdb68bd75445111f27fe36a3252c8bd26fdbd82801568e9c657b022fd39edabff90518a2e04377e4e813bf3bf7d9411e6e \ No newline at end of file diff --git a/tests/Application/config/jwt/.gitkeep b/tests/Application/config/jwt/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/Application/config/packages/_sylius.yaml b/tests/Application/config/packages/_sylius.yaml index 18acdd4..da15c39 100644 --- a/tests/Application/config/packages/_sylius.yaml +++ b/tests/Application/config/packages/_sylius.yaml @@ -1,18 +1,11 @@ imports: - { resource: "@SyliusCoreBundle/Resources/config/app/config.yml" } - + - { resource: "@SyliusPayumBundle/Resources/config/app/config.yaml" } - { resource: "@SyliusAdminBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusShopBundle/Resources/config/app/config.yml" } - - { resource: "@SyliusApiBundle/Resources/config/app/config.yaml" } + - { resource: "../parameters.yaml" } + parameters: sylius_core.public_dir: '%kernel.project_dir%/public' - -sylius_shop: - product_grid: - include_all_descendants: true - -sylius_api: - enabled: true diff --git a/tests/Application/config/packages/api_platform.yaml b/tests/Application/config/packages/api_platform.yaml new file mode 100644 index 0000000..9952e01 --- /dev/null +++ b/tests/Application/config/packages/api_platform.yaml @@ -0,0 +1,8 @@ +api_platform: + mapping: + paths: + - '%kernel.project_dir%/config/api_platform' + patch_formats: + json: ['application/merge-patch+json'] + swagger: + versions: [3] diff --git a/tests/Application/config/packages/assets.yaml b/tests/Application/config/packages/assets.yaml index b1ea48b..f97b2f9 100644 --- a/tests/Application/config/packages/assets.yaml +++ b/tests/Application/config/packages/assets.yaml @@ -1,7 +1,7 @@ framework: - assets: - packages: - shop: - json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' - admin: - json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' + assets: + packages: + admin: + json_manifest_path: '%kernel.project_dir%/public/build/admin/manifest.json' + shop: + json_manifest_path: '%kernel.project_dir%/public/build/shop/manifest.json' diff --git a/tests/Application/config/packages/debug.yaml b/tests/Application/config/packages/debug.yaml new file mode 100644 index 0000000..ad874af --- /dev/null +++ b/tests/Application/config/packages/debug.yaml @@ -0,0 +1,5 @@ +when@dev: + debug: + # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser. + # See the "server:dump" command to start a new server. + dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%" diff --git a/tests/Application/config/packages/dev/framework.yaml b/tests/Application/config/packages/dev/framework.yaml deleted file mode 100644 index 4b116de..0000000 --- a/tests/Application/config/packages/dev/framework.yaml +++ /dev/null @@ -1,2 +0,0 @@ -framework: - profiler: { only_exceptions: false } diff --git a/tests/Application/config/packages/dev/monolog.yaml b/tests/Application/config/packages/dev/monolog.yaml deleted file mode 100644 index da2b092..0000000 --- a/tests/Application/config/packages/dev/monolog.yaml +++ /dev/null @@ -1,9 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug - firephp: - type: firephp - level: info diff --git a/tests/Application/config/packages/dev/routing.yaml b/tests/Application/config/packages/dev/routing.yaml deleted file mode 100644 index 4116679..0000000 --- a/tests/Application/config/packages/dev/routing.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - router: - strict_requirements: true diff --git a/tests/Application/config/packages/dev/web_profiler.yaml b/tests/Application/config/packages/dev/web_profiler.yaml deleted file mode 100644 index 1f1cb2b..0000000 --- a/tests/Application/config/packages/dev/web_profiler.yaml +++ /dev/null @@ -1,3 +0,0 @@ -web_profiler: - toolbar: true - intercept_redirects: false diff --git a/tests/Application/config/packages/doctrine_migrations.yaml b/tests/Application/config/packages/doctrine_migrations.yaml index b3dffec..676e246 100644 --- a/tests/Application/config/packages/doctrine_migrations.yaml +++ b/tests/Application/config/packages/doctrine_migrations.yaml @@ -2,5 +2,8 @@ doctrine_migrations: storage: table_storage: table_name: sylius_migrations -# migrations_paths: -# 'App\Migrations': '%kernel.project_dir%/src/Migrations/' + migrations_paths: + # namespace is arbitrary but should be different from App\Migrations + # as migrations classes should NOT be autoloaded + #'App': '%kernel.project_dir%/migrations' + enable_profiler: false diff --git a/tests/Application/config/packages/flux_se_sylius_payum_stripe.yaml b/tests/Application/config/packages/flux_se_sylius_payum_stripe.yaml index c9163b6..9d63b11 100644 --- a/tests/Application/config/packages/flux_se_sylius_payum_stripe.yaml +++ b/tests/Application/config/packages/flux_se_sylius_payum_stripe.yaml @@ -1,5 +1,5 @@ imports: - - { resource: "@FluxSESyliusPayumStripePlugin/Resources/config/config.yaml" } + - { resource: "@FluxSESyliusPayumStripePlugin/config/config.yaml" } flux_se_sylius_payum_stripe: - refund_disabled: false \ No newline at end of file + refund_disabled: false diff --git a/tests/Application/config/packages/flysystem.yaml b/tests/Application/config/packages/flysystem.yaml new file mode 100644 index 0000000..cab68b7 --- /dev/null +++ b/tests/Application/config/packages/flysystem.yaml @@ -0,0 +1,7 @@ +flysystem: + storages: + sylius.storage: + adapter: 'local' + options: + directory: '%sylius_core.images_dir%' + directory_visibility: 'public' diff --git a/tests/Application/config/packages/fos_rest.yaml b/tests/Application/config/packages/fos_rest.yaml deleted file mode 100644 index a72eef7..0000000 --- a/tests/Application/config/packages/fos_rest.yaml +++ /dev/null @@ -1,11 +0,0 @@ -fos_rest: - exception: true - view: - formats: - json: true - xml: true - empty_content: 204 - format_listener: - rules: - - { path: '^/api/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true } - - { path: '^/', stop: true } diff --git a/tests/Application/config/packages/framework.yaml b/tests/Application/config/packages/framework.yaml index 9b44501..7954fdb 100644 --- a/tests/Application/config/packages/framework.yaml +++ b/tests/Application/config/packages/framework.yaml @@ -1,6 +1,24 @@ framework: + translator: { fallbacks: ["%locale%"] } secret: '%env(APP_SECRET)%' - form: true + form: + enabled: true csrf_protection: true + http_method_override: true session: handler_id: ~ + serializer: + mapping: + paths: [ '%kernel.project_dir%/config/serialization' ] + +when@dev: + framework: + profiler: { only_exceptions: false } + +when@test: &framework_test + framework: + test: true + session: + storage_factory_id: session.storage.factory.mock_file + +when@test_cached: *framework_test diff --git a/tests/Application/config/packages/http_client.yaml b/tests/Application/config/packages/http_client.yaml new file mode 100644 index 0000000..b24f9bc --- /dev/null +++ b/tests/Application/config/packages/http_client.yaml @@ -0,0 +1,9 @@ +when@test: &stripe_client + framework: + http_client: + scoped_clients: + tests.flux_se.sylius_payum_stripe.notify.http_client: + base_uri: 'https://127.0.0.1:8080' + verify_peer: false + +when@test_cached: *stripe_client diff --git a/tests/Application/config/packages/http_discovery.yaml b/tests/Application/config/packages/http_discovery.yaml new file mode 100644 index 0000000..2a789e7 --- /dev/null +++ b/tests/Application/config/packages/http_discovery.yaml @@ -0,0 +1,10 @@ +services: + Psr\Http\Message\RequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@http_discovery.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@http_discovery.psr17_factory' + + http_discovery.psr17_factory: + class: Http\Discovery\Psr17Factory diff --git a/tests/Application/config/packages/mailer.yaml b/tests/Application/config/packages/mailer.yaml new file mode 100644 index 0000000..7acef57 --- /dev/null +++ b/tests/Application/config/packages/mailer.yaml @@ -0,0 +1,12 @@ +framework: + mailer: + dsn: '%env(MAILER_DSN)%' + +when@test: &mailer_test + framework: + cache: + pools: + test.mailer_pool: + adapter: cache.adapter.filesystem + +when@test_cached: *mailer_test diff --git a/tests/Application/config/packages/monolog.yaml b/tests/Application/config/packages/monolog.yaml new file mode 100644 index 0000000..31325fa --- /dev/null +++ b/tests/Application/config/packages/monolog.yaml @@ -0,0 +1,63 @@ +monolog: + channels: + - deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists + +when@prod: + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + excluded_http_codes: [404, 405] + buffer_size: 50 # How many messages should be saved? Prevent memory leaks + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + formatter: monolog.formatter.json + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine"] + deprecation: + type: stream + channels: [deprecation] + path: "%kernel.logs_dir%/%kernel.environment%.log" + formatter: monolog.formatter.json + +when@dev: + monolog: + handlers: + main: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + channels: ["!event"] + # uncomment to get logging in your browser + # you may have to allow bigger header sizes in your Web server configuration + #firephp: + # type: firephp + # level: info + #chromephp: + # type: chromephp + # level: info + console: + type: console + process_psr_3_messages: false + channels: ["!event", "!doctrine", "!console"] + +when@test: &monolog_test + monolog: + handlers: + main: + type: fingers_crossed + action_level: error + handler: nested + channels: ["!event"] + nested: + type: stream + path: "%kernel.logs_dir%/%kernel.environment%.log" + level: debug + +when@test_cached: *monolog_test diff --git a/tests/Application/config/packages/nyholm_psr7.yaml b/tests/Application/config/packages/nyholm_psr7.yaml new file mode 100644 index 0000000..ade8312 --- /dev/null +++ b/tests/Application/config/packages/nyholm_psr7.yaml @@ -0,0 +1,11 @@ +services: + # Register nyholm/psr7 services for autowiring with PSR-17 (HTTP factories) + Psr\Http\Message\RequestFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\ResponseFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\ServerRequestFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\StreamFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\UploadedFileFactoryInterface: '@nyholm.psr7.psr17_factory' + Psr\Http\Message\UriFactoryInterface: '@nyholm.psr7.psr17_factory' + + nyholm.psr7.psr17_factory: + class: Nyholm\Psr7\Factory\Psr17Factory diff --git a/tests/Application/config/packages/prod/doctrine.yaml b/tests/Application/config/packages/prod/doctrine.yaml deleted file mode 100644 index 2f16f0f..0000000 --- a/tests/Application/config/packages/prod/doctrine.yaml +++ /dev/null @@ -1,31 +0,0 @@ -doctrine: - orm: - metadata_cache_driver: - type: service - id: doctrine.system_cache_provider - query_cache_driver: - type: service - id: doctrine.system_cache_provider - result_cache_driver: - type: service - id: doctrine.result_cache_provider - -services: - doctrine.result_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.result_cache_pool' - doctrine.system_cache_provider: - class: Symfony\Component\Cache\DoctrineProvider - public: false - arguments: - - '@doctrine.system_cache_pool' - -framework: - cache: - pools: - doctrine.result_cache_pool: - adapter: cache.app - doctrine.system_cache_pool: - adapter: cache.system diff --git a/tests/Application/config/packages/prod/monolog.yaml b/tests/Application/config/packages/prod/monolog.yaml deleted file mode 100644 index 6461211..0000000 --- a/tests/Application/config/packages/prod/monolog.yaml +++ /dev/null @@ -1,10 +0,0 @@ -monolog: - handlers: - main: - type: fingers_crossed - action_level: error - handler: nested - nested: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug diff --git a/tests/Application/config/packages/routing.yaml b/tests/Application/config/packages/routing.yaml index 368bc7f..4116679 100644 --- a/tests/Application/config/packages/routing.yaml +++ b/tests/Application/config/packages/routing.yaml @@ -1,3 +1,3 @@ framework: router: - strict_requirements: ~ + strict_requirements: true diff --git a/tests/Application/config/packages/security.yaml b/tests/Application/config/packages/security.yaml new file mode 100644 index 0000000..e93353c --- /dev/null +++ b/tests/Application/config/packages/security.yaml @@ -0,0 +1,137 @@ +security: + providers: + sylius_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_api_admin_user_provider: + id: sylius.admin_user_provider.email_or_name_based + sylius_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + sylius_api_shop_user_provider: + id: sylius.shop_user_provider.email_or_name_based + + password_hashers: + Sylius\Component\User\Model\UserInterface: argon2i + firewalls: + admin: + switch_user: true + context: admin + pattern: "%sylius.security.admin_regex%" + provider: sylius_admin_user_provider + user_checker: security.user_checker.chain.admin + form_login: + provider: sylius_admin_user_provider + login_path: sylius_admin_login + check_path: sylius_admin_login_check + failure_path: sylius_admin_login + default_target_path: sylius_admin_dashboard + use_forward: false + use_referer: true + enable_csrf: true + csrf_parameter: _csrf_admin_security_token + csrf_token_id: admin_authenticate + remember_me: + secret: "%env(APP_SECRET)%" + path: "/%sylius_admin.path_name%" + name: APP_ADMIN_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_admin_logout + target: sylius_admin_login + + api_admin: + pattern: "%sylius.security.api_admin_regex%/.*" + provider: sylius_api_admin_user_provider + user_checker: security.user_checker.chain.api_admin + stateless: true + entry_point: jwt + json_login: + check_path: "%sylius.security.api_admin_route%/administrators/token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + jwt: true + + api_shop: + pattern: "%sylius.security.api_shop_regex%/.*" + provider: sylius_api_shop_user_provider + user_checker: security.user_checker.chain.api_shop + stateless: true + entry_point: jwt + json_login: + check_path: "%sylius.security.api_shop_route%/customers/token" + username_path: email + password_path: password + success_handler: lexik_jwt_authentication.handler.authentication_success + failure_handler: lexik_jwt_authentication.handler.authentication_failure + jwt: true + + shop: + switch_user: { role: ROLE_ALLOWED_TO_SWITCH } + context: shop + pattern: "%sylius.security.shop_regex%" + provider: sylius_shop_user_provider + user_checker: security.user_checker.chain.shop + form_login: + success_handler: sylius.authentication.success_handler + failure_handler: sylius.authentication.failure_handler + provider: sylius_shop_user_provider + login_path: sylius_shop_login + check_path: sylius_shop_login_check + failure_path: sylius_shop_login + default_target_path: sylius_shop_homepage + use_forward: false + use_referer: true + enable_csrf: true + csrf_parameter: _csrf_shop_security_token + csrf_token_id: shop_authenticate + json_login: + check_path: sylius_shop_json_login_check + username_path: _username + password_path: _password + success_handler: sylius.authentication.success_handler + failure_handler: sylius.authentication.failure_handler + remember_me: + secret: "%env(APP_SECRET)%" + name: APP_SHOP_REMEMBER_ME + lifetime: 31536000 + remember_me_parameter: _remember_me + logout: + path: sylius_shop_logout + target: sylius_shop_homepage + invalidate_session: false + + image_resolver: + pattern: ^/media/cache/resolve + security: false + + dev: + pattern: ^/(_(profiler|wdt)|css|images|js)/ + security: false + + access_control: + - { path: "%sylius.security.admin_regex%/forgotten-password", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.admin_regex%/login", role: PUBLIC_ACCESS } + - { path: "%sylius.security.shop_regex%/login", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.shop_regex%/register", role: PUBLIC_ACCESS } + - { path: "%sylius.security.shop_regex%/verify", role: PUBLIC_ACCESS } + + - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } + - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } + + - { path: "%sylius.security.api_admin_route%/administrators/reset-password", role: PUBLIC_ACCESS } + - { path: "%sylius.security.api_admin_regex%/.*", role: ROLE_API_ACCESS } + - { path: "%sylius.security.api_admin_route%/administrators/token", role: PUBLIC_ACCESS } + - { path: "%sylius.security.api_shop_account_regex%/.*", role: ROLE_USER } + - { path: "%sylius.security.api_shop_route%/customers/token", role: PUBLIC_ACCESS } + - { path: "%sylius.security.api_shop_regex%/.*", role: PUBLIC_ACCESS } + +when@test: &security_test + security: + password_hashers: + Sylius\Component\User\Model\UserInterface: plaintext + +when@test_cached: *security_test diff --git a/tests/Application/config/packages/staging/monolog.yaml b/tests/Application/config/packages/staging/monolog.yaml deleted file mode 100644 index 6461211..0000000 --- a/tests/Application/config/packages/staging/monolog.yaml +++ /dev/null @@ -1,10 +0,0 @@ -monolog: - handlers: - main: - type: fingers_crossed - action_level: error - handler: nested - nested: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: debug diff --git a/tests/Application/config/packages/staging/swiftmailer.yaml b/tests/Application/config/packages/staging/swiftmailer.yaml deleted file mode 100644 index f438078..0000000 --- a/tests/Application/config/packages/staging/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - disable_delivery: true diff --git a/tests/Application/config/packages/sylius_admin.yaml b/tests/Application/config/packages/sylius_admin.yaml new file mode 100644 index 0000000..4f05227 --- /dev/null +++ b/tests/Application/config/packages/sylius_admin.yaml @@ -0,0 +1,6 @@ +when@test: &sylius_admin_test + sylius_admin: + notifications: + hub_enabled: false + +when@test_cached: *sylius_admin_test diff --git a/tests/Application/config/packages/sylius_api.yaml b/tests/Application/config/packages/sylius_api.yaml new file mode 100644 index 0000000..2bdd228 --- /dev/null +++ b/tests/Application/config/packages/sylius_api.yaml @@ -0,0 +1,3 @@ +when@dev: + sylius_api: + enabled: true diff --git a/tests/Application/config/packages/sylius_channel.yaml b/tests/Application/config/packages/sylius_channel.yaml new file mode 100644 index 0000000..940d56e --- /dev/null +++ b/tests/Application/config/packages/sylius_channel.yaml @@ -0,0 +1,3 @@ +when@test_cached: + sylius_channel: + debug: true diff --git a/tests/Application/config/packages/sylius_shop.yaml b/tests/Application/config/packages/sylius_shop.yaml new file mode 100644 index 0000000..a3bb877 --- /dev/null +++ b/tests/Application/config/packages/sylius_shop.yaml @@ -0,0 +1,3 @@ +sylius_shop: + product_grid: + include_all_descendants: true diff --git a/tests/Application/config/packages/sylius_theme.yaml b/tests/Application/config/packages/sylius_theme.yaml new file mode 100644 index 0000000..20c8adb --- /dev/null +++ b/tests/Application/config/packages/sylius_theme.yaml @@ -0,0 +1,6 @@ +when@test: &sylius_theme_test + sylius_theme: + sources: + test: ~ + +when@test_cached: *sylius_theme_test diff --git a/tests/Application/config/packages/sylius_uploader.yaml b/tests/Application/config/packages/sylius_uploader.yaml new file mode 100644 index 0000000..bb287b8 --- /dev/null +++ b/tests/Application/config/packages/sylius_uploader.yaml @@ -0,0 +1,6 @@ +when@test: &sylius_uploader_test + services: + sylius.generator.image_path: + class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator + +when@test_cached: *sylius_uploader_test diff --git a/tests/Application/config/packages/test/http_client.yaml b/tests/Application/config/packages/test/http_client.yaml deleted file mode 100644 index ea5c4fb..0000000 --- a/tests/Application/config/packages/test/http_client.yaml +++ /dev/null @@ -1,6 +0,0 @@ -framework: - http_client: - scoped_clients: - tests.flux_se.sylius_payum_stripe.notify.http_client: - base_uri: 'https://127.0.0.1:8080' - verify_peer: false diff --git a/tests/Application/config/packages/test/monolog.yaml b/tests/Application/config/packages/test/monolog.yaml deleted file mode 100644 index 7e2b9e3..0000000 --- a/tests/Application/config/packages/test/monolog.yaml +++ /dev/null @@ -1,6 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: error diff --git a/tests/Application/config/packages/test/sylius_theme.yaml b/tests/Application/config/packages/test/sylius_theme.yaml deleted file mode 100644 index 4d34199..0000000 --- a/tests/Application/config/packages/test/sylius_theme.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_theme: - sources: - test: ~ diff --git a/tests/Application/config/packages/test/sylius_uploader.yaml b/tests/Application/config/packages/test/sylius_uploader.yaml deleted file mode 100644 index ab9d6ca..0000000 --- a/tests/Application/config/packages/test/sylius_uploader.yaml +++ /dev/null @@ -1,3 +0,0 @@ -services: - Sylius\Component\Core\Generator\ImagePathGeneratorInterface: - class: Sylius\Behat\Service\Generator\UploadedImagePathGenerator diff --git a/tests/Application/config/packages/test/web_profiler.yaml b/tests/Application/config/packages/test/web_profiler.yaml deleted file mode 100644 index 03752de..0000000 --- a/tests/Application/config/packages/test/web_profiler.yaml +++ /dev/null @@ -1,6 +0,0 @@ -web_profiler: - toolbar: false - intercept_redirects: false - -framework: - profiler: { collect: false } diff --git a/tests/Application/config/packages/test_cached/doctrine.yaml b/tests/Application/config/packages/test_cached/doctrine.yaml deleted file mode 100644 index 4952860..0000000 --- a/tests/Application/config/packages/test_cached/doctrine.yaml +++ /dev/null @@ -1,16 +0,0 @@ -doctrine: - orm: - entity_managers: - default: - result_cache_driver: - type: memcached - host: localhost - port: 11211 - query_cache_driver: - type: memcached - host: localhost - port: 11211 - metadata_cache_driver: - type: memcached - host: localhost - port: 11211 diff --git a/tests/Application/config/packages/test_cached/fos_rest.yaml b/tests/Application/config/packages/test_cached/fos_rest.yaml deleted file mode 100644 index 2b4189d..0000000 --- a/tests/Application/config/packages/test_cached/fos_rest.yaml +++ /dev/null @@ -1,3 +0,0 @@ -fos_rest: - exception: - debug: true diff --git a/tests/Application/config/packages/test_cached/http_client.yaml b/tests/Application/config/packages/test_cached/http_client.yaml deleted file mode 100644 index 9ba7c4e..0000000 --- a/tests/Application/config/packages/test_cached/http_client.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/http_client.yaml" } diff --git a/tests/Application/config/packages/test_cached/monolog.yaml b/tests/Application/config/packages/test_cached/monolog.yaml deleted file mode 100644 index 7e2b9e3..0000000 --- a/tests/Application/config/packages/test_cached/monolog.yaml +++ /dev/null @@ -1,6 +0,0 @@ -monolog: - handlers: - main: - type: stream - path: "%kernel.logs_dir%/%kernel.environment%.log" - level: error diff --git a/tests/Application/config/packages/test_cached/sylius_channel.yaml b/tests/Application/config/packages/test_cached/sylius_channel.yaml deleted file mode 100644 index bab83ef..0000000 --- a/tests/Application/config/packages/test_cached/sylius_channel.yaml +++ /dev/null @@ -1,2 +0,0 @@ -sylius_channel: - debug: true diff --git a/tests/Application/config/packages/test_cached/sylius_theme.yaml b/tests/Application/config/packages/test_cached/sylius_theme.yaml deleted file mode 100644 index 4d34199..0000000 --- a/tests/Application/config/packages/test_cached/sylius_theme.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_theme: - sources: - test: ~ diff --git a/tests/Application/config/packages/test_cached/sylius_uploader.yaml b/tests/Application/config/packages/test_cached/sylius_uploader.yaml deleted file mode 100644 index cfa727e..0000000 --- a/tests/Application/config/packages/test_cached/sylius_uploader.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/sylius_uploader.yaml" } diff --git a/tests/Application/config/packages/test_cached/twig.yaml b/tests/Application/config/packages/test_cached/twig.yaml deleted file mode 100644 index 8c6e0b4..0000000 --- a/tests/Application/config/packages/test_cached/twig.yaml +++ /dev/null @@ -1,2 +0,0 @@ -twig: - strict_variables: true diff --git a/tests/Application/config/packages/twig.yaml b/tests/Application/config/packages/twig.yaml index 8545473..d9e743a 100644 --- a/tests/Application/config/packages/twig.yaml +++ b/tests/Application/config/packages/twig.yaml @@ -10,3 +10,8 @@ services: autoconfigure: true Twig\Extra\Intl\IntlExtension: ~ + Twig\Extra\String\StringExtension: ~ + +when@test_cached: + twig: + strict_variables: true diff --git a/tests/Application/config/packages/validator.yaml b/tests/Application/config/packages/validator.yaml new file mode 100644 index 0000000..8ff7da1 --- /dev/null +++ b/tests/Application/config/packages/validator.yaml @@ -0,0 +1,3 @@ +framework: + validation: + enable_attributes: true diff --git a/tests/Application/config/packages/web_profiler.yaml b/tests/Application/config/packages/web_profiler.yaml new file mode 100644 index 0000000..7732441 --- /dev/null +++ b/tests/Application/config/packages/web_profiler.yaml @@ -0,0 +1,14 @@ +when@dev: + web_profiler: + toolbar: true + intercept_redirects: false + +when@test: &web_profiler_test + web_profiler: + toolbar: false + intercept_redirects: false + + framework: + profiler: { collect: false } + +when@test_cached: *web_profiler_test diff --git a/tests/Application/config/packages/webpack_encore.yaml b/tests/Application/config/packages/webpack_encore.yaml index 9427d36..e87d4d2 100644 --- a/tests/Application/config/packages/webpack_encore.yaml +++ b/tests/Application/config/packages/webpack_encore.yaml @@ -1,5 +1,5 @@ webpack_encore: - output_path: '%kernel.project_dir%/public/build/default' - builds: - shop: '%kernel.project_dir%/public/build/shop' - admin: '%kernel.project_dir%/public/build/admin' + output_path: '%kernel.project_dir%/public/build/default' + builds: + admin: '%kernel.project_dir%/public/build/admin' + shop: '%kernel.project_dir%/public/build/shop' diff --git a/tests/Application/config/parameters.yaml b/tests/Application/config/parameters.yaml new file mode 100644 index 0000000..d1d8c7b --- /dev/null +++ b/tests/Application/config/parameters.yaml @@ -0,0 +1,2 @@ +parameters: + locale: en_US diff --git a/tests/Application/config/preload.php b/tests/Application/config/preload.php new file mode 100644 index 0000000..5ebcdb2 --- /dev/null +++ b/tests/Application/config/preload.php @@ -0,0 +1,5 @@ + ['all' => true], - BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/sylius/1.10/packages/_sylius.yaml b/tests/Application/config/sylius/1.10/packages/_sylius.yaml deleted file mode 100644 index 63c02ac..0000000 --- a/tests/Application/config/sylius/1.10/packages/_sylius.yaml +++ /dev/null @@ -1,2 +0,0 @@ -sylius_api: - enabled: true diff --git a/tests/Application/config/sylius/1.10/packages/api_platform.yaml b/tests/Application/config/sylius/1.10/packages/api_platform.yaml deleted file mode 100644 index 48c037b..0000000 --- a/tests/Application/config/sylius/1.10/packages/api_platform.yaml +++ /dev/null @@ -1,10 +0,0 @@ -api_platform: - mapping: - paths: - - '%kernel.project_dir%/../../vendor/sylius/sylius/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources' - - '%kernel.project_dir%/config/api_platform' - #- '%kernel.project_dir%/src/Entity' - patch_formats: - json: ['application/merge-patch+json'] - swagger: - versions: [3] diff --git a/tests/Application/config/sylius/1.10/packages/dev/jms_serializer.yaml b/tests/Application/config/sylius/1.10/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b..0000000 --- a/tests/Application/config/sylius/1.10/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.10/packages/dev/swiftmailer.yaml b/tests/Application/config/sylius/1.10/packages/dev/swiftmailer.yaml deleted file mode 100644 index f438078..0000000 --- a/tests/Application/config/sylius/1.10/packages/dev/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - disable_delivery: true diff --git a/tests/Application/config/sylius/1.10/packages/jms_serializer.yaml b/tests/Application/config/sylius/1.10/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc61..0000000 --- a/tests/Application/config/sylius/1.10/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/sylius/1.10/packages/payum.yaml b/tests/Application/config/sylius/1.10/packages/payum.yaml deleted file mode 100644 index e01f066..0000000 --- a/tests/Application/config/sylius/1.10/packages/payum.yaml +++ /dev/null @@ -1,25 +0,0 @@ -services: - app.payum.http_client: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\HttpClient\HttpClient - arguments: - $client: '@Psr\Http\Client\ClientInterface' - app.payum.message_factory: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\Factory\MessageFactory - arguments: - $requestFactory: '@Psr\Http\Client\ClientInterface' - $responseFactory: '@nyholm.psr17.factory' - $streamFactory: '@Psr\Http\Client\ClientInterface' - - nyholm.psr17.factory: - public: true - class: Nyholm\Psr7\Factory\Psr17Factory - -payum: - gateways: - core: - httplug.message_factory: '@app.payum.message_factory' - httplug.stream_factory: '@app.payum.message_factory' - httplug.client: '@Symfony\Component\HttpClient\HttplugClient' - payum.http_client: '@app.payum.http_client' diff --git a/tests/Application/config/sylius/1.10/packages/prod/jms_serializer.yaml b/tests/Application/config/sylius/1.10/packages/prod/jms_serializer.yaml deleted file mode 100644 index c288182..0000000 --- a/tests/Application/config/sylius/1.10/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.10/packages/swiftmailer.yaml b/tests/Application/config/sylius/1.10/packages/swiftmailer.yaml deleted file mode 100644 index 3bab0d3..0000000 --- a/tests/Application/config/sylius/1.10/packages/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - url: '%env(MAILER_URL)%' diff --git a/tests/Application/config/sylius/1.10/packages/test/swiftmailer.yaml b/tests/Application/config/sylius/1.10/packages/test/swiftmailer.yaml deleted file mode 100644 index c438f4b..0000000 --- a/tests/Application/config/sylius/1.10/packages/test/swiftmailer.yaml +++ /dev/null @@ -1,6 +0,0 @@ -swiftmailer: - disable_delivery: true - logging: true - spool: - type: file - path: "%kernel.cache_dir%/spool" diff --git a/tests/Application/config/sylius/1.10/packages/test_cached/swiftmailer.yaml b/tests/Application/config/sylius/1.10/packages/test_cached/swiftmailer.yaml deleted file mode 100644 index 1bc61b8..0000000 --- a/tests/Application/config/sylius/1.10/packages/test_cached/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/swiftmailer.yaml" } diff --git a/tests/Application/config/sylius/1.11/bundles.php b/tests/Application/config/sylius/1.11/bundles.php deleted file mode 100644 index 15f3aa7..0000000 --- a/tests/Application/config/sylius/1.11/bundles.php +++ /dev/null @@ -1,10 +0,0 @@ - ['all' => true], - BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], - Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/sylius/1.11/packages/_sylius.yaml b/tests/Application/config/sylius/1.11/packages/_sylius.yaml deleted file mode 100644 index 63c02ac..0000000 --- a/tests/Application/config/sylius/1.11/packages/_sylius.yaml +++ /dev/null @@ -1,2 +0,0 @@ -sylius_api: - enabled: true diff --git a/tests/Application/config/sylius/1.11/packages/api_platform.yaml b/tests/Application/config/sylius/1.11/packages/api_platform.yaml deleted file mode 100644 index 48c037b..0000000 --- a/tests/Application/config/sylius/1.11/packages/api_platform.yaml +++ /dev/null @@ -1,10 +0,0 @@ -api_platform: - mapping: - paths: - - '%kernel.project_dir%/../../vendor/sylius/sylius/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources' - - '%kernel.project_dir%/config/api_platform' - #- '%kernel.project_dir%/src/Entity' - patch_formats: - json: ['application/merge-patch+json'] - swagger: - versions: [3] diff --git a/tests/Application/config/sylius/1.11/packages/dev/jms_serializer.yaml b/tests/Application/config/sylius/1.11/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b..0000000 --- a/tests/Application/config/sylius/1.11/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.11/packages/dev/swiftmailer.yaml b/tests/Application/config/sylius/1.11/packages/dev/swiftmailer.yaml deleted file mode 100644 index f438078..0000000 --- a/tests/Application/config/sylius/1.11/packages/dev/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - disable_delivery: true diff --git a/tests/Application/config/sylius/1.11/packages/jms_serializer.yaml b/tests/Application/config/sylius/1.11/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc61..0000000 --- a/tests/Application/config/sylius/1.11/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/sylius/1.11/packages/payum.yaml b/tests/Application/config/sylius/1.11/packages/payum.yaml deleted file mode 100644 index 5c1cea2..0000000 --- a/tests/Application/config/sylius/1.11/packages/payum.yaml +++ /dev/null @@ -1,29 +0,0 @@ -services: - app.payum.http_client: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\HttpClient\HttpClient - arguments: - $client: '@Psr\Http\Client\ClientInterface' - app.payum.message_factory: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\Factory\MessageFactory - arguments: - $requestFactory: '@Psr\Http\Client\ClientInterface' - $responseFactory: '@nyholm.psr17.factory' - $streamFactory: '@Psr\Http\Client\ClientInterface' - - nyholm.psr17.factory: - public: true - class: Nyholm\Psr7\Factory\Psr17Factory - -framework: - http_client: - enabled: true # require to alias the service Psr\Http\Client\ClientInterface - -payum: - gateways: - core: - httplug.message_factory: '@app.payum.message_factory' - httplug.stream_factory: '@app.payum.message_factory' - httplug.client: '@Symfony\Component\HttpClient\HttplugClient' - payum.http_client: '@app.payum.http_client' diff --git a/tests/Application/config/sylius/1.11/packages/prod/jms_serializer.yaml b/tests/Application/config/sylius/1.11/packages/prod/jms_serializer.yaml deleted file mode 100644 index c288182..0000000 --- a/tests/Application/config/sylius/1.11/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.11/packages/swiftmailer.yaml b/tests/Application/config/sylius/1.11/packages/swiftmailer.yaml deleted file mode 100644 index 3bab0d3..0000000 --- a/tests/Application/config/sylius/1.11/packages/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - url: '%env(MAILER_URL)%' diff --git a/tests/Application/config/sylius/1.11/packages/test/swiftmailer.yaml b/tests/Application/config/sylius/1.11/packages/test/swiftmailer.yaml deleted file mode 100644 index c438f4b..0000000 --- a/tests/Application/config/sylius/1.11/packages/test/swiftmailer.yaml +++ /dev/null @@ -1,6 +0,0 @@ -swiftmailer: - disable_delivery: true - logging: true - spool: - type: file - path: "%kernel.cache_dir%/spool" diff --git a/tests/Application/config/sylius/1.11/packages/test_cached/swiftmailer.yaml b/tests/Application/config/sylius/1.11/packages/test_cached/swiftmailer.yaml deleted file mode 100644 index 1bc61b8..0000000 --- a/tests/Application/config/sylius/1.11/packages/test_cached/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/swiftmailer.yaml" } diff --git a/tests/Application/config/sylius/1.12/bundles.php b/tests/Application/config/sylius/1.12/bundles.php deleted file mode 100644 index 4a8358c..0000000 --- a/tests/Application/config/sylius/1.12/bundles.php +++ /dev/null @@ -1,8 +0,0 @@ - ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], - Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], - League\FlysystemBundle\FlysystemBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/sylius/1.12/packages/dev/jms_serializer.yaml b/tests/Application/config/sylius/1.12/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b..0000000 --- a/tests/Application/config/sylius/1.12/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.12/packages/jms_serializer.yaml b/tests/Application/config/sylius/1.12/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc61..0000000 --- a/tests/Application/config/sylius/1.12/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/sylius/1.12/packages/mailer.yaml b/tests/Application/config/sylius/1.12/packages/mailer.yaml deleted file mode 100644 index 0a0697c..0000000 --- a/tests/Application/config/sylius/1.12/packages/mailer.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - mailer: - dsn: '%env(MAILER_DSN)%' diff --git a/tests/Application/config/sylius/1.12/packages/prod/jms_serializer.yaml b/tests/Application/config/sylius/1.12/packages/prod/jms_serializer.yaml deleted file mode 100644 index c288182..0000000 --- a/tests/Application/config/sylius/1.12/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.12/packages/test/mailer.yaml b/tests/Application/config/sylius/1.12/packages/test/mailer.yaml deleted file mode 100644 index 52610d6..0000000 --- a/tests/Application/config/sylius/1.12/packages/test/mailer.yaml +++ /dev/null @@ -1,5 +0,0 @@ -framework: - cache: - pools: - test.mailer_pool: - adapter: cache.adapter.filesystem diff --git a/tests/Application/config/sylius/1.12/packages/test_cached/mailer.yaml b/tests/Application/config/sylius/1.12/packages/test_cached/mailer.yaml deleted file mode 100644 index 16f3170..0000000 --- a/tests/Application/config/sylius/1.12/packages/test_cached/mailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/mailer.yaml" } diff --git a/tests/Application/config/sylius/1.13/bundles.php b/tests/Application/config/sylius/1.13/bundles.php deleted file mode 100644 index 59d3af1..0000000 --- a/tests/Application/config/sylius/1.13/bundles.php +++ /dev/null @@ -1,9 +0,0 @@ - ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], - Sylius\Calendar\SyliusCalendarBundle::class => ['all' => true], - League\FlysystemBundle\FlysystemBundle::class => ['all' => true], - Sylius\Abstraction\StateMachine\SyliusStateMachineAbstractionBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/sylius/1.13/packages/dev/jms_serializer.yaml b/tests/Application/config/sylius/1.13/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b..0000000 --- a/tests/Application/config/sylius/1.13/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.13/packages/jms_serializer.yaml b/tests/Application/config/sylius/1.13/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc61..0000000 --- a/tests/Application/config/sylius/1.13/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/sylius/1.13/packages/mailer.yaml b/tests/Application/config/sylius/1.13/packages/mailer.yaml deleted file mode 100644 index 0a0697c..0000000 --- a/tests/Application/config/sylius/1.13/packages/mailer.yaml +++ /dev/null @@ -1,3 +0,0 @@ -framework: - mailer: - dsn: '%env(MAILER_DSN)%' diff --git a/tests/Application/config/sylius/1.13/packages/prod/jms_serializer.yaml b/tests/Application/config/sylius/1.13/packages/prod/jms_serializer.yaml deleted file mode 100644 index c288182..0000000 --- a/tests/Application/config/sylius/1.13/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION 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 deleted file mode 100644 index ceee098..0000000 --- a/tests/Application/config/sylius/1.13/packages/sylius_state_machine_abstraction.yaml +++ /dev/null @@ -1,2 +0,0 @@ -sylius_state_machine_abstraction: - default_adapter: symfony_workflow diff --git a/tests/Application/config/sylius/1.13/packages/test/mailer.yaml b/tests/Application/config/sylius/1.13/packages/test/mailer.yaml deleted file mode 100644 index 52610d6..0000000 --- a/tests/Application/config/sylius/1.13/packages/test/mailer.yaml +++ /dev/null @@ -1,5 +0,0 @@ -framework: - cache: - pools: - test.mailer_pool: - adapter: cache.adapter.filesystem diff --git a/tests/Application/config/sylius/1.13/packages/test_cached/mailer.yaml b/tests/Application/config/sylius/1.13/packages/test_cached/mailer.yaml deleted file mode 100644 index 16f3170..0000000 --- a/tests/Application/config/sylius/1.13/packages/test_cached/mailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/mailer.yaml" } diff --git a/tests/Application/config/sylius/1.9/bundles.php b/tests/Application/config/sylius/1.9/bundles.php deleted file mode 100644 index b4f7d4a..0000000 --- a/tests/Application/config/sylius/1.9/bundles.php +++ /dev/null @@ -1,11 +0,0 @@ - ['all' => true], - BabDev\PagerfantaBundle\BabDevPagerfantaBundle::class => ['all' => true], - SyliusLabs\Polyfill\Symfony\Security\Bundle\SyliusLabsPolyfillSymfonySecurityBundle::class => ['all' => true], - FOS\OAuthServerBundle\FOSOAuthServerBundle::class => ['all' => true], - Sylius\Bundle\AdminApiBundle\SyliusAdminApiBundle::class => ['all' => true], -]; diff --git a/tests/Application/config/sylius/1.9/packages/_sylius.yaml b/tests/Application/config/sylius/1.9/packages/_sylius.yaml deleted file mode 100644 index 1674a97..0000000 --- a/tests/Application/config/sylius/1.9/packages/_sylius.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "@SyliusAdminApiBundle/Resources/config/app/config.yml" } diff --git a/tests/Application/config/sylius/1.9/packages/dev/jms_serializer.yaml b/tests/Application/config/sylius/1.9/packages/dev/jms_serializer.yaml deleted file mode 100644 index 2f32a9b..0000000 --- a/tests/Application/config/sylius/1.9/packages/dev/jms_serializer.yaml +++ /dev/null @@ -1,12 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_PRETTY_PRINT - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.9/packages/dev/swiftmailer.yaml b/tests/Application/config/sylius/1.9/packages/dev/swiftmailer.yaml deleted file mode 100644 index f438078..0000000 --- a/tests/Application/config/sylius/1.9/packages/dev/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - disable_delivery: true diff --git a/tests/Application/config/sylius/1.9/packages/jms_serializer.yaml b/tests/Application/config/sylius/1.9/packages/jms_serializer.yaml deleted file mode 100644 index ed7bc61..0000000 --- a/tests/Application/config/sylius/1.9/packages/jms_serializer.yaml +++ /dev/null @@ -1,4 +0,0 @@ -jms_serializer: - visitors: - xml_serialization: - format_output: '%kernel.debug%' diff --git a/tests/Application/config/sylius/1.9/packages/payum.yaml b/tests/Application/config/sylius/1.9/packages/payum.yaml deleted file mode 100644 index e01f066..0000000 --- a/tests/Application/config/sylius/1.9/packages/payum.yaml +++ /dev/null @@ -1,25 +0,0 @@ -services: - app.payum.http_client: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\HttpClient\HttpClient - arguments: - $client: '@Psr\Http\Client\ClientInterface' - app.payum.message_factory: - public: true - class: Tests\FluxSE\SyliusPayumStripePlugin\App\Payum\Factory\MessageFactory - arguments: - $requestFactory: '@Psr\Http\Client\ClientInterface' - $responseFactory: '@nyholm.psr17.factory' - $streamFactory: '@Psr\Http\Client\ClientInterface' - - nyholm.psr17.factory: - public: true - class: Nyholm\Psr7\Factory\Psr17Factory - -payum: - gateways: - core: - httplug.message_factory: '@app.payum.message_factory' - httplug.stream_factory: '@app.payum.message_factory' - httplug.client: '@Symfony\Component\HttpClient\HttplugClient' - payum.http_client: '@app.payum.http_client' diff --git a/tests/Application/config/sylius/1.9/packages/prod/jms_serializer.yaml b/tests/Application/config/sylius/1.9/packages/prod/jms_serializer.yaml deleted file mode 100644 index c288182..0000000 --- a/tests/Application/config/sylius/1.9/packages/prod/jms_serializer.yaml +++ /dev/null @@ -1,10 +0,0 @@ -jms_serializer: - visitors: - json_serialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION - json_deserialization: - options: - - JSON_UNESCAPED_SLASHES - - JSON_PRESERVE_ZERO_FRACTION diff --git a/tests/Application/config/sylius/1.9/packages/swiftmailer.yaml b/tests/Application/config/sylius/1.9/packages/swiftmailer.yaml deleted file mode 100644 index 3bab0d3..0000000 --- a/tests/Application/config/sylius/1.9/packages/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -swiftmailer: - url: '%env(MAILER_URL)%' diff --git a/tests/Application/config/sylius/1.9/packages/test/swiftmailer.yaml b/tests/Application/config/sylius/1.9/packages/test/swiftmailer.yaml deleted file mode 100644 index c438f4b..0000000 --- a/tests/Application/config/sylius/1.9/packages/test/swiftmailer.yaml +++ /dev/null @@ -1,6 +0,0 @@ -swiftmailer: - disable_delivery: true - logging: true - spool: - type: file - path: "%kernel.cache_dir%/spool" diff --git a/tests/Application/config/sylius/1.9/packages/test_cached/swiftmailer.yaml b/tests/Application/config/sylius/1.9/packages/test_cached/swiftmailer.yaml deleted file mode 100644 index 1bc61b8..0000000 --- a/tests/Application/config/sylius/1.9/packages/test_cached/swiftmailer.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/swiftmailer.yaml" } diff --git a/tests/Application/config/sylius/1.9/routes/sylius_admin_api.yaml b/tests/Application/config/sylius/1.9/routes/sylius_admin_api.yaml deleted file mode 100644 index 80aed45..0000000 --- a/tests/Application/config/sylius/1.9/routes/sylius_admin_api.yaml +++ /dev/null @@ -1,3 +0,0 @@ -sylius_admin_api: - resource: "@SyliusAdminApiBundle/Resources/config/routing.yml" - prefix: /api diff --git a/tests/Application/config/symfony/5.4/packages/security.yaml b/tests/Application/config/symfony/5.4/packages/security.yaml deleted file mode 100644 index b06ffce..0000000 --- a/tests/Application/config/symfony/5.4/packages/security.yaml +++ /dev/null @@ -1,142 +0,0 @@ -parameters: - sylius.security.admin_regex: "^/%sylius_admin.path_name%" - sylius.security.shop_regex: "^/(?!%sylius_admin.path_name%|api/.*|api$|media/.*)[^/]++" - sylius.security.new_api_route: "/api/v2" - sylius.security.new_api_regex: "^%sylius.security.new_api_route%" - sylius.security.new_api_admin_route: "%sylius.security.new_api_route%/admin" - sylius.security.new_api_admin_regex: "^%sylius.security.new_api_admin_route%" - sylius.security.new_api_shop_route: "%sylius.security.new_api_route%/shop" - sylius.security.new_api_shop_regex: "^%sylius.security.new_api_shop_route%" - sylius.security.new_api_user_account_route: "%sylius.security.new_api_shop_route%/account" - sylius.security.new_api_user_account_regex: "^%sylius.security.new_api_user_account_route%" - -security: - always_authenticate_before_granting: true - providers: - sylius_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_api_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - sylius_api_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - - encoders: - Sylius\Component\User\Model\UserInterface: argon2i - firewalls: - admin: - switch_user: true - context: admin - pattern: "%sylius.security.admin_regex%" - provider: sylius_admin_user_provider - form_login: - provider: sylius_admin_user_provider - login_path: sylius_admin_login - check_path: sylius_admin_login_check - failure_path: sylius_admin_login - default_target_path: sylius_admin_dashboard - use_forward: false - use_referer: true - csrf_token_generator: security.csrf.token_manager - csrf_parameter: _csrf_admin_security_token - csrf_token_id: admin_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - path: "/%sylius_admin.path_name%" - name: APP_ADMIN_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_admin_logout - target: sylius_admin_login - anonymous: true - - new_api_admin_user: - pattern: "%sylius.security.new_api_admin_regex%/.*" - provider: sylius_api_admin_user_provider - stateless: true - anonymous: true - json_login: - check_path: "%sylius.security.new_api_admin_route%/authentication-token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - guard: - authenticators: - - lexik_jwt_authentication.jwt_token_authenticator - - new_api_shop_user: - pattern: "%sylius.security.new_api_shop_regex%/.*" - provider: sylius_api_shop_user_provider - stateless: true - anonymous: true - json_login: - check_path: "%sylius.security.new_api_shop_route%/authentication-token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - guard: - authenticators: - - lexik_jwt_authentication.jwt_token_authenticator - - shop: - switch_user: { role: ROLE_ALLOWED_TO_SWITCH } - context: shop - pattern: "%sylius.security.shop_regex%" - provider: sylius_shop_user_provider - form_login: - success_handler: sylius.authentication.success_handler - failure_handler: sylius.authentication.failure_handler - provider: sylius_shop_user_provider - login_path: sylius_shop_login - check_path: sylius_shop_login_check - failure_path: sylius_shop_login - default_target_path: sylius_shop_homepage - use_forward: false - use_referer: true - csrf_token_generator: security.csrf.token_manager - csrf_parameter: _csrf_shop_security_token - csrf_token_id: shop_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - name: APP_SHOP_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_shop_logout - target: sylius_shop_login - invalidate_session: false - success_handler: sylius.handler.shop_user_logout - anonymous: true - - dev: - pattern: ^/(_(profiler|wdt)|css|images|js)/ - security: false - - image_resolver: - pattern: ^/media/cache/resolve - security: false - - access_control: - - { path: "%sylius.security.admin_regex%/_partial", role: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS } - - { path: "%sylius.security.shop_regex%/_partial", role: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS } - - - { path: "%sylius.security.admin_regex%/login", role: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: "%sylius.security.shop_regex%/login", role: IS_AUTHENTICATED_ANONYMOUSLY } - - - { path: "%sylius.security.shop_regex%/register", role: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: "%sylius.security.shop_regex%/verify", role: IS_AUTHENTICATED_ANONYMOUSLY } - - - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } - - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } - - - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS } - - { path: "%sylius.security.new_api_admin_route%/authentication-token", role: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER } - - { path: "%sylius.security.new_api_shop_route%/authentication-token", role: IS_AUTHENTICATED_ANONYMOUSLY } - - { path: "%sylius.security.new_api_shop_regex%/.*", role: IS_AUTHENTICATED_ANONYMOUSLY } diff --git a/tests/Application/config/symfony/5.4/packages/test/framework.yaml b/tests/Application/config/symfony/5.4/packages/test/framework.yaml deleted file mode 100644 index 76d7e5e..0000000 --- a/tests/Application/config/symfony/5.4/packages/test/framework.yaml +++ /dev/null @@ -1,4 +0,0 @@ -framework: - test: ~ - session: - storage_id: session.storage.mock_file diff --git a/tests/Application/config/symfony/5.4/packages/test_cached/framework.yaml b/tests/Application/config/symfony/5.4/packages/test_cached/framework.yaml deleted file mode 100644 index 7c6483d..0000000 --- a/tests/Application/config/symfony/5.4/packages/test_cached/framework.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/framework.yaml" } diff --git a/tests/Application/config/symfony/6.4/packages/security.yaml b/tests/Application/config/symfony/6.4/packages/security.yaml deleted file mode 100644 index a85e21a..0000000 --- a/tests/Application/config/symfony/6.4/packages/security.yaml +++ /dev/null @@ -1,126 +0,0 @@ -security: - enable_authenticator_manager: true - providers: - sylius_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_api_admin_user_provider: - id: sylius.admin_user_provider.email_or_name_based - sylius_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - sylius_api_shop_user_provider: - id: sylius.shop_user_provider.email_or_name_based - password_hashers: - Sylius\Component\User\Model\UserInterface: argon2i - - firewalls: - admin: - switch_user: true - context: admin - pattern: "%sylius.security.admin_regex%" - provider: sylius_admin_user_provider - form_login: - provider: sylius_admin_user_provider - login_path: sylius_admin_login - check_path: sylius_admin_login_check - failure_path: sylius_admin_login - default_target_path: sylius_admin_dashboard - use_forward: false - use_referer: true - enable_csrf: true - csrf_parameter: _csrf_admin_security_token - csrf_token_id: admin_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - path: "/%sylius_admin.path_name%" - name: APP_ADMIN_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_admin_logout - target: sylius_admin_login - - new_api_admin_user: - pattern: "%sylius.security.new_api_admin_regex%/.*" - provider: sylius_api_admin_user_provider - stateless: true - entry_point: jwt - json_login: - check_path: "%sylius.security.new_api_admin_route%/administrators/token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - jwt: true - - new_api_shop_user: - pattern: "%sylius.security.new_api_shop_regex%/.*" - provider: sylius_api_shop_user_provider - stateless: true - entry_point: jwt - json_login: - check_path: "%sylius.security.new_api_shop_route%/customers/token" - username_path: email - password_path: password - success_handler: lexik_jwt_authentication.handler.authentication_success - failure_handler: lexik_jwt_authentication.handler.authentication_failure - jwt: true - - shop: - switch_user: { role: ROLE_ALLOWED_TO_SWITCH } - context: shop - pattern: "%sylius.security.shop_regex%" - provider: sylius_shop_user_provider - form_login: - success_handler: sylius.authentication.success_handler - failure_handler: sylius.authentication.failure_handler - provider: sylius_shop_user_provider - login_path: sylius_shop_login - check_path: sylius_shop_login_check - failure_path: sylius_shop_login - default_target_path: sylius_shop_homepage - use_forward: false - use_referer: true - enable_csrf: true - csrf_parameter: _csrf_shop_security_token - csrf_token_id: shop_authenticate - remember_me: - secret: "%env(APP_SECRET)%" - name: APP_SHOP_REMEMBER_ME - lifetime: 31536000 - remember_me_parameter: _remember_me - logout: - path: sylius_shop_logout - target: sylius_shop_homepage - invalidate_session: false - - image_resolver: - pattern: ^/media/cache/resolve - security: false - - dev: - pattern: ^/(_(profiler|wdt)|css|images|js)/ - security: false - - access_control: - - { path: "%sylius.security.admin_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.admin_regex%/_partial", role: ROLE_NO_ACCESS } - - { path: "%sylius.security.shop_regex%/_partial", role: PUBLIC_ACCESS, ips: [127.0.0.1, ::1] } - - { path: "%sylius.security.shop_regex%/_partial", role: ROLE_NO_ACCESS } - - - { path: "%sylius.security.admin_regex%/forgotten-password", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.admin_regex%/login", role: PUBLIC_ACCESS } - - { path: "%sylius.security.shop_regex%/login", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.shop_regex%/register", role: PUBLIC_ACCESS } - - { path: "%sylius.security.shop_regex%/verify", role: PUBLIC_ACCESS } - - - { path: "%sylius.security.admin_regex%", role: ROLE_ADMINISTRATION_ACCESS } - - { path: "%sylius.security.shop_regex%/account", role: ROLE_USER } - - - { path: "%sylius.security.new_api_admin_route%/administrators/reset-password", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_admin_regex%/.*", role: ROLE_API_ACCESS } - - { path: "%sylius.security.new_api_admin_route%/administrators/token", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_user_account_regex%/.*", role: ROLE_USER } - - { path: "%sylius.security.new_api_shop_route%/customers/token", role: PUBLIC_ACCESS } - - { path: "%sylius.security.new_api_shop_regex%/.*", role: PUBLIC_ACCESS } diff --git a/tests/Application/config/symfony/6.4/packages/test/framework.yaml b/tests/Application/config/symfony/6.4/packages/test/framework.yaml deleted file mode 100644 index 28277fd..0000000 --- a/tests/Application/config/symfony/6.4/packages/test/framework.yaml +++ /dev/null @@ -1,4 +0,0 @@ -framework: - test: ~ - session: - storage_factory_id: session.storage.factory.mock_file diff --git a/tests/Application/config/symfony/6.4/packages/test_cached/framework.yaml b/tests/Application/config/symfony/6.4/packages/test_cached/framework.yaml deleted file mode 100644 index 7c6483d..0000000 --- a/tests/Application/config/symfony/6.4/packages/test_cached/framework.yaml +++ /dev/null @@ -1,2 +0,0 @@ -imports: - - { resource: "../test/framework.yaml" } diff --git a/tests/Application/package.json b/tests/Application/package.json index 7f77d97..d0538e4 100644 --- a/tests/Application/package.json +++ b/tests/Application/package.json @@ -1,55 +1,20 @@ { - "dependencies": { - "chart.js": "^3.7.1", - "jquery": "^3.5.0", - "jquery.dirtyforms": "^2.0.0", - "lightbox2": "^2.9.0", - "semantic-ui-css": "^2.2.0", - "slick-carousel": "^1.8.1" - }, - "devDependencies": { - "@babel/core": "^7.0.0", - "@babel/eslint-parser": "^7.19.1", - "@babel/plugin-proposal-object-rest-spread": "^7.18.9", - "@babel/preset-env": "^7.18.10", - "@babel/register": "^7.18.9", - "@rollup/plugin-babel": "^6.0.3", - "@rollup/plugin-commonjs": "^23.0.3", - "@rollup/plugin-inject": "^5.0.2", - "@rollup/plugin-node-resolve": "^15.0.1", - "@semantic-ui-react/css-patch": "^1.1.2", - "@symfony/webpack-encore": "^4.0.0", - "babel-plugin-fast-async": "^6.1.2", - "babel-plugin-module-resolver": "^4.1.0", - "dedent": "^0.7.0", - "eslint": "^8.28.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-import-resolver-babel-module": "^5.3.1", - "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-import": "^2.26.0", - "eslint-webpack-plugin": "^3.2.0", - "fast-async": "^6.3.8", - "merge-stream": "^2.0.0", - "rollup": "^2.79.1", - "rollup-plugin-terser": "^7.0.2", - "sass": "^1.56.1", - "sass-loader": "^13.0.0", - "webpack": "^5.75.0", - "webpack-cli": "^4.10.0" - }, - "engineStrict": true, + "license": "MIT", "scripts": { - "watch": "encore dev --watch", "build": "encore dev", "build:prod": "encore production", - "lint": "yarn lint:js", - "lint:js": "eslint webpack.config.js assets/admin assets/shop", - "postinstall": "semantic-ui-css-patch" + "watch": "encore dev --watch" }, - "repository": { - "type": "git", - "url": "git+https://github.com/Sylius/Sylius.git" + "dependencies": { + "@sylius-ui/admin": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/AdminBundle", + "@sylius-ui/shop": "file:../../vendor/sylius/sylius/src/Sylius/Bundle/ShopBundle", + "@symfony/ux-autocomplete": "file:../../vendor/symfony/ux-autocomplete/assets", + "@symfony/ux-live-component": "file:../../vendor/symfony/ux-live-component/assets" }, - "author": "Paweł Jędrzejewski", - "license": "MIT" + "devDependencies": { + "@hotwired/stimulus": "^3.0.0", + "@symfony/stimulus-bridge": "^3.2.0", + "@symfony/webpack-encore": "^5.0.1", + "tom-select": "^2.2.2" + } } diff --git a/tests/Application/public/.htaccess b/tests/Application/public/.htaccess index 99ed00d..6d02fc2 100644 --- a/tests/Application/public/.htaccess +++ b/tests/Application/public/.htaccess @@ -1,25 +1,73 @@ -DirectoryIndex app.php +# Use the front controller as index file. It serves as a fallback solution when +# every other rewrite/redirect fails (e.g. in an aliased environment without +# mod_rewrite). Additionally, this reduces the matching process for the +# start page (path "/") because otherwise Apache will apply the rewriting rules +# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl). +DirectoryIndex index.php + +# By default, Apache does not evaluate symbolic links if you did not enable this +# feature in your server configuration. Uncomment the following line if you +# install assets as symlinks or if you experience problems related to symlinks +# when compiling LESS/Sass/CoffeScript assets. +# Options FollowSymlinks + +# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve +# to the front controller "/index.php" but be rewritten to "/index.php/index". + + Options -MultiViews + RewriteEngine On - RewriteCond %{HTTP:Authorization} ^(.*) - RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] - + # Determine the RewriteBase automatically and set it as environment variable. + # If you are using Apache aliases to do mass virtual hosting or installed the + # project in a subdirectory, the base path will be prepended to allow proper + # resolution of the index.php file and to redirect to the correct URI. It will + # work in environments without path prefix as well, providing a safe, one-size + # fits all solution. But as you do not need it in this case, you can comment + # the following 2 lines to eliminate the overhead. RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ RewriteRule ^(.*) - [E=BASE:%1] + # Sets the HTTP_AUTHORIZATION header removed by Apache + RewriteCond %{HTTP:Authorization} . + RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect to URI without front controller to prevent duplicate content + # (with and without `/index.php`). Only do this redirect on the initial + # rewrite by Apache and not on subsequent cycles. Otherwise we would get an + # endless redirect loop (request -> rewrite to front controller -> + # redirect -> request -> ...). + # So in case you get a "too many redirects" error or you always get redirected + # to the start page because your Apache does not expose the REDIRECT_STATUS + # environment variable, you have 2 choices: + # - disable this feature by commenting the following 2 lines or + # - use Apache >= 2.3.9 and replace all L flags by END flags and remove the + # following RewriteCond (best solution) RewriteCond %{ENV:REDIRECT_STATUS} ^$ - RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] + RewriteRule ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [R=301,L] + # If the requested filename exists, simply serve it. + # We only want to let Apache serve files and not directories. RewriteCond %{REQUEST_FILENAME} -f - RewriteRule .? - [L] + RewriteRule ^ - [L] - RewriteRule .? %{ENV:BASE}/index.php [L] + # Rewrite all other queries to the front controller. + RewriteRule ^ %{ENV:BASE}/index.php [L] - RedirectMatch 302 ^/$ /index.php/ + # When mod_rewrite is not available, we instruct a temporary redirect of + # the start page to the front controller explicitly so that the website + # and the generated links can still be used. + RedirectMatch 307 ^/$ /index.php/ + # RedirectTemp cannot be used instead + + + # Prevent clickjacking + Header set X-Frame-Options SAMEORIGIN + diff --git a/tests/Application/webpack.config.js b/tests/Application/webpack.config.js index f07f525..f1b3c98 100644 --- a/tests/Application/webpack.config.js +++ b/tests/Application/webpack.config.js @@ -1,54 +1,10 @@ const path = require('path'); const Encore = require('@symfony/webpack-encore'); -const syliusBundles = path.resolve(__dirname, '../../vendor/sylius/sylius/src/Sylius/Bundle/'); -const uiBundleResources = path.resolve(syliusBundles, 'UiBundle/Resources/private/'); -const uiBundleScripts = path.resolve(uiBundleResources, 'js/'); +const SyliusAdmin = require('@sylius-ui/admin'); +const SyliusShop = require('@sylius-ui/shop'); -// Shop config -Encore - .setOutputPath('public/build/shop/') - .setPublicPath('/build/shop') - .addEntry('shop-entry', './assets/shop/entry.js') - .disableSingleRuntimeChunk() - .cleanupOutputBeforeBuild() - .enableSourceMaps(!Encore.isProduction()) - .enableVersioning(Encore.isProduction()) - .enableSassLoader(); -// Disabled because it create error : -// > 'sylius' should be listed in the project's dependencies. Run 'npm i -S sylius' to add it import/no-extraneous-dependencies -//.enableEslintPlugin(); +const adminConfig = SyliusAdmin.getWebpackConfig(path.resolve(__dirname)); +const shopConfig = SyliusShop.getWebpackConfig(path.resolve(__dirname)); -const shopConfig = Encore.getWebpackConfig(); - -shopConfig.resolve.alias['sylius/ui'] = uiBundleScripts; -shopConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; -shopConfig.resolve.alias['sylius/bundle'] = syliusBundles; -shopConfig.name = 'shop'; - -Encore.reset(); - -// Admin config -Encore - .setOutputPath('public/build/admin/') - .setPublicPath('/build/admin') - .addEntry('admin-entry', './assets/admin/entry.js') - .disableSingleRuntimeChunk() - .cleanupOutputBeforeBuild() - .enableSourceMaps(!Encore.isProduction()) - .enableVersioning(Encore.isProduction()) - .enableSassLoader(); -// Disabled because it create error : -// > 'sylius' should be listed in the project's dependencies. Run 'npm i -S sylius' to add it import/no-extraneous-dependencies -// .enableEslintPlugin(); - -const adminConfig = Encore.getWebpackConfig(); - -adminConfig.resolve.alias['sylius/ui'] = uiBundleScripts; -adminConfig.resolve.alias['sylius/ui-resources'] = uiBundleResources; -adminConfig.resolve.alias['sylius/bundle'] = syliusBundles; -adminConfig.resolve.alias['chart.js/dist/Chart.min'] = path.resolve(__dirname, 'node_modules/chart.js/dist/chart.min.js'); -adminConfig.externals = { ...adminConfig.externals, ...{ window: 'window', document: 'document' } }; -adminConfig.name = 'admin'; - -module.exports = [shopConfig, adminConfig]; +module.exports = [adminConfig, shopConfig]; diff --git a/tests/Behat/Bug/PantherCookieSetter.php b/tests/Behat/Bug/PantherCookieSetter.php index ffb41f9..6586e52 100644 --- a/tests/Behat/Bug/PantherCookieSetter.php +++ b/tests/Behat/Bug/PantherCookieSetter.php @@ -8,18 +8,12 @@ use Behat\Mink\Session; use Sylius\Behat\Service\Setter\CookieSetterInterface; -final class PantherCookieSetter implements CookieSetterInterface +final readonly class PantherCookieSetter implements CookieSetterInterface { - private Session $minkSession; - - private CookieSetterInterface $decoratedCookieSetter; - public function __construct( - Session $minkSession, - CookieSetterInterface $decoratedCookieSetter + private Session $minkSession, + private CookieSetterInterface $decoratedCookieSetter, ) { - $this->decoratedCookieSetter = $decoratedCookieSetter; - $this->minkSession = $minkSession; } public function setCookie($name, $value): void diff --git a/tests/Behat/Context/Api/Shop/CartContext.php b/tests/Behat/Context/Api/Shop/CartContext.php index 78b4604..69e5cc7 100644 --- a/tests/Behat/Context/Api/Shop/CartContext.php +++ b/tests/Behat/Context/Api/Shop/CartContext.php @@ -10,34 +10,15 @@ use Sylius\Behat\Client\ResponseCheckerInterface; use Sylius\Behat\Context\Api\Resources; use Sylius\Behat\Service\SharedStorageInterface; +use Symfony\Component\HttpFoundation\Response; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\StripeCheckoutSessionMocker; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\StripeJsMocker; use Webmozart\Assert\Assert; -final class CartContext implements Context +final readonly class CartContext implements Context { - private ApiClientInterface $shopClient; - - private ResponseCheckerInterface $responseChecker; - - private SharedStorageInterface $sharedStorage; - - private StripeCheckoutSessionMocker $stripeCheckoutSessionMocker; - - private StripeJsMocker $stripeJsMocker; - - public function __construct( - ApiClientInterface $shopClient, - ResponseCheckerInterface $responseChecker, - SharedStorageInterface $sharedStorage, - StripeCheckoutSessionMocker $stripeCheckoutSessionMocker, - StripeJsMocker $stripeJsMocker - ) { - $this->shopClient = $shopClient; - $this->responseChecker = $responseChecker; - $this->sharedStorage = $sharedStorage; - $this->stripeCheckoutSessionMocker = $stripeCheckoutSessionMocker; - $this->stripeJsMocker = $stripeJsMocker; + public function __construct(private ApiClientInterface $shopClient, private ResponseCheckerInterface $responseChecker, private SharedStorageInterface $sharedStorage, private StripeCheckoutSessionMocker $stripeCheckoutSessionMocker, private StripeJsMocker $stripeJsMocker) + { } /** @@ -65,6 +46,7 @@ public function iSeeThePaymentConfigurationForStripeJs(): void */ public function iShouldBeAbleToGetWithValue(string $key, string $expectedValue): void { + /** @var Response $response */ $response = $this->sharedStorage->get('response'); $value = $this->responseChecker->getValue($response, $key); Assert::eq($value, $expectedValue); @@ -75,6 +57,7 @@ public function iShouldBeAbleToGetWithValue(string $key, string $expectedValue): */ public function iShouldBeAbleToGetWithABooleanValue(string $key, bool $expectedValue): void { + /** @var Response $response */ $response = $this->sharedStorage->get('response'); $value = $this->responseChecker->getValue($response, $key); Assert::eq($value, $expectedValue); @@ -90,24 +73,35 @@ public function showPaymentConfiguration(): void '%s/%s/%s/configuration', $tokenValue, Resources::PAYMENTS, - $this->getCart()['payments'][0]['id'] - ) + $this->getCart()['payments'][0]['id'], + ), ); $this->sharedStorage->set('response', $this->shopClient->getLastResponse()); } + /** + * @return array{payments: array} + */ private function getCart(): array { - return $this->responseChecker->getResponseContent($this->shopClient->show(Resources::ORDERS, $this->getCartTokenValue())); + $cart = $this->shopClient->show(Resources::ORDERS, $this->getCartTokenValue()); + + /** @var array{payments: array} $responseContent */ + $responseContent = $this->responseChecker->getResponseContent($cart); + + return $responseContent; } private function getCartTokenValue(): string { if ($this->sharedStorage->has('cart_token')) { - return $this->sharedStorage->get('cart_token'); + /** @var string $cartToken */ + $cartToken = $this->sharedStorage->get('cart_token'); + + return $cartToken; } - throw new LogicException('Unable to found the cart_token inside the shared storage.'); + throw new LogicException('Unable to find the cart_token inside the shared storage.'); } } diff --git a/tests/Behat/Context/Setup/StripeContext.php b/tests/Behat/Context/Setup/StripeContext.php index e12c7a3..bcc9f06 100644 --- a/tests/Behat/Context/Setup/StripeContext.php +++ b/tests/Behat/Context/Setup/StripeContext.php @@ -14,24 +14,15 @@ class StripeContext implements Context { - private SharedStorageInterface $sharedStorage; - - private PaymentMethodRepositoryInterface $paymentMethodRepository; - - private ExampleFactoryInterface $paymentMethodExampleFactory; - - private EntityManagerInterface $paymentMethodManager; - + /** + * @param PaymentMethodRepositoryInterface $paymentMethodRepository + */ public function __construct( - SharedStorageInterface $sharedStorage, - PaymentMethodRepositoryInterface $paymentMethodRepository, - ExampleFactoryInterface $paymentMethodExampleFactory, - EntityManagerInterface $paymentMethodManager + private readonly SharedStorageInterface $sharedStorage, + private readonly PaymentMethodRepositoryInterface $paymentMethodRepository, + private readonly ExampleFactoryInterface $paymentMethodExampleFactory, + private readonly EntityManagerInterface $paymentMethodManager, ) { - $this->sharedStorage = $sharedStorage; - $this->paymentMethodRepository = $paymentMethodRepository; - $this->paymentMethodExampleFactory = $paymentMethodExampleFactory; - $this->paymentMethodManager = $paymentMethodManager; } /** @@ -41,13 +32,13 @@ public function __construct( public function theStoreHasAPaymentMethodWithACodeAndStripeCheckoutSessionPaymentGateway( string $paymentMethodName, string $paymentMethodCode, - bool $useAuthorize = false + bool $useAuthorize = false, ): void { $paymentMethod = $this->createPaymentMethodStripe( $paymentMethodName, $paymentMethodCode, 'stripe_checkout_session', - 'Stripe Checkout Session' + 'Stripe Checkout Session', ); $this->createPaymentMethod($paymentMethod, $useAuthorize); @@ -58,7 +49,7 @@ public function theStoreHasAPaymentMethodWithACodeAndStripeCheckoutSessionPaymen */ public function theStoreHasAPaymentMethodWithACodeAndStripeCheckoutSessionPaymentGatewayUsingAuthorize( string $paymentMethodName, - string $paymentMethodCode + string $paymentMethodCode, ): void { $this->theStoreHasAPaymentMethodWithACodeAndStripeCheckoutSessionPaymentGateway($paymentMethodName, $paymentMethodCode, true); } @@ -70,13 +61,13 @@ public function theStoreHasAPaymentMethodWithACodeAndStripeCheckoutSessionPaymen public function theStoreHasAPaymentMethodWithACodeAndStripeJsPaymentGateway( string $paymentMethodName, string $paymentMethodCode, - bool $useAuthorize = false + bool $useAuthorize = false, ): void { $paymentMethod = $this->createPaymentMethodStripe( $paymentMethodName, $paymentMethodCode, 'stripe_js', - 'Stripe JS' + 'Stripe JS', ); $this->createPaymentMethod($paymentMethod, $useAuthorize); @@ -87,7 +78,7 @@ public function theStoreHasAPaymentMethodWithACodeAndStripeJsPaymentGateway( */ public function theStoreHasAPaymentMethodWithACodeAndStripeJsPaymentGatewayUsingAuthorize( string $paymentMethodName, - string $paymentMethodCode + string $paymentMethodCode, ): void { $this->theStoreHasAPaymentMethodWithACodeAndStripeJsPaymentGateway($paymentMethodName, $paymentMethodCode, true); } @@ -98,7 +89,7 @@ private function createPaymentMethodStripe( string $factoryName, string $description = '', bool $addForCurrentChannel = true, - int $position = null + int $position = null, ): PaymentMethodInterface { /** @var PaymentMethodInterface $paymentMethod */ $paymentMethod = $this->paymentMethodExampleFactory->create([ diff --git a/tests/Behat/Context/Ui/Admin/ManagingOrdersContext.php b/tests/Behat/Context/Ui/Admin/ManagingOrdersContext.php index d0d32f9..20bfa7f 100644 --- a/tests/Behat/Context/Ui/Admin/ManagingOrdersContext.php +++ b/tests/Behat/Context/Ui/Admin/ManagingOrdersContext.php @@ -6,31 +6,22 @@ use Behat\Behat\Context\Context; use Doctrine\Persistence\ObjectManager; -use SM\Factory\FactoryInterface; use Stripe\Checkout\Session; use Stripe\PaymentIntent; +use Sylius\Abstraction\StateMachine\StateMachineInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\PaymentInterface; use Sylius\Component\Payment\PaymentTransitions; -use Sylius\Component\Resource\StateMachine\StateMachineInterface; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\StripeCheckoutSessionMocker; +use Webmozart\Assert\Assert; class ManagingOrdersContext implements Context { - private FactoryInterface $stateMachineFactory; - - private ObjectManager $objectManager; - - private StripeCheckoutSessionMocker $stripeCheckoutSessionMocker; - public function __construct( - FactoryInterface $stateMachineFactory, - ObjectManager $objectManager, - StripeCheckoutSessionMocker $stripeCheckoutSessionMocker + private readonly StateMachineInterface $stateMachine, + private readonly ObjectManager $objectManager, + private readonly StripeCheckoutSessionMocker $stripeCheckoutSessionMocker, ) { - $this->stateMachineFactory = $stateMachineFactory; - $this->objectManager = $objectManager; - $this->stripeCheckoutSessionMocker = $stripeCheckoutSessionMocker; } /** @@ -49,9 +40,7 @@ public function thisOrderIsAlreadyPaid(OrderInterface $order, string $stripePaym ]; $payment->setDetails($details); - /** @var StateMachineInterface $stateMachine */ - $stateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH); - $stateMachine->apply(PaymentTransitions::TRANSITION_COMPLETE); + $this->applyTransitionToState($payment, PaymentInterface::STATE_COMPLETED); $this->objectManager->flush(); } @@ -72,9 +61,7 @@ public function thisOrderIsAlreadyAuthorized(OrderInterface $order, string $stri ]; $payment->setDetails($details); - /** @var StateMachineInterface $stateMachine */ - $stateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH); - $stateMachine->apply(PaymentTransitions::TRANSITION_AUTHORIZE); + $this->applyTransitionToState($payment, PaymentInterface::STATE_AUTHORIZED); $this->objectManager->flush(); } @@ -87,13 +74,12 @@ public function thisOrderIsNotYetPaidStripeCheckoutSession(OrderInterface $order /** @var PaymentInterface $payment */ $payment = $order->getPayments()->first(); - $details = [ + $payment->setDetails([ 'object' => Session::OBJECT_NAME, 'id' => $stripeCheckoutSessionId, 'status' => Session::STATUS_OPEN, 'payment_status' => Session::PAYMENT_STATUS_UNPAID, - ]; - $payment->setDetails($details); + ]); $this->objectManager->flush(); } @@ -106,12 +92,11 @@ public function thisOrderIsNotYetPaidStripeJs(OrderInterface $order, string $str /** @var PaymentInterface $payment */ $payment = $order->getPayments()->first(); - $details = [ + $payment->setDetails([ 'object' => PaymentIntent::OBJECT_NAME, 'id' => $stripePaymentIntentId, 'status' => PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, - ]; - $payment->setDetails($details); + ]); $this->objectManager->flush(); } @@ -124,9 +109,7 @@ public function thisOrderPaymentHasBeenCancelled(OrderInterface $order): void /** @var PaymentInterface $payment */ $payment = $order->getPayments()->first(); - /** @var StateMachineInterface $stateMachine */ - $stateMachine = $this->stateMachineFactory->get($payment, PaymentTransitions::GRAPH); - $stateMachine->apply(PaymentTransitions::TRANSITION_CANCEL); + $this->applyTransitionToState($payment, PaymentInterface::STATE_CANCELLED); $this->objectManager->flush(); } @@ -140,7 +123,9 @@ public function iAmPreparedToCancelThisOrder(OrderInterface $order): void $payment = $order->getPayments()->first(); $details = $payment->getDetails(); + /** @var string $status */ $status = $details['status'] ?? PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD; + /** @var string $captureMethod */ $captureMethod = $details['capture_method'] ?? PaymentIntent::CAPTURE_METHOD_AUTOMATIC; $this->stripeCheckoutSessionMocker->mockCancelPayment($status, $captureMethod); @@ -161,7 +146,7 @@ public function iAmPreparedToExpireThePaymentIntentOnThisOrder(): void { $this->stripeCheckoutSessionMocker->mockCancelPayment( PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, - PaymentIntent::CAPTURE_METHOD_AUTOMATIC + PaymentIntent::CAPTURE_METHOD_AUTOMATIC, ); } @@ -182,9 +167,28 @@ public function iAmPreparedToCaptureAuthorizationOfThisOrder(OrderInterface $ord $payment = $order->getPayments()->first(); $details = $payment->getDetails(); + /** @var string $status */ $status = $details['status'] ?? PaymentIntent::STATUS_REQUIRES_CAPTURE; + /** @var string $captureMethod */ $captureMethod = $details['capture_method'] ?? PaymentIntent::CAPTURE_METHOD_MANUAL; $this->stripeCheckoutSessionMocker->mockCaptureAuthorization($status, $captureMethod); } + + private function applyTransitionToState(PaymentInterface $payment, string $state): void + { + $transition = $this->stateMachine->getTransitionToState( + $payment, + PaymentTransitions::GRAPH, + $state, + ); + + Assert::notNull($transition, 'Transition cannot be null at this point.'); + + $this->stateMachine->apply( + $payment, + PaymentTransitions::GRAPH, + $transition, + ); + } } diff --git a/tests/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php b/tests/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php index 465a27d..74ed778 100644 --- a/tests/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php +++ b/tests/Behat/Context/Ui/Admin/ManagingPaymentMethodsContext.php @@ -5,42 +5,18 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Behat\Context\Ui\Admin; use Behat\Behat\Context\Context; -use FriendsOfBehat\PageObjectExtension\Page\UnexpectedPageException; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Page\Admin\PaymentMethod\CreatePageInterface; use Webmozart\Assert\Assert; class ManagingPaymentMethodsContext implements Context { - /** @var CreatePageInterface */ - private $createPage; - - public function __construct(CreatePageInterface $createPage) - { - $this->createPage = $createPage; - } - - /** - * @Given /^I want to create a new Stripe Checkout Session payment method$/ - * - * @throws UnexpectedPageException - */ - public function iWantToCreateANewStripeCheckoutSessionPaymentMethod(): void - { - $this->createPage->open(['factory' => 'stripe_checkout_session']); - } - - /** - * @Given /^I want to create a new Stripe JS payment method$/ - * - * @throws UnexpectedPageException - */ - public function iWantToCreateANewStripeJsPaymentMethod(): void - { - $this->createPage->open(['factory' => 'stripe_js']); + public function __construct( + private readonly CreatePageInterface $createPage, + ) { } /** - * @When I configure it with test stripe gateway data :secretKey, :publishableKey + * @When I configure it with test stripe gateway data :secretKey and :publishableKey */ public function iConfigureItWithTestStripeGatewayData(string $secretKey, string $publishableKey): void { @@ -53,7 +29,7 @@ public function iConfigureItWithTestStripeGatewayData(string $secretKey, string */ public function iAddAWebhookSecretKey(string $webhookKey): void { - $this->createPage->setStripeWebhookSecretKey($webhookKey); + $this->createPage->addStripeWebhookSecretKey($webhookKey); } /** @@ -81,9 +57,9 @@ public function iShouldSeeAWarningMessageUnderTheUseAuthorizeField(): void } /** - * @Given /^I shouldn't see a warning message under the use authorize field$/ + * @Given /^I should not see a warning message under the use authorize field$/ */ - public function iShouldntSeeAWarningMessageUnderTheUseAuthorizeField(): void + public function iShouldNotSeeAWarningMessageUnderTheUseAuthorizeField(): void { Assert::false($this->createPage->isUseAuthorizeWarningMessageDisplayed()); } diff --git a/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php b/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php index 86165e7..8cb4e41 100644 --- a/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php +++ b/tests/Behat/Context/Ui/Shop/StripeCheckoutSessionShopContext.php @@ -16,24 +16,8 @@ class StripeCheckoutSessionShopContext extends MinkContext implements Context { - private StripeCheckoutSessionMocker $stripeCheckoutSessionMocker; - - private CompletePageInterface $summaryPage; - - private ShowPageInterface $orderDetails; - - private StripePage $paymentPage; - - public function __construct( - StripeCheckoutSessionMocker $stripeCheckoutSessionMocker, - CompletePageInterface $summaryPage, - ShowPageInterface $orderDetails, - StripePage $paymentPage - ) { - $this->stripeCheckoutSessionMocker = $stripeCheckoutSessionMocker; - $this->summaryPage = $summaryPage; - $this->orderDetails = $orderDetails; - $this->paymentPage = $paymentPage; + public function __construct(private readonly StripeCheckoutSessionMocker $stripeCheckoutSessionMocker, private readonly CompletePageInterface $summaryPage, private readonly ShowPageInterface $orderDetails, private readonly StripePage $paymentPage) + { } /** @@ -75,7 +59,7 @@ function () { }, function () { $this->paymentPage->captureOrAuthorizeThenGoToAfterUrl(); - } + }, ); } @@ -107,7 +91,7 @@ function () { }, function () { $this->paymentPage->captureOrAuthorizeThenGoToAfterUrl(); - } + }, ); } @@ -162,6 +146,7 @@ public function iShouldBeNotifiedThatMyPaymentHasBeenAuthorized(): void private function assertNotification(string $expectedNotification): void { + /** @var string[] $notifications */ $notifications = $this->orderDetails->getNotifications(); $hasNotifications = ''; diff --git a/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php b/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php index f452dd9..107b90f 100644 --- a/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php +++ b/tests/Behat/Context/Ui/Shop/StripeJsShopContext.php @@ -16,24 +16,8 @@ class StripeJsShopContext extends MinkContext implements Context { - private StripeJsMocker $stripeJsMocker; - - private CompletePageInterface $summaryPage; - - private ShowPageInterface $orderDetails; - - private StripePage $paymentPage; - - public function __construct( - StripeJsMocker $stripeJsMocker, - CompletePageInterface $summaryPage, - ShowPageInterface $orderDetails, - StripePage $paymentPage - ) { - $this->stripeJsMocker = $stripeJsMocker; - $this->summaryPage = $summaryPage; - $this->orderDetails = $orderDetails; - $this->paymentPage = $paymentPage; + public function __construct(private readonly StripeJsMocker $stripeJsMocker, private readonly CompletePageInterface $summaryPage, private readonly ShowPageInterface $orderDetails, private readonly StripePage $paymentPage) + { } /** @@ -64,7 +48,7 @@ function () { }, function () { $this->paymentPage->captureOrAuthorizeThenGoToAfterUrl(); - } + }, ); } @@ -96,7 +80,7 @@ function () { }, function () { $this->paymentPage->captureOrAuthorizeThenGoToAfterUrl(); - } + }, ); } @@ -162,6 +146,7 @@ public function iShouldBeNotifiedThatMyPaymentHasBeenAuthorized(): void private function assertNotification(string $expectedNotification): void { + /** @var string[] $notifications */ $notifications = $this->orderDetails->getNotifications(); $hasNotifications = ''; diff --git a/tests/Behat/Mocker/Api/CheckoutSessionMocker.php b/tests/Behat/Mocker/Api/CheckoutSessionMocker.php index df04f47..3381f5e 100644 --- a/tests/Behat/Mocker/Api/CheckoutSessionMocker.php +++ b/tests/Behat/Mocker/Api/CheckoutSessionMocker.php @@ -4,7 +4,6 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api; -use ArrayObject; use FluxSE\PayumStripe\Action\Api\Resource\AbstractAllAction; use FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction; use FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction; @@ -12,45 +11,38 @@ use FluxSE\PayumStripe\Request\Api\Resource\CreateSession; use FluxSE\PayumStripe\Request\Api\Resource\ExpireSession; use FluxSE\PayumStripe\Request\Api\Resource\RetrieveSession; +use Mockery\MockInterface; use Stripe\Checkout\Session; use Stripe\Collection; -use Sylius\Behat\Service\Mocker\MockerInterface; final class CheckoutSessionMocker { - /** @var MockerInterface */ - private $mocker; - - public function __construct(MockerInterface $mocker) - { - $this->mocker = $mocker; + public function __construct( + private MockInterface&AbstractCreateAction $mockCreateSessionAction, + private MockInterface&AbstractRetrieveAction $mockRetrieveSessionAction, + private MockInterface&AbstractAllAction $mockAllSessionAction, + private MockInterface&AbstractRetrieveAction $mockExpireSessionAction, + ) { } public function mockCreateAction(): void { - $mockCreateSession = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.create_session', - AbstractCreateAction::class - ); - - $mockCreateSession + $this->mockCreateSessionAction ->shouldReceive('setApi') ->once(); - $mockCreateSession + $this->mockCreateSessionAction ->shouldReceive('setGateway') ->once(); - $mockCreateSession + $this->mockCreateSessionAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof CreateSession; - }); + ->andReturnUsing(fn ($request) => $request instanceof CreateSession); - $mockCreateSession + $this->mockCreateSessionAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (CreateSession $request) { - /** @var ArrayObject $rModel */ + /** @var \ArrayObject $rModel */ $rModel = $request->getModel(); $session = Session::constructFrom(array_merge([ 'id' => 'cs_1', @@ -64,25 +56,18 @@ public function mockCreateAction(): void public function mockRetrieveAction(string $status, string $paymentStatus): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.retrieve_session', - AbstractRetrieveAction::class - ); - - $mock + $this->mockRetrieveSessionAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockRetrieveSessionAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockRetrieveSessionAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof RetrieveSession; - }); + ->andReturnUsing(fn ($request) => $request instanceof RetrieveSession); - $mock + $this->mockRetrieveSessionAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (RetrieveSession $request) use ($status, $paymentStatus) { @@ -98,25 +83,18 @@ public function mockRetrieveAction(string $status, string $paymentStatus): void public function mockAllAction(string $status): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.all_session', - AbstractAllAction::class - ); - - $mock + $this->mockAllSessionAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockAllSessionAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockAllSessionAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof AllSession; - }); + ->andReturnUsing(fn ($request) => $request instanceof AllSession); - $mock + $this->mockAllSessionAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (AllSession $request) use ($status) { @@ -127,32 +105,25 @@ public function mockAllAction(string $status): void 'object' => Session::OBJECT_NAME, 'status' => $status, ], - ]]) + ]]), ); }); } public function mockExpireAction(): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.expire_session', - AbstractRetrieveAction::class - ); - - $mock + $this->mockExpireSessionAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockExpireSessionAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockExpireSessionAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof ExpireSession; - }); + ->andReturnUsing(fn ($request) => $request instanceof ExpireSession); - $mock + $this->mockExpireSessionAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (ExpireSession $request) { @@ -163,4 +134,12 @@ public function mockExpireAction(): void ])); }); } + + public function unmock(): void + { + $this->mockCreateSessionAction->expects([]); + $this->mockRetrieveSessionAction->expects([]); + $this->mockAllSessionAction->expects([]); + $this->mockExpireSessionAction->expects([]); + } } diff --git a/tests/Behat/Mocker/Api/PaymentIntentMocker.php b/tests/Behat/Mocker/Api/PaymentIntentMocker.php index c41ca2c..1e081bc 100644 --- a/tests/Behat/Mocker/Api/PaymentIntentMocker.php +++ b/tests/Behat/Mocker/Api/PaymentIntentMocker.php @@ -4,7 +4,6 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api; -use ArrayObject; use FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction; use FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction; use FluxSE\PayumStripe\Action\Api\Resource\AbstractUpdateAction; @@ -13,43 +12,38 @@ use FluxSE\PayumStripe\Request\Api\Resource\CreatePaymentIntent; use FluxSE\PayumStripe\Request\Api\Resource\RetrievePaymentIntent; use FluxSE\PayumStripe\Request\Api\Resource\UpdatePaymentIntent; +use Mockery\MockInterface; use Stripe\PaymentIntent; -use Sylius\Behat\Service\Mocker\MockerInterface; -final class PaymentIntentMocker +final readonly class PaymentIntentMocker { - private MockerInterface $mocker; - - public function __construct(MockerInterface $mocker) - { - $this->mocker = $mocker; + public function __construct( + private MockInterface&AbstractCreateAction $mockCreatePaymentIntentAction, + private MockInterface&AbstractRetrieveAction $mockRetrievePaymentIntentAction, + private MockInterface&AbstractUpdateAction $mockUpdatePaymentIntentAction, + private MockInterface&AbstractRetrieveAction $mockCancelPaymentIntentAction, + private MockInterface&AbstractRetrieveAction $mockCapturePaymentIntentAction, + ) { } public function mockCreateAction(): void { - $mockCreatePaymentIntent = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.create_payment_intent', - AbstractCreateAction::class - ); - - $mockCreatePaymentIntent + $this->mockCreatePaymentIntentAction ->shouldReceive('setApi') ->once(); - $mockCreatePaymentIntent + $this->mockCreatePaymentIntentAction ->shouldReceive('setGateway') ->once(); - $mockCreatePaymentIntent + $this->mockCreatePaymentIntentAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof CreatePaymentIntent; - }); + ->andReturnUsing(fn ($request) => $request instanceof CreatePaymentIntent); - $mockCreatePaymentIntent + $this->mockCreatePaymentIntentAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (CreatePaymentIntent $request) { - /** @var ArrayObject $rModel */ + /** @var \ArrayObject $rModel */ $rModel = $request->getModel(); $paymentIntent = PaymentIntent::constructFrom(array_merge([ 'id' => 'pi_1', @@ -62,25 +56,18 @@ public function mockCreateAction(): void public function mockRetrieveAction(string $status): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.retrieve_payment_intent', - AbstractRetrieveAction::class - ); - - $mock + $this->mockRetrievePaymentIntentAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockRetrievePaymentIntentAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockRetrievePaymentIntentAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof RetrievePaymentIntent; - }); + ->andReturnUsing(fn ($request) => $request instanceof RetrievePaymentIntent); - $mock + $this->mockRetrievePaymentIntentAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (RetrievePaymentIntent $request) use ($status) { @@ -95,25 +82,18 @@ public function mockRetrieveAction(string $status): void public function mockUpdateAction(string $status, string $captureMethod): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.update_payment_intent', - AbstractUpdateAction::class - ); - - $mock + $this->mockUpdatePaymentIntentAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockUpdatePaymentIntentAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockUpdatePaymentIntentAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof UpdatePaymentIntent; - }); + ->andReturnUsing(fn ($request) => $request instanceof UpdatePaymentIntent); - $mock + $this->mockUpdatePaymentIntentAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (UpdatePaymentIntent $request) use ($status, $captureMethod) { @@ -129,25 +109,18 @@ public function mockUpdateAction(string $status, string $captureMethod): void public function mockCancelAction(string $captureMethod): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.cancel_payment_intent', - AbstractRetrieveAction::class - ); - - $mock + $this->mockCancelPaymentIntentAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockCancelPaymentIntentAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockCancelPaymentIntentAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof CancelPaymentIntent; - }); + ->andReturnUsing(fn ($request) => $request instanceof CancelPaymentIntent); - $mock + $this->mockCancelPaymentIntentAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (CancelPaymentIntent $request) use ($captureMethod) { @@ -162,25 +135,18 @@ public function mockCancelAction(string $captureMethod): void public function mockCaptureAction(string $status): void { - $mock = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.capture_payment_intent', - AbstractRetrieveAction::class - ); - - $mock + $this->mockCapturePaymentIntentAction ->shouldReceive('setApi') ->once(); - $mock + $this->mockCapturePaymentIntentAction ->shouldReceive('setGateway') ->once(); - $mock + $this->mockCapturePaymentIntentAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof CapturePaymentIntent; - }); + ->andReturnUsing(fn ($request) => $request instanceof CapturePaymentIntent); - $mock + $this->mockCapturePaymentIntentAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (CapturePaymentIntent $request) use ($status) { @@ -192,4 +158,13 @@ public function mockCaptureAction(string $status): void ])); }); } + + public function unmock(): void + { + $this->mockCreatePaymentIntentAction->expects([]); + $this->mockRetrievePaymentIntentAction->expects([]); + $this->mockUpdatePaymentIntentAction->expects([]); + $this->mockCancelPaymentIntentAction->expects([]); + $this->mockCapturePaymentIntentAction->expects([]); + } } diff --git a/tests/Behat/Mocker/Api/RefundMocker.php b/tests/Behat/Mocker/Api/RefundMocker.php index f297a1d..29717e9 100644 --- a/tests/Behat/Mocker/Api/RefundMocker.php +++ b/tests/Behat/Mocker/Api/RefundMocker.php @@ -7,45 +7,35 @@ use ArrayObject; use FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction; use FluxSE\PayumStripe\Request\Api\Resource\CreateRefund; +use Mockery\MockInterface; use Stripe\Checkout\Session; use Stripe\Refund; -use Sylius\Behat\Service\Mocker\MockerInterface; final class RefundMocker { - /** @var MockerInterface */ - private $mocker; - - public function __construct(MockerInterface $mocker) - { - $this->mocker = $mocker; + public function __construct( + private MockInterface&AbstractCreateAction $mockCreateRefundAction, + ) { } public function mockCreateAction(): void { - $mockCreateSession = $this->mocker->mockService( - 'tests.flux_se.sylius_payum_stripe_plugin.behat.mocker.action.create_refund', - AbstractCreateAction::class - ); - - $mockCreateSession + $this->mockCreateRefundAction ->shouldReceive('setApi') ->once(); - $mockCreateSession + $this->mockCreateRefundAction ->shouldReceive('setGateway') ->once(); - $mockCreateSession + $this->mockCreateRefundAction ->shouldReceive('supports') - ->andReturnUsing(function ($request) { - return $request instanceof CreateRefund; - }); + ->andReturnUsing(fn ($request) => $request instanceof CreateRefund); - $mockCreateSession + $this->mockCreateRefundAction ->shouldReceive('execute') ->once() ->andReturnUsing(function (CreateRefund $request) { - /** @var ArrayObject $rModel */ + /** @var ArrayObject $rModel */ $rModel = $request->getModel(); $refund = Session::constructFrom(array_merge([ 'id' => 're_1', @@ -54,4 +44,9 @@ public function mockCreateAction(): void $request->setApiResource($refund); }); } + + public function unmock(): void + { + $this->mockCreateRefundAction->expects([]); + } } diff --git a/tests/Behat/Mocker/PayumActionMocker.php b/tests/Behat/Mocker/PayumActionMocker.php new file mode 100644 index 0000000..7240450 --- /dev/null +++ b/tests/Behat/Mocker/PayumActionMocker.php @@ -0,0 +1,29 @@ + $className + */ + public function __invoke(string $name, string $className): MockInterface + { + /** @var (MockInterface&ActionInterface)|null $mock */ + $mock = Mockery::fetchMock($name); + + if (null !== $mock) { + return $mock; + } + + return Mockery::namedMock($name, $className); + } +} diff --git a/tests/Behat/Mocker/StripeCheckoutSessionMocker.php b/tests/Behat/Mocker/StripeCheckoutSessionMocker.php index 8b5f205..b7568f8 100644 --- a/tests/Behat/Mocker/StripeCheckoutSessionMocker.php +++ b/tests/Behat/Mocker/StripeCheckoutSessionMocker.php @@ -6,31 +6,17 @@ use Stripe\Checkout\Session; use Stripe\PaymentIntent; -use Sylius\Behat\Service\Mocker\MockerInterface; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api\CheckoutSessionMocker; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api\PaymentIntentMocker; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api\RefundMocker; -final class StripeCheckoutSessionMocker +final readonly class StripeCheckoutSessionMocker { - private MockerInterface $mocker; - - private CheckoutSessionMocker $checkoutSessionMocker; - - private PaymentIntentMocker $paymentIntentMocker; - - private RefundMocker $refundMocker; - public function __construct( - MockerInterface $mocker, - CheckoutSessionMocker $checkoutSessionMocker, - PaymentIntentMocker $paymentIntentMocker, - RefundMocker $refundMocker + private CheckoutSessionMocker $checkoutSessionMocker, + private PaymentIntentMocker $paymentIntentMocker, + private RefundMocker $refundMocker, ) { - $this->mocker = $mocker; - $this->checkoutSessionMocker = $checkoutSessionMocker; - $this->paymentIntentMocker = $paymentIntentMocker; - $this->refundMocker = $refundMocker; } public function mockCaptureOrAuthorize(callable $action): void @@ -41,13 +27,13 @@ public function mockCaptureOrAuthorize(callable $action): void $action, Session::STATUS_OPEN, Session::PAYMENT_STATUS_UNPAID, - PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD + PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, ); } public function mockCancelPayment(string $status, string $captureMethod): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->paymentIntentMocker->mockUpdateAction($status, $captureMethod); $this->paymentIntentMocker->mockCancelAction($captureMethod); @@ -56,14 +42,14 @@ public function mockCancelPayment(string $status, string $captureMethod): void public function mockRefundPayment(): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->refundMocker->mockCreateAction(); } public function mockExpirePayment(): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->checkoutSessionMocker->mockExpireAction(); $this->checkoutSessionMocker->mockRetrieveAction(Session::STATUS_EXPIRED, Session::PAYMENT_STATUS_UNPAID); @@ -72,7 +58,7 @@ public function mockExpirePayment(): void public function mockCaptureAuthorization(string $status, string $captureMethod): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->paymentIntentMocker->mockUpdateAction($status, $captureMethod); $this->paymentIntentMocker->mockCaptureAction(PaymentIntent::STATUS_SUCCEEDED); @@ -86,7 +72,7 @@ public function mockGoBackPayment(callable $action): void $action, Session::STATUS_OPEN, Session::PAYMENT_STATUS_UNPAID, - PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD + PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, ); } @@ -96,7 +82,7 @@ public function mockSuccessfulPayment(callable $notifyAction, callable $action): $notifyAction, Session::STATUS_COMPLETE, Session::PAYMENT_STATUS_PAID, - PaymentIntent::STATUS_SUCCEEDED + PaymentIntent::STATUS_SUCCEEDED, ); $this->mockPaymentIntentSync($action, PaymentIntent::STATUS_SUCCEEDED); } @@ -107,7 +93,7 @@ public function mockAuthorizePayment(callable $notifyAction, callable $action): $notifyAction, Session::STATUS_COMPLETE, Session::PAYMENT_STATUS_UNPAID, - PaymentIntent::STATUS_REQUIRES_CAPTURE + PaymentIntent::STATUS_REQUIRES_CAPTURE, ); $this->mockPaymentIntentSync($action, PaymentIntent::STATUS_REQUIRES_CAPTURE); } @@ -118,7 +104,7 @@ public function mockSuccessfulPaymentWithoutWebhook(callable $action): void $action, Session::STATUS_COMPLETE, Session::PAYMENT_STATUS_PAID, - PaymentIntent::STATUS_SUCCEEDED + PaymentIntent::STATUS_SUCCEEDED, ); } @@ -128,7 +114,7 @@ public function mockSuccessfulPaymentWithoutWebhookUsingAuthorize(callable $acti $action, Session::STATUS_COMPLETE, Session::PAYMENT_STATUS_UNPAID, - PaymentIntent::STATUS_REQUIRES_CAPTURE + PaymentIntent::STATUS_REQUIRES_CAPTURE, ); } @@ -138,14 +124,14 @@ public function mockPaymentIntentSync(callable $action, string $status): void $action(); - $this->mocker->unmockAll(); + $this->unmockAll(); } public function mockSessionSync( callable $action, string $sessionStatus, string $paymentStatus, - string $paymentIntentStatus + string $paymentIntentStatus, ): void { $this->checkoutSessionMocker->mockRetrieveAction($sessionStatus, $paymentStatus); $this->mockPaymentIntentSync($action, $paymentIntentStatus); @@ -156,4 +142,11 @@ public function mockExpireSession(string $sessionStatus): void $this->checkoutSessionMocker->mockAllAction($sessionStatus); $this->checkoutSessionMocker->mockExpireAction(); } + + private function unmockAll(): void + { + $this->checkoutSessionMocker->unmock(); + $this->paymentIntentMocker->unmock(); + $this->refundMocker->unmock(); + } } diff --git a/tests/Behat/Mocker/StripeJsMocker.php b/tests/Behat/Mocker/StripeJsMocker.php index c2eb92b..04528fe 100644 --- a/tests/Behat/Mocker/StripeJsMocker.php +++ b/tests/Behat/Mocker/StripeJsMocker.php @@ -5,42 +5,31 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker; use Stripe\PaymentIntent; -use Sylius\Behat\Service\Mocker\MockerInterface; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api\PaymentIntentMocker; use Tests\FluxSE\SyliusPayumStripePlugin\Behat\Mocker\Api\RefundMocker; -final class StripeJsMocker +final readonly class StripeJsMocker { - private MockerInterface $mocker; - - private PaymentIntentMocker $paymentIntentMocker; - - private RefundMocker $refundMocker; - public function __construct( - MockerInterface $mocker, - PaymentIntentMocker $paymentIntentMocker, - RefundMocker $refundMocker + private PaymentIntentMocker $paymentIntentMocker, + private RefundMocker $refundMocker, ) { - $this->mocker = $mocker; - $this->paymentIntentMocker = $paymentIntentMocker; - $this->refundMocker = $refundMocker; } public function mockCaptureOrAuthorize(callable $action): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->paymentIntentMocker->mockCreateAction(); $this->mockPaymentIntentSync( $action, - PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD + PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, ); } public function mockCancelPayment(string $status, string $captureMethod): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->paymentIntentMocker->mockUpdateAction($status, $captureMethod); $this->paymentIntentMocker->mockCancelAction($captureMethod); @@ -49,14 +38,14 @@ public function mockCancelPayment(string $status, string $captureMethod): void public function mockRefundPayment(): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->refundMocker->mockCreateAction(); } public function mockCaptureAuthorization(string $status, string $captureMethod): void { - $this->mocker->unmockAll(); + $this->unmockAll(); $this->paymentIntentMocker->mockUpdateAction($status, $captureMethod); $this->paymentIntentMocker->mockCaptureAction(PaymentIntent::STATUS_SUCCEEDED); @@ -67,7 +56,7 @@ public function mockGoBackPayment(callable $action): void { $this->mockPaymentIntentSync( $action, - PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD + PaymentIntent::STATUS_REQUIRES_PAYMENT_METHOD, ); } @@ -75,7 +64,7 @@ public function mockSuccessfulPayment(callable $notifyAction, callable $action): { $this->mockPaymentIntentSync( $notifyAction, - PaymentIntent::STATUS_SUCCEEDED + PaymentIntent::STATUS_SUCCEEDED, ); $this->mockPaymentIntentSync($action, PaymentIntent::STATUS_SUCCEEDED); } @@ -84,7 +73,7 @@ public function mockAuthorizePayment(callable $notifyAction, callable $action): { $this->mockPaymentIntentSync( $notifyAction, - PaymentIntent::STATUS_REQUIRES_CAPTURE + PaymentIntent::STATUS_REQUIRES_CAPTURE, ); $this->mockPaymentIntentSync($action, PaymentIntent::STATUS_REQUIRES_CAPTURE); } @@ -93,7 +82,7 @@ public function mockSuccessfulPaymentWithoutWebhook(callable $action): void { $this->mockPaymentIntentSync( $action, - PaymentIntent::STATUS_SUCCEEDED + PaymentIntent::STATUS_SUCCEEDED, ); } @@ -101,7 +90,7 @@ public function mockSuccessfulPaymentWithoutWebhookUsingAuthorize(callable $acti { $this->mockPaymentIntentSync( $action, - PaymentIntent::STATUS_REQUIRES_CAPTURE + PaymentIntent::STATUS_REQUIRES_CAPTURE, ); } @@ -111,6 +100,11 @@ public function mockPaymentIntentSync(callable $action, string $status): void $action(); - $this->mocker->unmockAll(); + $this->unmockAll(); + } + + private function unmockAll(): void + { + $this->paymentIntentMocker->unmock(); } } diff --git a/tests/Behat/Page/Admin/PaymentMethod/CreatePage.php b/tests/Behat/Page/Admin/PaymentMethod/CreatePage.php index 31b859a..43cedbc 100644 --- a/tests/Behat/Page/Admin/PaymentMethod/CreatePage.php +++ b/tests/Behat/Page/Admin/PaymentMethod/CreatePage.php @@ -9,14 +9,16 @@ final class CreatePage extends BaseCreatePage implements CreatePageInterface { - private int $webhookSecretKeysListIndex = 0; - protected function getDefinedElements(): array { return array_merge(parent::getDefinedElements(), [ - 'webhook_secret_keys_list_element' => '#sylius_payment_method_gatewayConfig_config_webhook_secret_keys_%index%', - 'use_authorize_info' => '#sylius_payment_method_gatewayConfig_config_use_authorize_info', - 'use_authorize' => '#sylius_payment_method_gatewayConfig_config_use_authorize', + 'add_webhook_secret_key' => '[data-test-add-webhook-secret-key]', + 'webhook_secret_key' => '[data-test-webhook-secret-key]:contains("%name%")', + 'webhook_secret_key_added' => '[data-test-webhook-secret-key]:last-child input:empty', + 'webhook_secret_key_delete' => '[data-test-webhook-secret-key]:contains("%name%") button[data-test-delete-webhook-secret-key]', + 'webhook_secret_key_last' => '[data-test-webhook-secret-key]:last-child', + 'use_authorize_info' => '[data-test-use-authorize-info]', + 'use_authorize' => '[data-test-use-authorize]', ]); } @@ -33,16 +35,19 @@ public function setStripePublishableKey(string $publishableKey): void /** * @throws ElementNotFoundException */ - public function setStripeWebhookSecretKey(string $webhookSecretKey): void + public function addStripeWebhookSecretKey(string $webhookSecretKey): void { - $this->getDocument()->clickLink('Add'); - $this - ->getElement('webhook_secret_keys_list_element', [ - '%index%' => $this->webhookSecretKeysListIndex, - ]) - ->setValue($webhookSecretKey) - ; - ++$this->webhookSecretKeysListIndex; + $this->getElement('add_webhook_secret_key')->click(); + + $this->waitForElement(5, 'webhook_secret_key_added'); + + $input = $this->getElement('webhook_secret_key_last')->find('css', 'input'); + + if (null === $input) { + throw new ElementNotFoundException($this->getSession(), 'input', 'css', 'input'); + } + + $input->setValue($webhookSecretKey); } /** @@ -51,8 +56,7 @@ public function setStripeWebhookSecretKey(string $webhookSecretKey): void public function setStripeIsAuthorized(bool $isAuthorized): void { if ($isAuthorized) { - // ->check() is not working anymore because the checkbox is not visible - $this->getElement('use_authorize')->click(); + $this->getElement('use_authorize')->check(); } else { $this->getElement('use_authorize')->uncheck(); } @@ -67,4 +71,19 @@ public function isUseAuthorizeWarningMessageDisplayed(): bool { return $this->getElement('use_authorize_info')->isVisible(); } + + /** + * @param array $parameters + */ + private function waitForElement( + int $timeout, + string $elementName, + array $parameters = [], + bool $shouldExist = true, + ): void { + $this->getDocument()->waitFor( + $timeout, + fn (): bool => $shouldExist && $this->hasElement($elementName, $parameters), + ); + } } diff --git a/tests/Behat/Page/Admin/PaymentMethod/CreatePageInterface.php b/tests/Behat/Page/Admin/PaymentMethod/CreatePageInterface.php index c64d98e..004060d 100644 --- a/tests/Behat/Page/Admin/PaymentMethod/CreatePageInterface.php +++ b/tests/Behat/Page/Admin/PaymentMethod/CreatePageInterface.php @@ -12,7 +12,7 @@ public function setStripeSecretKey(string $secretKey): void; public function setStripePublishableKey(string $publishableKey): void; - public function setStripeWebhookSecretKey(string $webhookSecretKey): void; + public function addStripeWebhookSecretKey(string $webhookSecretKey): void; public function setStripeIsAuthorized(bool $isAuthorized): void; diff --git a/tests/Behat/Page/External/StripePage.php b/tests/Behat/Page/External/StripePage.php index 17752ef..5bb9803 100644 --- a/tests/Behat/Page/External/StripePage.php +++ b/tests/Behat/Page/External/StripePage.php @@ -16,34 +16,21 @@ final class StripePage extends Page implements StripePageInterface { - private RepositoryInterface $securityTokenRepository; - - private HttpKernelBrowser $client; - - private PayumNotifyPageInterface $payumNotifyPage; - /** @var string[] */ private array $deadTokens = []; - private string $gatewayName; - /** - * @param array|ArrayAccess $minkParameters + * @param array|ArrayAccess $minkParameters */ public function __construct( Session $session, $minkParameters, - RepositoryInterface $securityTokenRepository, - HttpKernelBrowser $client, - PayumNotifyPageInterface $payumNotifyPage, - string $gatewayName + private readonly RepositoryInterface $securityTokenRepository, + private readonly HttpKernelBrowser $client, + private readonly PayumNotifyPageInterface $payumNotifyPage, + private readonly string $gatewayName, ) { parent::__construct($session, $minkParameters); - - $this->securityTokenRepository = $securityTokenRepository; - $this->client = $client; - $this->payumNotifyPage = $payumNotifyPage; - $this->gatewayName = $gatewayName; } /** @@ -53,7 +40,7 @@ public function captureOrAuthorizeThenGoToAfterUrl(): void { try { $token = $this->findToken(); - } catch (RuntimeException $e) { + } catch (RuntimeException) { // No easy way to know if we need authorize or not $token = $this->findToken('authorize'); } @@ -100,7 +87,7 @@ public function notify(string $content): void [], [], $this->generateSignature($payload), - $payload + $payload, ); } @@ -114,7 +101,7 @@ private function findToken(string $type = 'capture'): TokenInterface continue; } - if (false === strpos($token->getTargetUrl(), $type)) { + if (!str_contains($token->getTargetUrl(), $type)) { continue; } @@ -132,7 +119,7 @@ private function findToken(string $type = 'capture'): TokenInterface if ($type !== 'notify') { $relatedToken = null; foreach ($tokens as $token) { - if (false === strpos($foundToken->getAfterUrl(), $token->getHash())) { + if (!str_contains($foundToken->getAfterUrl(), $token->getHash())) { continue; } $relatedToken = $token; @@ -148,6 +135,9 @@ private function findToken(string $type = 'capture'): TokenInterface return $foundToken; } + /** + * @param array $urlParameters + */ protected function getUrl(array $urlParameters = []): string { return 'https://stripe.com'; diff --git a/tests/Behat/Page/Shop/PayumNotifyPage.php b/tests/Behat/Page/Shop/PayumNotifyPage.php index 2f19813..a4f3a9d 100644 --- a/tests/Behat/Page/Shop/PayumNotifyPage.php +++ b/tests/Behat/Page/Shop/PayumNotifyPage.php @@ -4,22 +4,23 @@ namespace Tests\FluxSE\SyliusPayumStripePlugin\Behat\Page\Shop; +use ArrayAccess; use Behat\Mink\Session; use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage; use Symfony\Component\Routing\RouterInterface; class PayumNotifyPage extends SymfonyPage implements PayumNotifyPageInterface { - private string $routeName; - + /** + * @param array|ArrayAccess $minkParameters + */ public function __construct( Session $session, $minkParameters, RouterInterface $router, - string $routeName + private readonly string $routeName, ) { parent::__construct($session, $minkParameters, $router); - $this->routeName = $routeName; } public function getNotifyUrl(array $urlParameters): string diff --git a/tests/Behat/Page/Shop/PayumNotifyPageInterface.php b/tests/Behat/Page/Shop/PayumNotifyPageInterface.php index f425741..6d5f216 100644 --- a/tests/Behat/Page/Shop/PayumNotifyPageInterface.php +++ b/tests/Behat/Page/Shop/PayumNotifyPageInterface.php @@ -8,5 +8,8 @@ interface PayumNotifyPageInterface extends SymfonyPageInterface { + /** + * @param array $urlParameters + */ public function getNotifyUrl(array $urlParameters): string; } diff --git a/tests/Behat/Resources/services/context.xml b/tests/Behat/Resources/services/context.xml index 60226a7..9a5c89f 100644 --- a/tests/Behat/Resources/services/context.xml +++ b/tests/Behat/Resources/services/context.xml @@ -4,6 +4,18 @@ + + + + + + + Stripe Checkout Session + Stripe JS + + + @@ -19,7 +31,7 @@ - + diff --git a/tests/Behat/Resources/services/mocker.xml b/tests/Behat/Resources/services/mocker.xml index 666193b..5adeb9c 100644 --- a/tests/Behat/Resources/services/mocker.xml +++ b/tests/Behat/Resources/services/mocker.xml @@ -5,7 +5,6 @@ - @@ -13,24 +12,30 @@ - - + + + + - + + + + + - + diff --git a/tests/Behat/Resources/services/payum_mocks.xml b/tests/Behat/Resources/services/payum_mocks.xml index cfa46ce..0e45c5f 100644 --- a/tests/Behat/Resources/services/payum_mocks.xml +++ b/tests/Behat/Resources/services/payum_mocks.xml @@ -2,61 +2,92 @@ + + class="Mockery\MockInterface" public="true"> + create_session + FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction + + class="Mockery\MockInterface" public="true"> + retrieve_session + FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction + + class="Mockery\MockInterface" public="true"> + all_session + FluxSE\PayumStripe\Action\Api\Resource\AbstractAllAction + + class="Mockery\MockInterface" public="true"> + expire_session + FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction + + class="Mockery\MockInterface" public="true"> + create_payment_intent + FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction + + class="Mockery\MockInterface" public="true"> + retrieve_payment_intent + FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction + + class="Mockery\MockInterface" public="true"> + update_payment_intent + FluxSE\PayumStripe\Action\Api\Resource\AbstractUpdateAction + + class="Mockery\MockInterface" public="true"> + cancel_payment_intent + FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction + + class="Mockery\MockInterface" public="true"> + capture_payment_intent + FluxSE\PayumStripe\Action\Api\Resource\AbstractRetrieveAction + + class="Mockery\MockInterface" public="true"> + create_refund + FluxSE\PayumStripe\Action\Api\Resource\AbstractCreateAction + diff --git a/tests/Behat/Resources/suites/admin.yaml b/tests/Behat/Resources/suites/admin.yaml index 2403bd1..627d3f1 100644 --- a/tests/Behat/Resources/suites/admin.yaml +++ b/tests/Behat/Resources/suites/admin.yaml @@ -23,10 +23,9 @@ default: - sylius.behat.context.setup.user - sylius.behat.context.setup.zone - - tests.flux_se.sylius_payum_stripe_plugin.behat.context.setup.stripe - - - sylius.behat.context.ui.admin.managing_payment_methods - sylius.behat.context.ui.admin.notification + - tests.flux_se.sylius_payum_stripe_plugin.behat.context.ui.admin.managing_payment_methods.stripe + - tests.flux_se.sylius_payum_stripe_plugin.behat.context.setup.stripe - tests.flux_se.sylius_payum_stripe_plugin.behat.context.ui.admin.managing_payment_methods filters: diff --git a/tests/Unit/Action/ConvertPaymentActionTest.php b/tests/Unit/Action/ConvertPaymentActionTest.php new file mode 100644 index 0000000..ec5d82d --- /dev/null +++ b/tests/Unit/Action/ConvertPaymentActionTest.php @@ -0,0 +1,110 @@ +detailsProviderMock = $this->createMock(DetailsProviderInterface::class); + $this->convertPaymentAction = new ConvertPaymentAction($this->detailsProviderMock); + } + + public function testImplementsActionInterface(): void + { + $this->assertInstanceOf(ActionInterface::class, $this->convertPaymentAction); + $this->assertInstanceOf(ConvertPaymentActionInterface::class, $this->convertPaymentAction); + } + + /** + * @throws Exception + */ + public function testExecutes(): void + { + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + + $details = []; + $paymentMock + ->expects(self::atLeastOnce()) + ->method('getOrder') + ->willReturn($orderMock) + ; + + $requestMock + ->expects(self::atLeastOnce()) + ->method('getSource') + ->willReturn($paymentMock) + ; + + $requestMock + ->expects(self::atLeastOnce()) + ->method('getTo') + ->willReturn('array') + ; + + $this->detailsProviderMock + ->expects(self::atLeastOnce()) + ->method('getDetails') + ->with($orderMock) + ->willReturn($details) + ; + + $requestMock + ->expects(self::atLeastOnce()) + ->method('setResult') + ->with($details) + ; + + $this->convertPaymentAction->execute($requestMock); + } + + /** + * @throws Exception + */ + public function testSupportsOnlyConvertRequestPaymentSourceAndArrayTo(): void + { + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + + $requestMock + ->expects(self::atLeastOnce()) + ->method('getSource') + ->willReturn($paymentMock) + ; + + $requestMock + ->expects(self::atLeastOnce()) + ->method('getTo') + ->willReturn('array') + ; + + $this->assertTrue($this->convertPaymentAction->supports($requestMock)); + } +} diff --git a/tests/Unit/Extension/CancelExistingPaymentIntentExtensionTest.php b/tests/Unit/Extension/CancelExistingPaymentIntentExtensionTest.php new file mode 100644 index 0000000..75daec7 --- /dev/null +++ b/tests/Unit/Extension/CancelExistingPaymentIntentExtensionTest.php @@ -0,0 +1,289 @@ +expireSessionRequestFactoryMock = $this->createMock(ExpireSessionRequestFactoryInterface::class); + $this->allSessionRequestFactoryMock = $this->createMock(AllSessionRequestFactoryInterface::class); + $this->cancelExistingPaymentIntentExtension = new CancelExistingPaymentIntentExtension($this->expireSessionRequestFactoryMock, $this->allSessionRequestFactoryMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(ExtensionInterface::class, $this->cancelExistingPaymentIntentExtension); + } + + /** + * @throws Exception + */ + public function testDoesNothingWhenActionIsNotTheConvertPaymentActionTargeted(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ActionInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + + $this->allSessionRequestFactoryMock->expects(self::never())->method('createNew'); + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testDoesNothingWhenPaymentDetailsAreEmpty(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ConvertPaymentActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ConvertPaymentActionInterface::class); + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getSource')->willReturn($paymentMock); + $paymentMock->expects(self::atLeastOnce())->method('getDetails')->willReturn([]); + + $this->allSessionRequestFactoryMock->expects(self::never())->method('createNew'); + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testDoesNothingWhenPaymentDetailsAreSomethingElseThanAPaymentIntent(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ConvertPaymentActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ConvertPaymentActionInterface::class); + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getSource')->willReturn($paymentMock); + $paymentMock->expects(self::atLeastOnce())->method('getDetails')->willReturn([ + 'object' => SetupIntent::OBJECT_NAME, + ]); + + $this->allSessionRequestFactoryMock->expects(self::never())->method('createNew'); + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testDoesntFoundTheRelatedSessionAndDoNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ConvertPaymentActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ConvertPaymentActionInterface::class); + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + /** @var GatewayInterface&MockObject $gatewayMock */ + $gatewayMock = $this->createMock(GatewayInterface::class); + /** @var AllInterface&MockObject $allSessionRequestMock */ + $allSessionRequestMock = $this->createMock(AllInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getSource')->willReturn($paymentMock); + $contextMock->expects(self::atLeastOnce())->method('getGateway')->willReturn($gatewayMock); + $piId = 'pi_test_0000000000000000000'; + $paymentMock->expects(self::atLeastOnce())->method('getDetails')->willReturn([ + 'id' => $piId, + 'object' => PaymentIntent::OBJECT_NAME, + ]); + $this->allSessionRequestFactoryMock->expects(self::atLeastOnce())->method('createNew') + ->willReturn($allSessionRequestMock); + $allSessionRequestMock->expects(self::atLeastOnce())->method('setParameters')->with([ + 'payment_intent' => $piId, + ]); + $allSessionRequestMock->expects(self::atLeastOnce())->method('getApiResources')->willReturn(Collection::constructFrom(['data' => []])); + $gatewayMock->expects(self::atLeastOnce())->method('execute')->with($allSessionRequestMock); + + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testFoundsARelatedExpiredSessionAndDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ConvertPaymentActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ConvertPaymentActionInterface::class); + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + /** @var GatewayInterface&MockObject $gatewayMock */ + $gatewayMock = $this->createMock(GatewayInterface::class); + /** @var AllInterface&MockObject $allSessionRequestMock */ + $allSessionRequestMock = $this->createMock(AllInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getSource')->willReturn($paymentMock); + $contextMock->expects(self::atLeastOnce())->method('getGateway')->willReturn($gatewayMock); + $piId = 'pi_test_0000000000000000000'; + $csId = 'cs_test_0000000000000000000'; + $paymentMock->expects(self::atLeastOnce())->method('getDetails')->willReturn([ + 'id' => $piId, + 'object' => PaymentIntent::OBJECT_NAME, + ]); + $this->allSessionRequestFactoryMock->expects(self::atLeastOnce())->method('createNew') + ->willReturn($allSessionRequestMock); + $allSessionRequestMock->expects(self::atLeastOnce())->method('setParameters')->with([ + 'payment_intent' => $piId, + ]); + $allSessionRequestMock->expects(self::atLeastOnce())->method('getApiResources')->willReturn(Collection::constructFrom([ + 'data' => [ + [ + 'id' => $csId, + 'status' => Session::STATUS_EXPIRED, + ], + ], + ])); + $gatewayMock->expects(self::atLeastOnce())->method('execute')->with($allSessionRequestMock); + + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testFoundsARelatedSessionAndExpiresIt(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ConvertPaymentActionInterface&MockObject $actionMock */ + $actionMock = $this->createMock(ConvertPaymentActionInterface::class); + /** @var Convert&MockObject $requestMock */ + $requestMock = $this->createMock(Convert::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + /** @var GatewayInterface&MockObject $gatewayMock */ + $gatewayMock = $this->createMock(GatewayInterface::class); + /** @var AllInterface&MockObject $allSessionRequestMock */ + $allSessionRequestMock = $this->createMock(AllInterface::class); + /** @var CustomCallInterface&MockObject $expireSessionRequestMock */ + $expireSessionRequestMock = $this->createMock(CustomCallInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getAction')->willReturn($actionMock); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getSource')->willReturn($paymentMock); + $contextMock->expects(self::atLeastOnce())->method('getGateway')->willReturn($gatewayMock); + $piId = 'pi_test_0000000000000000000'; + $csId = 'cs_test_0000000000000000000'; + $paymentMock->expects(self::atLeastOnce())->method('getDetails')->willReturn([ + 'id' => $piId, + 'object' => PaymentIntent::OBJECT_NAME, + ]); + $this->allSessionRequestFactoryMock->expects(self::once())->method('createNew') + ->willReturn($allSessionRequestMock); + $allSessionRequestMock->expects(self::once())->method('setParameters')->with([ + 'payment_intent' => $piId, + ]); + $allSessionRequestMock->expects(self::atLeastOnce())->method('getApiResources')->willReturn(Collection::constructFrom([ + 'data' => [ + [ + 'id' => $csId, + 'status' => Session::STATUS_OPEN, + ], + ], + ])); + $this->expireSessionRequestFactoryMock->expects(self::once())->method('createNew')->with($csId) + ->willReturn($expireSessionRequestMock); + + $matcher = self::exactly(2); + $gatewayMock + ->expects($matcher) + ->method('execute') + ->willReturnCallback(function ($request) use ($matcher, $allSessionRequestMock, $expireSessionRequestMock) { + match ($matcher->numberOfInvocations()) { + 1 => $this->assertEquals($allSessionRequestMock, $request), + 2 => $this->assertEquals($expireSessionRequestMock, $request), + default => self::fail('Number of invocations not expected!'), + }; + }); + $this->cancelExistingPaymentIntentExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPreExecuteDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + + $this->allSessionRequestFactoryMock->expects(self::never())->method('createNew'); + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onPreExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + + $this->allSessionRequestFactoryMock->expects(self::never())->method('createNew'); + $this->expireSessionRequestFactoryMock->expects(self::never())->method('createNew'); + + $this->cancelExistingPaymentIntentExtension->onPostExecute($contextMock); + } +} diff --git a/tests/Unit/Extension/UpdatePaymentStateExtensionTest.php b/tests/Unit/Extension/UpdatePaymentStateExtensionTest.php new file mode 100644 index 0000000..5bcf686 --- /dev/null +++ b/tests/Unit/Extension/UpdatePaymentStateExtensionTest.php @@ -0,0 +1,259 @@ +stateMachineMock = $this->createMock(StateMachineInterface::class); + $this->storageMock = $this->createMock(StorageInterface::class); + $this->getStatusRequestFactoryMock = $this->createMock(GetStatusFactoryInterface::class); + $this->updatePaymentStateExtension = new UpdatePaymentStateExtension($this->stateMachineMock, $this->storageMock, $this->getStatusRequestFactoryMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(ExtensionInterface::class, $this->updatePaymentStateExtension); + } + + /** + * @throws Exception + */ + public function testOnPreExecuteWithIdentityFindsTheRelatedPaymentAndStoresIt(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var IdentityInterface&MockObject $modelMock */ + $modelMock = $this->createMock(IdentityInterface::class); // deprecated : implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary) + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($modelMock); + $this->storageMock->expects(self::atLeastOnce())->method('find')->with($modelMock)->willReturn($paymentMock); + $paymentMock->expects(self::once())->method('getId')->willReturn(1); + + $this->updatePaymentStateExtension->onPreExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPreExecuteWithPaymentStoresIt(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PaymentInterface&MockObject $modelMock */ + $modelMock = $this->createMock(PaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($modelMock); + $modelMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $this->updatePaymentStateExtension->onPreExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPreExecuteWithoutPaymentOrIdentifyDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PayumPaymentInterface&MockObject $modelMock */ + $modelMock = $this->createMock(PayumPaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($modelMock); + $this->updatePaymentStateExtension->onPreExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPreExecuteWithoutModelAggregateInterfaceDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var TokenAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(TokenAggregateInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $this->updatePaymentStateExtension->onPreExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnExecuteDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + + $contextMock->expects(self::never())->method(self::anything()); + + $this->updatePaymentStateExtension->onExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteApplyATransition(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + /** @var GetStatusInterface&MockObject $statusMock */ + $statusMock = $this->createMock(GetStatusInterface::class); + /** @var GatewayInterface&MockObject $gatewayMock */ + $gatewayMock = $this->createMock(GatewayInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn(null); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($paymentMock); + $paymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $contextMock->expects(self::atLeastOnce())->method('getPrevious')->willReturn([]); + $contextMock->expects(self::atLeastOnce())->method('getGateway')->willReturn($gatewayMock); + $this->getStatusRequestFactoryMock->expects(self::atLeastOnce())->method('createNewWithModel')->with($paymentMock)->willReturn($statusMock); + $gatewayMock->expects(self::atLeastOnce())->method('execute')->with($statusMock); + $paymentMock->expects(self::atLeastOnce())->method('getState')->willReturn(PaymentInterface::STATE_NEW); + $statusMock->expects(self::atLeastOnce())->method('getValue')->willReturn(PaymentInterface::STATE_COMPLETED); + $this->stateMachineMock->expects(self::atLeastOnce())->method('getTransitionToState')->with($paymentMock, PaymentTransitions::GRAPH, PaymentInterface::STATE_COMPLETED)->willReturn('complete'); + $this->stateMachineMock->expects(self::atLeastOnce())->method('apply')->with($paymentMock, PaymentTransitions::GRAPH, 'complete'); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteApplyATransitionWithoutASyliusPaymentInterfaceWhenThereWasPreviouslyStoredPayment(): void + { + /** @var Context&MockObject $previousContextMock */ + $previousContextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $previousRequestMock */ + $previousRequestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PaymentInterface&MockObject $previousPaymentMock */ + $previousPaymentMock = $this->createMock(PaymentInterface::class); + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PayumPaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PayumPaymentInterface::class); + /** @var GetStatusInterface&MockObject $statusMock */ + $statusMock = $this->createMock(GetStatusInterface::class); + /** @var GatewayInterface&MockObject $gatewayMock */ + $gatewayMock = $this->createMock(GatewayInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn(null); + $previousContextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($previousRequestMock); + $previousRequestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($previousPaymentMock); + $previousPaymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($paymentMock); + $contextMock->expects(self::atLeastOnce())->method('getPrevious')->willReturn([]); + $contextMock->expects(self::atLeastOnce())->method('getGateway')->willReturn($gatewayMock); + $this->getStatusRequestFactoryMock->expects(self::atLeastOnce())->method('createNewWithModel')->with($previousPaymentMock)->willReturn($statusMock); + $gatewayMock->expects(self::atLeastOnce())->method('execute')->with($statusMock); + $previousPaymentMock->expects(self::atLeastOnce())->method('getState')->willReturn(PaymentInterface::STATE_NEW); + $statusMock->expects(self::atLeastOnce())->method('getValue')->willReturn(PaymentInterface::STATE_COMPLETED); + $this->stateMachineMock->expects(self::atLeastOnce())->method('getTransitionToState')->with($previousPaymentMock, PaymentTransitions::GRAPH, PaymentInterface::STATE_COMPLETED)->willReturn('complete'); + $this->stateMachineMock->expects(self::atLeastOnce())->method('apply')->with($previousPaymentMock, PaymentTransitions::GRAPH, 'complete'); + $this->updatePaymentStateExtension->onPreExecute($previousContextMock); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteWithoutModelAggregateInterfaceDoesNothingIfThereIsPreviousContext(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var TokenAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(TokenAggregateInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn(null); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $contextMock->expects(self::atLeastOnce())->method('getPrevious')->willReturn([1]); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteWithoutModelAggregateInterfaceDoesNothingIfThereIsNoPreviousContext(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var TokenAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(TokenAggregateInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn(null); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $contextMock->expects(self::atLeastOnce())->method('getPrevious')->willReturn([]); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteWithModelAggregateInterfaceDoesNothingIfItIsNotASyliusPaymentInterface(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + /** @var ModelAggregateInterface&MockObject $requestMock */ + $requestMock = $this->createMock(ModelAggregateInterface::class); + /** @var PayumPaymentInterface&MockObject $modelMock */ + $modelMock = $this->createMock(PayumPaymentInterface::class); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn(null); + $contextMock->expects(self::atLeastOnce())->method('getRequest')->willReturn($requestMock); + $requestMock->expects(self::atLeastOnce())->method('getModel')->willReturn($modelMock); + $contextMock->expects(self::atLeastOnce())->method('getPrevious')->willReturn([]); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } + + /** + * @throws Exception + */ + public function testOnPostExecuteWithExceptionDoesNothing(): void + { + /** @var Context&MockObject $contextMock */ + $contextMock = $this->createMock(Context::class); + $exception = new \Exception(); + $contextMock->expects(self::atLeastOnce())->method('getException')->willReturn($exception); + $this->updatePaymentStateExtension->onPostExecute($contextMock); + } +} diff --git a/tests/Unit/Provider/CustomerEmailProviderTest.php b/tests/Unit/Provider/CustomerEmailProviderTest.php new file mode 100644 index 0000000..5821c83 --- /dev/null +++ b/tests/Unit/Provider/CustomerEmailProviderTest.php @@ -0,0 +1,54 @@ +customerEmailProvider = new CustomerEmailProvider(); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(CustomerEmailProvider::class, $this->customerEmailProvider); + $this->assertInstanceOf(CustomerEmailProviderInterface::class, $this->customerEmailProvider); + } + + /** + * @throws Exception + */ + public function testGetCustomerEmailFromACustomer(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + /** @var CustomerInterface&MockObject $customerMock */ + $customerMock = $this->createMock(CustomerInterface::class); + $orderMock->expects(self::atLeastOnce())->method('getCustomer')->willReturn($customerMock); + $customerMock->expects(self::atLeastOnce())->method('getEmail')->willReturn('customer@domain.tld'); + $this->assertSame('customer@domain.tld', $this->customerEmailProvider->getCustomerEmail($orderMock)); + } + + /** + * @throws Exception + */ + public function testCouldReturnNull(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderMock->expects(self::atLeastOnce())->method('getCustomer')->willReturn(null); + $this->assertNull($this->customerEmailProvider->getCustomerEmail($orderMock)); + } +} diff --git a/tests/Unit/Provider/DetailsProviderTest.php b/tests/Unit/Provider/DetailsProviderTest.php new file mode 100644 index 0000000..9ce23f9 --- /dev/null +++ b/tests/Unit/Provider/DetailsProviderTest.php @@ -0,0 +1,82 @@ +customerEmailProviderMock = $this->createMock(CustomerEmailProviderInterface::class); + $this->lineItemsProviderMock = $this->createMock(LineItemsProviderInterface::class); + $this->paymentMethodTypesProviderMock = $this->createMock(PaymentMethodTypesProviderInterface::class); + $this->modeProviderMock = $this->createMock(ModeProviderInterface::class); + $this->detailsProvider = new DetailsProvider($this->customerEmailProviderMock, $this->lineItemsProviderMock, $this->paymentMethodTypesProviderMock, $this->modeProviderMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(DetailsProvider::class, $this->detailsProvider); + $this->assertInstanceOf(DetailsProviderInterface::class, $this->detailsProvider); + } + + /** + * @throws Exception + */ + public function testGetFullDetails(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $this->customerEmailProviderMock->expects(self::atLeastOnce())->method('getCustomerEmail')->with($orderMock)->willReturn('customer@domain.tld'); + $this->lineItemsProviderMock->expects(self::atLeastOnce())->method('getLineItems')->with($orderMock)->willReturn([]); + $this->paymentMethodTypesProviderMock->expects(self::atLeastOnce())->method('getPaymentMethodTypes')->with($orderMock)->willReturn(['card']); + $this->modeProviderMock->expects(self::atLeastOnce())->method('getMode')->with($orderMock)->willReturn(Session::MODE_PAYMENT); + $this->assertSame([ + 'customer_email' => 'customer@domain.tld', + 'mode' => Session::MODE_PAYMENT, + 'line_items' => [], + 'payment_method_types' => ['card'], + ], $this->detailsProvider->getDetails($orderMock)); + } + + /** + * @throws Exception + */ + public function testGetMinimumDetails(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $this->customerEmailProviderMock->expects(self::atLeastOnce())->method('getCustomerEmail')->with($orderMock)->willReturn(null); + $this->lineItemsProviderMock->expects(self::atLeastOnce())->method('getLineItems')->with($orderMock)->willReturn(null); + $this->paymentMethodTypesProviderMock->expects(self::atLeastOnce())->method('getPaymentMethodTypes')->with($orderMock)->willReturn([]); + $this->modeProviderMock->expects(self::atLeastOnce())->method('getMode')->with($orderMock)->willReturn(Session::MODE_PAYMENT); + $this->assertSame([ + 'mode' => Session::MODE_PAYMENT, + ], $this->detailsProvider->getDetails($orderMock)); + } +} diff --git a/tests/Unit/Provider/LineItemImagesProviderTest.php b/tests/Unit/Provider/LineItemImagesProviderTest.php new file mode 100644 index 0000000..3a64bcf --- /dev/null +++ b/tests/Unit/Provider/LineItemImagesProviderTest.php @@ -0,0 +1,114 @@ +imagineCacheManagerMock = $this->createMock(CacheManager::class); + $this->lineItemImagesProvider = new LineItemImagesProvider($this->imagineCacheManagerMock, 'my_filter', 'https://somewhere-online.tld/fallbak.jpg'); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(LineItemImagesProvider::class, $this->lineItemImagesProvider); + $this->assertInstanceOf(LineItemImagesProviderInterface::class, $this->lineItemImagesProvider); + } + + /** + * @throws Exception + */ + public function testGetImageUrls(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + /** @var ProductImageInterface&MockObject $productImageMock */ + $productImageMock = $this->createMock(ProductImageInterface::class); + $productImageMock->expects(self::atLeastOnce())->method('getPath')->willReturn('/path/image.jpg'); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $productMock->expects(self::atLeastOnce())->method('getImages')->willReturn(new ArrayCollection([ + $productImageMock, + ])); + $this->imagineCacheManagerMock->expects(self::atLeastOnce())->method('getBrowserPath')->with('/path/image.jpg', 'my_filter') + ->willReturn('https://somewhere-online.tld/path/image.jpg'); + $this->assertSame('https://somewhere-online.tld/path/image.jpg', $this->lineItemImagesProvider->getImageUrlFromProduct($productMock)); + + $imageUrls = $this->lineItemImagesProvider->getImageUrls($orderItemMock); + + $this->assertSame([ + 'https://somewhere-online.tld/path/image.jpg', + ], $imageUrls); + } + + /** + * @throws Exception + */ + public function testGetFallbackImageUrlsOnLocalhost(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + /** @var ProductImageInterface&MockObject $productImageMock */ + $productImageMock = $this->createMock(ProductImageInterface::class); + $productImageMock->expects(self::atLeastOnce())->method('getPath')->willReturn('/path/image.jpg'); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $productMock->expects(self::atLeastOnce())->method('getImages')->willReturn(new ArrayCollection([ + $productImageMock, + ])); + $this->imagineCacheManagerMock->expects(self::exactly(2)) + ->method('getBrowserPath') + ->with('/path/image.jpg', 'my_filter') + ->willReturn('https://localhost/path/image.jpg') + ; + $this->assertSame('https://somewhere-online.tld/fallbak.jpg', $this->lineItemImagesProvider->getImageUrlFromProduct($productMock)); + + $imageUrls = $this->lineItemImagesProvider->getImageUrls($orderItemMock); + + $this->assertSame([ + 'https://somewhere-online.tld/fallbak.jpg', + ], $imageUrls); + } + + /** + * @throws Exception + */ + public function testGetFallbackImageUrlsWhenThereIsNoImage(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $productMock->expects(self::atLeastOnce())->method('getImages')->willReturn(new ArrayCollection()); + + $imageUrlFromProduct = $this->lineItemImagesProvider->getImageUrlFromProduct($productMock); + $this->assertSame('https://somewhere-online.tld/fallbak.jpg', $imageUrlFromProduct); + + $imageUrls = $this->lineItemImagesProvider->getImageUrls($orderItemMock); + $this->assertSame(['https://somewhere-online.tld/fallbak.jpg'], $imageUrls); + } +} diff --git a/tests/Unit/Provider/LineItemProviderTest.php b/tests/Unit/Provider/LineItemProviderTest.php new file mode 100644 index 0000000..c672995 --- /dev/null +++ b/tests/Unit/Provider/LineItemProviderTest.php @@ -0,0 +1,134 @@ +lineItemImagesProviderMock = $this->createMock(LineItemImagesProviderInterface::class); + $this->lineItemNameProviderMock = $this->createMock(LinetItemNameProviderInterface::class); + $this->lineItemProvider = new LineItemProvider($this->lineItemImagesProviderMock, $this->lineItemNameProviderMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(LineItemProvider::class, $this->lineItemProvider); + $this->assertInstanceOf(LineItemProviderInterface::class, $this->lineItemProvider); + } + + /** + * @throws Exception + */ + public function testGetLineItem(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getOrder')->willReturn($orderMock); + $orderItemMock->expects(self::atLeastOnce())->method('getTotal')->willReturn(1000); + $orderMock->expects(self::atLeastOnce())->method('getCurrencyCode')->willReturn('USD'); + $this->lineItemImagesProviderMock->expects(self::atLeastOnce())->method('getImageUrls')->with($orderItemMock)->willReturn(['/path/image.jpg']); + $this->lineItemNameProviderMock->expects(self::atLeastOnce())->method('getItemName')->with($orderItemMock)->willReturn('1x - My item name'); + $this->assertSame([ + 'price_data' => [ + 'unit_amount' => 1000, + 'currency' => 'USD', + 'product_data' => [ + 'name' => '1x - My item name', + 'images' => [ + '/path/image.jpg', + ], + ], + ], + 'quantity' => 1, + ], $this->lineItemProvider->getLineItem($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetLineItemWithNoImages(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getOrder')->willReturn($orderMock); + $orderItemMock->expects(self::atLeastOnce())->method('getTotal')->willReturn(1000); + $orderMock->expects(self::atLeastOnce())->method('getCurrencyCode')->willReturn('USD'); + $this->lineItemImagesProviderMock->expects(self::atLeastOnce())->method('getImageUrls')->with($orderItemMock)->willReturn([]); + $this->lineItemNameProviderMock->expects(self::atLeastOnce())->method('getItemName')->with($orderItemMock)->willReturn('1x - My item name'); + $this->assertSame([ + 'price_data' => [ + 'unit_amount' => 1000, + 'currency' => 'USD', + 'product_data' => [ + 'name' => '1x - My item name', + 'images' => [], + ], + ], + 'quantity' => 1, + ], $this->lineItemProvider->getLineItem($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetLineItemWhenQuantityIsGreaterThan1(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getOrder')->willReturn($orderMock); + $orderItemMock->expects(self::atLeastOnce())->method('getTotal')->willReturn(1000); + $orderMock->expects(self::atLeastOnce())->method('getCurrencyCode')->willReturn('USD'); + $this->lineItemImagesProviderMock->expects(self::atLeastOnce())->method('getImageUrls')->with($orderItemMock)->willReturn([]); + $this->lineItemNameProviderMock->expects(self::atLeastOnce())->method('getItemName')->with($orderItemMock)->willReturn('2x - My item name'); + $this->assertSame([ + 'price_data' => [ + 'unit_amount' => 1000, + 'currency' => 'USD', + 'product_data' => [ + 'name' => '2x - My item name', + 'images' => [], + ], + ], + 'quantity' => 1, + ], $this->lineItemProvider->getLineItem($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetLineItemWithNullOrder(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getOrder')->willReturn(null); + $this->assertNull($this->lineItemProvider->getLineItem($orderItemMock)); + } +} diff --git a/tests/Unit/Provider/LineItemsProviderTest.php b/tests/Unit/Provider/LineItemsProviderTest.php new file mode 100644 index 0000000..35590e0 --- /dev/null +++ b/tests/Unit/Provider/LineItemsProviderTest.php @@ -0,0 +1,75 @@ +lineItemProviderMock = $this->createMock(LineItemProviderInterface::class); + $this->shippingLineItemProviderMock = $this->createMock(ShippingLineItemProviderInterface::class); + $this->lineItemsProvider = new LineItemsProvider($this->lineItemProviderMock, $this->shippingLineItemProviderMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(LineItemsProvider::class, $this->lineItemsProvider); + $this->assertInstanceOf(LineItemsProviderInterface::class, $this->lineItemsProvider); + } + + /** + * @throws Exception + */ + public function testGetLineItems(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + $lineItem = []; + $orderItems = new ArrayCollection([ + $orderItemMock, + ]); + $orderMock->expects(self::atLeastOnce())->method('getItems')->willReturn($orderItems); + $this->lineItemProviderMock->expects(self::atLeastOnce())->method('getLineItem')->with($orderItemMock)->willReturn($lineItem); + $this->shippingLineItemProviderMock->expects(self::atLeastOnce())->method('getLineItem')->with($orderMock)->willReturn(null); + $this->assertSame([ + $lineItem, + ], $this->lineItemsProvider->getLineItems($orderMock)); + } + + /** + * @throws Exception + */ + public function testGetEmptyLineItems(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderItems = new ArrayCollection([]); + $orderMock->expects(self::atLeastOnce())->method('getItems')->willReturn($orderItems); + $this->shippingLineItemProviderMock->expects(self::atLeastOnce())->method('getLineItem')->with($orderMock)->willReturn(null); + $this->assertSame([], $this->lineItemsProvider->getLineItems($orderMock)); + } +} diff --git a/tests/Unit/Provider/LinetItemNameProviderTest.php b/tests/Unit/Provider/LinetItemNameProviderTest.php new file mode 100644 index 0000000..4f1232b --- /dev/null +++ b/tests/Unit/Provider/LinetItemNameProviderTest.php @@ -0,0 +1,106 @@ +linetItemNameProvider = new LinetItemNameProvider(); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(LinetItemNameProvider::class, $this->linetItemNameProvider); + $this->assertInstanceOf(LinetItemNameProviderInterface::class, $this->linetItemNameProvider); + } + + /** + * @throws Exception + */ + public function testGetProductAndVariantNameWhenProductHasOptions(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getQuantity')->willReturn(1); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $orderItemMock->expects(self::atLeastOnce())->method('getProductName')->willReturn('My Product'); + $orderItemMock->expects(self::atLeastOnce())->method('getVariantName')->willReturn('variant'); + $productMock->expects(self::atLeastOnce())->method('hasOptions')->willReturn(true); + $this->assertSame('1x - My Product variant', $this->linetItemNameProvider->getItemName($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetProductAndVariantNameWhenProductHasNoOptions(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getQuantity')->willReturn(1); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $orderItemMock->expects(self::atLeastOnce())->method('getProductName')->willReturn('My Product'); + $orderItemMock->expects(self::atLeastOnce())->method('getVariantName')->willReturn('variant'); + $productMock->expects(self::atLeastOnce())->method('hasOptions')->willReturn(false); + $this->assertSame('1x - variant', $this->linetItemNameProvider->getItemName($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetItemNameWithVariantName(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + /** @var ProductInterface&MockObject $productMock */ + $productMock = $this->createMock(ProductInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getQuantity')->willReturn(1); + $orderItemMock->expects(self::atLeastOnce())->method('getProduct')->willReturn($productMock); + $orderItemMock->expects(self::atLeastOnce())->method('getProductName')->willReturn(null); + $orderItemMock->expects(self::atLeastOnce())->method('getVariantName')->willReturn('My variant name'); + $productMock->expects(self::atLeastOnce())->method('hasOptions')->willReturn(false); + $this->assertSame('1x - My variant name', $this->linetItemNameProvider->getItemName($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetItemNameWithProductName(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getQuantity')->willReturn(1); + $orderItemMock->expects(self::atLeastOnce())->method('getProductName')->willReturn('My variant name'); + $orderItemMock->expects(self::atLeastOnce())->method('getVariantName')->willReturn(null); + $this->assertSame('1x - My variant name', $this->linetItemNameProvider->getItemName($orderItemMock)); + } + + /** + * @throws Exception + */ + public function testGetItemNameWithoutVariantNameOrProductName(): void + { + /** @var OrderItemInterface&MockObject $orderItemMock */ + $orderItemMock = $this->createMock(OrderItemInterface::class); + $orderItemMock->expects(self::atLeastOnce())->method('getQuantity')->willReturn(1); + $orderItemMock->expects(self::atLeastOnce())->method('getProductName')->willReturn(null); + $orderItemMock->expects(self::atLeastOnce())->method('getVariantName')->willReturn(null); + $this->assertSame('1x - ', $this->linetItemNameProvider->getItemName($orderItemMock)); + } +} diff --git a/tests/Unit/Provider/ModeProviderTest.php b/tests/Unit/Provider/ModeProviderTest.php new file mode 100644 index 0000000..e066f6b --- /dev/null +++ b/tests/Unit/Provider/ModeProviderTest.php @@ -0,0 +1,39 @@ +modeProvider = new ModeProvider(); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(ModeProvider::class, $this->modeProvider); + $this->assertInstanceOf(ModeProviderInterface::class, $this->modeProvider); + } + + /** + * @throws Exception + */ + public function testGetPaymentMethodTypes(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $this->assertSame(Session::MODE_PAYMENT, $this->modeProvider->getMode($orderMock)); + } +} diff --git a/tests/Unit/Provider/PaymentMethodTypesProviderTest.php b/tests/Unit/Provider/PaymentMethodTypesProviderTest.php new file mode 100644 index 0000000..fe471cc --- /dev/null +++ b/tests/Unit/Provider/PaymentMethodTypesProviderTest.php @@ -0,0 +1,42 @@ +paymentMethodTypesProvider = new PaymentMethodTypesProvider([ + 'card', + ]); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(PaymentMethodTypesProvider::class, $this->paymentMethodTypesProvider); + $this->assertInstanceOf(PaymentMethodTypesProviderInterface::class, $this->paymentMethodTypesProvider); + } + + /** + * @throws Exception + */ + public function testGetPaymentMethodTypes(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $this->assertSame([ + 'card', + ], $this->paymentMethodTypesProvider->getPaymentMethodTypes($orderMock)); + } +} diff --git a/tests/Unit/Provider/ShippingLineItemNameProviderTest.php b/tests/Unit/Provider/ShippingLineItemNameProviderTest.php new file mode 100644 index 0000000..cf721c1 --- /dev/null +++ b/tests/Unit/Provider/ShippingLineItemNameProviderTest.php @@ -0,0 +1,90 @@ +shippingLineItemNameProvider = new ShippingLineItemNameProvider(); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(ShippingLineItemNameProvider::class, $this->shippingLineItemNameProvider); + $this->assertInstanceOf(ShippingLineItemNameProviderInterface::class, $this->shippingLineItemNameProvider); + } + + /** + * @throws Exception + */ + public function testGetItemName(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + /** @var ShipmentInterface&MockObject $shipmentMock */ + $shipmentMock = $this->createMock(ShipmentInterface::class); + /** @var ShippingMethodInterface&MockObject $shippingMethodMock */ + $shippingMethodMock = $this->createMock(ShippingMethodInterface::class); + $shippingMethodMock->expects(self::atLeastOnce())->method('getName')->willReturn('My shipping method'); + $shipmentMock->expects(self::atLeastOnce())->method('getMethod')->willReturn($shippingMethodMock); + $shipments = new ArrayCollection([ + $shipmentMock, + ]); + $orderMock->expects(self::atLeastOnce())->method('getShipments')->willReturn($shipments); + $this->assertSame('My shipping method', $this->shippingLineItemNameProvider->getItemName($orderMock)); + } + + /** + * @throws Exception + */ + public function testGetItemNameWhenThereIsMultipleShipments(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + /** @var ShipmentInterface&MockObject $shipmentMock */ + $shipmentMock = $this->createMock(ShipmentInterface::class); + /** @var ShippingMethodInterface&MockObject $shippingMethodMock */ + $shippingMethodMock = $this->createMock(ShippingMethodInterface::class); + /** @var ShipmentInterface&MockObject $shipment2Mock */ + $shipment2Mock = $this->createMock(ShipmentInterface::class); + /** @var ShippingMethodInterface&MockObject $shippingMethod2Mock */ + $shippingMethod2Mock = $this->createMock(ShippingMethodInterface::class); + $shippingMethodMock->expects(self::atLeastOnce())->method('getName')->willReturn('My shipping method #1'); + $shipmentMock->expects(self::atLeastOnce())->method('getMethod')->willReturn($shippingMethodMock); + $shippingMethod2Mock->expects(self::atLeastOnce())->method('getName')->willReturn('My shipping method #2'); + $shipment2Mock->expects(self::atLeastOnce())->method('getMethod')->willReturn($shippingMethod2Mock); + $shipments = new ArrayCollection([ + $shipmentMock, + $shipment2Mock, + ]); + $orderMock->expects(self::atLeastOnce())->method('getShipments')->willReturn($shipments); + $this->assertSame('My shipping method #1, My shipping method #2', $this->shippingLineItemNameProvider->getItemName($orderMock)); + } + + /** + * @throws Exception + */ + public function testGetItemNameWhenThereIsNoShipments(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $shipments = new ArrayCollection(); + $orderMock->expects(self::atLeastOnce())->method('getShipments')->willReturn($shipments); + $this->assertSame('', $this->shippingLineItemNameProvider->getItemName($orderMock)); + } +} diff --git a/tests/Unit/Provider/ShippingLineItemProviderTest.php b/tests/Unit/Provider/ShippingLineItemProviderTest.php new file mode 100644 index 0000000..a2e0159 --- /dev/null +++ b/tests/Unit/Provider/ShippingLineItemProviderTest.php @@ -0,0 +1,68 @@ +shippingLineItemNameProviderMock = $this->createMock(ShippingLineItemNameProviderInterface::class); + $this->shippingLineItemProvider = new ShippingLineItemProvider($this->shippingLineItemNameProviderMock); + } + + public function testInitializable(): void + { + $this->assertInstanceOf(ShippingLineItemProvider::class, $this->shippingLineItemProvider); + $this->assertInstanceOf(ShippingLineItemProviderInterface::class, $this->shippingLineItemProvider); + } + + /** + * @throws Exception + */ + public function testGetLineItem(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $this->shippingLineItemNameProviderMock->expects(self::atLeastOnce())->method('getItemName')->with($orderMock)->willReturn('My shipping method'); + $orderMock->expects(self::atLeastOnce())->method('getShippingTotal')->willReturn(1000); + $orderMock->expects(self::atLeastOnce())->method('getCurrencyCode')->willReturn('USD'); + $this->assertSame([ + 'price_data' => [ + 'unit_amount' => 1000, + 'currency' => 'USD', + 'product_data' => [ + 'name' => 'My shipping method', + ], + ], + 'quantity' => 1, + ], $this->shippingLineItemProvider->getLineItem($orderMock)); + } + + /** + * @throws Exception + */ + public function testGetLineItemWhenThereIsNoShipping(): void + { + /** @var OrderInterface&MockObject $orderMock */ + $orderMock = $this->createMock(OrderInterface::class); + $orderMock->expects(self::atLeastOnce())->method('getShippingTotal')->willReturn(0); + $this->assertNull($this->shippingLineItemProvider->getLineItem($orderMock)); + } +} diff --git a/tests/Unit/StateMachine/CancelOrderProcessorTest.php b/tests/Unit/StateMachine/CancelOrderProcessorTest.php new file mode 100644 index 0000000..0a98e28 --- /dev/null +++ b/tests/Unit/StateMachine/CancelOrderProcessorTest.php @@ -0,0 +1,80 @@ +commandBusMock = $this->createMock(MessageBusInterface::class); + $this->cancelOrderProcessor = new CancelOrderProcessor($this->commandBusMock); + } + + /** + * @throws Exception + */ + public function testInvokableWhenItIsNew(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $command = new CancelPayment(1); + $this->commandBusMock->expects(self::atLeastOnce())->method('dispatch')->with($command)->willReturn(new Envelope($command)); + $this->cancelOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_NEW); + } + + /** + * @throws Exception + */ + public function testInvokableWhenIsAuthorized(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $command = new CancelPayment(1); + $this->commandBusMock->expects(self::atLeastOnce())->method('dispatch')->with($command)->willReturn(new Envelope($command)); + $this->cancelOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_AUTHORIZED); + } + + /** + * @throws Exception + */ + public function testDoNothingWhenItIsCompleted(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::never())->method(self::anything()); + + $this->cancelOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_COMPLETED); + } + + /** + * @throws Exception + */ + public function testDoNothingWhenItIsRefunded(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::never())->method(self::anything()); + + $this->cancelOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_REFUNDED); + } +} diff --git a/tests/Unit/StateMachine/CaptureAuthorizedOrderProcessorTest.php b/tests/Unit/StateMachine/CaptureAuthorizedOrderProcessorTest.php new file mode 100644 index 0000000..8309584 --- /dev/null +++ b/tests/Unit/StateMachine/CaptureAuthorizedOrderProcessorTest.php @@ -0,0 +1,67 @@ +commandBusMock = $this->createMock(MessageBusInterface::class); + $this->captureAuthorizedOrderProcessor = new CaptureAuthorizedOrderProcessor($this->commandBusMock); + } + + /** + * @throws Exception + */ + public function testInvokable(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $command = new CaptureAuthorizedPayment(1); + $this->commandBusMock->expects(self::atLeastOnce())->method('dispatch')->with($command)->willReturn(new Envelope($command)); + $this->captureAuthorizedOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_AUTHORIZED); + } + + /** + * @throws Exception + */ + public function testDoNothingWhenItIsCompleted(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::never())->method(self::anything()); + + $this->captureAuthorizedOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_COMPLETED); + } + + /** + * @throws Exception + */ + public function testDoNothingWhenItIsRefunded(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::never())->method(self::anything()); + + $this->captureAuthorizedOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_REFUNDED); + } +} diff --git a/tests/Unit/StateMachine/RefundOrderProcessorTest.php b/tests/Unit/StateMachine/RefundOrderProcessorTest.php new file mode 100644 index 0000000..ac19e78 --- /dev/null +++ b/tests/Unit/StateMachine/RefundOrderProcessorTest.php @@ -0,0 +1,56 @@ +commandBusMock = $this->createMock(MessageBusInterface::class); + $this->refundOrderProcessor = new RefundOrderProcessor($this->commandBusMock, false); + } + + /** + * @throws Exception + */ + public function testInvokable(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $paymentMock->expects(self::atLeastOnce())->method('getId')->willReturn(1); + $command = new RefundPayment(1); + $this->commandBusMock->expects(self::atLeastOnce())->method('dispatch')->with($command)->willReturn(new Envelope($command)); + $this->refundOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_COMPLETED); + } + + /** + * @throws Exception + */ + public function testDoNothingWhenItIsDisabled(): void + { + /** @var PaymentInterface&MockObject $paymentMock */ + $paymentMock = $this->createMock(PaymentInterface::class); + $this->refundOrderProcessor = new RefundOrderProcessor($this->commandBusMock, true); + $command = new RefundPayment(1); + $this->commandBusMock->expects($this->never())->method('dispatch')->with($command); + $this->refundOrderProcessor->__invoke($paymentMock, PaymentInterface::STATE_COMPLETED); + } +} diff --git a/translations/messages.de.yaml b/translations/messages.de.yaml new file mode 100644 index 0000000..93affa6 --- /dev/null +++ b/translations/messages.de.yaml @@ -0,0 +1,13 @@ +flux_se_sylius_payum_stripe_plugin: + payum_gateway_factory: + stripe_checkout_session: Stripe Checkout-Session + stripe_js: Stripe JS + form: + gateway_configuration: + stripe: + publishable_key: Öffentlicher Schlüssel + secret_key: Geheimschlüssel + use_authorize: Autorisierung verwenden + webhook_secret_keys: Geheimschlüssel für Webhooks + info: + use_authorize: Wenn eine Zahlung autorisiert wird, garantiert die Bank den Betrag und reserviert ihn bis zu sieben Tage auf der Karte des Kunden. diff --git a/translations/messages.en.yaml b/translations/messages.en.yaml new file mode 100644 index 0000000..4abc596 --- /dev/null +++ b/translations/messages.en.yaml @@ -0,0 +1,16 @@ +flux_se_sylius_payum_stripe_plugin: + payum_gateway_factory: + stripe_checkout_session: Stripe Checkout Session + stripe_js: Stripe JS + form: + gateway_configuration: + stripe: + publishable_key: Publishable key + secret_key: Secret key + use_authorize: Use authorize + webhook_secret_keys: Webhook secret keys + info: + use_authorize: When a payment is authorized, the bank guarantees the amount and holds it on the customer’s card for up to seven days. + webhook_secret_key: Create a new webhook endpoint to generate a new webhook secret key on the Stripe dashboard and listen for several events. + action: + webhook_secret_key: Create a new webhook endpoint. diff --git a/translations/messages.fr.yaml b/translations/messages.fr.yaml new file mode 100644 index 0000000..67543a8 --- /dev/null +++ b/translations/messages.fr.yaml @@ -0,0 +1,16 @@ +flux_se_sylius_payum_stripe_plugin: + payum_gateway_factory: + stripe_checkout_session: Stripe Checkout Session + stripe_js: Stripe JS + form: + gateway_configuration: + stripe: + publishable_key: Clé publique + secret_key: Clé secrète + use_authorize: Utiliser "authorize" + webhook_secret_keys: Clés secrètes du webhook + info: + use_authorize: Lorsqu'un paiement est autorisé, la banque garantit le montant et le conserve sur la carte du client jusqu'à sept jours. + webhook_secret_key: Créez un nouveau webhook endpoint pour créer une clé secrète de webhook sur le tableau de bord Stripe et écoutez plusieurs événements. + action: + webhook_secret_key: Créez un nouveau webhook endpoint. diff --git a/src/Resources/translations/messages.nl.yaml b/translations/messages.nl.yaml similarity index 90% rename from src/Resources/translations/messages.nl.yaml rename to translations/messages.nl.yaml index d271671..840927f 100644 --- a/src/Resources/translations/messages.nl.yaml +++ b/translations/messages.nl.yaml @@ -1,6 +1,6 @@ flux_se_sylius_payum_stripe_plugin: payum_gateway_factory: - stripe_checkout_session: Stripe Checkout Sessie (met SCA-ondersteuning) + stripe_checkout_session: Stripe Checkout Sessie form: gateway_configuration: stripe: diff --git a/src/Resources/translations/validators.de.yaml b/translations/validators.de.yaml similarity index 100% rename from src/Resources/translations/validators.de.yaml rename to translations/validators.de.yaml diff --git a/translations/validators.en.yaml b/translations/validators.en.yaml new file mode 100644 index 0000000..7bd1ef6 --- /dev/null +++ b/translations/validators.en.yaml @@ -0,0 +1,8 @@ +flux_se_sylius_payum_stripe_plugin: + stripe: + webhook_secret_keys: + not_blank: Please enter Stripe webhook secret key. + secret_key: + not_blank: Please enter Stripe secret key. + publishable_key: + not_blank: Please enter Stripe publishable key. diff --git a/src/Resources/translations/validators.fr.yaml b/translations/validators.fr.yaml similarity index 96% rename from src/Resources/translations/validators.fr.yaml rename to translations/validators.fr.yaml index f48f774..605f9b3 100644 --- a/src/Resources/translations/validators.fr.yaml +++ b/translations/validators.fr.yaml @@ -1,7 +1,7 @@ flux_se_sylius_payum_stripe_plugin: stripe: webhook_secret_keys: - not_blank: Veuillez saisir la clé secrète du webhook stripe. + not_blank: Veuillez saisir la clé secrète du webhook Stripe. secret_key: not_blank: Veuillez entrer votre clé secrète Stripe. publishable_key: